为什么SCons的VariantDir()不将输出放在指定目录中?
我在考虑用SCons来做一个新项目。这个工具看起来不错,不过我对VariantDir
有点搞不懂。
我的项目很简单,只有几个C语言源文件在一个文件夹里。我想要在“正常”和“配置”模式下构建,也就是用两套不同的gcc选项。我希望输出的文件分别放在normal/和profile/这两个文件夹里。
为了测试,我把项目简化成只有一个源文件t.c,里面有一个main()
函数。我的
normal = DefaultEnvironment(tools=['mingw'], CCFLAGS = '-O2')
normal.VariantDir('release', '.', duplicate=0)
normal.Program('t', ['t.c'])
#profile = normal.Clone(CCFLAGS='-O2 -pg', LINKFLAGS = '-pg')
#profile.VariantDir('profile', '.', duplicate=0)
#profile.Program('t', ['t.c'])
当我运行scons的时候,我希望它把t.o和t.exe放到release/文件夹里,但它却把它们放在了当前目录。而且如果我把3行配置的代码取消注释,我根本无法运行,出现这个错误:
scons: *** 为同一个目标t.o指定了两个不同操作的环境。
总之,我不明白为什么我的VariantDir()调用没有告诉scons把输出放到指定的输出目录release
里。
(我看了不少文档和讨论组的内容,但没有找到能解答这个问题的。最接近的一个是这个页面,它描述了类似的情况,但涉及到一个单独的src/文件夹和两个不同的scons文件,还要在它们之间导入/导出变量。这看起来不太方便。)
3 个回答
正如这个链接所说,
请注意,当你没有在src子目录中使用SConscript文件时,你必须明确告诉程序,它需要从build/hello.c文件构建,而这个文件会在build子目录中被SCons复制。
VariantDir('release','.',duplicate=0)
env=Environment()
env.Program('release/t',['release/t.c'])
当我在Linux上运行这个命令
scons -u .
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: release
gcc -o release/t.o -c t.c
gcc -o release/t release/t.o
scons: done building targets.
我想在Win32上也能正常工作。
我可以通过这个方法把构建目录里的二进制文件分开:
# SConstruct
SConscript('SConscript', variant_dir='build', src_dir='..', duplicate=0)
如果你想把二进制文件放到比当前目录低两个层级的地方,可以这样做:
# SConstruct
SConscript('SConscript', variant_dir='build/release', src_dir='../..', duplicate=0)
简单来说,你需要把src_dir
这个参数设置为从你的构建目录回到源代码目录的路径。
没错,VariantDir在scons中确实让人困惑。虽然这个信息没有被广泛宣传,但你可以把SConstruct和SConscript放在同一个文件夹里,这样就可以用当前文件夹作为源文件夹。
# SConstruct
SConscript('SConscript', build_dir='build', src='.')
而且
# SConscript
Program('main.c')
我从来没找到过不使用两个文件的方法,同时还能保持理智去理解variant dir :)