Home   Notes   Contact Me

SCons

Local

External

Home page: http://scons.org


Linking

LIBLINKPREFIX LIBS LIBLINKSUFFIX '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}'

SConstruct File examples

Program('hello.c') # What it does: # hello.c -> hello.o -> hello # or # hello.c -> hello.obj -> hello.exe
Object('hello.c') # compiles only: # hello.c -> hello.o
Program('new_hello', 'hello.c') # builds the executable: # hello.c -> hello.o -> new_hello # hello.c -> hello.obj -> new_hello.exe
Program(['main.c', 'file1.c', 'file2.c']) # main.c -> main.o # file1.c -> file1.o # file2.c -> file2.o # main.o file1.o file2.o -> main
Program('myprog', ['main.c', 'file1.c', 'file2.c']) # main.c -> main.o # file1.c -> file1.o # file2.c -> file2.o # main.o file1.o file2.o -> myprog
Program('myprog', Split('main.c file1.c file2.c')) # main.c -> main.o # file1.c -> file1.o # file2.c -> file2.o # main.o file1.o file2.o -> myprog
list = Split('main.c file1.c file2.c') Program('myprog', list) # main.c -> main.o # file1.c -> file1.o # file2.c -> file2.o # main.o file1.o file2.o -> myprog
Library('foo', Split('f1.c f2.c f3.c')) # or StaticLibrary('foo', Split('f1.c f2.c f3.c')) # f1.c -> f1.o # f2.c -> f2.o # f3.c -> f3.o # f1.o f2.o f3.o -> foo.a # or # f1.obj f2.obj f3.obj -> foo.lib
SharedLibrary('foo', Split('f1.c f2.c f3.c')) # f1.c -> f1.os # f2.c -> f2.os # f3.c -> f3.os # f1.os f2.os f3.os -> foo.so # or # f1.obj f2.obj f3.obj -> foo.dll foo.lib
Library('foo', Split('f1.c f2.c f3.c')) Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='libs')
hello_list = Object('hello.c', CCFLAGS='-DHELLO') goodbye_list = Object('goodbye.c', CCFLAGS='-DGOODBYE') Program(hello_list + goodby_list) # Node[] hello_list # hello_list = [ 'Node of hello.o' ]
Program('hello.c', CPPPATH = [ '.', '/myinc'] ) # will find hello.h in $CPPPATH
envOpt = Environment(CCFLAGS = '-O2') envDbg = Environment(CCFLAGS = '-g') objOpt = envOpt.Object('foo-opt', 'foo.c') objDbg = envDbg.Object('foo-dbg', 'foo.c') envOpt.Program(objOpt) evnOpt.Program(objDbg) # foo.c -> foo-opt.o # foo.c -> foo-dbg.o # foo-opt.o -> foo-opt # foo-dbg.o -> foo-dbg
envBase = Environment(CC = 'gcc') envOpt = envBase.Clone(CCFLAGS = '-O2') envDbg = envBase.Clone(CCFLAGS = '-g') objOpt = envOpt.Object('foo-opt', 'foo.c') objDbg = envDbg.Object('foo-dbg', 'foo.c') envOpt.Program(objOpt) evnOpt.Program(objDbg) # foo.c -> foo-opt.o # foo.c -> foo-dbg.o # foo-opt.o -> foo-opt # foo-dbg.o -> foo-dbg
# env is a Python dictionary so you can do: >>> env = Environment(CC = 'gcc') >>> print "CC is: ", env['CC'] 'gcc'
(Pdb) env2 = Environment() (Pdb) p env2['CCCOM'] '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' (Pdb) p env2.subst('$CCCOM') 'cc -o -c' (Pdb) (Pdb) env2 = Environment(CCFLAGS = [ '-Dflag1', '-Dflag2' ], CPPPATH = [ '.', 'incdir' ]) (Pdb) p env2['CCFLAGS'] ['-Dflag1', '-Dflag2'] (Pdb) p env2['CPPPATH'] ['.', 'incdir'] (Pdb) p env2.subst('$CCCOM') 'cc -o -c -Dflag1 -Dflag2 -I. -Iincdir' (Pdb) p env2.subst('here is $CC and $CPPPATH should have been are') 'here is cc and . incdir should have been are' (Pdb)
(Pdb) env2.Replace(CC = 'myCC') (Pdb) p env2['CC'] 'myCC' (Pdb) p env2['NEWTHING'] *** KeyError: (Pdb) env2.Replace(NEWTHING = 'new thing') (Pdb) p env2['NEWTHING'] 'new thing'
(Pdb) p env2['CCFLAGS'] ['-Dflag1', '-Dflag2'] (Pdb) env2.Append(CCFLAGS, '-Dflag3') *** NameError: name 'CCFLAGS' is not defined (Pdb) env2.Append(CCFLAGS = '-Dflag3') (Pdb) p env2['CCFLAGS'] ['-Dflag1', '-Dflag2', '-Dflag3'] (Pdb) p env2['NEWERTHING'] *** KeyError: (Pdb) p env2.Append(NEWERTHING = '-Dnewerflag') None (Pdb) p env2['NEWERTHING'] '-Dnewerflag' (Pdb) env2.Prepend(NEWERTHING = '-Dnewerflag2 ') (Pdb) p env2['NEWERTHING'] '-Dnewerflag2 -Dnewerflag'
(Pdb) env['ENV'] {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin:/usr/ccs/bin', 'PWD': '/vol/qalib/petritis/workSolaris/imagine/version/gen3/depot/Mainline/Generation_4/apollo/core/raster.native/cppwrappers', 'USER': 'petritis', 'P4CLIENT': 'p4.cfg'} (Pdb) env['ENV']['PATH'] '/usr/local/bin:/opt/bin:/bin:/usr/bin:/usr/ccs/bin'
(Pdb) newPath = ['/home/bin', '/usr/local/bin'] (Pdb) env2['ENV']['PATH'] '/usr/local/bin:/opt/bin:/bin:/usr/bin:/usr/ccs/bin' (Pdb) env2['ENV']['PATH'] = newPath (Pdb) env2['ENV']['PATH'] ['/home/bin', '/usr/local/bin']
# Reading an external (to scons that is) env variable (Pdb) import os (Pdb) os.environ['SHELL'] '/bin/tcsh'
env = Environment() hello = env.Program('hello.c') env.Install('./bin', hello) # hello.c -> hello.o # hello.o -> hello # hello -> ./bin/hello # this will not work because /usr/bin is not in the build directory or a subdirectory # of where scons was run (unless on the run line you said '/usr/bin' to add # it to the list of build directores env.Install('/usr/bin', hello) # hello -> /usr/bin/hello # instead use a fake name that points to somewhere else # this saves you from having to type so much on the scons command line # you can just tack the alias name to the command line, in the follow # case you need to add 'install' env = Environment() hello = env.Program('hello.c') env.Install('/usr/bin', hello) env.Alias('install' '/usr/bin')
# multiple installs are fine env.Install('./bin', hello) env.Install('./bin', hello2) env.Install('./bin', [ hello3, hello4 ])
# rename installs env.InstallAs('./bin/hello-new', 'hello-orig') env.InstallAs(['./bin/hello-new', './bin/bye-new'], ['hello-orig', 'bye-orig'])

Show Dependency Tree

# show the tree while building scons --tree=all # show the tree and do _not_ build scons --tree=all -n

Debugging from the Command Line

# Start scons in a debugger, stopped at the first line of code scons --debug=pdb # place a breakpoint on line 3 of file.py b /fullpath/to/file.py:3

Factories

FactoryDetails
Copy({outfile},{infile})
Copies infile to outfile, note that it uses file names, not directory paths
StaticLibrary('libname', ['source1.cpp', 'source2.cpp']
SharedLibrary('libname', ['source1.cpp', 'source2.cpp']

Dependancy Order

# Given 2 targets to build: lib1 = SConscript( ... ) lib2 = SConscript( ... ) # to make lib2 build first: Depends(lib2, lib1) # to make lib1 build first: Depends(lib1, lib2)

Install C++ compiler

# this worked apt-get install build-essential # these were bad, they worked from outside of scons, but not when trying to use scons apt-get install libc6-dev apt-get install g++-4.1

Gotchas