Move all build env settings from SENFSCons to SConstruct
g0dil [Wed, 19 Aug 2009 15:07:37 +0000 (15:07 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1305 270642c3-0616-0410-b53a-bc976706d245

.gitignore
SConstruct
doclib/doxygen.sh
senfscons/Boost.py [new file with mode: 0644]
senfscons/SENFSCons.py
senfscons/senfutil.py

index e32c449..f3de496 100644 (file)
@@ -8,6 +8,7 @@
 /build-indep-stamp
 /configure-stamp
 /linklint
+/SConscript.local
 
 # File name patters to ignore in all directories
 *.pyc
index 2340272..cca03b8 100644 (file)
@@ -8,9 +8,17 @@ import SENFSCons, senfutil
 ###########################################################################
 # Load utilities and setup libraries and configure build
 
-SENFSCons.UseBoost()
-SENFSCons.UseSTLPort()
-env = SENFSCons.MakeEnvironment()
+env = Environment()
+
+# Load all the local SCons tools
+env.Tool('Doxygen', [ 'senfscons' ])
+env.Tool('Dia2Png', [ 'senfscons' ])
+env.Tool('PkgDraw', [ 'senfscons' ])
+env.Tool('CopyToDir', [ 'senfscons' ])
+env.Tool('ProgramNoScan', [ 'senfscons' ])
+env.Tool('CompileCheck', [ 'senfscons' ])
+env.Tool('Boost', [ 'senfscons' ])
+env.Tool('BoostUnitTests', [ 'senfscons' ])
 
 env.Help("""
 Additional top-level build targets:
@@ -28,32 +36,77 @@ fixlinks     Fix broken links in doxygen documentation
 valgrind     Run all tests under valgrind/memcheck
 """)
 
+# Compile options
+
 # Options used to debug inlining:
 #
-# INLINE_OPTS = [ '-finline-limit=20000', '--param','large-function-growth=10000',
-#                 '--param', 'large-function-insns=10000', '--param','inline-unit-growth=10000',
-#                 '-fvisibility-inlines-hidden', '-fno-inline-functions', '-Winline' ]
-#
 # BEWARE: You need lots of ram to compile with these settings (approx 1G)
 
-INLINE_OPTS = [ '-finline-limit=5000' ]
+class BuildTypeOptions:
+    def __init__(self, var):
+        self._var = var
+
+    def __call__(self, source, target, env, for_signature):
+        type = env['final'] and "final" or env['debug'] and "debug" or "normal"
+        return env[self._var + "_" + type]
 
 env.Append(
-   CPPPATH         = [ '#/include' ],
-   CXXFLAGS        = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ] + INLINE_OPTS,
-   LIBS            = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
-                       '$BOOSTFSLIB' ],
-   TEST_EXTRA_LIBS = [ ],
-   ENV             = { 'PATH' : os.environ.get('PATH') },
-   CLEAN_PATTERNS  = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign', '.sconsign.dblite' ],
+   ENV                    = { 'PATH' : os.environ.get('PATH') },
+   CLEAN_PATTERNS         = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*' ],
+
+   CPPPATH                = [ '#/include' ],
+   LOCALLIBDIR            = '#',
+   LIBPATH                = [ '$LOCALLIBDIR' ],
+   LIBS                   = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
+                              '$BOOSTFSLIB' ], 
+   TEST_EXTRA_LIBS        = [ ],
+
+   PREFIX                 = '/usr/local',
+   LIBINSTALLDIR          = '$PREFIX/lib',
+   BININSTALLDIR          = '$PREFIX/bin',
+   INCLUDEINSTALLDIR      = '$PREFIX/include',
+   OBJINSTALLDIR          = '$LIBINSTALLDIR',
+   DOCINSTALLDIR          = '$PREFIX/doc',
+   CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ],
+   CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ],
+
+   # These options are insane. Only useful for inline debugging. Need at least 1G free RAM
+   INLINE_OPTS_DEBUG      = [ '-finline-limit=20000', '-fvisibility-inlines-hidden', 
+                              '-fno-inline-functions', '-Winline' 
+                              '--param','large-function-growth=10000',
+                              '--param', 'large-function-insns=10000', 
+                              '--param','inline-unit-growth=10000' ],
+   INLINE_OPTS_NORMAL     = [ '-finline-limit=5000' ],
+   INLINE_OPTS            = [ '$INLINE_OPTS_NORMAL' ],
+   CXXFLAGS               = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS',
+                              '$CXXFLAGS_' ],
+   CXXFLAGS_              = BuildTypeOptions('CXXFLAGS'),
+   CXXFLAGS_final         = [ '-O3' ],
+   CXXFLAGS_normal        = [ '-O0', '-g' ],
+   CXXFLAGS_debug         = [ '$CXXFLAGS_normal' ],
+
+   CPPDEFINES             = [ '$expandLogOption', '$CPPDEFINES_' ],
+   expandLogOption        = senfutil.expandLogOption,
+   CPPDEFINES_            = BuildTypeOptions('CPPDEFINES'),
+   CPPDEFINES_final       = [ ],
+   CPPDEFINES_normal      = [ 'SENF_DEBUG' ],
+   CPPDEFINES_debug       = [ '$CPPDEFINES_normal' ],
+
+   LINKFLAGS              = [ '-rdynamic', '$LINKFLAGS_' ],
+   LINKFLAGS_             = BuildTypeOptions('LINKFLAGS'),
+   LINKFLAGS_final        = [ ],
+   LINKFLAGS_normal       = [ '-Wl,-S' ],
+   LINKFLAGS_debug        = [ ],
 )
 
 env.SetDefault(
-    LIBSENF = "senf"
+    LIBSENF = "senf",
+    final   = 0,
+    debug   = 0,
 )
 
