SCons:单个SConscript文件中的variant_dir不同

时间:2014-06-19 06:15:39

标签: python c++ build scons build-tools

我需要使用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文件夹中的共享和静态库以及相关的目标文件,有没有办法可以使用变量目录,对于SharedLibrary,它使用目标目录为{dll / lib_rel,dll / lib_dbg}和StaticLibrary方法,它使用variant_dir作为{lib / lib_rel,lib / lib_dbg}

可能的一种方法是为SharedLibrary和StaticLibrary分别使用SConscript。但这是非常典型的,每个库构建器方法都需要两个不同的文件。

请建议妥善解决此问题。

2 个答案:

答案 0 :(得分:1)

我会将Static-ness和Debug-ness视为两个维度,并将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)

答案 1 :(得分: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)

应该有效。没试过。