1
votes

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.

2
The library names shouldn't change, rather the directory names the different libraries are in should be different. - Brady
@Brady, Yes here my question is not about changing library name, I am seeking solution to create lib_rel/libfoo.a and lib_dbg/libfoo.a inside 'lib' directory And similarly lib_rel/libfoo.so and lib_dbg/libfoo.so inside 'dll' directory. What changes I need to do for this ? - Harry Cruise

2 Answers

1
votes

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)
0
votes

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.