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

How to pass construction variables between subdirectories in hierarchical Scons builds

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

基本(目录)结构如下:

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

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

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

这是我现在所拥有的,遵循 scons 文档的第 14.5 章(为简单起见,仅使用 CPPDEFINES):

module/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'])

这个设置似乎工作正常,但也有点麻烦。

问题:有没有更直接的方法达到预期目标?

您可以使用 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 来做到这一点。