Rename senfscons to site_scons and move python files arround
[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                = [ '#/include' ],
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 # Create local_config.h
115 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
116     Execute(Touch("local_config.hh"))
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. Need to load some first (they change the global environment)
123 initSConscripts = [ 
124     "debian/SConscript",
125     "doclib/SConscript",
126 ]
127
128 SConscript(initSConscripts)
129
130 if os.path.exists('SConscript.local'):
131     SConscript('SConscript.local')
132
133 SConscript(list(set(glob.glob("*/SConscript")) - set(initSConscripts)))
134
135 ###########################################################################
136 # Define build targets
137
138 #### doc
139 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
140
141 #### libsenf.a
142 libsenf = env.Library(env.subst("$LIBSENF$LIBADDSUFFIX"), env['ALLOBJECTS'])
143 env.Default(libsenf)
144
145 env.InstallSubdir(target = '$INCLUDEINSTALLDIR', source = [ 'config.hh' ])
146 env.Install('$LIBINSTALLDIR', libsenf)
147
148 #### install_all, default, all_tests, all
149 env.Alias('install_all', env.FindInstalledFiles())
150 env.Alias('default', DEFAULT_TARGETS)
151 env.Alias('all_tests', env.FindAllBoostUnitTests())
152 env.Alias('all', [ 'default', 'all_tests', 'all_docs' ])
153
154 #### prepare
155 env.PhonyTarget('prepare', [], [])
156
157 #### valgrind
158 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
159     find -name .test.bin 
160         | while read test; do
161             echo;
162             echo "Running $$test";
163             echo;
164             valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup 
165                 $$test $BOOSTTESTARGS;
166             [ $$? -ne 99 ] || exit 1;
167         done
168 """.replace("\n"," ") ])
169
170 #### clean
171 env.Clean('all', '.prepare-stamp')
172 env.Clean('all', libsenf)
173 env.Clean('all', env.Dir('linklint')) # env.Dir to disambiguate from linklint PhonyTarget
174
175 if env.GetOption('clean'):
176     env.Clean('all', [ os.path.join(path,f)
177                        for path, subdirs, files in os.walk('.')
178                        for pattern in env['CLEAN_PATTERNS']
179                        for f in fnmatch.filter(files,pattern) ])
180
181 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
182     Execute(Touch(".prepare-stamp"))