From: g0dil Date: Fri, 13 Aug 2010 11:16:36 +0000 (+0000) Subject: More SCons/Configure cleanup X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=c1704e837e8bcf6b50da633326213f65cd5a8c46 More SCons/Configure cleanup git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1683 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/SConfigure b/SConfigure index b8ad5cd..5d7dae2 100644 --- a/SConfigure +++ b/SConfigure @@ -19,7 +19,7 @@ def CheckSTLCopyN(context): context.Result(name) context.sconf.Define("HAVE_%s_COPYN" % define, 1, - "Define one of " + "Define one of " + ", ".join(("HAVE_%s_COPYN" % elt[2] for elt in versions))) return ret @@ -41,7 +41,7 @@ def CheckTempBufferStrategy(context): "void test(int a){void *b(alloca(a));}" ".cc") if ret: return "alloca" - + # fallback: new return "new" @@ -71,33 +71,25 @@ def CheckValgrindWildcards(context): ########################################################################### -conf = env.Configure(clean=False, - help=False, - config_h="#/senf/autoconf.hh") +conf = env.Configure(clean=False, help=False, config_h="#/senf/autoconf.hh") # Boost -res = conf.CheckBoostVersion() -if not res : conf.Fail("Boost includes not found") - +res = conf.CheckBoostVersion(fail=True) res = conf.CheckBoostVariants() - -res = conf.CheckCXXHeader("boost/bimap.hpp") -conf.env.Replace(NEED_BOOST_EXT = not res) - res = conf.CheckCXXHeader("boost/spirit/include/classic.hpp") - +res = conf.CheckCXXHeader("boost/bimap.hpp"); \ + conf.env.Replace(NEED_BOOST_EXT = not res) + # Compiler support res = conf.CheckTempBufferStrategy() # Standard library stuff -res = conf.CheckSTLCopyN() -if not res : conf.Fail("No 'copy_n' implementation found") - res = conf.CheckFunc("timerfd_create") +res = conf.CheckSTLCopyN(); \ + conf.env.Fail(condition=not res, message="No 'copy_n' implementation found") # valgrind -res = conf.CheckValgrind() \ - and conf.CheckValgrindWildcards() -conf.env.Replace(HAVE_VALGRIND = res) +res = conf.CheckValgrind() and conf.CheckValgrindWildcards(); \ + conf.env.Replace(HAVE_VALGRIND = res) env = conf.Finish() diff --git a/SConscript b/SConscript index da0f6c4..9542fa9 100644 --- a/SConscript +++ b/SConscript @@ -13,11 +13,10 @@ env.Default(libsenf) env.Install('$LIBINSTALLDIR', libsenf) env.SetDefault( - __NEED_BOOST_EXT_OPT = "-I$$SENFINCDIR/boost_ext", - _NEED_BOOST_EXT_OPT = "${NEED_BOOST_EXT and __NEED_BOOST_EXT_OPT or ''}") + _BOOST_EXT_INC_OPT = "${NEED_BOOST_EXT and '-I$$SENFINCDIR/boost_ext' or ''}") -conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf", - env.Value(env.subst('$_NEED_BOOST_EXT_OPT $_CPPDEFFLAGS'))) +conf = env.CreateFile("${LOCALLIBDIR}/${LIBSENF}${LIBADDSUFFIX}.conf", + env.Value(env.subst('$_BOOST_EXT_INC_OPT $_CPPDEFFLAGS'))) env.Default(conf) env.Install('$CONFINSTALLDIR', conf) @@ -26,4 +25,3 @@ cobject = env.CombinedObject('${LOCALLIBDIR}/${NAME}${OBJADDSUFFIX}', env['PACKE NAME="AllBundles") env.Default(cobject) env.Install('${OBJINSTALLDIR}', cobject) - diff --git a/SConstruct b/SConstruct index 9538cfc..873892b 100644 --- a/SConstruct +++ b/SConstruct @@ -38,7 +38,7 @@ by calling scons @[@] -Some more elaborate unit tests may be enabled by setting appropritate variables +Some more elaborate unit tests may be enabled by setting appropritate variables in the shell (unix) environment SENF_TIMING_CRITICAL_TESTS @@ -65,7 +65,7 @@ env.Replace( ) env.Append( IMPORT_ENV = [ 'PATH', 'HOME', 'SSH_*', 'SENF*', 'CCACHE_*', 'DISTCC_*' ], - + CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign*', '.sconf_temp' ], @@ -82,10 +82,10 @@ env.Append( CPP_EXCLUDE_EXTENSIONS = [ '.test.hh' ], # INLINE_OPTS_DEBUG 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' + INLINE_OPTS_DEBUG = [ '-finline-limit=20000', '-fvisibility-inlines-hidden', + '-fno-inline-functions', '-Winline' '--param','large-function-growth=10000', - '--param', 'large-function-insns=10000', + '--param', 'large-function-insns=10000', '--param','inline-unit-growth=10000' ], INLINE_OPTS_NORMAL = [ '-finline-limit=5000' ], INLINE_OPTS = [ '$INLINE_OPTS_NORMAL' ], @@ -122,7 +122,7 @@ env.SetDefault( GENHTML = "genhtml", VALGRIND = "valgrind", SCONSBIN = env.File("#/tools/scons"), - SCONSARGS = ([ '-Q', '-j$CONCURRENCY_LEVEL' ] + + SCONSARGS = ([ '-Q', '-j$CONCURRENCY_LEVEL' ] + [ '%s=%s' % (k,v) for k,v in ARGUMENTS.iteritems() ]), SCONS = "@$SCONSBIN $SCONSARGS", CONCURRENCY_LEVEL = env.GetOption('num_jobs') or 1, @@ -161,7 +161,7 @@ SConscript('SConfigure') # Only add this here, after all configure checks have run env.Append(LIBS = '$LIBSENF$LIBADDSUFFIX', - EXTRA_LIBS = [ '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', + EXTRA_LIBS = [ '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ]) ########################################################################### @@ -221,9 +221,9 @@ env.PhonyTarget('prepare', [], []) env.Alias('all_valgrinds') if env['HAVE_VALGRIND']: for test in env.FindAllBoostUnitTests(): - stamp = env.Command(test[0].dir.File('.test-valgrind.stamp'), + stamp = env.Command(test[0].dir.File('.test-valgrind.stamp'), [ test[0].dir.File('.test.bin'), 'tools/valgrind.sup' ], - [ """$VALGRIND --tool=memcheck + [ """$VALGRIND --tool=memcheck --error-exitcode=1 --suppressions=${SOURCES[1]} $VALGRINDARGS @@ -240,13 +240,13 @@ env.PhonyTarget('lcov', [], [ '$LCOV --output-file lcov.info --remove /tmp/senf_lcov.info "*/include/*" "*/boost/*" "*.test.*" ', '$GENHTML --output-directory doc/lcov --title all_tests lcov.info', 'rm /tmp/senf_lcov.info' ]) -if env.GetOption('clean'): +if env.GetOption('clean'): env.Clean('lcov', [ os.path.join(path,f) for path, subdirs, files in os.walk('.') for pattern in ('*.gcno', '*.gcda', '*.gcov') - for f in fnmatch.filter(files,pattern) ] + + for f in fnmatch.filter(files,pattern) ] + [ 'lcov.info', env.Dir('doc/lcov'), env.Dir('build/lcov') ]) - + #### clean env.Clean('all', ('.prepare-stamp', env.Dir('dist'), env.Dir('build'))) if env.GetOption('clean') : env.Depends('all', ('lcov', 'all_valgrinds')) diff --git a/site_scons/SENFSCons.py b/site_scons/SENFSCons.py index 01681e4..09e4c4d 100644 --- a/site_scons/SENFSCons.py +++ b/site_scons/SENFSCons.py @@ -5,12 +5,12 @@ from SCons.Script import * def Glob(env, exclude=[], subdirs=[]): testSources = env.Glob("*.test.cc",strings=True) - sources = [ x - for x in env.Glob("*.cc",strings=True) + sources = [ x + for x in env.Glob("*.cc",strings=True) if x not in testSources and x not in exclude ] for subdir in subdirs: testSources += env.Glob(os.path.join(subdir,"*.test.cc"),strings=True) - sources += [ x + sources += [ x for x in env.Glob(os.path.join(subdir,"*.cc"),strings=True) if x not in testSources and x not in exclude ] includes = [] @@ -63,7 +63,7 @@ def Doxygen(env, doxyfile = "Doxyfile", extra_sources = [], output_directory = " tagfile = env.Doxygen(doxyfile, DOXYOPTS = opts + [ '--tagfile' ], **vars(generate_tagfile='${OUTPUT_DIRECTORY}/${MODULE}.tag')) env.Append(ALL_TAGFILES = [ tagfile[0].abspath ]) - env.Depends(tagfile, [ env.File('#/site_scons/lib/doxygen.sh'), + env.Depends(tagfile, [ env.File('#/site_scons/lib/doxygen.sh'), env.File('#/site_scons/lib/tag-munge.xsl') ]) env.Install(env.Dir('$DOCINSTALLDIR').Dir(tagfile[0].dir.get_path(env.Dir('#'))), @@ -100,7 +100,7 @@ def AllIncludesHH(env, exclude=[]): if f.name not in exclude and not f.name.endswith('.test.hh') ] headers.sort(key=lambda x:x.name) target = env.File("all_includes.hh") - allinch = env.CreateFile(target, + allinch = env.CreateFile(target, env.Value("".join([ '#include <%s>\n' % f.srcnode().get_path(env.Dir('#')) for f in headers ]))) env.Default(allinch) diff --git a/site_scons/senfutil.py b/site_scons/senfutil.py index fce11f0..331b3a8 100644 --- a/site_scons/senfutil.py +++ b/site_scons/senfutil.py @@ -6,7 +6,7 @@ senfutildir = os.path.dirname(__file__) # Fix for SCons 0.97 compatibility try: Variables -except NameError: +except NameError: Variables = Options BoolVariable = BoolOption @@ -28,7 +28,7 @@ Any construction environment variable may be set from the scons command line (see SConstruct file and SCons documentation for a list of variables) using - VARNAME=value Assign new value + VARNAME=value Assign new value VARNAME+=value Append value at end Special command line parameters: @@ -46,7 +46,7 @@ Special command line parameters: env.Append(ARGUMENT_VARIABLES = {k:v}) def importProcessEnv(env): - env.Append( ENV = dict(( (k,v) + env.Append( ENV = dict(( (k,v) for pattern in env.get('IMPORT_ENV',[]) for k,v in os.environ.iteritems() if fnmatch.fnmatchcase(k,pattern) )) ) @@ -108,13 +108,14 @@ def SetupForSENF(env, senf_path = [], flavor=None): try_flavors = [ '', 'g' ] if flavor is not None: try_flavors[0:0] = [ flavor ] - + res = detect_senf(env, senf_path, try_flavors) - if not env.GetOption('no_progress'): - if res: - print env.subst("scons: Using${SENFSYSLAYOUT and ' system' or ''} 'libsenf${LIBADDSUFFIX}' in '$SENFDIR'") - else: - print "scons: SENF library not found, trying to build anyway ..." + if res: + if not env.GetOption('no_progress'): + print env.subst("scons: Using${SENFSYSLAYOUT and ' system' or ''} " + "'libsenf${LIBADDSUFFIX}' in '$SENFDIR'") + else: + print "scons: SENF library not found, trying to build anyway ..." loadTools(env) @@ -125,36 +126,35 @@ def SetupForSENF(env, senf_path = [], flavor=None): LIBPATH = [ '$SENFDIR' ], ) - conf = env.Configure(clean=False, help=False) - if not conf.CheckBoostVersion(): - conf.Fail("Boost includes not found") - conf.CheckBoostVariants() - conf.Finish() - + if env['BOOST_VARIANT'] is None: + conf = env.Configure(clean=False, help=False) + conf.CheckBoostVersion(fail=True) + conf.CheckBoostVariants() + conf.Finish() + env.Replace( expandLogOption = expandLogOption, ) env.SetDefault( - FLAVOR = flavor, LIBADDSUFFIX = '${FLAVOR and "_$FLAVOR" or ""}', OBJADDSUFFIX = '${LIBADDSUFFIX}', + BUNDLEDIR = '$SENFDIR${SENFSYSLAYOUT and "/lib/senf" or ""}', + SENFINCDIR = '$SENFDIR${SENFSYSLAYOUT and "/include" or ""}', + PROJECTNAME = "Unnamed project", DOCLINKS = [], PROJECTEMAIL = "nobody@nowhere.org", COPYRIGHT = "nobody", REVISION = "unknown", - BUNDLEDIR = '$SENFDIR${SENFSYSLAYOUT and "/lib/senf" or ""}', - SENFINCDIR = '$SENFDIR${SENFSYSLAYOUT and "/include" or ""}', ) env.Append( - CPPPATH = [ '${NEED_BOOST_EXT and "$SENFINCDIR/boost_ext" or None}' ], CPPDEFINES = [ '$expandLogOption' ], CXXFLAGS = [ '-Wno-long-long', '-fno-strict-aliasing' ], LINKFLAGS = [ '-rdynamic' ], - LIBS = [ 'senf$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', + LIBS = [ 'senf$LIBADDSUFFIX', 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB', '$BOOSTFSLIB' ], ) - + try: path = env.File('$BUNDLEDIR/senf${LIBADDSUFFIX}.conf').abspath env.MergeFlags(file(path).read()) @@ -179,7 +179,7 @@ def DefaultOptions(env): LINKFLAGS = [ '$LINKFLAGS_' ], LOGLEVELS = [ '$LOGLEVELS_' ], ) - env.SetDefault( + env.SetDefault( CXXFLAGS_final = [], CXXFLAGS_normal = [], CXXFLAGS_debug = [], @@ -199,7 +199,7 @@ def DefaultOptions(env): # Interpret command line options parseArguments( - env, + env, BoolVariable('final', 'Build final (optimized) build', False), BoolVariable('debug', 'Link in debug symbols', False), ) @@ -220,12 +220,12 @@ def DefaultOptions(env): def Glob(env, exclude=[], subdirs=[]): testSources = env.Glob("*.test.cc", strings=True) - sources = [ x - for x in env.Glob("*.cc", strings=True) + sources = [ x + for x in env.Glob("*.cc", strings=True) if x not in testSources and x not in exclude ] for subdir in subdirs: testSources += env.Glob(os.path.join(subdir,"*.test.cc"), strings=True) - sources += [ x + sources += [ x for x in env.Glob(os.path.join(subdir,"*.cc"), strings=True) if x not in testSources and x not in exclude ] sources.sort() @@ -242,7 +242,7 @@ def Doxygen(env, doxyheader=None, doxyfooter=None, doxycss=None, mydoxyfile=Fals global senfutildir global tagfiles libdir=os.path.join(senfutildir, 'lib') - + if tagfiles is None: senfdocdir = None senfdoc_path.extend(('senfdoc', '$SENFDIR', '$SENFDIR/manual', @@ -259,12 +259,12 @@ def Doxygen(env, doxyheader=None, doxyfooter=None, doxycss=None, mydoxyfile=Fals else: for dir, dirs, files in os.walk(senfdocdir): tagfiles.extend([ os.path.join(dir,f) for f in files if f.endswith('.tag') ]) - if dir.endswith('/doc') : + if dir.endswith('/doc') : try: dirs.remove('html') except ValueError: pass - for d in dirs: + for d in dirs: if d.startswith('.') : dirs.remove(d) - + if env.GetOption('clean'): env.Clean('doc', env.Dir('doc')) if not mydoxyfile: @@ -272,7 +272,7 @@ def Doxygen(env, doxyheader=None, doxyfooter=None, doxycss=None, mydoxyfile=Fals if not mydoxyfile: # Create Doxyfile NOW - site_tools.Yaptu.yaptuAction("Doxyfile", + site_tools.Yaptu.yaptuAction("Doxyfile", os.path.join(libdir, "Doxyfile.yap"), env) @@ -283,7 +283,7 @@ def Doxygen(env, doxyheader=None, doxyfooter=None, doxycss=None, mydoxyfile=Fals env.Value('$REVISION') ] # The other files are created using dependencies - if doxyheader: + if doxyheader: doxyheader = env.CopyToDir(env.Dir("doc"), doxyheader) else: doxyheader = env.Yaptu("doc/doxyheader.html", os.path.join(libdir, "doxyheader.yap"), **kw) @@ -308,7 +308,7 @@ def Doxygen(env, doxyheader=None, doxyfooter=None, doxycss=None, mydoxyfile=Fals 'html_dir' : 'html', 'html' : 'YES', 'DOXYGEN' : '$DOXYGEN' }, - TAGFILES = tagfiles, + TAGFILES = tagfiles, DOCLIBDIR = libdir, DOXYGENCOM = "$DOCLIBDIR/doxygen.sh $DOXYOPTS $SOURCE") diff --git a/site_scons/site_tools/Boost.py b/site_scons/site_tools/Boost.py index 2f12041..629dd3e 100644 --- a/site_scons/site_tools/Boost.py +++ b/site_scons/site_tools/Boost.py @@ -51,7 +51,7 @@ def CompileCheck(target, source, env): print "Passed test '%s': %s" % (delay_name, message) delay_name = None continue - + filename = os.path.abspath(filename) if filename != source[0].abspath : continue @@ -87,7 +87,7 @@ def BoostUnitTest(env, target=None, source=None, **kw): binnode = target.dir.File('.' + target.name + '.bin') stampnode = target.dir.File('.' + target.name + '.stamp') - bin = env.Program(binnode, source, + bin = env.Program(binnode, source, LIBS = env['LIBS'] + [ '$TEST_EXTRA_LIBS' ], _LIBFLAGS = ' -Wl,-Bstatic -l$BOOSTTESTLIB -Wl,-Bdynamic ' + env['_LIBFLAGS'], **kw) @@ -98,7 +98,7 @@ def BoostUnitTest(env, target=None, source=None, **kw): alias = env.Command(env.File(target), stamp, [ env.NopAction() ] ) - compileTests = [ src for src in source + compileTests = [ src for src in source if src.suffix in SCons.Tool.cplusplus.CXXSuffixes \ and src.exists() \ and 'COMPILE_CHECK' in file(str(src)).read() ] @@ -106,7 +106,7 @@ def BoostUnitTest(env, target=None, source=None, **kw): env.Depends(alias, env.CompileCheck(source = compileTests)) _ALL_TESTS.append(alias) - + return alias def FindAllBoostUnitTests(env, target, source): @@ -121,20 +121,50 @@ def NopAction(env, target, source): ConfTest = CustomTests.ConfTest() @ConfTest -def CheckBoostVersion(context): - context.Message( "Checking boost version... " ) +def CheckBoostVersion(context,fail=False,min=None,max=None): + """Check for boost includes. + +Will place the boost version number (BOOST_LIB_VERSION) into the +BOOST_VERSION environment variable. + +Options: + + min/max compare boost version against given range. + + fail if fail is set to True, the build will be terminated, + when no valid boost includes are found.""" + if min and max: + msg = ' in range %s to %s' % (min,max) + elif min: + msg = ' at least %s' % min + elif max: + msg = ' at most %s' % max + else: + msg = '' + context.Message( "Checking boost version%s... " % msg ) ret = context.TryRun("#include \n" "#include \n" "int main(int, char **) { std::cout << BOOST_LIB_VERSION << std::endl; }", ".cc")[-1].strip() + if not ret: - context.Result("no boost includes found") - context.env.Replace( BOOST_VERSION = '' ) - return None + msg = "no boost includes found" + context.env.Replace( BOOST_VERSION = None ) else: - context.Result(ret) context.env.Replace( BOOST_VERSION = ret ) - return ret + msg = ret + if min or max: + try: version = map(int,ret.split('_')) + except ValueError: + msg = "[%s] invalid version syntax" % ret + ret = None + else: + if min : ret = ret and (version>=map(int,min.split('_'))) + if max : ret = ret and (version<=map(int,max.split('_'))) + msg = '[%s] %s' % (msg, ret and "yes" or "no") + context.Result(msg) + if fail and not ret : context.env.Fail('No valid boost includes found') + return ret @ConfTest def CheckBoostVariants(context, *variants): diff --git a/site_scons/site_tools/CustomTests.py b/site_scons/site_tools/CustomTests.py index 81a8eba..218a7bc 100644 --- a/site_scons/site_tools/CustomTests.py +++ b/site_scons/site_tools/CustomTests.py @@ -35,7 +35,7 @@ the decorator. This usage is primarily interesting for tool writers: from CustomTests import ConfTest MY_TESTS = {} - + @ConfTest(MY_TESTS) def CheckMyFoo(context): pass @@ -73,7 +73,7 @@ This usage is interesting for SConstruct and SConscript writers: env = Environment() env.Tool('CustomTests') - + @env.ConfTest() def CheckMyFoo(context): pass @@ -86,7 +86,7 @@ The new configuration test is automatically added to env['CUSTOM_TESTS'] and is thus automatically available to all configuration contexts created from the environment. """ - + def __init__(self, registry=None): if registry is None: self.tests = {} @@ -99,17 +99,19 @@ configuration contexts created from the environment. self.tests[func.__name__] = func return func -DefaultTest = ConfTest() - def Configure(self, *args, **kw): try: kw['custom_tests'].update(self['CUSTOM_TESTS']) except KeyError: kw['custom_tests'] = dict(self['CUSTOM_TESTS']) return self._CustomTests_orig_Configure(*args, **kw) -@DefaultTest -def Fail(context, msg): - SCons.Util.display("scons: *** %s" % msg) - SCons.Script.Exit(1) +def Fail(context, message, condition=True): + if condition: + SCons.Util.display("scons: *** %s" % message) + SCons.Script.Exit(1) + +DefaultTest = ConfTest() + +# Hmm .. no default tests for now ... def generate(env): env.Append( CUSTOM_TESTS = DefaultTest.tests )