Move sourcecode into 'senf/' directory
[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
21 env.Help("""
22 Additional top-level build targets:
23
24 prepare      Create all target files not part of the repository
25 all_tests    Build and run unit tests for all modules
26 all_docs     Build documentation for all modules
27 all          Build everything
28 install_all  Install SENF into $PREFIX
29 deb          Build debian source and binary package
30 debsrc       Build debian source package
31 debbin       Build debian binary package
32 linklint     Check links of doxygen documentation with 'linklint'
33 fixlinks     Fix broken links in doxygen documentation
34 valgrind     Run all tests under valgrind/memcheck
35 """)
36
37 class BuildTypeOptions:
38     def __init__(self, var):
39         self._var = var
40
41     def __call__(self, target, source, env, for_signature):
42         type = env['final'] and "final" or env['debug'] and "debug" or "normal"
43         return env[self._var + "_" + type]
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                 = '/usr/local',
61    LIBINSTALLDIR          = '$PREFIX/lib',
62    BININSTALLDIR          = '$PREFIX/bin',
63    INCLUDEINSTALLDIR      = '$PREFIX/include',
64    OBJINSTALLDIR          = '$LIBINSTALLDIR',
65    DOCINSTALLDIR          = '$PREFIX/doc',
66    CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
67    CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
68
69    # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
70    INLINE_OPTS_DEBUG      = [ '-finline-limit=20000', '-fvisibility-inlines-hidden', 
71                               '-fno-inline-functions', '-Winline' 
72                               '--param','large-function-growth=10000',
73                               '--param', 'large-function-insns=10000', 
74                               '--param','inline-unit-growth=10000' ],
75    INLINE_OPTS_NORMAL     = [ '-finline-limit=5000' ],
76    INLINE_OPTS            = [ '$INLINE_OPTS_NORMAL' ],
77    CXXFLAGS               = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
78                               '$CXXFLAGS_' ],
79    CXXFLAGS_              = BuildTypeOptions('CXXFLAGS'),
80    CXXFLAGS_final         = [ '-O3' ],
81    CXXFLAGS_normal        = [ '-O0', '-g' ],
82    CXXFLAGS_debug         = [ '$CXXFLAGS_normal' ],
83
84    CPPDEFINES             = [ '$expandLogOption', '$CPPDEFINES_' ],
85    expandLogOption        = senfutil.expandLogOption,
86    CPPDEFINES_            = BuildTypeOptions('CPPDEFINES'),
87    CPPDEFINES_final       = [ ],
88    CPPDEFINES_normal      = [ 'SENF_DEBUG' ],
89    CPPDEFINES_debug       = [ '$CPPDEFINES_normal' ],
90
91    LINKFLAGS              = [ '-rdynamic', '$LINKFLAGS_' ],
92    LINKFLAGS_             = BuildTypeOptions('LINKFLAGS'),
93    LINKFLAGS_final        = [ ],
94    LINKFLAGS_normal       = [ '-Wl,-S' ],
95    LINKFLAGS_debug        = [ ],
96 )
97
98 env.SetDefault(
99     LIBSENF = "senf",
100     final   = 0,
101     debug   = 0,
102 )
103
104 # Set variables from command line
105 env.Replace(**ARGUMENTS)
106
107 Export('env')
108
109 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
110 # Create it even when cleaning, to silence the doxygen builder warnings
111 if not os.path.exists("Doxyfile.local"):
112     Execute(Touch("Doxyfile.local"))
113
114 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
115    and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
116     env.Execute([ "scons prepare" ])
117
118 # Load SConscripts
119
120 SConscript("debian/SConscript")
121 SConscript("doclib/SConscript")
122 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
123
124 SConscript("senf/SConscript")
125
126 SConscript("Examples/SConscript")
127 SConscript("HowTos/SConscript")
128
129 ###########################################################################
130 # Define build targets
131
132 #### doc
133 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
134
135 #### libsenf.a
136 libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS'])
137 env.Default(libsenf)
138
139 env.Install('$LIBINSTALLDIR', libsenf)
140
141 #### install_all, default, all_tests, all
142 env.Alias('install_all', env.FindInstalledFiles())
143 env.Alias('default', DEFAULT_TARGETS)
144 env.Alias('all_tests', env.FindAllBoostUnitTests())
145 env.Alias('all', [ 'default', 'all_tests', 'all_docs' ])
146
147 #### prepare
148 env.PhonyTarget('prepare', [], [])
149
150 #### valgrind
151 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
152     find -name .test.bin 
153         | while read test; do
154             echo;
155             echo "Running $$test";
156             echo;
157             valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup 
158                 $$test $BOOSTTESTARGS;
159             [ $$? -ne 99 ] || exit 1;
160         done
161 """.replace("\n"," ") ])
162
163 #### clean
164 env.Clean('all', '.prepare-stamp')
165 env.Clean('all', libsenf)
166 env.Clean('all', env.Dir('linklint')) # env.Dir to disambiguate from linklint PhonyTarget
167
168 if env.GetOption('clean'):
169     env.Clean('all', [ os.path.join(path,f)
170                        for path, subdirs, files in os.walk('.')
171                        for pattern in env['CLEAN_PATTERNS']
172                        for f in fnmatch.filter(files,pattern) ])
173
174 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
175     Execute(Touch(".prepare-stamp"))