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