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
18 env.Tool('InstallSubdir')
21 env.Tool('CombinedObject')
22 env.Tool('PhonyTarget')
23 env.Tool('InstallDir')
24 env.Tool('CreateFile')
27 Additional top-level build targets:
29 prepare Create all target files not part of the repository
30 default Build all default targets (like calling scons with no arguments)
31 examples Build all examples
32 all_tests Build and run unit tests for all modules
33 all_docs Build documentation for all modules
35 install_all Install SENF into $$PREFIX
36 deb Build debian source and binary package
37 debsrc Build debian source package
38 debbin Build debian binary package
39 linklint Check links of doxygen documentation with 'linklint'
40 fixlinks Fix broken links in doxygen documentation
41 all_valgrinds Run all tests under valgrind/memcheck
42 lcov Generate test coverage output in doc/lcov and lcov.info
46 ENV = { 'PATH' : os.environ.get('PATH'), 'HOME' : os.environ.get('HOME') },
47 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*' ],
50 CPPPATH = [ '$BUILDDIR', '#' ],
51 LOCALLIBDIR = '$BUILDDIR',
52 LIBPATH = [ '$LOCALLIBDIR' ],
53 LIBS = [ '$LIBSENF$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB',
54 '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ],
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 SCONS = "@$SCONSBIN -Q -j$CONCURRENCY_LEVEL",
105 CONCURRENCY_LEVEL = env.GetOption('num_jobs') or 1,
106 TOPDIR = env.Dir('#').abspath,
109 # Set variables from command line
110 senfutil.parseArguments(
112 BoolVariable('final', 'Build final (optimized) build', False),
113 BoolVariable('debug', 'Link in debug symbols', False),
114 BoolVariable('syslayout', 'Install in to system layout directories (lib/, include/ etc)', False),
119 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
120 # Create it even when cleaning, to silence the doxygen builder warnings
121 if not os.path.exists("doclib/Doxyfile.local"):
122 Execute(Touch("doclib/Doxyfile.local"))
124 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
125 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
126 env.Execute([ "$SCONS prepare" ])
131 SConscript("debian/SConscript")
133 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
134 if env['BUILDDIR'] == '#':
135 SConscript("SConscript")
137 SConscript("SConscript", variant_dir=env['BUILDDIR'], src_dir='#', duplicate=False)
138 SConscript("Examples/SConscript")
139 SConscript("HowTos/SConscript")
140 SConscript("doclib/SConscript")
142 ###########################################################################
143 # Define build targets
145 #### install_all, default, all_tests, all
146 env.Install('${SCONSINSTALLDIR}', [ 'site_scons/__init__.py',
147 'site_scons/senfutil.py',
148 'site_scons/yaptu.py' ])
149 env.InstallDir('${SCONSINSTALLDIR}', [ 'site_scons/site_tools', 'site_scons/lib' ],
150 FILTER_SUFFIXES=[ '','.css','.pl','.py','.sh','.sty','.xml','.xsl','.yap' ])
151 env.Install('${INCLUDEINSTALLDIR}', 'boost')
153 env.Alias('install_all', env.FindInstalledFiles())
154 env.Alias('default', DEFAULT_TARGETS)
155 env.Alias('all_tests', env.FindAllBoostUnitTests())
156 env.Alias('all', [ 'default', 'all_tests', 'examples', 'all_docs' ])
159 env.PhonyTarget('prepare', [], [])
162 for test in env.FindAllBoostUnitTests():
163 stamp = env.Command(test[0].dir.File('.test-valgrind.stamp'),
164 [ test[0].dir.File('.test.bin'), 'tools/valgrind.sup' ],
165 [ """valgrind --tool=memcheck
167 --suppressions=${SOURCES[1]}
169 ${SOURCES[0]} $BOOSTTESTARGS;
170 [ $$? -ne 99 ] || exit 1""".replace("\n"," "),
172 alias = env.Command(test[0].dir.File('valgrind'), stamp, [ env.NopAction() ])
173 env.Alias('all_valgrinds', alias)
176 env.PhonyTarget('lcov', [], [
177 '$SCONS debug=1 BUILDDIR="#/lcov-build" CCFLAGS+="-fprofile-arcs -ftest-coverage" LIBS+="gcov" all_tests',
178 '$LCOV --follow --directory $TOPDIR/lcov-build/senf --capture --output-file /tmp/senf_lcov.info --base-directory $TOPDIR',
179 '$LCOV --output-file lcov.info --remove /tmp/senf_lcov.info "*/include/*" "*/boost/*" "*.test.*" ',
180 '$GENHTML --output-directory doc/lcov --title all_tests lcov.info',
181 'rm /tmp/senf_lcov.info' ])
182 if env.GetOption('clean'):
183 env.Clean('lcov', [ os.path.join(path,f)
184 for path, subdirs, files in os.walk('.')
185 for pattern in ('*.gcno', '*.gcda', '*.gcov')
186 for f in fnmatch.filter(files,pattern) ] +
187 [ 'lcov.info', env.Dir('doc/lcov'), env.Dir('lcov-build') ])
190 env.Clean('all', ('.prepare-stamp', env.Dir('dist')))
191 if env.GetOption('clean') : env.Depends('all', ('lcov', 'all_valgrinds'))
193 if env.GetOption('clean') and 'all' in BUILD_TARGETS:
194 env.Clean('all', [ os.path.join(path,f)
195 for path, subdirs, files in os.walk('.')
196 for pattern in env['CLEAN_PATTERNS']
197 for f in fnmatch.filter(files,pattern) ])
198 # Disable writing to the deleted .sconsign file
199 import SCons.SConsign
200 SCons.SConsign.write = lambda : None
202 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
203 Execute(Touch(".prepare-stamp"))