SCons: 在单个SConscript文件中使用不同的variant_dir
我需要使用scons来为一个大型项目生成发布版和调试版的构建。在发布版和调试版中,它会生成共享库和静态库。构建完成后,目录结构应该如下所示:
project_dir/
|_ src
|_ include
|_ lib
|_ lib_rel
|_ lib_dbg
|_ dll
|_ dll_rel
|_ dll_dbg
我该如何实现SConstruct和SConscript,以满足上述要求呢?
SConstruct的实现:
env = Environment()
relEnv = env.clone(CCFLAGS = ['-O3', '-pthread')]
dbgEnv = env.clone(CCFLAGS = ['-O0', '-g', '-pthread')]
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : relEnv}, variant_dir = 'lib_rel', duplicate = 0)
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : dbgEnv}, variant_dir = 'lib_dbg', duplicate = 0)
src/SConscript的实现:
Import('env')
src_list = Glob('*.cpp')
inc_list = ['dir_1/include', 'dir_2/include', 'common/include']
env.SharedLibrary(target = 'foo', source = src_list, CPP_PATH=inc_list)
env.StaticLibrary(target = 'foo', source = src_list, CPP_PATH=inc_list)
使用上述实现,可以在lib_rel文件夹中生成共享库和静态库,以及相关的目标文件。有没有办法让我使用变体目录,使得对于共享库,它的目标目录为{dll/lib_rel, dll/lib_dbg},而对于静态库,它的变体目录为{lib/lib_rel, lib/lib_dbg}?
一种可能的方法是为共享库和静态库分别使用不同的SConscript。但这样做很麻烦,因为每种库构建方法都需要两个不同的文件。
请给出合适的解决方案。
2 个回答
0
SConstruct
env = Environment()
relEnv = env.clone(CCFLAGS = ['-O3', '-pthread')]
dbgEnv = env.clone(CCFLAGS = ['-O0', '-g', '-pthread')]
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : relEnv, 'BUILD_TYPE'='rel'}, variant_dir = 'lib_rel', duplicate = 0)
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : dbgEnv, 'BUILD_TYPE'='dbg'}, variant_dir = 'lib_dbg', duplicate = 0)
SConscript
Import('env')
src_list = Glob('*.cpp')
inc_list = ['dir_1/include', 'dir_2/include', 'common/include']
env.SharedLibrary(target = '#/lib/lib_${BUILD_TYPE}/foo', source = src_list, CPP_PATH=inc_list)
env.StaticLibrary(target = '#/lib/lib_${BUILD_TYPE}/foo', source = src_list, CPP_PATH=inc_list)
应该可以用。还没试过。
1
我会把“静态”和“调试”看作两个不同的方面,然后调用四次SConscript,像这样:
env = Environment()
relEnv = env.Clone(CCFLAGS = ['-O3', '-pthread'])
dbgEnv = env.Clone(CCFLAGS = ['-O0', '-g', '-pthread'])
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : relEnv, 'Library' : relEnv.StaticLibrary}, variant_dir = 'lib/lib_rel', duplicate = 0)
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : dbgEnv, 'Library' : dbgEnv.StaticLibrary}, variant_dir = 'lib/lib_dbg', duplicate = 0)
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : relEnv, 'Library' : relEnv.SharedLibrary}, variant_dir = 'dll/dll_rel', duplicate = 0)
SConscript(dirs = 'src', name = 'SConscript', exports = {'env' : dbgEnv, 'Library' : dbgEnv.SharedLibrary}, variant_dir = 'dll/dll_dbg', duplicate = 0)
当然,这样写起来很麻烦,所以我其实会用一个循环来简化:
env = Environment()
relEnv = env.Clone(CCFLAGS = ['-O3', '-pthread'])
dbgEnv = env.Clone(CCFLAGS = ['-O0', '-g', '-pthread'])
for env, envPath in ((relEnv, 'rel'), (dbgEnv, 'dbg')):
for lib, libPath in ((env.StaticLibrary, 'lib'), (env.SharedLibrary, 'dll')):
SConscript(dirs = 'src',
name = 'SConscript',
exports = {'env' : env, 'Library' : lib},
variant_dir = '{libPath}/{libPath}_{envPath}'.format(**locals()),
duplicate = 0)
SConscript需要导入Library
,这点是必须的:
Import('env', 'Library')
src_list = Glob('*.cpp')
inc_list = ['dir_1/include', 'dir_2/include', 'common/include']
Library(target = 'foo', source = src_list, CPP_PATH=inc_list)