如何在分层Scons版本的子目录之间传递构造变量

时间:2019-07-17 13:53:16

标签: scons

我正在尝试构建一个包含多个库和可执行程序的C ++模块。

基本(目录)结构如下:

module
module/lib1
module/lib2
module/prog1
module/prog2

让我们假设prog1仅使用lib1,而prog2同时使用lib1和lib2。两个库都需要 某些附加的构造变量,例如包含和库路径,预处理器定义等。

我正在寻找一种方法,使lib *目录中的SConscript文件可以指定 必须使用这些库将它们添加到程序的构建环境中。

下面是scons文档的14.5章(为简单起见,仅使用CPPDEFINES):

模块/ SConstruct:

env = Environment();
env.Append(CPPDEFINES = 'GLOBAL_DEFINE')

Export('env')

use_lib1 = SConscript(['lib1/SConscript'])
use_lib2 = SConscript(['lib2/SConscript'])

Export('use_lib1', 'use_lib2')

SConscript(['prog1/SConscript'])
SConscript(['prog2/SConscript'])

module / lib1 / SConscript:

Import ('*')

def use_lib1(i_environment):
    i_environment.Append(CPPDEFINES = 'DEFINE_FOR_LIB1')

Return('use_lib1')

module / lib2 / SConscript:

Import ('*')

def use_lib2(i_environment):
    i_environment.Append(CPPDEFINES = ['DEFINE_FOR_LIB2'])

Return('use_lib2')

module / prog1 / SConscript:

Import ('*')

prog1_env = env.Clone()

use_lib1(prog1_env)

print "PROG1: CPPDEFINES = " + str(prog1_env['CPPDEFINES'])

module / prog2 / SConscript:

Import ('*')

prog2_env = env.Clone()

use_lib1(prog2_env)
use_lib2(prog2_env)

print "PROG2: CPPDEFINES = " + str(prog2_env['CPPDEFINES'])

此设置似乎可以正常运行,但也有点麻烦。

问题:还有没有更简单的方法可以实现期望的目标?

1 个答案:

答案 0 :(得分:1)

您可以使用PseudoBuilder将use_lib1添加到您的环境中。

请参阅:https://scons.org/doc/production/HTML/scons-user/ch20.html

这将消除传递use_lib1等的需要。

您可以执行以下操作:

Import ('*')

env.Program('myprogram',['source1.c','source2.c'],CPPDEFINES=env['CPPDEFINES']+env.lib1_cppdefines()+env.lib2_cppdefines())

您可以定义一个PseudoMethod来在将每个库添加到env的地方做更多的事情:

env['LIB1_CPPDEFINES']=['LIB1','LIB1_AWESOME']
env['LIB1_LIBS']=['LIB1','LIB1_AWESOME']

然后是PseudoBuilder(在您的SConstruct中,或者在site_scons / site_init.py中为逻辑):

def LibProgram(env, target, sources, libs=None):
    LIBS=env.get('LIBS',[])
    CPPDEFINES=env.get('CPPDEFINES',[])
    for lib in libs:
       LIBS.extend(env.get('%s_LIBS'%lib,[])
       CPPDEFINES.extend(env.get('%s_CPPDEFINES'%lib,[])

    return env.Program(target,sources, CPPDEFINES=CPPDEFINES, LIBS=LIBS)

env.AddMethod(LibProgram, "LibProgram")

那么您的prog2 / SConscript将是:

Import ('*')
env.LibProgram('prog2',prog2_sources,libs=['lib1','lib2'])

有很多不同的方法可以减少冗长的SConscripts。