SCons设置用于分层源但单个目标

5

我有一个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文档,特别是分层构建部分,并考虑使用适当的“SConscript”调用多个SConscript文件的想法。一切清晰明了,尤其是整齐。然而,看起来这是为具有多个目标的层次结构而设计的。在只有一个目标文件的情况下,我能否使用同样的功能?
(我确实考虑过顶层SConstruct / SConscript文件,至少对于所涉及的库,列出所有子目录的源文件,但这不是最佳方法。也许这确实是前进的方法?)
非常感谢您提供的任何建议/见解。
2个回答

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文件反映了设计。我还喜欢使用来收集cpp文件,允许我根据需要添加和删除文件,而无需编辑任何构建文件以进行此类琐碎操作。


谢谢!我今晚打算试一下,我认为这几乎就是我要找的东西。唯一未解决的问题是更改特定文件的构建标志(以禁用包括第三方库生成的警告等)。不过我可以容忍这些警告... - bitcyber
在更改环境时,请记得进行深拷贝,否则更改将影响后续的程序包。env.Clone() 可以很好地复制环境。 - daramarak
是的 - 很好的观点!当然我立刻就遇到了这个问题 :-) 。你的评论证实了我错在哪里。 - bitcyber

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])

在我看来,一个特定二进制文件中所有源文件的单个顶级光栅比这更可取,因为当文件层次结构发生变化时需要更多的布线。

谢谢!这确实突出了一个我在文档中显然跳过(或误解)的功能。我的请求源于我想处理的两种情况: i)选择性包含某些文件;和 ii)为单个文件指定不同的构建标志。经过审查,情况(i)实际上是我懒惰的一个例子。现在我只剩下情况(ii)-一个例子是禁用特定文件的警告,但不在全局范围内禁用它。(我希望通过适当的环境处理在特定的SConscript文件中处理此问题。虽然我可能又走错了路线...) - bitcyber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接