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