Fix documentation dependencies
[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',
62    BININSTALLDIR          = '$PREFIX',
63    INCLUDEINSTALLDIR      = '$PREFIX',
64    OBJINSTALLDIR          = '$LIBINSTALLDIR',
65    DOCINSTALLDIR          = '$PREFIX/docs',
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 if os.path.exists('SConscript.local') : SConscript('SConscript.local')
122 SConscript("senf/SConscript")
123 SConscript("Examples/SConscript")
124 SConscript("HowTos/SConscript")
125 SConscript("doclib/SConscript")
126
127 ###########################################################################
128 # Define build targets
129
130 #### doc
131 env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION']))
132
133 #### libsenf.a
134 libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS'])
135 env.Default(libsenf)
136
137 env.Install('$LIBINSTALLDIR', libsenf)
138
139 #### install_all, default, all_tests, all
140 env.Alias('install_all', env.FindInstalledFiles())
141 env.Alias('default', DEFAULT_TARGETS)
142 env.Alias('all_tests', env.FindAllBoostUnitTests())
143 env.Alias('all', [ 'default', 'all_tests', 'all_docs' ])
144
145 #### prepare
146 env.PhonyTarget('prepare', [], [])
147
148 #### valgrind
149 env.PhonyTarget('valgrind', [ 'all_tests' ], [ """
150     find -name .test.bin 
151         | while read test; do
152             echo;
153             echo "Running $$test";
154             echo;
155             valgrind --tool=memcheck --error-exitcode=99 --suppressions=valgrind.sup 
156                 $$test $BOOSTTESTARGS;
157             [ $$? -ne 99 ] || exit 1;
158         done
159 """.replace("\n"," ") ])
160
161 #### clean
162 env.Clean('all', '.prepare-stamp')
163 env.Clean('all', libsenf)
164 env.Clean('all', env.Dir('linklint')) # env.Dir to disambiguate from linklint PhonyTarget
165
166 if env.GetOption('clean'):
167     env.Clean('all', [ os.path.join(path,f)
168                        for path, subdirs, files in os.walk('.')
169                        for pattern in env['CLEAN_PATTERNS']
170                        for f in fnmatch.filter(files,pattern) ])
171     env.Clean('all', '.')
172
173 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
174     Execute(Touch(".prepare-stamp"))