3 import sys, os.path, fnmatch
4 import SENFSCons, senfutil
6 ###########################################################################
7 # Load utilities and setup libraries and configure build
11 env.Decider('MD5-timestamp')
12 env.EnsureSConsVersion(1,2)
14 # Load all the local SCons tools
15 senfutil.loadTools(env)
18 Additional top-level build targets:
20 prepare Create all target files not part of the repository
21 default Build all default targets (like calling scons with no arguments)
22 examples Build all examples
23 all_tests Build and run unit tests for all modules
24 all_docs Build documentation for all modules
26 install_all Install SENF into $$PREFIX
27 deb Build debian source and binary package
28 debsrc Build debian source package
29 debbin Build debian binary package
30 linklint Check links of doxygen documentation with 'linklint'
31 fixlinks Fix broken links in doxygen documentation
32 all_valgrinds Run all tests under valgrind/memcheck
33 lcov Generate test coverage output in doc/lcov and lcov.info
35 You may execute targets on a remote host (if the directory layout is the same)
38 scons <target>@[<user>@]<host>
42 ENV = { 'PATH' : os.environ.get('PATH'),
43 'HOME' : os.environ.get('HOME'),
44 'SSH_AGENT_PID': os.environ.get('SSH_AGENT_PID'),
45 'SSH_AUTH_SOCK': os.environ.get('SSH_AUTH_SOCK') },
46 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*' ],
48 BUILDDIR = '${FLAVOR and "#/build/$FLAVOR" or "#"}',
49 CPPPATH = [ '$BUILDDIR', '#' ],
50 LOCALLIBDIR = '$BUILDDIR',
51 LIBPATH = [ '$LOCALLIBDIR' ],
52 LIBS = [ '$LIBSENF$LIBADDSUFFIX', '$EXTRA_LIBS' ],
53 EXTRA_LIBS = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
55 TEST_EXTRA_LIBS = [ ],
56 VALGRINDARGS = [ '--num-callers=50' ],
59 LIBINSTALLDIR = '$PREFIX${syslayout and "/lib" or ""}',
60 BININSTALLDIR = '$PREFIX${syslayout and "/bin" or ""}',
61 INCLUDEINSTALLDIR = '$PREFIX${syslayout and "/include" or ""}',
62 CONFINSTALLDIR = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}',
63 OBJINSTALLDIR = '$CONFINSTALLDIR',
64 DOCINSTALLDIR = '$PREFIX${syslayout and "/share/doc/senf" or "/manual"}',
65 SCONSINSTALLDIR = '$CONFINSTALLDIR/site_scons',
67 CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
68 CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
70 # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
71 INLINE_OPTS_DEBUG = [ '-finline-limit=20000', '-fvisibility-inlines-hidden',
72 '-fno-inline-functions', '-Winline'
73 '--param','large-function-growth=10000',
74 '--param', 'large-function-insns=10000',
75 '--param','inline-unit-growth=10000' ],
76 INLINE_OPTS_NORMAL = [ '-finline-limit=5000' ],
77 INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ],
78 CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
80 CXXFLAGS_ = senfutil.BuildTypeOptions('CXXFLAGS'),
81 CXXFLAGS_final = [ '-O3' ],
82 CXXFLAGS_normal = [ '-O0', '-g' ],
83 CXXFLAGS_debug = [ '$CXXFLAGS_normal' ],
85 CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ],
86 expandLogOption = senfutil.expandLogOption,
87 CPPDEFINES_ = senfutil.BuildTypeOptions('CPPDEFINES'),
88 CPPDEFINES_final = [ ],
89 CPPDEFINES_normal = [ 'SENF_DEBUG' ],
90 CPPDEFINES_debug = [ '$CPPDEFINES_normal' ],
92 LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ],
93 LINKFLAGS_ = senfutil.BuildTypeOptions('LINKFLAGS'),
94 LINKFLAGS_final = [ ],
95 LINKFLAGS_normal = [ '-Wl,-S' ],
96 LINKFLAGS_debug = [ '-g' ],
103 SCONSBIN = env.File("#/tools/scons"),
104 SCONSARGS = [ '-Q', '-j$CONCURRENCY_LEVEL', 'debug=$debug', 'final=$final' ],
105 SCONS = "@$SCONSBIN $SCONSARGS",
106 CONCURRENCY_LEVEL = env.GetOption('num_jobs') or 1,
107 TOPDIR = env.Dir('#').abspath,
108 LIBADDSUFFIX = '${FLAVOR and "_$FLAVOR" or ""}',
109 OBJADDSUFFIX = '${LIBADDSUFFIX}',
113 # Set variables from command line
114 senfutil.parseArguments(
116 BoolVariable('final', 'Build final (optimized) build', False),
117 BoolVariable('debug', 'Link in debug symbols', False),
118 BoolVariable('syslayout', 'Install in to system layout directories (lib/, include/ etc)', False),
119 BoolVariable('sparse_tests', 'Link tests against object files and not the senf lib', False)
122 if env.has_key('only_tests') : env['sparse_tests'] = True
125 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
126 # Create it even when cleaning, to silence the doxygen builder warnings
127 if not os.path.exists("doclib/Doxyfile.local"):
128 Execute(Touch("doclib/Doxyfile.local"))
130 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
131 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
132 env.Execute([ "$SCONS prepare" ])
137 SConscript("debian/SConscript")
139 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
140 if env['sparse_tests']:
141 import SparseTestHack
142 SparseTestHack.setup(env)
143 if env.subst('$BUILDDIR') == '#':
144 SConscript("SConscript")
146 SConscript("SConscript", variant_dir=env.subst('$BUILDDIR'), src_dir='#', duplicate=False)
147 SConscript("Examples/SConscript")
148 SConscript("HowTos/SConscript")
149 SConscript("doclib/SConscript")
150 if env['sparse_tests']:
151 SparseTestHack.build(env)
153 ###########################################################################
154 # Define build targets
156 #### install_all, default, all_tests, all
157 env.Install('${SCONSINSTALLDIR}', [ 'site_scons/__init__.py',
158 'site_scons/senfutil.py',
159 'site_scons/yaptu.py' ])
160 env.InstallDir('${SCONSINSTALLDIR}', [ 'site_scons/site_tools', 'site_scons/lib' ],
161 FILTER_SUFFIXES=[ '','.css','.pl','.py','.sh','.sty','.xml','.xsl','.yap' ])
162 env.Install('${INCLUDEINSTALLDIR}', 'boost')
164 env.Alias('install_all', env.FindInstalledFiles())
165 env.Alias('default', DEFAULT_TARGETS)
166 env.Alias('all_tests', env.FindAllBoostUnitTests())
167 env.Alias('all', [ 'default', 'all_tests', 'examples', 'all_docs' ])
170 env.PhonyTarget('prepare', [], [])
173 for test in env.FindAllBoostUnitTests():
174 stamp = env.Command(test[0].dir.File('.test-valgrind.stamp'),
175 [ test[0].dir.File('.test.bin'), 'tools/valgrind.sup' ],
176 [ """valgrind --tool=memcheck
178 --suppressions=${SOURCES[1]}
180 ${SOURCES[0]} $BOOSTTESTARGS;
181 [ $$? -ne 99 ] || exit 1""".replace("\n"," "),
183 alias = env.Command(test[0].dir.File('valgrind'), stamp, [ env.NopAction() ])
184 env.Alias('all_valgrinds', alias)
187 env.PhonyTarget('lcov', [], [
188 '$SCONS debug=1 BUILDDIR="#/build/lcov" CCFLAGS+="-fprofile-arcs -ftest-coverage" LIBS+="gcov" all_tests',
189 '$LCOV --follow --directory $TOPDIR/build/lcov/senf --capture --output-file /tmp/senf_lcov.info --base-directory $TOPDIR',
190 '$LCOV --output-file lcov.info --remove /tmp/senf_lcov.info "*/include/*" "*/boost/*" "*.test.*" ',
191 '$GENHTML --output-directory doc/lcov --title all_tests lcov.info',
192 'rm /tmp/senf_lcov.info' ])
193 if env.GetOption('clean'):
194 env.Clean('lcov', [ os.path.join(path,f)
195 for path, subdirs, files in os.walk('.')
196 for pattern in ('*.gcno', '*.gcda', '*.gcov')
197 for f in fnmatch.filter(files,pattern) ] +
198 [ 'lcov.info', env.Dir('doc/lcov'), env.Dir('build/lcov') ])
201 env.Clean('all', ('.prepare-stamp', env.Dir('dist'), env.Dir('build')))
202 if env.GetOption('clean') : env.Depends('all', ('lcov', 'all_valgrinds'))
204 if env.GetOption('clean') and 'all' in BUILD_TARGETS:
205 env.Clean('all', [ os.path.join(path,f)
206 for path, subdirs, files in os.walk('.')
207 for pattern in env['CLEAN_PATTERNS']
208 for f in fnmatch.filter(files,pattern) ])
209 # Disable writing to the deleted .sconsign file
210 import SCons.SConsign
211 SCons.SConsign.write = lambda : None
213 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
214 Execute(Touch(".prepare-stamp"))
216 ### execute targets on remote hosts
217 for target in COMMAND_LINE_TARGETS:
219 realtarget, host = target.split('@',1)
220 cwd=env.GetLaunchDir()
221 home=os.environ['HOME']+'/'
222 if cwd.startswith(home) : cwd = cwd[len(home):]
223 args = [ '$SCONSARGS' ]
224 if env.GetLaunchDir() != os.getcwd():
226 env.PhonyTarget(target, [], [ "ssh $HOST scons $SCONSARGS -C $DIR $RTARGET" ],
227 HOST=host, RTARGET=realtarget, DIR=cwd, SCONSARGS=args)