scons建设环境继承

Ted*_*ton 5 c c++ python build scons

我在基于scons重构构建系统时遇到了一些问题.我们有一个C/C++源代码树,它包含几个不同的输出对象(dll,可执行文件,测试可执行文件),以及我们的源文件的某种异构布局(尽管它大多数位于带有src/inc/目录的'module' 目录中).

当前设置的一个最大问题是我们真的希望所有这些构建产品默认使用一致的编译器选项构建.我们当前的布局有一个主SConstruct文件,在子目录中调用许多子SConscript文件,然后构建更大的构建产品(.a例如).默认情况下,SConscript()scons中的函数不会将当前构造环境对象传递或继承到被调用的SConstruct文件.这意味着目前所有这些子SConstript文件都使用自己不同的构造环境.

我正在尝试组合的新布局有一个主构建环境,它在源树根处放在一起,包含我们需要的所有必需的CFLAGS和构建定义.我想这样的施工环境要传递到子SConscript文件,使我知道,每一个.c.cpp我们构建树文件正在建有相同的命令行.

不过,我不确定如何在scons中这样做.有Import()Export()函数,但那些基本上是丑陋的全局变量 - 调用SConstruct文件没有很多控制子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
Run Code Online (Sandbox Code Playgroud)

我知道我可以做一些笨拙的事情,有点像这样:

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' ) 
Run Code Online (Sandbox Code Playgroud)

这样做有一种优雅的方式吗?

更新:

所以我已经玩了更多这个,看起来只要我在主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 )
Run Code Online (Sandbox Code Playgroud)

然后在 somelib/SConscript

Import( 'env' )
env.Append( CXXFLAGS=['-weirdoption1', ... ] )
lib = env.StaticLibrary( 'somelib', source=['source1.cpp', 'source2.cpp', ...] )
Return( "lib" )
Run Code Online (Sandbox Code Playgroud)

然后master_env在主SConstruct中没有被污染.对我来说这项Export( env=env.Clone() )工作很重要,因为我不想依赖所有子SConscripts来执行安全 - 克隆() - 该策略应该是父SConscript/SConstruct文件.

但是,必须env通过政策作为参数名称有点难看.

Tom*_*Tom 7

我所知道的最好的方法是从您的主SConstruct中执行此操作:

env = Environment()

env.SConscript('src/SConscript', 'env')
Run Code Online (Sandbox Code Playgroud)

然后在你的src/SConscript文件中:

Import('env')
Run Code Online (Sandbox Code Playgroud)

然后,您可以像在SConstruct文件中一样引用env变量.如果您不想在src/SConscript中改变SConstruct的env,请在导入后将其放入:

env = env.Clone()
Run Code Online (Sandbox Code Playgroud)

很确定这就是它的全部.