-# Parse the log option command line parameter into the SENF_LOG_CONF macro
-senfutil.setLogOption(env)
+# Set variables from command line
+env.Replace(**ARGUMENTS)
 
 Export('env')
 
@@ -71,17 +124,25 @@ if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
 
 # Before defining any targets, check wether this is the first build in
 # pristine directory tree. If so, call 'scons prepare' so the dependencies
-# created later are correct
+# created later are correct (yes, this is a hack :-( )
 
 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
    and not os.environ.get("SCONS") and COMMAND_LINE_TARGETS != [ 'prepare' ]:
     env.Execute([ "scons prepare" ])
 env.Clean('all', '.prepare-stamp')
 
-# Load SConscripts. Need to load debian and doclib first (they change the global environment)
-SConscript("debian/SConscript")
-SConscript("doclib/SConscript")
-SConscript(list(set(glob.glob("*/SConscript")) - set(("debian/SConscript", "doclib/SConscript"))))
+# Load SConscripts. Need to load some first (they change the global environment)
+initSConscripts = [ 
+    "debian/SConscript",
+    "doclib/SConscript",
+]
+
+SConscript(initSConscripts)
+
+if os.path.exists('SConscript.local'):
+    SConscript('SConscript.local')
+
+SConscript(list(set(glob.glob("*/SConscript")) - set(initSConscripts)))
 
 # Define the main targets
 SENFSCons.StandardTargets(env)
index b2acf84..e78b914 100755 (executable)
@@ -122,7 +122,6 @@ if [ ! -r "SConstruct" ]; then
 fi
 TOPDIR="`pwd`";
 reltopdir="`relpath "$doxydir/$output_dir/$html_dir" "$TOPDIR"`" #`"
-echo "relpath $doxydir/$output_dir/$html_dir $TOPDIR -> $reltopdir"
 cd "$doxydir"
 
 
