我有一个问题,重构基于scons的构建系统。我们有一个包含几个不同输出对象(dll,可执行文件,测试可执行文件)的C/C++源代码树,以及我们的源文件(尽管它大部分位于具有src/
和inc/
目录的'模块'目录)中有点异构的布局。scons建设环境继承
当前设置的一个最大问题是,我们真的希望所有这些构建产品都默认使用一致的编译器选项进行构建。我们目前的布局有一个主SConstruct文件,在子目录中调用许多子SConscript文件,然后构建更大的构建产品(例如.a
)。默认情况下,scons中的SConscript()
函数不会将当前构造环境对象传递或继承到被调用的SConstruct文件。这意味着目前所有这些sub-SConstript文件都使用他们自己的不同构建环境。
我试图放在一起的新布局有一个主要的构建环境放在一起在源代码树根与所有必要的CFLAGS和构建定义我们需要。我希望将这个构建环境传递给sub-SConscript文件,以便我知道构建树中的每个文件.c
和.cpp
都使用相同的命令行构建。
虽然我不确定如何在scons中做到这一点。有Import()
和Export()
函数,但这些基本上都是丑陋的全局变量 - 调用的SConstruct文件对子文件结构文件对Export()
编辑的全局变量所做的操作没有太多控制权。是否有任何干净的方式,基本上把当前的施工环境作为参数传递给子SConscript文件,而不必让它修改它呢?可能的东西喜欢:
master_env = Environment()
master_env.Append(CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ])
### add other stuff that we want everything to use
SConscript('somelibrary/SConstruct', inherited_environment=master_env.Clone())
### master_env has now been used to build a
### .dll in somelibrary/, but any variations
### made to somelibrary/SConstruct's inherited
### env haven't contaminated master_env
我知道我可以做这样的事情笨拙和排序总值:
clobber_env = Environment()
master_env = Environment()
master_env.Append(CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ])
call_somelibrary_sconstruct(master_env)
def call_somelibrary_sconstruct(env):
param_env = env.Clone()
Export('param_env')
SConstript('somelibrary/SConstruct')
# because we don't want any contamination of our global variable
# between SConscript calls. I'm not even sure if this is necessary
# or does what I think it does because I'm not sure how this ugly
# Export()'d global variable environment works with locals like
# param_env here.
param_env = clobber_env
Export('param_env')
是否有这样做的一个优雅的方式?
更新:
所以我这个多一些玩耍了,它看起来像我只要做到这一点在主SConstruct文件:
def build_somelib(env):
Export(env=env.Clone())
somelib = SConscript('somelib/SConscript')
return somelib
master_env = Environment()
master_env.Append(CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ])
build_somelib(master_env)
,然后在somelib/SConscript
Import('env')
env.Append(CXXFLAGS=['-weirdoption1', ... ])
lib = env.StaticLibrary('somelib', source=['source1.cpp', 'source2.cpp', ...])
Return("lib")
那么主SCONStruct中的master_env
未被污染。 Export(env=env.Clone())
对我来说很重要,因为我不想依赖所有的子SConscripts来执行安全性克隆() - 该策略应该是父SConscript/SConstruct文件。
但是,根据策略,必须将env
作为参数名称有点难看。
谢谢汤姆。有一点需要补充:如果'env'不一定是第二个参数,则可以使用语法:'exports ='env''。 – 2013-11-14 23:48:09
不幸的是,这仍然留下克隆到子模块的自由裁量权,所以不能保证下一个模块会这样做。 – 2016-02-17 05:18:53