Add senf.conf support and update senfutil
[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 Build parameters:
40
41 final=1      Build optimized library without debug symbols
42 debug=1      Link all binaries with debug symbols (slow!)
43 syslayout=1  Install into system layout directories ($$PREFIX/lib, $$PREFIX/include etc)
44
45 additionally, any construction environment variable may be set from the scons
46 command line (see SConstruct file and SCons documentation for a list of variables).
47 """)
48
49 env.Replace(
50    PKGDRAW                = 'doclib/pkgdraw',
51 )
52
53 env.Append(
54    ENV                    = { 'PATH' : os.environ.get('PATH') },
55    CLEAN_PATTERNS         = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*', '.sconsign' ],
56
57    CPPPATH                = [ '#' ],
58    LOCALLIBDIR            = '#',
59    LIBPATH                = [ '$LOCALLIBDIR' ],
60    LIBS                   = [ '$LIBSENF$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB', 
61                               '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ], 
62    TEST_EXTRA_LIBS        = [  ],
63
64    PREFIX                 = '#/dist',
65    LIBINSTALLDIR          = '$PREFIX${syslayout and "/lib" or ""}',
66    BININSTALLDIR          = '$PREFIX${syslayout and "/bin" or ""}',
67    INCLUDEINSTALLDIR      = '$PREFIX${syslayout and "/include" or ""}',
68    OBJINSTALLDIR          = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}',
69    DOCINSTALLDIR          = '$PREFIX/manual',
70    SCONSINSTALLDIR        = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}/site_scons',
71    CONFINSTALLDIR         = '$OBJINSTALLDIR',
72
73    CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
74    CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
75
76    # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
77    INLINE_OPTS_DEBUG      = [ '-finline-limit=20000', '-fvisibility-inlines-hidden', 
78                               '-fno-inline-functions', '-Winline' 
79                               '--param','large-function-growth=10000',
80                               '--param', 'large-function-insns=10000', 
81                               '--param','inline-unit-growth=10000' ],
82    INLINE_OPTS_NORMAL     = [ '-finline-limit=5000' ],
83    INLINE_OPTS            = [ '$INLINE_OPTS_NORMAL' ],
84    CXXFLAGS               = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
85                               '$CXXFLAGS_' ],
86    CXXFLAGS_              = senfutil.BuildTypeOptions('CXXFLAGS'),
87    CXXFLAGS_final         = [ '-O3' ],
88    CXXFLAGS_normal        = [ '-O0', '-g' ],
89    CXXFLAGS_debug         = [ '$CXXFLAGS_normal' ],
90
91    CPPDEFINES             = [ '$expandLogOption', '$CPPDEFINES_' ],
92    expandLogOption        = senfutil.expandLogOption,
93    CPPDEFINES_            = senfutil.BuildTypeOptions('CPPDEFINES'),
94    CPPDEFINES_final       = [ ],
95    CPPDEFINES_normal      = [ 'SENF_DEBUG' ],
96    CPPDEFINES_debug       = [ '$CPPDEFINES_normal' ],
97
98    LINKFLAGS              = [ '-rdynamic', '$LINKFLAGS_' ],
99    LINKFLAGS_             = senfutil.BuildTypeOptions('LINKFLAGS'),
100    LINKFLAGS_final        = [ ],
101    LINKFLAGS_normal       = [ '-Wl,-S' ],
102    LINKFLAGS_debug        = [ ],
103 )
104
105 env.SetDefault(
106     LIBSENF   = "senf",
107     final     = 0,
108     debug     = 0,
109     syslayout = 0
110 )
111
112 # Set variables from command line
113 env.Replace(**ARGUMENTS)
114
115 Export('env')
116
117 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
118 # Create it even when cleaning, to silence the doxygen builder warnings
119 if not os.path.exists("Doxyfile.local"):
120     Execute(Touch("Doxyfile.local"))
121
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
126 # Load SConscripts
127
128 SConscriptChdir(0)
129 SConscript("debian/SConscript")
130 SConscriptChdir(1)
131 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
132 SConscript("senf/SConscript")
133 SConscript("Examples/SConscript")
134 SConscript("HowTos/SConscript")
135 SConscript("doclib/SConscript")
136
137 ###########################################################################
138 # Define build targets
139
140 #### doc
141 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
142
143 #### libsenf.a
144 libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS'])
145 env.Default(libsenf)
146 env.Install('$LIBINSTALLDIR', libsenf)
147
148 def create(target, source, env): 
149     file(str(target[0]), 'w').write(source[0].get_contents()+"\n")
150 env['BUILDERS']['CreateFile'] = Builder(action = create)
151
152 conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf", 
153                       env.Value(env.subst("$_CPPDEFFLAGS")))
154 env.Default(conf)
155 env.Install('$CONFINSTALLDIR', conf)
156
157 #### install_all, default, all_tests, all
158 env.Install('${SCONSINSTALLDIR}', 'site_scons/senfutil.py')
159
160 env.Alias('install_all', env.FindInstalledFiles())
161 env.Alias('default', DEFAULT_TARGETS)
162 env.Alias('all_tests', env.FindAllBoostUnitTests())
163 env.Alias('all', [ 'default', 'all_tests', 'examples', 'all_docs' ])
164
165 #### prepare
166 env.PhonyTarget('prepare', [], [])
167
168 #### valgrind
169 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
170     find -name .test.bin 
171         | while read test; do
172             echo;
173             echo "Running $$test";
174             echo;
175             valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup 
176                 $$test $BOOSTTESTARGS;
177             [ $$? -ne 99 ] || exit 1;
178         done
179 """.replace("\n"," ") ])
180
181 #### clean
182 env.Clean('all', '.prepare-stamp')
183 env.Clean('all', libsenf)
184 env.Clean('all', env.Dir('linklint')) # env.Dir to disambiguate from linklint PhonyTarget
185
186 if env.GetOption('clean'):
187     env.Clean('all', [ os.path.join(path,f)
188                        for path, subdirs, files in os.walk('.')
189                        for pattern in env['CLEAN_PATTERNS']
190                        for f in fnmatch.filter(files,pattern) ])
191
192 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
193     Execute(Touch(".prepare-stamp"))