如何在分层 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 来做到这一点。
我正在尝试构建一个包含多个库和可执行程序的 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 来做到这一点。