3 import sys, glob, os.path, fnmatch
4 import SENFSCons, senfutil
6 # Fix for SCons 0.97 compatibility
10 BoolVariable = BoolOption
12 ###########################################################################
13 # Load utilities and setup libraries and configure build
17 env.Decider('MD5-timestamp')
19 # Load all the local SCons tools
23 env.Tool('InstallSubdir')
26 env.Tool('CombinedObject')
27 env.Tool('PhonyTarget')
28 env.Tool('InstallDir')
31 Additional top-level build targets:
33 prepare Create all target files not part of the repository
34 default Build all default targets (like calling scons with no arguments)
35 examples Build all examples
36 all_tests Build and run unit tests for all modules
37 all_docs Build documentation for all modules
39 install_all Install SENF into $$PREFIX
40 deb Build debian source and binary package
41 debsrc Build debian source package
42 debbin Build debian binary package
43 linklint Check links of doxygen documentation with 'linklint'
44 fixlinks Fix broken links in doxygen documentation
45 valgrind Run all tests under valgrind/memcheck
49 ENV = { 'PATH' : os.environ.get('PATH') },
50 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*' ],
54 LIBPATH = [ '$LOCALLIBDIR' ],
55 LIBS = [ '$LIBSENF$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB',
56 '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ],
57 TEST_EXTRA_LIBS = [ ],
60 LIBINSTALLDIR = '$PREFIX${syslayout and "/lib" or ""}',
61 BININSTALLDIR = '$PREFIX${syslayout and "/bin" or ""}',
62 INCLUDEINSTALLDIR = '$PREFIX${syslayout and "/include" or ""}',
63 CONFINSTALLDIR = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}',
64 OBJINSTALLDIR = '$CONFINSTALLDIR',
65 DOCINSTALLDIR = '$PREFIX${syslayout and "/share/doc/senf" or "/manual"}',
66 SCONSINSTALLDIR = '$CONFINSTALLDIR/site_scons',
68 CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
69 CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
71 # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
72 INLINE_OPTS_DEBUG = [ '-finline-limit=20000', '-fvisibility-inlines-hidden',
73 '-fno-inline-functions', '-Winline'
74 '--param','large-function-growth=10000',
75 '--param', 'large-function-insns=10000',
76 '--param','inline-unit-growth=10000' ],
77 INLINE_OPTS_NORMAL = [ '-finline-limit=5000' ],
78 INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ],
79 CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
81 CXXFLAGS_ = senfutil.BuildTypeOptions('CXXFLAGS'),
82 CXXFLAGS_final = [ '-O3' ],
83 CXXFLAGS_normal = [ '-O0', '-g' ],
84 CXXFLAGS_debug = [ '$CXXFLAGS_normal' ],
86 CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ],
87 expandLogOption = senfutil.expandLogOption,
88 CPPDEFINES_ = senfutil.BuildTypeOptions('CPPDEFINES'),
89 CPPDEFINES_final = [ ],
90 CPPDEFINES_normal = [ 'SENF_DEBUG' ],
91 CPPDEFINES_debug = [ '$CPPDEFINES_normal' ],
93 LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ],
94 LINKFLAGS_ = senfutil.BuildTypeOptions('LINKFLAGS'),
95 LINKFLAGS_final = [ ],
96 LINKFLAGS_normal = [ '-Wl,-S' ],
97 LINKFLAGS_debug = [ '-g' ],
107 # Set variables from command line
108 senfutil.parseArguments(
110 BoolVariable('final', 'Build final (optimized) build', False),
111 BoolVariable('debug', 'Link in debug symbols', False),
112 BoolVariable('syslayout', 'Install in to system layout directories (lib/, include/ etc)', False),
117 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
118 # Create it even when cleaning, to silence the doxygen builder warnings
119 if not os.path.exists("Doxyfile.local"):
120 Execute(Touch("Doxyfile.local"))
122 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
123 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
124 env.Execute([ "scons prepare" ])
129 SConscript("debian/SConscript")
131 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
132 SConscript("senf/SConscript")
133 SConscript("Examples/SConscript")
134 SConscript("HowTos/SConscript")
135 SConscript("doclib/SConscript")
137 ###########################################################################
138 # Define build targets
141 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
144 libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS'])
146 env.Install('$LIBINSTALLDIR', libsenf)
148 def create(target, source, env):
149 file(str(target[0]), 'w').write(source[0].get_contents()+"\n")
150 env['BUILDERS']['CreateFile'] = Builder(action = create)
152 conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf",
153 env.Value(env.subst("$_CPPDEFFLAGS")))
155 env.Install('$CONFINSTALLDIR', conf)
157 #### install_all, default, all_tests, all
158 env.Install('${SCONSINSTALLDIR}', [ 'site_scons/__init__.py',
159 'site_scons/senfutil.py',
160 'site_scons/yaptu.py' ])
161 env.InstallDir('${SCONSINSTALLDIR}', [ 'site_scons/site_tools', 'site_scons/lib' ],
162 FILTER_SUFFIXES=[ '','.css','.pl','.py','.sh','.sty','.xml','.xsl','.yap' ])
163 env.Install('${INCLUDEINSTALLDIR}', 'boost')
165 env.Alias('install_all', env.FindInstalledFiles())
166 env.Alias('default', DEFAULT_TARGETS)
167 env.Alias('all_tests', env.FindAllBoostUnitTests())
168 env.Alias('all', [ 'default', 'all_tests', 'examples', 'all_docs' ])
171 env.PhonyTarget('prepare', [], [])
174 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
176 | while read test; do
178 echo "Running $$test";
180 valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup
181 $$test $BOOSTTESTARGS;
182 [ $$? -ne 99 ] || exit 1;
184 """.replace("\n"," ") ])
187 env.Clean('all', '.prepare-stamp')
188 env.Clean('all', libsenf)
189 env.Clean('all', env.Dir('linklint')) # env.Dir to disambiguate from linklint PhonyTarget
190 env.Clean('all', env.Dir('dist'))
192 if env.GetOption('clean'):
193 env.Clean('all', [ os.path.join(path,f)
194 for path, subdirs, files in os.walk('.')
195 for pattern in env['CLEAN_PATTERNS']
196 for f in fnmatch.filter(files,pattern) ])
198 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
199 Execute(Touch(".prepare-stamp"))