Correctly parse boolen command line arguments
[senf.git] / SConstruct
1 # -*- python -*-
2
3 import sys, glob, os.path, fnmatch
4 import SENFSCons, senfutil
5
6 ###########################################################################
7 # Load utilities and setup libraries and configure build
8
9 env = Environment()
10
11 # Load all the local SCons tools
12 env.Tool('Doxygen')
13 env.Tool('Dia2Png')
14 env.Tool('PkgDraw')
15 env.Tool('InstallSubdir')
16 env.Tool('CopyToDir')
17 env.Tool('Boost')
18 env.Tool('CombinedObject')
19 env.Tool('PhonyTarget')
20 env.Tool('InstallDir')
21
22 env.Help("""
23 Additional top-level build targets:
24
25 prepare      Create all target files not part of the repository
26 default      Build all default targets (like calling scons with no arguments)
27 examples     Build all examples
28 all_tests    Build and run unit tests for all modules
29 all_docs     Build documentation for all modules
30 all          Build everything
31 install_all  Install SENF into $$PREFIX
32 deb          Build debian source and binary package
33 debsrc       Build debian source package
34 debbin       Build debian binary package
35 linklint     Check links of doxygen documentation with 'linklint'
36 fixlinks     Fix broken links in doxygen documentation
37 valgrind     Run all tests under valgrind/memcheck
38 """)
39
40 env.Replace(
41    PKGDRAW                = 'doclib/pkgdraw',
42 )
43
44 env.Append(
45    ENV                    = { 'PATH' : os.environ.get('PATH') },
46    CLEAN_PATTERNS         = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*', '.sconsign' ],
47
48    CPPPATH                = [ '#' ],
49    LOCALLIBDIR            = '#',
50    LIBPATH                = [ '$LOCALLIBDIR' ],
51    LIBS                   = [ '$LIBSENF$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB', 
52                               '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ], 
53    TEST_EXTRA_LIBS        = [  ],
54
55    PREFIX                 = '#/dist',
56    LIBINSTALLDIR          = '$PREFIX${syslayout and "/lib" or ""}',
57    BININSTALLDIR          = '$PREFIX${syslayout and "/bin" or ""}',
58    INCLUDEINSTALLDIR      = '$PREFIX${syslayout and "/include" or ""}',
59    OBJINSTALLDIR          = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}',
60    DOCINSTALLDIR          = '$PREFIX/manual',
61    SCONSINSTALLDIR        = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}/site_scons',
62    CONFINSTALLDIR         = '$OBJINSTALLDIR',
63
64    CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
65    CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
66
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',
76                               '$CXXFLAGS_' ],
77    CXXFLAGS_              = senfutil.BuildTypeOptions('CXXFLAGS'),
78    CXXFLAGS_final         = [ '-O3' ],
79    CXXFLAGS_normal        = [ '-O0', '-g' ],
80    CXXFLAGS_debug         = [ '$CXXFLAGS_normal' ],
81
82    CPPDEFINES             = [ '$expandLogOption', '$CPPDEFINES_' ],
83    expandLogOption        = senfutil.expandLogOption,
84    CPPDEFINES_            = senfutil.BuildTypeOptions('CPPDEFINES'),
85    CPPDEFINES_final       = [ ],
86    CPPDEFINES_normal      = [ 'SENF_DEBUG' ],
87    CPPDEFINES_debug       = [ '$CPPDEFINES_normal' ],
88
89    LINKFLAGS              = [ '-rdynamic', '$LINKFLAGS_' ],
90    LINKFLAGS_             = senfutil.BuildTypeOptions('LINKFLAGS'),
91    LINKFLAGS_final        = [ ],
92    LINKFLAGS_normal       = [ '-Wl,-S' ],
93    LINKFLAGS_debug        = [ '-g' ],
94 )
95
96 env.SetDefault(
97     LIBSENF   = "senf",
98     final     = False,
99     debug     = False,
100     syslayout = False
101 )
102
103 # Set variables from command line
104 senfutil.parseArguments(
105     env,
106     BoolVariable('final', 'Build final (optimized) build', False),
107     BoolVariable('debug', 'Link in debug symbols', False),
108     BoolVariable('syslayout', 'Install in to system layout directories (lib/, include/ etc)', False),
109 )
110
111 Export('env')
112
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"))
117
118 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
119    and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
120     env.Execute([ "scons prepare" ])
121
122 # Load SConscripts
123
124 SConscriptChdir(0)
125 SConscript("debian/SConscript")
126 SConscriptChdir(1)
127 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
128 SConscript("senf/SConscript")
129 SConscript("Examples/SConscript")
130 SConscript("HowTos/SConscript")
131 SConscript("doclib/SConscript")
132
133 ###########################################################################
134 # Define build targets
135
136 #### doc
137 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
138
139 #### libsenf.a
140 libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS'])
141 env.Default(libsenf)
142 env.Install('$LIBINSTALLDIR', libsenf)
143
144 def create(target, source, env): 
145     file(str(target[0]), 'w').write(source[0].get_contents()+"\n")
146 env['BUILDERS']['CreateFile'] = Builder(action = create)
147
148 conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf", 
149                       env.Value(env.subst("$_CPPDEFFLAGS")))
150 env.Default(conf)
151 env.Install('$CONFINSTALLDIR', conf)
152
153 #### install_all, default, all_tests, all
154 env.Install('${SCONSINSTALLDIR}', 'site_scons/senfutil.py')
155
156 env.Alias('install_all', env.FindInstalledFiles())
157 env.Alias('default', DEFAULT_TARGETS)
158 env.Alias('all_tests', env.FindAllBoostUnitTests())
159 env.Alias('all', [ 'default', 'all_tests', 'examples', 'all_docs' ])
160
161 #### prepare
162 env.PhonyTarget('prepare', [], [])
163
164 #### valgrind
165 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
166     find -name .test.bin 
167         | while read test; do
168             echo;
169             echo "Running $$test";
170             echo;
171             valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup 
172                 $$test $BOOSTTESTARGS;
173             [ $$? -ne 99 ] || exit 1;
174         done
175 """.replace("\n"," ") ])
176
177 #### clean
178 env.Clean('all', '.prepare-stamp')
179 env.Clean('all', libsenf)
180 env.Clean('all', env.Dir('linklint')) # env.Dir to disambiguate from linklint PhonyTarget
181
182 if env.GetOption('clean'):
183     env.Clean('all', [ os.path.join(path,f)
184                        for path, subdirs, files in os.walk('.')
185                        for pattern in env['CLEAN_PATTERNS']
186                        for f in fnmatch.filter(files,pattern) ])
187
188 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
189     Execute(Touch(".prepare-stamp"))