【问题标题】:Tell SCons not to auto-create directories?告诉 SCons 不要自动创建目录?
【发布时间】:2013-08-02 19:57:16
【问题描述】:

我正在尝试让 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/scripts> /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')

有没有更好的处理方法?

【问题讨论】:

    标签: scons


    【解决方案1】:

    由于无法告诉git 目录确实是空的(即使它有空的子目录),我们也无法弄清楚如何告诉SCons 不要自动创建子目录,您可以创建您自己的依赖项检查并使用SCons Execute() 函数调用git clone,该函数在执行任何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)
    

    【讨论】:

      【解决方案2】:

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

      这意味着您的第一次尝试将通过简单地创建目录来创建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(即在 Brady 的回答中使用 Execute 函数)。

      【讨论】:

        猜你喜欢
        • 2012-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-22
        • 1970-01-01
        相关资源
        最近更新 更多