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('CompileCheck', [ 'senfscons' ])
19 env.Tool('Boost', [ 'senfscons' ])
20 env.Tool('BoostUnitTests', [ 'senfscons' ])
23 Additional top-level build targets:
25 prepare Create all source files not part of the repository
26 all_tests Build and run unit tests for all modules
27 all_docs Build documentation for all modules
29 install_all Install SENF into $PREFIX
30 deb Build debian source and binary package
31 debsrc Build debian source package
32 debbin Build debian binary package
33 linklint Check links of doxygen documentation with 'linklint'
34 fixlinks Fix broken links in doxygen documentation
35 valgrind Run all tests under valgrind/memcheck
38 class BuildTypeOptions:
39 def __init__(self, var):
42 def __call__(self, source, target, env, for_signature):
43 type = env['final'] and "final" or env['debug'] and "debug" or "normal"
44 return env[self._var + "_" + type]
47 ENV = { 'PATH' : os.environ.get('PATH') },
48 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*', '.sconsign' ],
50 CPPPATH = [ '#/include' ],
52 LIBPATH = [ '$LOCALLIBDIR' ],
53 LIBS = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
55 TEST_EXTRA_LIBS = [ ],
57 PREFIX = '/usr/local',
58 LIBINSTALLDIR = '$PREFIX/lib',
59 BININSTALLDIR = '$PREFIX/bin',
60 INCLUDEINSTALLDIR = '$PREFIX/include',
61 OBJINSTALLDIR = '$LIBINSTALLDIR',
62 DOCINSTALLDIR = '$PREFIX/doc',
63 CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
64 CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
66 # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
67 INLINE_OPTS_DEBUG = [ '-finline-limit=20000', '-fvisibility-inlines-hidden',
68 '-fno-inline-functions', '-Winline'
69 '--param','large-function-growth=10000',
70 '--param', 'large-function-insns=10000',
71 '--param','inline-unit-growth=10000' ],
72 INLINE_OPTS_NORMAL = [ '-finline-limit=5000' ],
73 INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ],
74 CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
76 CXXFLAGS_ = BuildTypeOptions('CXXFLAGS'),
77 CXXFLAGS_final = [ '-O3' ],
78 CXXFLAGS_normal = [ '-O0', '-g' ],
79 CXXFLAGS_debug = [ '$CXXFLAGS_normal' ],
81 CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ],
82 expandLogOption = senfutil.expandLogOption,
83 CPPDEFINES_ = BuildTypeOptions('CPPDEFINES'),
84 CPPDEFINES_final = [ ],
85 CPPDEFINES_normal = [ 'SENF_DEBUG' ],
86 CPPDEFINES_debug = [ '$CPPDEFINES_normal' ],
88 LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ],
89 LINKFLAGS_ = BuildTypeOptions('LINKFLAGS'),
90 LINKFLAGS_final = [ ],
91 LINKFLAGS_normal = [ '-Wl,-S' ],
92 LINKFLAGS_debug = [ ],
101 # Set variables from command line
102 env.Replace(**ARGUMENTS)
106 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
107 # Create it even when cleaning, to silence the doxygen builder warnings
108 if not os.path.exists("Doxyfile.local"):
109 Execute(Touch("Doxyfile.local"))
111 # Create local_config.h
112 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
113 Execute(Touch("local_config.hh"))
115 ###########################################################################
116 # Define build targets
118 # Before defining any targets, check wether this is the first build in
119 # pristine directory tree. If so, call 'scons prepare' so the dependencies
120 # created later are correct (yes, this is a hack :-( )
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" ])
125 env.Clean('all', '.prepare-stamp')
127 # Load SConscripts. Need to load some first (they change the global environment)
133 SConscript(initSConscripts)
135 if os.path.exists('SConscript.local'):
136 SConscript('SConscript.local')
138 SConscript(list(set(glob.glob("*/SConscript")) - set(initSConscripts)))
140 # Define the main targets
141 env.Alias('all', [ 'default', 'all_tests', 'all_docs' ])
143 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
145 libsenf = env.Library(env.subst("$LIBSENF$LIBADDSUFFIX"), env['ALLOBJECTS'])
147 env.Clean('all', libsenf)
148 env.Alias('default', libsenf)
150 SENFSCons.InstallIncludeFiles(env, [ 'config.hh' ])
151 env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
153 if env.GetOption('clean'):
154 env.Clean('all', [ os.path.join(path,f)
155 for path, subdirs, files in os.walk('.')
156 for pattern in env['CLEAN_PATTERNS']
157 for f in fnmatch.filter(files,pattern) ])
159 SENFSCons.PhonyTarget(env, 'prepare', [ 'true' ])
161 SENFSCons.PhonyTarget(env, 'valgrind', [ """
163 | while read test; do
165 echo "Running $$test";
167 valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup
168 $$test $BOOSTTESTARGS;
169 [ $$? -ne 99 ] || exit 1;
171 """.replace("\n"," ") ], [ 'all_tests' ])
173 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
174 Execute(Touch(".prepare-stamp"))