Harry Cruise
Harry Cruise

Reputation: 91

SCons: Different variant_dir in single SConscript file

I need to use scons to generate release and debug build for a large project. For both release and debug build it generates shared and static library. After the build the directory structure should look as follows:

project_dir/
   |_ src
   |_ include
   |_ lib
      |_ lib_rel
      |_ lib_dbg
   |_ dll
      |_ dll_rel
      |_ dll_dbg

How could I implement SConstruct and SConscript adhere with above requirements ?

SConstruct Implementation:

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 Implementation:

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)

Using above implementation it could generate shared and static library in lib_rel folder and also related object files, Is there any way that I can use variant dir in such way that for SharedLibrary it use target directory as {dll/lib_rel , dll/lib_dbg} and for StaticLibrary method it uses variant_dir as {lib/lib_rel, lib/lib_dbg}

One approach that can be possible is to have separate SConscript for SharedLibrary and StaticLibrary. But This is very typical that two different files required for each library builder methods.

Kindly suggest proper solution for this.

Upvotes: 1

Views: 882

Answers (2)

Robᵩ
Robᵩ

Reputation: 168626

I would treat the Static-ness and the Debug-ness as two dimensions and call the SConscript four times, like so:

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)

Of course, that's ugly, so I'd actually use a loop:

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)

The SConscript needs to import Library, of course:

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)

Upvotes: 1

bdbaddog
bdbaddog

Reputation: 3511

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)

Should work. Haven't tried it.

Upvotes: 0

Related Questions