Tell SCons not to auto-create directories?

隐身守侯 提交于 2020-01-24 09:39:08

问题


I'm trying to make SCons check out a git repo that I need (and hopefully keep that repo up-to-date). The problem is that I have to tell it which files the git repo contains for it to use them in the build, and if I do that, SCons will create the repo before it tries to clone it.

For example, say I want to clone GStreamer, and use the create-uninstalled-setup.sh script (this isn't what I'm actually doing, but it's a much simpler/faster script that exibits the same problem):

Command(['gstreamer/.git', 'gstreamer/scripts/create-uninstalled-setup.sh'],
    None, 'git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer')
Command('~/gst/git', 'gstreamer/scripts/create-uninstalled-setup.sh',
    'gstreamer/scripts/create-uninstalled-setup.sh')

But it fails because SCons creates gstreamer/scripts before it tries to clone gstreamer:

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer
fatal: destination path 'gstreamer' already exists and is not an empty directory.
scons: *** [gstreamer/.git] Error 128
scons: building terminated because of errors.
$ ls gstreamer/
scripts

If I tell the first command that it creates the "gstreamer" folder, it creates a dependency cycle:

Command(['gstreamer', 'gstreamer/scripts/create-uninstalled-setup.sh'],
    None, 'git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer')
Command('~/gst/git', 'gstreamer/scripts/create-uninstalled-setup.sh',
    'gstreamer/scripts/create-uninstalled-setup.sh')

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: done building targets.

scons: *** Found dependency cycle(s):
gstreamer/scripts -> gstreamer/scripts/create-uninstalled-setup.sh -> gstreamer/scripts
gstreamer/scripts/create-uninstalled-setup.sh -> gstreamer/scripts -> gstreamer/scripts> /create-uninstalled-setup.sh

File "/usr/lib/scons/SCons/Taskmaster.py", line 1019, in cleanup

If I don't tell the first command that it creates "create-uninstalled-setup.sh", it gets confused because it doesn't exist:

Command(['gstreamer'],
    None, 'git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer')
Command('~/gst/git', 'gstreamer/scripts/create-uninstalled-setup.sh',
    'gstreamer/scripts/create-uninstalled-setup.sh')

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: *** [~/gst/git] Source `gstreamer/scripts/create-uninstalled-setup.sh' not found, needed by target `~/gst/git'.
scons: building terminated because of errors.

As a workaround, I can rm -rf the folder before I clone, but that's obviously not ideal:

Command(['gstreamer/.git', 'gstreamer/scripts/create-uninstalled-setup.sh'], None,
    'rm -rf gstreamer && git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer')
Command('~/gst/git', 'gstreamer/scripts/create-uninstalled-setup.sh',
    'gstreamer/scripts/create-uninstalled-setup.sh')

Is there a better way of handling this?


回答1:


Since there is no way to tell git that the dir is indeed empty (even though it has empty subdirs), and we cant figure out how to tell SCons not to auto-create the subdirs, you could create your own dependency check and call git clone with the SCons Execute() function, which is executed before any SCons builtin dependency checking is performed, as follows:

import os.path

setup_file = 'gstreamer/scripts/create-uninstalled-setup.sh'
if not os.path.exists(setup_file)
    Execute('git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer')

Command('~/gst/git', setup_file, setup_file)



回答2:


What happens and what seem to be the problem is that during preparing to build a target all the directory up to it is created if they don't exist. This seem to be done by building the directory node which by default is done by just creating the directory.

This means that your first try will create the gstreamer directory by simply creating the directory. The reason your second try fails I really don't know. And the third is because you simply has no rule to build gstreamer/scripts/create-uninstalled-setup.sh.

A solution seem to be to define a rule that builds the gstreamer directory:

Command(Dir("gstreamer"), [], "git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer")

then a rule to create gstreamer/scripts/create-uninstalled-setup.sh. Ideally I'd like to include it in the above rule, but it doesn't seem to work. However since it will be created when the gstreamer directory is being created by the above rule you only need a dummy rule (no dependencies, no further action - the preparation to build it will do the work):

Command("gstreamer/scripts/create-uninstalled-setup.sh", [], [])

The drawback with this approach is that it would require every source found in the git would have to be explicitely tell scons about these, at least I've found no way to do this automatically. If this is a problem to you you would have to make sure you clone the git when the SConstruct file is being read (ie use the Execute function as in Brady's answer).



来源:https://stackoverflow.com/questions/18025187/tell-scons-not-to-auto-create-directories

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!