169b0f3931c441568d9727d24494ae76d427d6d7
[senf.git] / satscons / SatSCons.py
1 import os.path, SCons.Options, SCons.Environment, SCons.Script.SConscript, glob
2
3 opts = None
4 finalizers = []
5
6 def InitOpts():
7     global opts
8     if opts is not None: return
9     opts = SCons.Options.Options('SConfig')
10     opts.Add('CXX', 'C++ compiler to use', 'g++')
11     opts.Add('EXTRA_DEFINES', 'Additional preprocessor defines', '')
12     opts.Add('EXTRA_LIBS', 'Additional libraries to link against', '')
13     opts.Add(SCons.Options.BoolOption('final','Enable optimization',0))
14
15 def Finalizer(f):
16     global finalizers
17     finalizers.append(f)
18
19 def UseBoost():
20     global opts
21     InitOpts()
22     opts.Add('BOOST_INCLUDES', 'Boost include directory', '')
23     opts.Add('BOOST_VARIANT', 'The boost variant to use', '')
24     opts.Add('BOOST_TOOLSET', 'The boost toolset to use', '')
25     opts.Add('BOOST_RUNTIME', 'The boost runtime to use', '')
26     opts.Add('BOOST_DEBUG_RUNTIME', 'The boost debug runtime to use', '')
27     opts.Add('BOOST_LIBDIR', 'The directory of the boost libraries', '')
28     Finalizer(FinalizeBoost)
29
30 def FinalizeBoost(env):
31     env.Tool('BoostUnitTests', [os.path.split(__file__)[0]])
32
33     if env['BOOST_TOOLSET']:
34         runtime = ""
35         if env['final'] : runtime += env.get('BOOST_RUNTIME','')
36         else            : runtime += env.get('BOOST_DEBUG_RUNTIME','gd')
37         if env['STLPORT_LIB'] : runtime += "p"
38         if runtime: runtime = "-" + runtime
39         env['BOOST_VARIANT'] = "-" + env['BOOST_TOOLSET'] + runtime
40
41     env['BOOSTTESTLIB'] = 'libboost_unit_test_framework' + env['BOOST_VARIANT']
42
43     env.Append(LIBPATH = [ '$BOOST_LIBDIR' ],
44                CPPPATH = [ '$BOOST_INCLUDES' ])
45
46 def UseSTLPort():
47     global opts
48     InitOpts()
49     opts.Add('STLPORT_INCLUDES', 'STLport include directory', '')
50     opts.Add('STLPORT_LIB', 'Name of the stlport library or empty to not use stlport', '')
51     opts.Add('STLPORT_DEBUGLIB', 'Name of the stlport debug library','')
52     opts.Add('STLPORT_LIBDIR', 'The directory of the stlport libraries','')
53     Finalizer(FinalizeSTLPort)
54
55 def FinalizeSTLPort(env):
56     if env['STLPORT_LIB']:
57         if not env['STLPORT_DEBUGLIB']:
58             env['STLPORT_DEBUGLIB'] = env['STLPORT_LIB'] + '_stldebug'
59         env.Append(LIBPATH = [ '$STLPORT_LIBDIR' ],
60                    CPPPATH = [ '$STLPORT_INCLUDES' ])
61         if env['final']:
62             env.Append(LIBS = [ '$STLPORT_LIB' ])
63         else:
64             env.Append(LIBS = [ '$STLPORT_DEBUGLIB' ],
65                        CPPDEFINES = [ '_STLP_DEBUG' ])
66
67 def UseDoxygen():
68     Finalizer(FinalizeDoxygen)
69
70 def FinalizeDoxygen(env):
71     env.Tool('Doxygen', [os.path.split(__file__)[0]])
72     
73 def MakeEnvironment():
74     global opts, finalizers
75     InitOpts()
76     env = SCons.Environment.Environment(options=opts)
77     if SCons.Script.SConscript.Arguments.get('final'):
78         env['final'] = 1
79     env.Help(opts.GenerateHelpText(env))
80     #conf = env.Configure()
81     #env = conf.env
82     if os.environ.has_key('SSH_AUTH_SOCK'):
83         env.Append( ENV = { 'SSH_AUTH_SOCK': os.environ['SSH_AUTH_SOCK'] } )
84
85     for finalizer in finalizers:
86         finalizer(env)
87
88     env.Append(CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ],
89                LOCALLIBDIR = [ '#' ],
90                LIBPATH = [ '$LOCALLIBDIR' ])
91
92     if env['final']:
93         env.Append(CXXFLAGS = [ '-O3' ],
94                    CPPDEFINES = [ 'NDEBUG' ])
95     else:
96         env.Append(CXXFLAGS = [ '-O0', '-g', '-fno-inline' ],
97                    LINKFLAGS = [ '-g' ])
98
99     env.Append(CPPDEFINES = [ '$EXTRA_DEFINES' ],
100                LIBS = [ '$EXTRA_LIBS' ])
101
102     #return conf.Finish()
103     return env
104
105 def GlobSources(exclude=[]):
106     testSources = glob.glob("*.test.cc")
107     sources = [ x for x in glob.glob("*.cc") if x not in testSources and x not in exclude ]
108     return (sources, testSources)
109     
110 def StandardTargets(env):
111     all = env.Alias('all')
112     env.Clean(all, [ '.sconsign', '.sconf_temp', 'config.log', 'ChangeLog.bak', '.clean'
113                      ] + glob.glob("*~"))
114     env.Depends(all, '.')
115
116 def GlobalTargets(env):
117     command = "find -name .svn -prune -o \( -name '*.hh' -o -name '*.ih' -o -name '*.cc' -o -name '*.cci' -o -name '*.ct' -o -name '*.cti' -o -name '*.mpp' \) -print " \
118               "| xargs -r awk -F '//' '/%s/{print ARGV[ARGIND] \":\" FNR \":\" $2}' > $TARGET"
119     env.AlwaysBuild(env.Command('TODOS',None,[ command % 'TODO' ]))
120     env.AlwaysBuild(env.Command('FIXMES',None,[ command % ' FIXME' ]))
121     env.AlwaysBuild(env.Command('BUGS',None,[ command % 'BUG' ] ))
122     env.Alias('status',[ 'TODOS', 'FIXMES', 'BUGS' ])
123
124 def LibPath(lib): return '$LOCALLIBDIR/lib%s.a' % lib
125     
126 def Objects(env, sources, testSources = None, LIBS = []):
127     if type(sources) == type(()):
128         testSources = sources[1]
129         sources = sources[0]
130
131     objects = None
132     if sources:
133         objects = env.Object(sources)
134
135     if testSources:
136         test = env.BoostUnitTests(
137             target = 'test',
138             source = sources,
139             test_source = testSources,
140             LIBS = LIBS,
141             DEPENDS = [ env.File(LibPath(x)) for x in LIBS ])
142         env.Alias('all_tests', test)
143         # Hmm ... here I'd like to use an Alias instead of a file
144         # however the alias does not seem to live in the subdirectory
145         # which breaks 'scons -u test'
146         env.Alias(env.File('test'), test)
147
148     return objects
149
150 def DoxyGlob(exclude=[]):
151     sources = [ f
152                 for ext in ("cci", "ct", "cti", "h", "hh", "ih", "mmc", "dox")
153                 for f in glob.glob("*."+ext)
154                 if f not in exclude ]
155     return sources
156
157 def Doxygen(env, cc_sources = [], doc_sources = None, target='doc', image = []):
158     if type(cc_sources) == type(()):
159         cc_sources = cc_sources[0]
160     sources = cc_sources
161     if doc_sources is not None:
162         sources += doc_sources
163     doc = env.Doxygen(
164         target = target,
165         source = sources,
166         image = image)
167
168     env.Alias('all_docs', doc)
169     return doc
170
171 def Lib(env, library, sources, testSources = None, LIBS = []):
172     objects = Objects(env,sources,testSources,LIBS=LIBS)
173     lib = None
174     if objects:
175         lib = env.Library(env.File(LibPath(library)),objects)
176         env.Default(lib)
177         env.Append(ALLLIBS = library)
178     return lib
179
180 def Binary(env, binary, sources, testSources = None, LIBS = []):
181     objects = Objects(env,sources,testSources,LIBS=LIBS)
182     program = None
183     if objects:
184         progEnv = env.Copy()
185         progEnv.Prepend(LIBS = LIBS)
186         program = progEnv.Program(target=binary,source=objects)
187         env.Default(program)
188         env.Depends(program, [ env.File(LibPath(x)) for x in LIBS ])
189     return program