From: g0dil Date: Fri, 28 Aug 2009 09:28:48 +0000 (+0000) Subject: Add senf.conf support and update senfutil X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=3b28ce6a5f2029bdf2fba77f46e2aff31eef7f33 Add senf.conf support and update senfutil git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1349 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/.gitignore b/.gitignore index f5aa1f7..1bab2c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,8 @@ -# Local files (files in this directory) -/Doxyfile.local -/.prepare-stamp -/libsenf.a -/build-arch-debug-stamp -/build-arch-final-stamp -/build-indep-stamp -/configure-stamp -/linklint -/SConscript.local - # File name patters to ignore in all directories *.pyc *.png *.o +*.a *.test.checked .sconsign* *~ @@ -24,6 +14,12 @@ all_includes.hh doc/ .test.bin .test.stamp -/libsenf_g.a + +# Local files (files in this directory) +/Doxyfile.local +/SConscript.local +/*-stamp +/*.conf +/linklint /TODO /dist/ diff --git a/Mainpage.dox b/Mainpage.dox index 77ead86..571a519 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -55,54 +55,112 @@ \code import sys sys.path.extend(('senf/site_scons','/usr/lib/senf/site_scons')) - import os.path, glob, senfutil + import glob, senfutil env = Environment() + senfutil.SetupForSENF(env) + senfutil.DefaultOptions(env) - senfutil.SetupForSENF( env ) + env.Append( LOGLEVELS_debug = [ 'senf::log::Debug||VERBOSE' ] ) - env.Append( + env.Default( + env.Program( target = 'udpforward', source = glob.glob('*.cc') ) + ) + \endcode + + This example builds a simple binary from a number of source files (all '.cc' files). It links + against the SENF library and automatically sets all the correct compiler options using + senfutil.SetupForSENF( env ). + + This script automatically uses a SENF installation either symlinked or imported into the current + project in directory 'senf' or, if this directory does not exist, a globally installed SENF. - LIBS = [ ], - CXXFLAGS = [ '-Wall', '-Woverloaded-virtual' ], - LINKFLAGS = [ ], + \see \ref senf_senfutil +*/ + +/** \page senf_senfutil SENF SCons build utility + + The \c senfutil utility for SCons helps setting up a project to compile against SENF: + + \li \c senfutil adds all necessary libraries to link against + \li \c senfutil will set necessary compile options. + \li \c senfutil supports normal, debug and final project build options + \li \c senfutil allows specifying variables on the scons command line + \li \c senfutil supports more readable compile-time SENF loglevel configuration + + Using the utility is quite simple - CXXFLAGS_debug = [ ], - LINKFLAGS_debug = [ ], - LOGLEVELS_debug = [ 'senf::log::Debug||VERBOSE' ], + \code + import sys + sys.path.extend(('senf/site_scons','/usr/lib/senf/site_scons')) + import glob, senfutil - CXXFLAGS_final = [ '-O3' ], - LINKFLAGS_final = [ ], - LOGLEVELS_final = [ ], + env = Environment() + senfutil.SetupForSENF(env) + # senfutil.DefaultOptions(env) - SENF_BUILDOPTS = [ ], + # Set or change SCons environment variables with env.Append, env.Replace or env.SetDefault + env.Append( + CXXFLAGS = [ '-Wall', '-Woverloaded-virtual' ], + CXXFLAGS_final = [ '-O2' ], + CXXFLAGS_normal = [ '-O0', '-g' ], + CXXFLAGS_debug = [ '$CXXFLAGS_normal' ], + + LINKFLAGS_normal = [ '-Wl,-S' ], + LOGLEVELS_debug = [ 'senf::log::Debug||VERBOSE' ], ) env.Default( - env.Program( target = 'udpforward', - source = glob.glob('*.cc') ) + env.Program( target='udpforward', source=glob.glob('*.cc') ) ) - - env.Clean(DEFAULT_TARGETS, [ 'udpforward.log', 'udpforward.pid' ]) \endcode - This example builds a simple binary from a number of source files (all '.cc' files). It links - against the SENF library and automatically sets all the correct compiler options using - senfutil.SetupForSENF( env ). + \section senf_senfutil_options Build options - This script automatically uses a SENF installation either symlinked or imported into the current - project in directory 'senf' or, if this directory does not exist, a globaly installed SENF. A - locally installed SENF is automatically recompiled if needed. Parallel building is also - supported. + \c senfutil supports the debug=1 or final=1 build options. These parameters + select one of the build configurations 'debug', 'normal' or 'final'. The following variables are + supported each with separate values for all three configurations: - This script automatically supports the \c final and \c LOGLEVELS command line parameters. The - LOGLEVELS parameter uses a much more readable syntax than SENF_LOG_CONF: -
-    $ scons -j2 final=1 \
-          LOGLEVELS='senf::log::Debug||IMPORTANT myapp::Transactions|mytrans::Area|VERBOSE'
-    
-*/ + \li \c CXXFLAGS + \li \c CPPDEFINES + \li \c LINKFLAGS + \li \c LOGLEVELS + + \c senfutil will detect the type of SENF library used (final or not) and set the correct compile + options. + + \section senf_senfutil_loglevels Specifying compile-time loglevels + + To simplify specifying the compile-time loglevel configuration, the build variable \c LOGLEVELS + (and it's build configuration specific variants) may be set. This variable will be parsed and + converted into the correct \c SENF_LOG_CONF definition. The \c LOGLEVELS Syntax is + + \par "" \e optional_stream \c | \e optional_area | \e level + + where \e optional_stream and \e optional_area are optional fully scoped C++ names (e.g. \c + senf::log::Debug) and \e level is the loglevel. There must be \e no whitespace in a single + specification, multiple specifications are either specified using an array or separated with + whitespace. + + \section senf_senfutil_default Default options + + In the example above, all compile options are set manually. To specify the default customary + compile options for SENF programs, \c senfutil.DefaultOptions(env) is provided. This function is + identical to: + + \code + senfutil.DefaultOptions(env) => + env.Append( + CXXFLAGS = [ '-Wall', '-Woverloaded-virtual' ], + CXXFLAGS_final = [ '-O2' ], + CXXFLAGS_normal = [ '-O0', '-g' ], + CXXFLAGS_debug = [ '$CXXFLAGS_normal' ], + + LINKFLAGS_normal = [ '-Wl,-S' ], + ) + \endcode + */ /** \page senf_usage Using the SENF framework diff --git a/SConstruct b/SConstruct index 9538c95..f56ce4f 100644 --- a/SConstruct +++ b/SConstruct @@ -46,14 +46,6 @@ additionally, any construction environment variable may be set from the scons command line (see SConstruct file and SCons documentation for a list of variables). """) -class BuildTypeOptions: - def __init__(self, var): - self._var = var - - def __call__(self, target, source, env, for_signature): - type = env['final'] and "final" or env['debug'] and "debug" or "normal" - return env[self._var + "_" + type] - env.Replace( PKGDRAW = 'doclib/pkgdraw', ) @@ -76,6 +68,8 @@ env.Append( OBJINSTALLDIR = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}', DOCINSTALLDIR = '$PREFIX/manual', SCONSINSTALLDIR = '${syslayout and "$LIBINSTALLDIR/senf" or "$PREFIX"}/site_scons', + CONFINSTALLDIR = '$OBJINSTALLDIR', + CPP_INCLUDE_EXTENSIONS = [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti' ], CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ], @@ -89,20 +83,20 @@ env.Append( INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ], CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', '$INLINE_OPTS', '$CXXFLAGS_' ], - CXXFLAGS_ = BuildTypeOptions('CXXFLAGS'), + CXXFLAGS_ = senfutil.BuildTypeOptions('CXXFLAGS'), CXXFLAGS_final = [ '-O3' ], CXXFLAGS_normal = [ '-O0', '-g' ], CXXFLAGS_debug = [ '$CXXFLAGS_normal' ], CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ], expandLogOption = senfutil.expandLogOption, - CPPDEFINES_ = BuildTypeOptions('CPPDEFINES'), + CPPDEFINES_ = senfutil.BuildTypeOptions('CPPDEFINES'), CPPDEFINES_final = [ ], CPPDEFINES_normal = [ 'SENF_DEBUG' ], CPPDEFINES_debug = [ '$CPPDEFINES_normal' ], LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ], - LINKFLAGS_ = BuildTypeOptions('LINKFLAGS'), + LINKFLAGS_ = senfutil.BuildTypeOptions('LINKFLAGS'), LINKFLAGS_final = [ ], LINKFLAGS_normal = [ '-Wl,-S' ], LINKFLAGS_debug = [ ], @@ -149,9 +143,17 @@ env.Depends(SENFSCons.Doxygen(env), env.Value(env['ENV']['REVISION'])) #### libsenf.a libsenf = env.Library("$LOCALLIBDIR/${LIBSENF}${LIBADDSUFFIX}", env['ALLOBJECTS']) env.Default(libsenf) - env.Install('$LIBINSTALLDIR', libsenf) +def create(target, source, env): + file(str(target[0]), 'w').write(source[0].get_contents()+"\n") +env['BUILDERS']['CreateFile'] = Builder(action = create) + +conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf", + env.Value(env.subst("$_CPPDEFFLAGS"))) +env.Default(conf) +env.Install('$CONFINSTALLDIR', conf) + #### install_all, default, all_tests, all env.Install('${SCONSINSTALLDIR}', 'site_scons/senfutil.py') diff --git a/site_scons/senfutil.py b/site_scons/senfutil.py index 52d9c1e..61fb998 100644 --- a/site_scons/senfutil.py +++ b/site_scons/senfutil.py @@ -14,6 +14,13 @@ def expandLogOption(target, source, env, for_signature): else: return [] +class BuildTypeOptions: + def __init__(self, var): + self._var = var + + def __call__(self, target, source, env, for_signature): + type = env['final'] and "final" or env['debug'] and "debug" or "normal" + return env[self._var + "_" + type] ########################################################################### # This looks much more complicated than it is: We do three things here: @@ -22,52 +29,90 @@ def expandLogOption(target, source, env, for_signature): # c) check for a local SENF, set options accordingly and update that SENF if needed def SetupForSENF(env, senf_paths = []): - senf_paths.extend(('senf', '../senf', os.path.dirname(os.path.dirname(__file__)))) - env.Append( LIBS = [ 'senf', 'rt', '$BOOSTREGEXLIB', - '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', - '$BOOSTFSLIB' ], - BOOSTREGEXLIB = 'boost_regex', - BOOSTIOSTREAMSLIB = 'boost_iostreams', - BOOSTSIGNALSLIB = 'boost_signals', - BOOSTFSLIB = 'boost_filesystem', - CXXFLAGS = [ '-Wno-long-long', - '${"$CXXFLAGS_"+(final and "final" or "debug")}', - '${profile and ("-g","-pg") or None}' ], - LINKFLAGS = [ '${"$LINKFLAGS_"+(final and "final" or "debug")}', - '${profile and "-pg" or None}' ], - 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' - opts = Options() + senf_paths.extend(('senf', '../senf', os.path.dirname(os.path.dirname(__file__)), + '/usr/local', '/usr')) + env.Append( + LIBS = [ 'senf', 'rt', '$BOOSTREGEXLIB', + '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', + '$BOOSTFSLIB' ], + BOOSTREGEXLIB = 'boost_regex', + BOOSTIOSTREAMSLIB = 'boost_iostreams', + BOOSTSIGNALSLIB = 'boost_signals', + BOOSTFSLIB = 'boost_filesystem', + + CXXFLAGS = [ '-Wno-long-long', '$CXXFLAGS_' ], + CXXFLAGS_ = BuildTypeOptions('CXXFLAGS'), + + CPPDEFINES = [ '$expandLogOption', '$CPPDEFINES_' ], + expandLogOption = expandLogOption, + CPPDEFINES_ = BuildTypeOptions('CPPDEFINES'), + + LINKFLAGS = [ '-rdynamic', '$LINKFLAGS_' ], + LINKFLAGS_ = BuildTypeOptions('LINKFLAGS'), + + LOGLEVELS = [ '$LOGLEVELS_' ], + LOGLEVELS_ = BuildTypeOptions('LOGLEVELS'), + ) + + env.SetDefault( + CXXFLAGS_final = [], + CXXFLAGS_normal = [], + CXXFLAGS_debug = [], + + CPPDEFINES_final = [], + CPPDEFINES_normal = [], + CPPDEFINES_debug = [], + + LINKFLAGS_final = [], + LINKFLAGS_normal = [], + LINKFLAGS_debug = [], + + LOGLEVELS_final = [], + LOGLEVELS_normal = [], + LOGLEVELS_debug = [], + ) + + # Interpret command line options + opts = Variables(ARGUMENTS) opts.Add( 'LOGLEVELS', 'Special log levels. Syntax: |[]| ...', '${"$LOGLEVELS_"+(final and "final" or "debug")}' ) opts.Add( BoolOption('final', 'Build final (optimized) build', False) ) opts.Add( BoolOption('debug', 'Link in debug symbols', False) ) - opts.Add( BoolOption('profile', 'Add profile information', False) ) opts.Update(env) - + env.Replace(**dict(opts.UnknownVariables())) env.Help(opts.GenerateHelpText(env)) # If we have a symbolic link (or directory) 'senf', we use it as our # senf repository for path in senf_paths: + if not path.startswith('/') : sconspath = '#/%s' % path + else : sconspath = path if os.path.exists(os.path.join(path,"senf/config.hh")): - print "\nUsing SENF in '%s/'\n" % os.path.abspath(path) - env.Append( LIBPATH = [ path ], - CPPPATH = [ path ], - SENF_BUILDOPTS = [ '${final and "final=1" or None}', - '${debug and "debug=1" or None}', - '${profile and "profile=1" or None}' ], - CPPDEFINES = [ '${not(final) and "SENF_DEBUG" or None}' ] ) - #env.Default( - # env.AlwaysBuild( - # env.Command('senf/libsenf.a', [], [ 'scons -C %s $SENF_BUILDOPTS libsenf.a' % os.path.realpath('senf')]))) + print "\nUsing SENF in '%s'\n" \ + % ('/..' in sconspath and os.path.abspath(path) or sconspath) + env.Append( LIBPATH = [ sconspath ], + CPPPATH = [ sconspath ], + BUNDLEDIR = sconspath ) + try: + env.MergeFlags(file(os.path.join(path,"senf.conf")).read()) + except IOError: + print "(SENF configuration file 'senf.conf' not found, assuming non-final SENF)" + env.Append(CPPDEFINES = [ 'SENF_DEBUG' ]) + break + elif os.path.exists(os.path.join(path,"include/senf/config.hh")): + print "\nUsing system SENF in '%s/'\n" % sconspath + env.Append(BUNDLEDIR = os.path.join(sconspath,"lib/senf")) break else: - print '\nUsing global SENF\n' + print "\nSENF library not found .. trying build anyway !!\n" + + +def DefaultOptions(env): + env.Append( + CXXFLAGS = [ '-Wall', '-Woverloaded-virtual' ], + CXXFLAGS_final = [ '-O2' ], + CXXFLAGS_normal = [ '-O0', '-g' ], + CXXFLAGS_debug = [ '$CXXFLAGS_normal' ], + + LINKFLAGS_normal = [ '-Wl,-S' ], + )