Remove ProgramNoScan builder
[senf.git] / SConstruct
1 # -*- python -*-
2
3 import sys, glob, os.path, datetime, pwd, time, fnmatch, string
4 sys.path.append(Dir('#/senfscons').abspath)
5 sys.path.append(Dir('#/doclib').abspath)
6 import SENFSCons, senfutil
7
8 ###########################################################################
9 # Load utilities and setup libraries and configure build
10
11 env = Environment()
12
13 # Load all the local SCons tools
14 env.Tool('Doxygen', [ 'senfscons' ])
15 env.Tool('Dia2Png', [ 'senfscons' ])
16 env.Tool('PkgDraw', [ 'senfscons' ])
17 env.Tool('CopyToDir', [ 'senfscons' ])
18 env.Tool('CompileCheck', [ 'senfscons' ])
19 env.Tool('Boost', [ 'senfscons' ])
20 env.Tool('BoostUnitTests', [ 'senfscons' ])
21
22 env.Help("""
23 Additional top-level build targets:
24
25 prepare      Create all source files not part of the repository
26 all_tests    Build and run unit tests for all modules
27 all_docs     Build documentation for all modules
28 all          Build everything
29 install_all  Install SENF into $PREFIX
30 deb          Build debian source and binary package
31 debsrc       Build debian source package
32 debbin       Build debian binary package
33 linklint     Check links of doxygen documentation with 'linklint'
34 fixlinks     Fix broken links in doxygen documentation
35 valgrind     Run all tests under valgrind/memcheck
36 """)
37
38 class BuildTypeOptions:
39     def __init__(self, var):
40         self._var = var
41
42     def __call__(self, source, target, env, for_signature):
43         type = env['final'] and "final" or env['debug'] and "debug" or "normal"
44         return env[self._var + "_" + type]
45
46 env.Append(
47    ENV                    = { 'PATH' : os.environ.get('PATH') },
48    CLEAN_PATTERNS         = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*', '.sconsign' ],
49
50    CPPPATH                = [ '#/include' ],
51    LOCALLIBDIR            = '#',
52    LIBPATH                = [ '$LOCALLIBDIR' ],
53    LIBS                   = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
54                               '$BOOSTFSLIB' ], 
55    TEST_EXTRA_LIBS        = [ ],
56
57    PREFIX                 = '/usr/local',
58    LIBINSTALLDIR          = '$PREFIX/lib',
59    BININSTALLDIR          = '$PREFIX/bin',
60    INCLUDEINSTALLDIR      = '$PREFIX/include',
61    OBJINSTALLDIR          = '$LIBINSTALLDIR',
62    DOCINSTALLDIR          = '$PREFIX/doc',
63    CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
64    CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
65
66    # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
67    INLINE_OPTS_DEBUG      = [ '-finline-limit=20000', '-fvisibility-inlines-hidden', 
68                               '-fno-inline-functions', '-Winline' 
69                               '--param','large-function-growth=10000',
70                               '--param', 'large-function-insns=10000', 
71                               '--param','inline-unit-growth=10000' ],
72    INLINE_OPTS_NORMAL     = [ '-finline-limit=5000' ],
73    INLINE_OPTS            = [ '$INLINE_OPTS_NORMAL' ],
74    CXXFLAGS               = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
75                               '$CXXFLAGS_' ],
76    CXXFLAGS_              = BuildTypeOptions('CXXFLAGS'),
77    CXXFLAGS_final         = [ '-O3' ],
78    CXXFLAGS_normal        = [ '-O0', '-g' ],
79    CXXFLAGS_debug         = [ '$CXXFLAGS_normal' ],
80
81    CPPDEFINES             = [ '$expandLogOption', '$CPPDEFINES_' ],
82    expandLogOption        = senfutil.expandLogOption,
83    CPPDEFINES_            = BuildTypeOptions('CPPDEFINES'),
84    CPPDEFINES_final       = [ ],
85    CPPDEFINES_normal      = [ 'SENF_DEBUG' ],
86    CPPDEFINES_debug       = [ '$CPPDEFINES_normal' ],
87
88    LINKFLAGS              = [ '-rdynamic', '$LINKFLAGS_' ],
89    LINKFLAGS_             = BuildTypeOptions('LINKFLAGS'),
90    LINKFLAGS_final        = [ ],
91    LINKFLAGS_normal       = [ '-Wl,-S' ],
92    LINKFLAGS_debug        = [ ],
93 )
94
95 env.SetDefault(
96     LIBSENF = "senf",
97     final   = 0,
98     debug   = 0,
99 )
100
101 # Set variables from command line
102 env.Replace(**ARGUMENTS)
103
104 Export('env')
105
106 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
107 # Create it even when cleaning, to silence the doxygen builder warnings
108 if not os.path.exists("Doxyfile.local"):
109     Execute(Touch("Doxyfile.local"))
110
111 # Create local_config.h
112 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
113     Execute(Touch("local_config.hh"))
114
115 ###########################################################################
116 # Define build targets
117
118 # Before defining any targets, check wether this is the first build in
119 # pristine directory tree. If so, call 'scons prepare' so the dependencies
120 # created later are correct (yes, this is a hack :-( )
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 env.Clean('all', '.prepare-stamp')
126
127 # Load SConscripts. Need to load some first (they change the global environment)
128 initSConscripts = [ 
129     "debian/SConscript",
130     "doclib/SConscript",
131 ]
132
133 SConscript(initSConscripts)
134
135 if os.path.exists('SConscript.local'):
136     SConscript('SConscript.local')
137
138 SConscript(list(set(glob.glob("*/SConscript")) - set(initSConscripts)))
139
140 # Define the main targets
141 env.Alias('all', [ 'default', 'all_tests', 'all_docs' ])
142
143 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
144
145 libsenf = env.Library(env.subst("$LIBSENF$LIBADDSUFFIX"), env['ALLOBJECTS'])
146 env.Default(libsenf)
147 env.Clean('all', libsenf)
148 env.Alias('default', libsenf)
149
150 SENFSCons.InstallIncludeFiles(env, [ 'config.hh' ])
151 env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
152
153 if env.GetOption('clean'):
154     env.Clean('all', [ os.path.join(path,f)
155                        for path, subdirs, files in os.walk('.')
156                        for pattern in env['CLEAN_PATTERNS']
157                        for f in fnmatch.filter(files,pattern) ])
158
159 SENFSCons.PhonyTarget(env, 'prepare', [ 'true' ])
160
161 SENFSCons.PhonyTarget(env, 'valgrind', [ """
162     find -name .test.bin 
163         | while read test; do
164             echo;
165             echo "Running $$test";
166             echo;
167             valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup 
168                 $$test $BOOSTTESTARGS;
169             [ $$? -ne 99 ] || exit 1;
170         done
171 """.replace("\n"," ") ], [ 'all_tests' ])
172
173 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
174     Execute(Touch(".prepare-stamp"))