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