3 import sys, glob, 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
18 env.Tool('InstallSubdir')
21 env.Tool('CombinedObject')
22 env.Tool('PhonyTarget')
23 env.Tool('InstallDir')
26 Additional top-level build targets:
28 prepare Create all target files not part of the repository
29 default Build all default targets (like calling scons with no arguments)
30 examples Build all examples
31 all_tests Build and run unit tests for all modules
32 all_docs Build documentation for all modules
34 install_all Install SENF into $$PREFIX
35 deb Build debian source and binary package
36 debsrc Build debian source package
37 debbin Build debian binary package
38 linklint Check links of doxygen documentation with 'linklint'
39 fixlinks Fix broken links in doxygen documentation
40 valgrind Run all tests under valgrind/memcheck
41 lcov Generate test coverage output in doc/lcov and lcov.info
45 ENV = { 'PATH' : os.environ.get('PATH'), 'HOME' : os.environ.get('HOME') },
46 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*',
47 '*.gcno', '*.gcda', '*.gcov' ],
51 LIBPATH = [ '$LOCALLIBDIR' ],
52 LIBS = [ '$LIBSENF$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB',
53 '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ],
54 TEST_EXTRA_LIBS = [ ],
57 LIBINSTALLDIR = '$PREFIX${syslayout and "/lib" or ""}',
58 BININSTALLDIR = '$PREFIX${syslayout and "/bin" or ""}',
59 INCLUDEINSTALLDIR = '$PREFIX${syslayout and "/include" or ""}',
60 CONFINSTALLDIR = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}',
61 OBJINSTALLDIR = '$CONFINSTALLDIR',
62 DOCINSTALLDIR = '$PREFIX${syslayout and "/share/doc/senf" or "/manual"}',
63 SCONSINSTALLDIR = '$CONFINSTALLDIR/site_scons',
65 CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
66 CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
68 # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
69 INLINE_OPTS_DEBUG = [ '-finline-limit=20000', '-fvisibility-inlines-hidden',
70 '-fno-inline-functions', '-Winline'
71 '--param','large-function-growth=10000',
72 '--param', 'large-function-insns=10000',
73 '--param','inline-unit-growth=10000' ],
74 INLINE_OPTS_NORMAL = [ '-finline-limit=5000' ],
75 INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ],
76 CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
78 CXXFLAGS_ = senfutil.BuildTypeOptions('CXXFLAGS'),
79 CXXFLAGS_final = [ '-O3' ],
80 CXXFLAGS_normal = [ '-O0', '-g' ],
81 CXXFLAGS_debug = [ '$CXXFLAGS_normal' ],
83 CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ],
84 expandLogOption = senfutil.expandLogOption,
85 CPPDEFINES_ = senfutil.BuildTypeOptions('CPPDEFINES'),
86 CPPDEFINES_final = [ ],
87 CPPDEFINES_normal = [ 'SENF_DEBUG' ],
88 CPPDEFINES_debug = [ '$CPPDEFINES_normal' ],
90 LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ],
91 LINKFLAGS_ = senfutil.BuildTypeOptions('LINKFLAGS'),
92 LINKFLAGS_final = [ ],
93 LINKFLAGS_normal = [ '-Wl,-S' ],
94 LINKFLAGS_debug = [ '-g' ],
101 SCONS = "./tools/scons -j$CONCURRENCY_LEVEL",
102 CONCURRENCY_LEVEL = env.GetOption('num_jobs') or 1,
105 # Set variables from command line
106 senfutil.parseArguments(
108 BoolVariable('final', 'Build final (optimized) build', False),
109 BoolVariable('debug', 'Link in debug symbols', False),
110 BoolVariable('syslayout', 'Install in to system layout directories (lib/, include/ etc)', False),
115 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
116 # Create it even when cleaning, to silence the doxygen builder warnings
117 if not os.path.exists("Doxyfile.local"):
118 Execute(Touch("Doxyfile.local"))
120 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
121 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
122 env.Execute([ "scons prepare" ])
127 SConscript("debian/SConscript")
129 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
130 SConscript("senf/SConscript")
131 SConscript("Examples/SConscript")
132 SConscript("HowTos/SConscript")
133 SConscript("doclib/SConscript")
135 ###########################################################################
136 # Define build targets
139 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
142 libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS'])
144 env.Install('$LIBINSTALLDIR', libsenf)
146 def create(target, source, env):
147 file(str(target[0]), 'w').write(source[0].get_contents()+"\n")
148 env['BUILDERS']['CreateFile'] = Builder(action = create)
150 conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf",
151 env.Value(env.subst("$_CPPDEFFLAGS")))
153 env.Install('$CONFINSTALLDIR', conf)
155 #### install_all, default, all_tests, all
156 env.Install('${SCONSINSTALLDIR}', [ 'site_scons/__init__.py',
157 'site_scons/senfutil.py',
158 'site_scons/yaptu.py' ])
159 env.InstallDir('${SCONSINSTALLDIR}', [ 'site_scons/site_tools', 'site_scons/lib' ],
160 FILTER_SUFFIXES=[ '','.css','.pl','.py','.sh','.sty','.xml','.xsl','.yap' ])
161 env.Install('${INCLUDEINSTALLDIR}', 'boost')
163 env.Alias('install_all', env.FindInstalledFiles())
164 env.Alias('default', DEFAULT_TARGETS)
165 env.Alias('all_tests', env.FindAllBoostUnitTests())
166 env.Alias('all', [ 'default', 'all_tests', 'examples', 'all_docs' ])
169 env.PhonyTarget('prepare', [], [])
172 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
174 | while read test; do
176 echo "Running $$test";
178 valgrind --tool=memcheck --error-exitcode=99 --suppressions=tools/valgrind.sup
179 $$test $BOOSTTESTARGS;
180 [ $$? -ne 99 ] || exit 1;
182 """.replace("\n"," ") ])
185 env.Alias('lcov', env.AlwaysBuild(
186 env.Command( [ env.Dir('doc/lcov'), 'lcov.info' ], [], [
187 '$SCONS debug=1 CCFLAGS+="-fprofile-arcs -ftest-coverage" LIBS+="gcov" all_tests',
188 '$LCOV --directory . --capture --output-file /tmp/senf_lcov.info --base-directory .',
189 '$LCOV --output-file ${TARGETS[1]} --remove /tmp/senf_lcov.info \\*/include/\\*',
190 '$GENHTML --output-directory ${TARGETS[0]} --title all_tests ${TARGETS[1]}',
191 'rm /tmp/senf_lcov.info' ])))
194 env.Clean('all', '.prepare-stamp')
195 env.Clean('all', libsenf)
196 env.Clean('all', env.Dir('linklint')) # env.Dir to disambiguate from linklint PhonyTarget
197 env.Clean('all', env.Dir('dist'))
198 env.Clean('all', 'lcov.info')
200 if env.GetOption('clean'):
201 env.Clean('all', [ os.path.join(path,f)
202 for path, subdirs, files in os.walk('.')
203 for pattern in env['CLEAN_PATTERNS']
204 for f in fnmatch.filter(files,pattern) ])
206 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
207 Execute(Touch(".prepare-stamp"))