4

我正在尝试让 SCons 检查出我需要的 git 存储库(并希望使该存储库保持最新)。问题是我必须告诉它 git repo 包含哪些文件才能在构建中使用它们,如果我这样做,SCons 将在尝试克隆它之前创建 repo。

例如,假设我想克隆 GStreamer,并使用create-uninstalled-setup.sh脚本(这不是我实际在做的事情,但它是一个更简单/更快的脚本,会出现同样的问题):

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')

但它失败了,因为 SCons 在尝试克隆 gstreamer 之前创建了 gstreamer/脚本:

$ scons
scons: 读取 SConscript 文件 ...
scons: 完成读取 SConscript 文件。
scons:构建目标...
git clone git://anongit.freedesktop.org/git/gstreamer/gstreamer
致命:目标路径“gstreamer”已经存在并且不是空目录。
scons: *** [gstreamer/.git] 错误 128
scons: 构建因错误而终止。
$ ls gstreamer/
脚本

如果我告诉第一个命令它创建了“gstreamer”文件夹,它会创建一个依赖循环:

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: 读取 SConscript 文件 ...
scons: 完成读取 SConscript 文件。
scons:构建目标...
scons:完成构建目标。

scons: *** 找到依赖循环:
gstreamer/scripts -> gstreamer/scripts/create-uninstalled-setup.sh -> gstreamer/scripts
gstreamer/scripts/create-uninstalled-setup.sh -> gstreamer/scripts - > gstreamer/脚本> /create-uninstalled-setup.sh

清理中的文件“/usr/lib/scons/SCons/Taskmaster.py”,第 1019 行

如果我不告诉第一个命令它创建“create-uninstalled-setup.sh”,它会因为它不存在而感到困惑:

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: 读取 SConscript 文件 ...
scons: 完成读取 SConscript 文件。
scons:构建目标 ...
scons:*** [~/gst/git] 源 `gstreamer/scripts/create-uninstalled-setup.sh' 未找到,目标 `~/gst/git' 需要。
scons:建筑因错误而终止。

作为一种解决方法,我可以rm -rf在克隆之前创建文件夹,但这显然并不理想:

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')

有没有更好的方法来处理这个?

4

2 回答 2

3

由于无法判断git该目录确实是空的(即使它有空的子目录),并且我们无法弄清楚如何告诉SCons不要自动创建子目录,您可以创建自己的依赖项检查并git clone使用该SCons Execute()函数调用,在执行任何SCons内置依赖检查之前执行,如下所示:

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)
于 2013-08-04T19:35:32.587 回答
-1

发生的事情以及似乎是问题在于,在准备构建目标期间,如果它们不存在,则会创建直到它的所有目录。这似乎是通过构建目录节点来完成的,默认情况下只通过创建目录来完成。

这意味着您的第一次尝试将gstreamer通过简单地创建目录来创建目录。你第二次尝试失败的原因我真的不知道。第三是因为你根本没有规则来构建gstreamer/scripts/create-uninstalled-setup.sh

一个解决方案似乎是定义一个构建gstreamer目录的规则:

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

然后创建一个规则gstreamer/scripts/create-uninstalled-setup.sh。理想情况下,我想将它包含在上述规则中,但它似乎不起作用。但是,由于它将gstreamer在上述规则创建目录时创建,因此您只需要一个虚拟规则(没有依赖关系,无需进一步操作 - 构建它的准备工作就可以完成):

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

这种方法的缺点是它需要在 git 中找到的每个源都必须明确地告诉scons这些,至少我没有找到自动执行此操作的方法。如果这对您来说是个问题,您必须确保在SConstruct读取文件时克隆 git(即使用ExecuteBrady 回答中的函数)。

于 2015-11-09T08:53:15.620 回答