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
39 class BuildTypeOptions:
40 def __init__(self, var):
43 def __call__(self, source, target, env, for_signature):
44 type = env['final'] and "final" or env['debug'] and "debug" or "normal"
45 return env[self._var + "_" + type]
48 ENV = { 'PATH' : os.environ.get('PATH') },
49 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*', '.sconsign' ],
51 CPPPATH = [ '#/include' ],
53 LIBPATH = [ '$LOCALLIBDIR' ],
54 LIBS = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
56 TEST_EXTRA_LIBS = [ ],
58 PREFIX = '/usr/local',
59 LIBINSTALLDIR = '$PREFIX/lib',
60 BININSTALLDIR = '$PREFIX/bin',
61 INCLUDEINSTALLDIR = '$PREFIX/include',
62 OBJINSTALLDIR = '$LIBINSTALLDIR',
63 DOCINSTALLDIR = '$PREFIX/doc',
64 CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
65 CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
67 # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
68 INLINE_OPTS_DEBUG = [ '-finline-limit=20000', '-fvisibility-inlines-hidden',
69 '-fno-inline-functions', '-Winline'
70 '--param','large-function-growth=10000',
71 '--param', 'large-function-insns=10000',
72 '--param','inline-unit-growth=10000' ],
73 INLINE_OPTS_NORMAL = [ '-finline-limit=5000' ],
74 INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ],
75 CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
77 CXXFLAGS_ = BuildTypeOptions('CXXFLAGS'),
78 CXXFLAGS_final = [ '-O3' ],
79 CXXFLAGS_normal = [ '-O0', '-g' ],
80 CXXFLAGS_debug = [ '$CXXFLAGS_normal' ],
82 CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ],
83 expandLogOption = senfutil.expandLogOption,
84 CPPDEFINES_ = BuildTypeOptions('CPPDEFINES'),
85 CPPDEFINES_final = [ ],
86 CPPDEFINES_normal = [ 'SENF_DEBUG' ],
87 CPPDEFINES_debug = [ '$CPPDEFINES_normal' ],
89 LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ],
90 LINKFLAGS_ = BuildTypeOptions('LINKFLAGS'),
91 LINKFLAGS_final = [ ],
92 LINKFLAGS_normal = [ '-Wl,-S' ],
93 LINKFLAGS_debug = [ ],
102 # Set variables from command line
103 env.Replace(**ARGUMENTS)
107 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
108 # Create it even when cleaning, to silence the doxygen builder warnings
109 if not os.path.exists("Doxyfile.local"):
110 Execute(Touch("Doxyfile.local"))
112 # Create local_config.h
113 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
114 Execute(Touch("local_config.hh"))
116 ###########################################################################
117 # Define build targets
119 # Before defining any targets, check wether this is the first build in
120 # pristine directory tree. If so, call 'scons prepare' so the dependencies
121 # created later are correct (yes, this is a hack :-( )
123 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
124 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
125 env.Execute([ "scons prepare" ])
126 env.Clean('all', '.prepare-stamp')
128 # Load SConscripts. Need to load some first (they change the global environment)
134 SConscript(initSConscripts)
136 if os.path.exists('SConscript.local'):
137 SConscript('SConscript.local')
139 SConscript(list(set(glob.glob("*/SConscript")) - set(initSConscripts)))
141 # Define the main targets
142 env.Alias('all', [ 'default', 'all_tests', 'all_docs' ])
144 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
146 libsenf = env.Library(env.subst("$LIBSENF$LIBADDSUFFIX"), env['ALLOBJECTS'])
148 env.Clean('all', libsenf)
149 env.Alias('default', libsenf)
151 SENFSCons.InstallIncludeFiles(env, [ 'config.hh' ])
152 env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
154 if env.GetOption('clean'):
155 env.Clean('all', [ os.path.join(path,f)
156 for path, subdirs, files in os.walk('.')
157 for pattern in env['CLEAN_PATTERNS']
158 for f in fnmatch.filter(files,pattern) ])
160 SENFSCons.PhonyTarget(env, 'prepare', [ 'true' ])
162 SENFSCons.PhonyTarget(env, 'valgrind', [ """
164 | while read test; do
166 echo "Running $$test";
168 valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup
169 $$test $BOOSTTESTARGS;
170 [ $$? -ne 99 ] || exit 1;
172 """.replace("\n"," ") ], [ 'all_tests' ])
174 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
175 Execute(Touch(".prepare-stamp"))