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
| Factory | Details |
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