我正在尝试让SCons将源文件从源目录复制到构建目录并运行一些命令来生成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时出错:
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,但这不重要,对吗?
我没有看到任何周期:
scons如何看待一个循环?似乎认为build / moo2 / Makefile依赖于build / moo2 / libmoo.a,这不是我想要指定的。
也欢迎任何相关的建议: - )
答案 0 :(得分:5)
你的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未附加到构建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个文件依赖于同一个文件树,你只会看到一次)