From: g0dil Date: Wed, 19 Aug 2009 15:07:37 +0000 (+0000) Subject: Move all build env settings from SENFSCons to SConstruct X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=a5428583d411aae9d768f55deea83b8a7abb25a1;p=senf.git Move all build env settings from SENFSCons to SConstruct git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1305 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/.gitignore b/.gitignore index e32c449..f3de496 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /build-indep-stamp /configure-stamp /linklint +/SConscript.local # File name patters to ignore in all directories *.pyc diff --git a/SConstruct b/SConstruct index 2340272..cca03b8 100644 --- a/SConstruct +++ b/SConstruct @@ -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) diff --git a/doclib/doxygen.sh b/doclib/doxygen.sh index b2acf84..e78b914 100755 --- a/doclib/doxygen.sh +++ b/doclib/doxygen.sh @@ -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 index 0000000..058efc5 --- /dev/null +++ b/senfscons/Boost.py @@ -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 diff --git a/senfscons/SENFSCons.py b/senfscons/SENFSCons.py index 1701b99..176b8ea 100644 --- a/senfscons/SENFSCons.py +++ b/senfscons/SENFSCons.py @@ -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 Boost library -# -# Configure the use of the Boost -# 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: -# -# -# -# -# -# -# -#
\c BOOST_INCLUDESInclude directory.
\c BOOST_LIBDIRLibrary directory
\c BOOST_VARIANTComplete variant specification
\c BOOST_TOOLSETToolset to use
\c BOOST_RUNTIMERuntime to use
\c BOOST_DEBUG_RUNTIMEExplicit debug runtime
-# -# 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 Boost.Build -# 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 STLPort 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: -# -# -# -# -# -#
\c STLPORT_INCLUDESInclude directory.
\c STLPORT_LIBDIRLibrary directory
\c STLPORT_LIBName of STLPort library
\c STLPORT_DEBUGLIBName of STLPort debug library
-# -# 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 final=1 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 diff --git a/senfscons/senfutil.py b/senfscons/senfutil.py index d1a2808..a2b1ce8 100644 --- a/senfscons/senfutil.py +++ b/senfscons/senfutil.py @@ -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'):