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