我有一个C ++ / Python项目,我一直在努力,到目前为止依靠Visual Studio来管理构建。现在我想自动化构建过程,希望包含多个平台支持(它是所有标准的C ++ / Python),并认为SCons可以成为完成这项工作的工具。
在多个目录中涉及很多源文件,但(立体声)典型示例如下:
foo.lib
directory_1
bar1_1.cpp
bar1_2.cpp
... etc. ...
directory_2
bar2_1.cpp
bar2_2.cpp
... etc. ...
因此,换句话说,源文件位于层次结构中,但只有一个目标。 (层次结构在代码中使用的命名空间中匹配,但这对于此问题而言是多余的。)
我的问题是:构建SConstruct和SConscript文件的最佳方法是什么?我阅读了SCons文档,特别是Hierarchical Builds部分以及使用具有合适的'SConscript'调用的多个SConscript文件的想法。一切似乎都很清楚,特别整洁。但是,它似乎适用于具有多个目标的层次结构。在只有一个目标的情况下,我可以使用同样的功能吗?
(我确实想到了一个顶级的SConstruct / SConscript文件,至少对于有问题的库来说,列出了所有带有子目录的源文件,但没有“感觉”这是最好的方法。也许这确实是前进的方向?)
非常感谢任何建议/见解。
答案 0 :(得分:5)
我有几次使用层次解决方案,就像你描述的那样。我选择了这样的解决方案:
SConscript中的:
#/bar/SConscript
Import("env")
env = specialize_env_for_this_subpackage()
myfiles = Glob(*.cpp)
apply_any_exclusions(myfiles)
myobjects = env.Object(myfiles)
Return(myobjects)
然后在SConstruct中:
#SConstruct
env = construct_general_environment()
subpackages = ["foo","bar","baz"] #or perhaps call your own find_subproject() function
objects = SCons.Node.NodeList
for package in subpackages:
pack_objects = env.SConscript(os.path.join(package,"SConscript"), exports = env)
objects.extend(pack_objects)
program = env.Program("myprog",objects)
Default(program)
然后你可以很好地控制每个包中的环境,并且巧妙地使用* site_scons *文件夹,你可以防止为每个sconscript反复重复相同的行。这种方法的另一个优点是scons文件反映了设计。我也更喜欢使用 Glob 来收集cpp文件,允许我按照自己喜欢的方式添加和删除文件,而无需为这些简单的操作编辑任何构建文件。
答案 1 :(得分:0)
将所有源文件列在一个SConstruct
文件中没有任何问题。层次结构化SConscripts也很好,但是你需要从每一层返回对象,这会有点傻:
# SConscript, for example
sources = ["bar1_1.cpp", "bar1_2.cpp", ...]
objects = [env.Object(x) for x in sources]
Return(objects)
# SConstruct (top-level)
directory_1_objects = SConscript("directory_1/SConscript")
directory_2_objects = SConscript("directory_2/SConscript")
program = env.Program("magical_wonders", [directory_1_objects, directory_2_objects])
在我看来,特定二进制文件中所有源文件的单个顶级栅格比这更好,这需要在文件层次结构发生变化时进行更多布线。