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('InstallSubdir', [ 'senfscons' ])
18 env.Tool('CopyToDir', [ 'senfscons' ])
19 env.Tool('Boost', [ 'senfscons' ])
20 env.Tool('CombinedObject', [ 'senfscons' ])
21 env.Tool('PhonyTarget', [ 'senfscons' ])
24 Additional top-level build targets:
26 prepare Create all target 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, target, source, env, for_signature):
44 type = env['final'] and "final" or env['debug'] and "debug" or "normal"
45 return env[self._var + "_" + type]
48 PKGDRAW = 'doclib/pkgdraw',
52 ENV = { 'PATH' : os.environ.get('PATH') },
53 CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*', '.sconsign' ],
55 CPPPATH = [ '#/include' ],
57 LIBPATH = [ '$LOCALLIBDIR' ],
58 LIBS = [ '$LIBSENF$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB',
59 '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ],
60 TEST_EXTRA_LIBS = [ ],
62 PREFIX = '/usr/local',
63 LIBINSTALLDIR = '$PREFIX/lib',
64 BININSTALLDIR = '$PREFIX/bin',
65 INCLUDEINSTALLDIR = '$PREFIX/include',
66 OBJINSTALLDIR = '$LIBINSTALLDIR',
67 DOCINSTALLDIR = '$PREFIX/doc',
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_ = 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_ = BuildTypeOptions('CPPDEFINES'),
89 CPPDEFINES_final = [ ],
90 CPPDEFINES_normal = [ 'SENF_DEBUG' ],
91 CPPDEFINES_debug = [ '$CPPDEFINES_normal' ],
93 LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ],
94 LINKFLAGS_ = BuildTypeOptions('LINKFLAGS'),
95 LINKFLAGS_final = [ ],
96 LINKFLAGS_normal = [ '-Wl,-S' ],
97 LINKFLAGS_debug = [ ],
106 # Set variables from command line
107 env.Replace(**ARGUMENTS)
111 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
112 # Create it even when cleaning, to silence the doxygen builder warnings
113 if not os.path.exists("Doxyfile.local"):
114 Execute(Touch("Doxyfile.local"))
116 # Create local_config.h
117 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
118 Execute(Touch("local_config.hh"))
120 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
121 and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
122 env.Execute([ "scons prepare" ])
124 # Load SConscripts. Need to load some first (they change the global environment)
130 SConscript(initSConscripts)
132 if os.path.exists('SConscript.local'):
133 SConscript('SConscript.local')
135 SConscript(list(set(glob.glob("*/SConscript")) - set(initSConscripts)))
137 ###########################################################################
138 # Define build targets
141 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
144 libsenf = env.Library(env.subst("$LIBSENF$LIBADDSUFFIX"), env['ALLOBJECTS'])
147 env.InstallSubdir(target = '$INCLUDEINSTALLDIR', source = [ 'config.hh' ])
148 env.Install('$LIBINSTALLDIR', libsenf)
150 #### install_all, default, all_tests, all
151 env.Alias('install_all', env.FindInstalledFiles())
152 env.Alias('default', DEFAULT_TARGETS)
153 env.Alias('all_tests', env.FindAllBoostUnitTests())
154 env.Alias('all', [ 'default', 'all_tests', 'all_docs' ])
157 env.PhonyTarget('prepare', [], [])
160 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
162 | while read test; do
164 echo "Running $$test";
166 valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup
167 $$test $BOOSTTESTARGS;
168 [ $$? -ne 99 ] || exit 1;
170 """.replace("\n"," ") ])
173 env.Clean('all', '.prepare-stamp')
174 env.Clean('all', libsenf)
175 env.Clean('all', 'linklint')
177 if env.GetOption('clean'):
178 env.Clean('all', [ os.path.join(path,f)
179 for path, subdirs, files in os.walk('.')
180 for pattern in env['CLEAN_PATTERNS']
181 for f in fnmatch.filter(files,pattern) ])
183 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
184 Execute(Touch(".prepare-stamp"))