【问题标题】:SCons: Dependency cycles?SCons:依赖循环?
【发布时间】:2011-09-12 16:38:28
【问题描述】:

我正在尝试让 SCons 将 Makefile 项目从源目录复制到构建目录并运行一些命令来生成 libmoo.a,但我遇到了依赖循环错误。详情如下:

./S构造:

env = Environment()
Export('env')

dirs = ['.']

variant_dir = 'build'

for dir in dirs:
        SConscript(dir + '/' + 'SConscript', variant_dir=variant_dir + '/' + dir, duplicate=0)

./SConscript:

import os
Import('env')

env.Command(env.Dir('moo2').abspath, env.Dir('#moo').abspath, ["echo copying moo to the build dir", Copy("$TARGET", "$SOURCE")])

env.Command(env.Dir('moo2/Makefile').abspath, env.Dir('moo2').abspath, 'echo would run moo2.configure')

moolib = env.Command(env.Dir('moo2/libmoo.a').abspath, env.Dir('moo2/Makefile').abspath, 'echo would run make')

Default(moolib)

运行 scons 时出错:

scons: *** Found dependency cycle(s):
  build/moo2/Makefile -> build/moo2 -> build/moo2/Makefile
  build/moo2/libmoo.a -> build/moo2 -> build/moo2/Makefile -> build/moo2/libmoo.a

也试过不使用 .abspath,但这应该没关系,对吧?

我没有看到任何循环:

  • build/moo2/libmoo.a 需要 build/moo2/Makefile
  • build/moo2/Makefile 需要 build/moo2
  • build/moo2 需要 (source/)moo

scons 是如何看到一个循环的?似乎认为 build/moo2/Makefile 依赖于 build/moo2/libmoo.a,这不是我打算指定的。

也欢迎任何相关建议:-)

【问题讨论】:

    标签: scons


    【解决方案1】:

    SConscript 中的任何地方都不需要 env.Dir('moo').abspath。所以这会将其更改为:

    Import('env')
    env.Command('moo2', '#moo', ["echo copying moo to the build dir", Copy("$TARGET", "$SOURCE")])
    env.Command('moo2/Makefile', 'moo2', 'echo would run moo2.configure')  # Look Here
    moolib = env.Command('moo2/libmoo.a', 'moo2/Makefile', 'echo would run make')
    Default(moolib)
    

    但这仍然会产生相同的错误:

    scons: *** Found dependency cycle(s):
    build/moo2/Makefile -> build/moo2 -> build/moo2/Makefile
    build/moo2/libmoo.a -> build/moo2/Makefile -> build/moo2/libmoo.a
    

    那是为什么呢? SCons 自动使目录依赖于其中包含的所有文件。 请参阅带有“# Look Here”注释的行。您添加了一个依赖项 moo2/Makefile 现在依赖于 moo2。 moo2 默认依赖于它的所有内容,因此依赖于你的循环。

    那么我们该如何解决呢?

    Import('env')
    env.Install('moo2',Glob('#moo/*'))
    env.Command('moo2/Makefile', env.Glob('moo2/*'), 'echo would run moo2.configure')
    moolib = env.Command('moo2/libmoo.a', 'moo2/Makefile', 'echo would run make')
    Default(moolib)
    

    我已从使用 Copy() 更改为 env.Install()。由于 Copy 未附加到 build Environment() 对象,因此它不会知道变体目录。 Install() 和 Copy() 在功能上是等效的,而 env.Install() 是 env 感知的。 此外,我让它复制/依赖于目录中的所有文件,而不是目录本身。

    现在让我们试一试:

    /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/bdbaddog/devel/scons/trunk/bootstrap/src/script/scons.py --tree=prune
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    Install file: "moo/abc.c" as "build/moo2/abc.c"
    Install file: "moo/configure" as "build/moo2/configure"
    Install file: "moo/def.c" as "build/moo2/def.c"
    echo would run moo2.configure
    would run moo2.configure
    echo would run make
    would run make
    +-build/moo2/libmoo.a
      +-build/moo2/Makefile
      | +-build/moo2/abc.c
      | | +-moo/abc.c
      | +-build/moo2/configure
      | | +-moo/configure
      | +-build/moo2/def.c
      | | +-moo/def.c
      | +-/bin/echo
      +-/bin/echo
    scons: done building targets.
    

    注意“--tree=prune”这个标志将使SCons打印出依赖树并修剪树中的重复项(所以如果2个文件依赖于同一个文件树,你只会看到一次)

    【讨论】:

    • 感谢您的帖子。太简单地将一些文件复制到我的变体目录中,一个包含两个命令的 SConscript 文件对我有用: Import('env') env.Install( '', Glob('#kernels/*.cl' ) )
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    • 2010-09-12
    • 2021-10-02
    • 1970-01-01
    相关资源
    最近更新 更多