SCons:依赖周期



我试图让SCons将Makefile项目从源目录复制到构建目录,并运行一些命令来生成libmoo。a,但是我遇到了一个依赖循环错误。细节如下:

。/SConstruct:

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: *** 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,但这应该无关紧要,对吗?

我没有看到任何循环:

  • 构建/moo2/libmoo。a需要build/moo2/Makefile
  • build/moo2/Makefile需要build/moo2
  • build/moo2 required (source/)moo

scons是如何看到周期的?它似乎认为build/moo2/Makefile依赖于build/moo2/libmooo。a,这不是我想指定的。

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

不需要env.Dir('moo')。在你征兵的任何地方。所以它会变成:

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()改为使用envy . install()。由于Copy没有附加到build Environment()对象,因此它不会知道变量dir。Install()和Copy()在功能上是等同的,其中env.Install()是环境感知的。此外,我让它复制/依赖于目录中的所有文件,而不是目录本身。

现在让我们试一下:

/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打印出依赖树并修剪树中的重复项(因此,如果两个文件依赖于相同的文件树,您将只看到它一次)

最新更新