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 all_valgrinds 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,
103 TOPDIR = env.Dir('#').abspath,
106 # Set variables from command line
107 senfutil.parseArguments(
109 BoolVariable('final', 'Build final (optimized) build', False),
110 BoolVariable('debug', 'Link in debug symbols', False),
111 BoolVariable('syslayout', 'Install in to system layout directories (lib/, include/ etc)', False),
116 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
117 # Create it even when cleaning, to silence the doxygen builder warnings
118 if not os.path.exists("doclib/Doxyfile.local"):
119 Execute(Touch("doclib/Doxyfile.local"))
121 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
122 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
123 env.Execute([ "scons prepare" ])
128 SConscript("debian/SConscript")
130 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
131 SConscript("senf/SConscript")
132 SConscript("Examples/SConscript")
133 SConscript("HowTos/SConscript")
134 SConscript("doclib/SConscript")
136 ###########################################################################
137 # Define build targets
140 libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS'])
142 env.Install('$LIBINSTALLDIR', libsenf)
144 def create(target, source, env):
145 file(str(target[0]), 'w').write(source[0].get_contents()+"\n")
146 env['BUILDERS']['CreateFile'] = Builder(action = create)
148 conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf",
149 env.Value(env.subst("$_CPPDEFFLAGS")))
151 env.Install('$CONFINSTALLDIR', conf)
153 #### install_all, default, all_tests, all
154 env.Install('${SCONSINSTALLDIR}', [ 'site_scons/__init__.py',
155 'site_scons/senfutil.py',
156 'site_scons/yaptu.py' ])
157 env.InstallDir('${SCONSINSTALLDIR}', [ 'site_scons/site_tools', 'site_scons/lib' ],
158 FILTER_SUFFIXES=[ '','.css','.pl','.py','.sh','.sty','.xml','.xsl','.yap' ])
159 env.Install('${INCLUDEINSTALLDIR}', 'boost')
161 env.Alias('install_all', env.FindInstalledFiles())
162 env.Alias('default', DEFAULT_TARGETS)
163 env.Alias('all_tests', env.FindAllBoostUnitTests())
164 env.Alias('all', [ 'default', 'all_tests', 'examples', 'all_docs' ])
167 env.PhonyTarget('prepare', [], [])
170 for test in env.FindAllBoostUnitTests():
171 stamp = env.Command(test[0].dir.File('.test-valgrind.stamp'),
172 [ test[0].dir.File('.test.bin'), test ],
173 [ """valgrind --tool=memcheck
175 --suppressions=tools/valgrind.sup
176 $SOURCE $BOOSTTESTARGS;
177 [ $$? -ne 99 ] || exit 1""".replace("\n"," "),
179 alias = env.Command(test[0].dir.File('valgrind'), stamp, [ env.NopAction() ])
180 env.Alias('all_valgrinds', alias)
183 env.PhonyTarget('lcov', [], [
184 '$SCONS debug=1 CCFLAGS+="-fprofile-arcs -ftest-coverage" LIBS+="gcov" all_tests',
185 '$LCOV --directory $TOPDIR/senf --capture --output-file /tmp/senf_lcov.info --base-directory $TOPDIR',
186 '$LCOV --output-file lcov.info --remove /tmp/senf_lcov.info "*/include/*" "*/boost/*" "*.test.*" ',
187 '$GENHTML --output-directory doc/lcov --title all_tests lcov.info',
188 'rm /tmp/senf_lcov.info' ])
191 env.Clean('all', '.prepare-stamp')
192 env.Clean('all', libsenf)
193 env.Clean('all', env.Dir('dist'))
194 env.Clean('all', 'lcov.info')
196 if env.GetOption('clean'):
197 env.Clean('all', [ os.path.join(path,f)
198 for path, subdirs, files in os.walk('.')
199 for pattern in env['CLEAN_PATTERNS']
200 for f in fnmatch.filter(files,pattern) ])
202 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
203 Execute(Touch(".prepare-stamp"))