我在重构基于 scons 的构建系统时遇到了一些问题。我们有一个 C/C++ 源代码树,其中包含几个不同的输出对象(dll、可执行文件、测试可执行文件),以及我们的源文件的某种异构布局(尽管其中大部分位于带有src/
和inc/
目录的“模块”目录中)。
我当前设置的最大问题之一是,我们真的希望所有这些构建产品在默认情况下都使用一致的编译器选项构建。我们当前的布局有一个主 SConstruct 文件调用子目录中的许多子 SConscript 文件,然后构建更大的构建产品的片段(.a
例如 's )。默认情况下,SConscript()
scons 中的函数不会将当前的构建环境对象传递或继承给被调用的 SConstruct 文件。这意味着目前所有这些子 SConstript 文件都在使用自己不同的构建环境。
我试图组合的新布局有一个主构建环境,它与我们需要的所有必要的 CFLAGS 和构建定义一起放在源树根目录中。我希望将此构建环境传递给子 SConscript 文件,以便我知道构建树中的每个文件.c
和文件都是使用相同的命令行构建的。.cpp
不过,我不确定如何在 scons 中执行此操作。有Import()
and函数,但这些基本上是丑陋的全局变量——调用 SConstruct 文件对子 SConstruct 文件对被'edExport()
的全局变量所做的事情没有太多控制。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" )
然后master_env
主 SConstruct 中的 未受污染。这项Export( env=env.Clone() )
工作对我来说很重要,因为我不想依赖所有子 SConscript 来执行安全克隆()-该策略应该是父 SConscript/SConstruct 文件。
env
尽管如此,必须通过策略将其作为参数名称还是有点难看。