diff --git a/senfscons/Boost.py b/senfscons/Boost.py
new file mode 100644 (file)
index 0000000..058efc5
--- /dev/null
@@ -0,0 +1,15 @@
+# Provide environment variables for boost libraries
+
+def generate(env):
+    env.SetDefault(
+        BOOST_VARIANT     = '',
+
+        BOOSTTESTLIB      = 'boost_unit_test_framework$BOOST_VARIANT',
+        BOOSTREGEXLIB     = 'boost_regex$BOOST_VARIANT',
+        BOOSTFSLIB        = 'boost_filesystem$BOOST_VARIANT',
+        BOOSTIOSTREAMSLIB = 'boost_iostreams$BOOST_VARIANT',
+        BOOSTSIGNALSLIB   = 'boost_signals$BOOST_VARIANT',
+    )
+
+def exists(env):
+    return True
index 1701b99..176b8ea 100644 (file)
@@ -46,250 +46,6 @@ from SCons.Script import *
 # The SENFSCons framework includes a series of builders. Each builder
 # is defined in it's own package.
 
-# Tools to load in MakeEnvironment
-SCONS_TOOLS = [
-    "Doxygen",
-    "Dia2Png",
-    "PkgDraw",
-    "CopyToDir",
-    "ProgramNoScan",
-    "CompileCheck",
-]
-
-opts = None
-finalizers = []
-
-# This is the directory SENFSCons.py resides
-basedir = os.path.abspath(os.path.split(__file__)[0])
-
-## \brief Initialize configuration options
-# \internal
-def InitOpts():
-    global opts
-    if opts is not None: return
-    opts = SCons.Options.Options('SConfig')
-    opts.Add('CXX', 'C++ compiler to use', 'g++')
-    opts.Add('EXTRA_DEFINES', 'Additional preprocessor defines', '')
-    opts.Add('EXTRA_LIBS', 'Additional libraries to link against', '')
-    opts.Add('EXTRA_CCFLAGS', 'Additional compilation parameters', '')
-    opts.Add(SCons.Options.BoolOption('final','Enable optimization',0))
-    opts.Add(SCons.Options.BoolOption('debug','Enable debug symbols in binaries',0))
-    opts.Add(SCons.Options.BoolOption('profile','Enable profiling',0))
-    opts.Add('PREFIX', 'Installation prefix', '/usr/local')
-    opts.Add('LIBINSTALLDIR', 'Library install dir', '$PREFIX/lib')
-    opts.Add('BININSTALLDIR', 'Executable install dir', '$PREFIX/bin')
-    opts.Add('INCLUDEINSTALLDIR', 'Include-file install dir', '$PREFIX/include')
-    opts.Add('OBJINSTALLDIR', 'Static object file install dir', '$LIBINSTALLDIR')
-    opts.Add('DOCINSTALLDIR', 'Documentation install dir', '$PREFIX/doc')
-    opts.Add('CPP_INCLUDE_EXTENSIONS', 'File extensions to include in source install',
-             [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti', '.mpp' ])
-    opts.Add('CPP_EXCLUDE_EXTENSIONS', 'File extensions to exclude from source install',
-             [ '.test.hh' ])
-
-# A finalizer is any callable object. All finalizers will be called
-# in MakeEnvironment. We use them so every finalizer has knowledge of
-# all frameworks in use (e.g.: the boost runtime depends on the use of
-# stlport).
-
-## \brief Register finalizer
-# \internal
-def Finalizer(f):
-    global finalizers
-    finalizers.append(f)
-
-## \brief Initialize the use of the <a href="http://www.boost.org/">Boost</a> library
-#
-# Configure the use of the <a href="http://www.boost.org">Boost</a>
-# libraries. Most of these libraries are header-only, some however
-# depend on a built library. The library selection is somewhat
-# involved and depends on the threading model and the type of build
-# (debug or final).
-#
-# \par Configuration Parameters:
-#     <table class="senf">
-#     <tr><td>\c BOOST_INCLUDES</td><td>Include directory.</td></tr>
-#     <tr><td>\c BOOST_LIBDIR</td><td>Library directory</td></tr>
-#     <tr><td>\c BOOST_VARIANT</td><td>Complete variant specification</td></tr>
-#     <tr><td>\c BOOST_TOOLSET</td><td>Toolset to use</td></tr>
-#     <tr><td>\c BOOST_RUNTIME</td><td>Runtime to use</td></tr>
-#     <tr><td>\c BOOST_DEBUG_RUNTIME</td><td>Explicit debug runtime</td></tr>
-#     </table>
-#
-# You can either specify \c BOOST_VARIANT explicitly or specify \c
-# BOOST_TOOLSET and \c BOOST_RUNTIME. If you give \c BOOST_TOOLSET, \c
-# BOOST_RUNTIME defaults to empty and \c BOOST_DEBUG_RUNTIME defaults
-# to \c gd, If \c BOOST_TOOLSET is specified and you have included
-# STLPort support (UseSTLPort()), then \c p is appended to both
-# runtimes.
-#
-# The Boost configuration can get realtively complex. If the boost
-# libraries are provided by the distribution, you probably don't need
-# to specify any parameters. If your configuration is more complex,
-# refer to the <a
-# href="http://www.boost.org/tools/build/v2/index.html">Boost.Build</a>
-# documentation for a definition of the terms used above (toolset,
-# variant, runtime ...).
-#
-# \ingroup use
-def UseBoost():
-    global opts
-    InitOpts()
-    opts.Add('BOOST_INCLUDES', 'Boost include directory', '')
-    opts.Add('BOOST_VARIANT', 'The boost variant to use', '')
-    opts.Add('BOOST_TOOLSET', 'The boost toolset to use', '')
-    opts.Add('BOOST_RUNTIME', 'The boost runtime to use', '')
-    opts.Add('BOOST_DEBUG_RUNTIME', 'The boost debug runtime to use', '')
-    opts.Add('BOOST_LIBDIR', 'The directory of the boost libraries', '')
-    opts.Add('BOOST_PREFIX', 'The prefix into which boost is installed', '')
-    opts.Add('BOOST_VERSION', 'The version of boost to use', '')
-    Finalizer(FinalizeBoost)
-
-## \brief Finalize Boost environment
-# \internal
-def FinalizeBoost(env):
-    env.Tool('BoostUnitTests', [basedir])
-
-    if env['BOOST_TOOLSET']:
-        runtime = ""
-        if env['final'] : runtime += env.get('BOOST_RUNTIME','')
-        else            : runtime += env.get('BOOST_DEBUG_RUNTIME','gd')
-        if env['STLPORT_LIB'] : runtime += "p"
-        if runtime: runtime = "-" + runtime
-        env['BOOST_VARIANT'] = "-" + env['BOOST_TOOLSET'] + runtime
-
-    if env['BOOST_VARIANT'] and env['BOOST_VERSION']:
-        env['BOOST_VARIANT'] = env['BOOST_VARIANT'] + '-%s' % env['BOOST_VERSION'].replace('.','_')
-
-    env['BOOSTTESTLIB'] = 'boost_unit_test_framework' + env['BOOST_VARIANT']
-    env['BOOSTREGEXLIB'] = 'boost_regex' + env['BOOST_VARIANT']
-    env['BOOSTFSLIB'] = 'boost_filesystem' + env['BOOST_VARIANT']
-    env['BOOSTIOSTREAMSLIB'] = 'boost_iostreams' + env['BOOST_VARIANT']
-    env['BOOSTSIGNALSLIB'] = 'boost_signals' + env['BOOST_VARIANT']
-
-    if env['BOOST_PREFIX']:
-        env['BOOST_LIBDIR'] = os.path.join(env['BOOST_PREFIX'], 'lib')
-        env['BOOST_INCLUDES'] = os.path.join(env['BOOST_PREFIX'],
-                                             'include/boost-%s'
-                                                 % env['BOOST_VERSION'].replace('.','_'))
-
-    env.Append(LIBPATH = [ '$BOOST_LIBDIR' ],
-               CPPPATH = [ '$BOOST_INCLUDES' ])
-
-    if env['BOOST_LIBDIR']:
-        env.Append(ENV = { 'LD_LIBRARY_PATH': env['BOOST_LIBDIR'] })
-
-## \brief Use STLPort as STL replacement if available
-#
-# Use <a href="http://www.stlport.org">STLPort</a> as a replacement
-# for the system STL. STLPort has the added feature of providing fully
-# checked containers and iterators. This can greatly simplify
-# debugging. However, STLPort and Boost interact in a non-trivial way
-# so the configuration is relatively complex. This command does not
-# enforce the use of STLPort, it is only used if available.
-#
-# \par Configuration Parameters:
-#     <table class="senf">
-#     <tr><td>\c STLPORT_INCLUDES</td><td>Include directory.</td></tr>
-#     <tr><td>\c STLPORT_LIBDIR</td><td>Library directory</td></tr>
-#     <tr><td>\c STLPORT_LIB</td><td>Name of STLPort library</td></tr>
-#     <tr><td>\c STLPORT_DEBUGLIB</td><td>Name of STLPort debug library</td></tr>
-#     </table>
-#
-# If \c STLPORT_LIB is specified, \c STLPORT_DEBUGLIB defaults to \c
-# STLPORT_LIB with \c _stldebug appended. The STLPort library will
-# only be used, if \c STLPORT_LIB is set in \c SConfig.
-#
-# \ingroup use
-def UseSTLPort():
-    global opts
-    InitOpts()
-    opts.Add('STLPORT_INCLUDES', 'STLport include directory', '')
-    opts.Add('STLPORT_LIB', 'Name of the stlport library or empty to not use stlport', '')
-    opts.Add('STLPORT_DEBUGLIB', 'Name of the stlport debug library','')
-    opts.Add('STLPORT_LIBDIR', 'The directory of the stlport libraries','')
-    Finalizer(FinalizeSTLPort)
-
-# \}
-
-## \brief Finalize STLPort environment
-# \internal
-def FinalizeSTLPort(env):
-    if env['STLPORT_LIB']:
-        if not env['STLPORT_DEBUGLIB']:
-            env['STLPORT_DEBUGLIB'] = env['STLPORT_LIB'] + '_stldebug'
-        env.Append(LIBPATH = [ '$STLPORT_LIBDIR' ],
-                   CPPPATH = [ '$STLPORT_INCLUDES' ])
-        if env['final']:
-            env.Append(LIBS = [ '$STLPORT_LIB' ])
-        else:
-            env.Append(LIBS = [ '$STLPORT_DEBUGLIB' ],
-                       CPPDEFINES = [ '_STLP_DEBUG' ])
-
-## \brief Build a configured construction environment
-#
-# This function is called after all frameworks are specified to build
-# a tailored construction environment. You can then use this
-# construction environment just like an ordinary SCons construction
-# environment (which it is ...)
-#
-# This call will set some default compilation parameters depending on
-# the \c final command line option: specifying <tt>final=1</tt> will
-# built a release version of the code.
-def MakeEnvironment():
-    global opts, finalizers
-    InitOpts()
-    env = SCons.Environment.Environment(options=opts)
-    env.Replace(**SCons.Script.SConscript.Arguments)
-    #for opt in opts.options:
-    #    if SCons.Script.SConscript.Arguments.get(opt.key):
-    #        env[opt.key] = SCons.Script.SConscript.Arguments.get(opt.key)
-    #if SCons.Script.SConscript.Arguments.get('final'):
-    #    env['final'] = 1
-    env.Help("\nSupported build variables (either in SConfig or on the command line:\n")
-    env.Help(opts.GenerateHelpText(env))
-
-    # We want to pass the SSH_AUTH_SOCK system env-var so we can ssh
-    # into other hosts from within SCons rules. I have used rules like
-    # this e.g. to automatically install stuff on a remote system ...
-    if os.environ.has_key('SSH_AUTH_SOCK'):
-        env.Append( ENV = { 'SSH_AUTH_SOCK': os.environ['SSH_AUTH_SOCK'] } )
-
-    for finalizer in finalizers:
-        finalizer(env)
-
-    for tool in SCONS_TOOLS:
-        env.Tool(tool, [basedir])
-
-    # These are the default compilation parameters. We should probably
-    # make these configurable
-    env.Append(LOCALLIBDIR = [ '#' ],
-               LIBPATH = [ '$LOCALLIBDIR' ])
-
-    if env['final']:
-        env.Append(CXXFLAGS = [ '-O3' ])
-        if env['profile']:
-            env.Append(CXXFLAGS = [ '-g', '-pg' ],
-                       LINKFLAGS = [ '-g', '-pg' ])
-    else:
-        # The boost-regex library is not compiled with _GLIBCXX_DEBUG so this fails:
-        #          CPPDEFINES = [ '_GLIBCXX_DEBUG' ],
-        env.Append(CXXFLAGS = [ '-O0', '-g' ],
-                   CPPDEFINES = { 'SENF_DEBUG': ''})
-        if env['profile']:
-            env.Append(CXXFLAGS = [ '-pg' ],
-                       LINKFLAGS = [ '-pg' ])
-        if env['debug'] or env['profile']:
-            env.Append(LINKFLAGS = [ '-g', '-rdynamic' ])
-        else:
-            env.Append(LINKFLAGS = [ '-Wl,-S', '-rdynamic' ])
-
-    env.Append(CPPDEFINES = [ '$EXTRA_DEFINES' ],
-               LIBS = [ '$EXTRA_LIBS' ],
-               CXXFLAGS = [ '$EXTRA_CCFLAGS' ],
-               ALLOBJECTS = [])
-
-    return env
-
 ## \brief Find normal and test C++ sources
 #
 # GlobSources() will return a list of all C++ source files (named
index d1a2808..a2b1ce8 100644 (file)
@@ -1,21 +1,18 @@
 import os.path
 from SCons.Script import *
 
-def setLogOption(env):
-    # Parse LOGLEVELS parameter
-    def parseLogOption(value):
-        stream, area, level = ( x.strip() for x in value.strip().split('|') )
-        stream = ''.join('(%s)' % x for x in stream.split('::') )
-        if area : area = ''.join( '(%s)' % x for x in area.split('::') )
-        else    : area = '(_)'
-        return '(( %s,%s,%s ))' % (stream,area,level)
+def parseLogOption(value):
+    stream, area, level = ( x.strip() for x in value.strip().split('|') )
+    stream = ''.join('(%s)' % x for x in stream.split('::') )
+    if area : area = ''.join( '(%s)' % x for x in area.split('::') )
+    else    : area = '(_)'
+    return '((%s,%s,%s))' % (stream,area,level)
 
-    def expandLogOption(target, source, env, for_signature):
-        return ' '.join( parseLogOption(x) for x in env.subst('$LOGLEVELS').split() )
-
-    if env.subst('$LOGLEVELS'):
-        env.Append( expandLogOption=expandLogOption )
-        env.Append( CPPDEFINES = { 'SENF_LOG_CONF': '$expandLogOption' } )
+def expandLogOption(target, source, env, for_signature):
+    if env.get('LOGLEVELS'):
+        return [ 'SENF_LOG_CONF="' + ''.join( parseLogOption(x) for x in env.subst('$LOGLEVELS').split() )+'"']
+    else:
+        return []
 
 
 ###########################################################################
@@ -40,6 +37,9 @@ def SetupForSENF(env):
                 SENF_BUILDOPTS = [ '-j%s' % (env.GetOption('num_jobs') or "1") ],
                 CXXFLAGS_debug  = [ '-O0', '-g', '-fno-inline' ],
                 LINKFLAGS_debug = [ '-g', '-rdynamic' ],
+                
+                expandLogOption = expandLogOption,
+                CPPDEFINES      = [ '$expandLogOptions' ],
                 )
 
     # Add command-line options: 'LOGLEVELS' and 'final'
@@ -53,8 +53,6 @@ def SetupForSENF(env):
 
     env.Help(opts.GenerateHelpText(env))
 
-    setLogOption(env)
-
     # If we have a symbolic link (or directory) 'senf', we use it as our
     # senf repository
     if os.path.exists('senf'):