问题
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.shFile "/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