Add senf.conf support and update senfutil
[senf.git] / site_scons / senfutil.py
1 import os.path
2 from SCons.Script import *
3
4 def parseLogOption(value):
5     stream, area, level = ( x.strip() for x in value.strip().split('|') )
6     stream = ''.join('(%s)' % x for x in stream.split('::') )
7     if area : area = ''.join( '(%s)' % x for x in area.split('::') )
8     else    : area = '(_)'
9     return '((%s,%s,%s))' % (stream,area,level)
10
11 def expandLogOption(target, source, env, for_signature):
12     if env.get('LOGLEVELS'):
13         return [ 'SENF_LOG_CONF="' + ''.join( parseLogOption(x) for x in env.subst('$LOGLEVELS').split() )+'"']
14     else:
15         return []
16
17 class BuildTypeOptions:
18     def __init__(self, var):
19         self._var = var
20
21     def __call__(self, target, source, env, for_signature):
22         type = env['final'] and "final" or env['debug'] and "debug" or "normal"
23         return env[self._var + "_" + type]
24
25 ###########################################################################
26 # This looks much more complicated than it is: We do three things here:
27 # a) switch between final or debug options
28 # b) parse the LOGLEVELS parameter into the correct SENF_LOG_CONF syntax
29 # c) check for a local SENF, set options accordingly and update that SENF if needed
30
31 def SetupForSENF(env, senf_paths = []):
32     senf_paths.extend(('senf', '../senf', os.path.dirname(os.path.dirname(__file__)),
33                        '/usr/local', '/usr'))
34     env.Append(
35         LIBS              = [ 'senf', 'rt', '$BOOSTREGEXLIB',
36                               '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
37                               '$BOOSTFSLIB' ],
38         BOOSTREGEXLIB     = 'boost_regex',
39         BOOSTIOSTREAMSLIB = 'boost_iostreams',
40         BOOSTSIGNALSLIB   = 'boost_signals',
41         BOOSTFSLIB        = 'boost_filesystem',
42         
43         CXXFLAGS          = [ '-Wno-long-long', '$CXXFLAGS_' ],
44         CXXFLAGS_         = BuildTypeOptions('CXXFLAGS'),
45         
46         CPPDEFINES        = [ '$expandLogOption', '$CPPDEFINES_' ],
47         expandLogOption   = expandLogOption,
48         CPPDEFINES_       = BuildTypeOptions('CPPDEFINES'),
49         
50         LINKFLAGS         = [ '-rdynamic', '$LINKFLAGS_' ],
51         LINKFLAGS_        = BuildTypeOptions('LINKFLAGS'),
52
53         LOGLEVELS         = [ '$LOGLEVELS_' ],
54         LOGLEVELS_        = BuildTypeOptions('LOGLEVELS'),
55         )
56
57     env.SetDefault( 
58         CXXFLAGS_final    = [],
59         CXXFLAGS_normal   = [],
60         CXXFLAGS_debug    = [],
61
62         CPPDEFINES_final  = [],
63         CPPDEFINES_normal = [],
64         CPPDEFINES_debug  = [],
65
66         LINKFLAGS_final   = [],
67         LINKFLAGS_normal  = [],
68         LINKFLAGS_debug   = [],
69
70         LOGLEVELS_final   = [],
71         LOGLEVELS_normal  = [],
72         LOGLEVELS_debug   = [],
73         )
74
75     # Interpret command line options
76     opts = Variables(ARGUMENTS)
77     opts.Add( 'LOGLEVELS', 'Special log levels. Syntax: <stream>|[<area>]|<level> ...',
78               '${"$LOGLEVELS_"+(final and "final" or "debug")}' )
79     opts.Add( BoolOption('final', 'Build final (optimized) build', False) )
80     opts.Add( BoolOption('debug', 'Link in debug symbols', False) )
81     opts.Update(env)
82     env.Replace(**dict(opts.UnknownVariables()))
83     env.Help(opts.GenerateHelpText(env))
84
85     # If we have a symbolic link (or directory) 'senf', we use it as our
86     # senf repository
87     for path in senf_paths:
88         if not path.startswith('/') : sconspath = '#/%s' % path
89         else                        : sconspath = path
90         if os.path.exists(os.path.join(path,"senf/config.hh")):
91             print "\nUsing SENF in '%s'\n" \
92                 % ('/..' in sconspath and os.path.abspath(path) or sconspath)
93             env.Append( LIBPATH = [ sconspath ],
94                         CPPPATH = [ sconspath ],
95                         BUNDLEDIR = sconspath )
96             try:
97                 env.MergeFlags(file(os.path.join(path,"senf.conf")).read())
98             except IOError:
99                 print "(SENF configuration file 'senf.conf' not found, assuming non-final SENF)"
100                 env.Append(CPPDEFINES = [ 'SENF_DEBUG' ])
101             break
102         elif os.path.exists(os.path.join(path,"include/senf/config.hh")):
103             print "\nUsing system SENF in '%s/'\n" % sconspath
104             env.Append(BUNDLEDIR = os.path.join(sconspath,"lib/senf"))
105             break
106     else:
107         print "\nSENF library not found .. trying build anyway !!\n"
108
109
110 def DefaultOptions(env):
111     env.Append(
112         CXXFLAGS         = [ '-Wall', '-Woverloaded-virtual' ],
113         CXXFLAGS_final   = [ '-O2' ],
114         CXXFLAGS_normal  = [ '-O0', '-g' ],
115         CXXFLAGS_debug   = [ '$CXXFLAGS_normal' ],
116
117         LINKFLAGS_normal = [ '-Wl,-S' ],
118     )