3 import sys, glob, os.path, datetime, pwd, time, fnmatch, string
4 sys.path.append(Dir('#/senfscons').abspath)
5 sys.path.append(Dir('#/doclib').abspath)
6 import SENFSCons, senfutil
8 ###########################################################################
9 # Load utilities and setup libraries and configure build
13 # Load all the local SCons tools
14 env.Tool('Doxygen', [ 'senfscons' ])
15 env.Tool('Dia2Png', [ 'senfscons' ])
16 env.Tool('PkgDraw', [ 'senfscons' ])
17 env.Tool('CopyToDir', [ 'senfscons' ])
18 env.Tool('ProgramNoScan', [ 'senfscons' ])
19 env.Tool('CompileCheck', [ 'senfscons' ])
20 env.Tool('Boost', [ 'senfscons' ])
21 env.Tool('BoostUnitTests', [ 'senfscons' ])
24 Additional top-level build targets:
26 prepare Create all source files not part of the repository
27 all_tests Build and run unit tests for all modules
28 all_docs Build documentation for all modules
30 install_all Install SENF into $PREFIX
31 deb Build debian source and binary package
32 debsrc Build debian source package
33 debbin Build debian binary package
34 linklint Check links of doxygen documentation with 'linklint'
35 fixlinks Fix broken links in doxygen documentation
36 valgrind Run all tests under valgrind/memcheck
41 # Options used to debug inlining:
43 # BEWARE: You need lots of ram to compile with these settings (approx 1G)
45 class BuildTypeOptions:
46 def __init__(self, var):
49 def __call__(self, source, target, env, for_signature):
50 type = env['final'] and "final" or env['debug'] and "debug" or "normal"
51 return env[self._var + "_" + type]
54 ENV = { 'PATH' : os.environ.get('PATH') },
55 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*' ],
57 CPPPATH = [ '#/include' ],
59 LIBPATH = [ '$LOCALLIBDIR' ],
60 LIBS = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
62 TEST_EXTRA_LIBS = [ ],
64 PREFIX = '/usr/local',
65 LIBINSTALLDIR = '$PREFIX/lib',
66 BININSTALLDIR = '$PREFIX/bin',
67 INCLUDEINSTALLDIR = '$PREFIX/include',
68 OBJINSTALLDIR = '$LIBINSTALLDIR',
69 DOCINSTALLDIR = '$PREFIX/doc',
70 CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
71 CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
73 # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
74 INLINE_OPTS_DEBUG = [ '-finline-limit=20000', '-fvisibility-inlines-hidden',
75 '-fno-inline-functions', '-Winline'
76 '--param','large-function-growth=10000',
77 '--param', 'large-function-insns=10000',
78 '--param','inline-unit-growth=10000' ],
79 INLINE_OPTS_NORMAL = [ '-finline-limit=5000' ],
80 INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ],
81 CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
83 CXXFLAGS_ = BuildTypeOptions('CXXFLAGS'),
84 CXXFLAGS_final = [ '-O3' ],
85 CXXFLAGS_normal = [ '-O0', '-g' ],
86 CXXFLAGS_debug = [ '$CXXFLAGS_normal' ],
88 CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ],
89 expandLogOption = senfutil.expandLogOption,
90 CPPDEFINES_ = BuildTypeOptions('CPPDEFINES'),
91 CPPDEFINES_final = [ ],
92 CPPDEFINES_normal = [ 'SENF_DEBUG' ],
93 CPPDEFINES_debug = [ '$CPPDEFINES_normal' ],
95 LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ],
96 LINKFLAGS_ = BuildTypeOptions('LINKFLAGS'),
97 LINKFLAGS_final = [ ],
98 LINKFLAGS_normal = [ '-Wl,-S' ],
99 LINKFLAGS_debug = [ ],
108 # Set variables from command line
109 env.Replace(**ARGUMENTS)
113 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
114 # Create it even when cleaning, to silence the doxygen builder warnings
115 if not os.path.exists("Doxyfile.local"):
116 Execute(Touch("Doxyfile.local"))
118 # Create local_config.h
119 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
120 Execute(Touch("local_config.hh"))
122 ###########################################################################
123 # Define build targets
125 # Before defining any targets, check wether this is the first build in
126 # pristine directory tree. If so, call 'scons prepare' so the dependencies
127 # created later are correct (yes, this is a hack :-( )
129 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
130 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
131 env.Execute([ "scons prepare" ])
132 env.Clean('all', '.prepare-stamp')
134 # Load SConscripts. Need to load some first (they change the global environment)
140 SConscript(initSConscripts)
142 if os.path.exists('SConscript.local'):
143 SConscript('SConscript.local')
145 SConscript(list(set(glob.glob("*/SConscript")) - set(initSConscripts)))
147 # Define the main targets
148 SENFSCons.StandardTargets(env)
149 SENFSCons.GlobalTargets(env)
151 env.Depends( SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']) )
153 libsenf = env.Library(env.subst("$LIBSENF$LIBADDSUFFIX"), env['ALLOBJECTS'])
155 env.Clean('all', libsenf)
156 env.Alias('default', libsenf)
158 SENFSCons.InstallIncludeFiles(env, [ 'config.hh' ])
159 env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
161 if env.GetOption('clean'):
162 env.Clean('all', [ os.path.join(path,f)
163 for path, subdirs, files in os.walk('.')
164 for pattern in env['CLEAN_PATTERNS']
165 for f in fnmatch.filter(files,pattern) ])
167 SENFSCons.PhonyTarget(env, 'prepare', [ 'true' ])
169 SENFSCons.PhonyTarget(env, 'valgrind', [ """
171 | while read test; do
173 echo "Running $$test";
175 valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup
176 $$test $BOOSTTESTARGS;
177 [ $$? -ne 99 ] || exit 1;
179 """.replace("\n"," ") ], [ 'all_tests' ])
181 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
182 Execute(Touch(".prepare-stamp"))