【问题标题】:SCons: Different variant_dir in single SConscript fileSCons:单个 SConscript 文件中的不同 variant_dir
【发布时间】:2014-08-09 14:18:33
【问题描述】:

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

一种可行的方法是为 SharedLibrary 和 StaticLibrary 设置单独的 SConscript。但这很典型,每个库构建器方法都需要两个不同的文件。

请为此提出适当的解决方案。

【问题讨论】:

  • 库名不应该改变,而是不同库所在的目录名应该不同。
  • @Brady,是的,我的问题不是关于更改库名称,我正在寻找在“lib”目录中创建 lib_rel/libfoo.a 和 lib_dbg/libfoo.a 以及类似的 lib_rel/libfoo 的解决方案。 so 和 lib_dbg/libfoo.so 在 'dll' 目录中。为此我需要做哪些改变?

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


【解决方案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)

【讨论】:

    【解决方案2】:

    S构造

    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)
    

    应该可以。没试过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-03
      相关资源
      最近更新 更多