X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senfscons%2FSENFSCons.py;h=4c3f3b8626edb8444f7294da8b70c6eef575b76e;hb=28489b2b034740ce21bcce6f38b8fa1701948b03;hp=aa5efa2e93b36cebf592429b7047e3554db421ca;hpb=41fe0d795abca302db24e7a955df6ef15ffed722;p=senf.git diff --git a/senfscons/SENFSCons.py b/senfscons/SENFSCons.py index aa5efa2..4c3f3b8 100644 --- a/senfscons/SENFSCons.py +++ b/senfscons/SENFSCons.py @@ -25,6 +25,7 @@ import os.path, glob import SCons.Options, SCons.Environment, SCons.Script.SConscript, SCons.Node.FS import SCons.Defaults, SCons.Action +from SCons.Script import * ## \defgroup use Predefined Framework Configurators # @@ -52,6 +53,7 @@ SCONS_TOOLS = [ "CopyToDir", "InstallIncludes", "ProgramNoScan", + "CompileCheck", ] opts = None @@ -78,6 +80,8 @@ def InitOpts(): 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 @@ -133,6 +137,8 @@ def UseBoost(): 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 @@ -148,13 +154,26 @@ def FinalizeBoost(env): if runtime: runtime = "-" + runtime env['BOOST_VARIANT'] = "-" + env['BOOST_TOOLSET'] + runtime - env['BOOSTTESTLIB'] = 'libboost_unit_test_framework' + env['BOOST_VARIANT'] - env['BOOSTREGEXLIB'] = 'libboost_regex' + env['BOOST_VARIANT'] - env['BOOSTFSLIB'] = 'libboost_filesystem' + env['BOOST_VARIANT'] + 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'] + + 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 @@ -216,11 +235,12 @@ def MakeEnvironment(): global opts, finalizers InitOpts() env = SCons.Environment.Environment(options=opts) - 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.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)) @@ -238,18 +258,17 @@ def MakeEnvironment(): # These are the default compilation parameters. We should probably # make these configurable - env.Append(CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ], - LOCALLIBDIR = [ '#' ], + env.Append(LOCALLIBDIR = [ '#' ], LIBPATH = [ '$LOCALLIBDIR' ]) if env['final']: - env.Append(CXXFLAGS = [ '-O3' ], - CPPDEFINES = [ 'NDEBUG' ]) + env.Append(CXXFLAGS = [ '-O3' ]) else: - env.Append(CXXFLAGS = [ '-O0', '-g', '-fno-inline' ], - # The boost-regex library is not compiled with _GLIBCXX_DEBUG so this fails. - # CPPDEFINES = [ '_GLIBCXX_DEBUG' ], - LINKFLAGS = [ '-g' ]) + # The boost-regex library is not compiled with _GLIBCXX_DEBUG so this fails: + # CPPDEFINES = [ '_GLIBCXX_DEBUG' ], + env.Append(CXXFLAGS = [ '-O0', '-g' ], + CPPDEFINES = { 'SENF_DEBUG': ''}, + LINKFLAGS = [ '-g', '-rdynamic' ]) env.Append(CPPDEFINES = [ '$EXTRA_DEFINES' ], LIBS = [ '$EXTRA_LIBS' ], @@ -297,7 +316,24 @@ def GlobalTargets(env): ## \brief Return path of a built library within $LOCALLIBDIR # \internal -def LibPath(lib): return '$LOCALLIBDIR/lib%s.a' % lib +def LibPath(lib): return '${LOCALLIBDIR}/${LIBPREFIX}%s${LIBADDSUFFIX}${LIBSUFFIX}' % lib + +def Test(env, sources, LIBS = [], OBJECTS = []): + test = [ env.BoostUnitTests( + target = 'test', + objects = [], + test_sources = sources, + LIBS = [ x + '$LIBADDSUFFIX' for x in LIBS ], + OBJECTS = OBJECTS, + DEPENDS = [ env.File(LibPath(x)) for x in LIBS ]) ] + compileTestSources = [ src for src in sources + if 'COMPILE_CHECK' in file(src).read() ] + if compileTestSources: + test.extend(env.CompileCheck(source = compileTestSources)) + env.Alias('all_tests', test) + env.Command(env.File('test'), test, []) + #env.Alias(env.File('test'), test) + ## \brief Build object files # @@ -316,7 +352,7 @@ def LibPath(lib): return '$LOCALLIBDIR/lib%s.a' % lib # provide both \a sources and \a testSources. # # \ingroup target -def Objects(env, sources, testSources = None, LIBS = [], OBJECTS = []): +def Objects(env, sources, testSources = None, LIBS = [], OBJECTS = [], no_includes = False): if type(sources) == type(()): testSources = sources[1] sources = sources[0] @@ -327,26 +363,31 @@ def Objects(env, sources, testSources = None, LIBS = [], OBJECTS = []): if sources: obsources = [ source for source in sources - if not str(source).endswith('.o') ] + if type(source) is type('') and not source.endswith('.o') ] objects = [ source for source in sources - if str(source).endswith('.o') ] + if type(source) is not type('') or source.endswith('.o') ] if obsources: objects += env.Object(obsources) if testSources: - test = env.BoostUnitTests( + test = [ env.BoostUnitTests( target = 'test', objects = objects, test_sources = testSources, - LIBS = LIBS, + LIBS = [ x + '$LIBADDSUFFIX' for x in LIBS ], OBJECTS = OBJECTS, - DEPENDS = [ env.File(LibPath(x)) for x in LIBS ]) + DEPENDS = [ env.File(LibPath(x)) for x in LIBS ]) ] + compileTestSources = [ src for src in testSources + if 'COMPILE_CHECK' in file(src).read() ] + if compileTestSources: + test.extend(env.CompileCheck(source = compileTestSources)) env.Alias('all_tests', test) # Hmm ... here I'd like to use an Alias instead of a file # however the alias does not seem to live in the subdirectory # which breaks 'scons -u test' - env.Alias(env.File('test'), test) + env.Command(env.File('test'), test, []) + #env.Alias(env.File('test'), test) return objects @@ -360,6 +401,15 @@ def InstallIncludeFiles(env, files): src = env.File(f) env.Alias('install_all', env.Install(target.Dir(src.dir.get_path(base)), src)) +def InstallSourceIncludes(env, sources): + target = env.Dir(env['INCLUDEINSTALLDIR']).Dir( + env.Dir('.').get_path(env.Dir(env['INSTALL_BASE']))) + install = env.InstallIncludes( target = target, + source = [ type(x) is str and env.File(x) or x + for x in sources ], + INSTALL_BASE = env.Dir('.') ) + env.Alias( 'install_all', install ) + def InstallWithSources(env, targets, dir, sources, testSources = [], no_includes = False): if type(sources) is type(()): sources, testSources = sources @@ -369,17 +419,14 @@ def InstallWithSources(env, targets, dir, sources, testSources = [], no_includes testSources = [ testSources ] installs = [ env.Install(dir, targets) ] + env.Alias( 'install_all', installs[:] ) if not no_includes: - target = env.Dir(env['INCLUDEINSTALLDIR']).Dir( - env.Dir('.').get_path(env.Dir(env['INSTALL_BASE']))) - source = targets + sources = targets if testSources: - source.append( env.File('.test.bin') ) - installs.append(env.InstallIncludes( - target = target, - source = targets, - INSTALL_BASE = env.Dir('.') )) + sources.append( env.File('.test.bin') ) + installs.append( + InstallSourceIncludes(env, sources)) return installs @@ -421,6 +468,8 @@ def InstallWithSources(env, targets, dir, sources, testSources = [], no_includes # # \ingroup target def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []): + if not 'all' in BUILD_TARGETS and not 'doc' in BUILD_TARGETS and not 'all_docs' in BUILD_TARGETS: + return [] # ARGHHH !!! without the [:] we are changing the target list # ||| WITHIN THE DOXYGEN BUILDER docs = env.Doxygen(doxyfile)[:] @@ -454,13 +503,12 @@ def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []): docs, SCons.Action.Action(("for html in %s/*.html; do " + " echo $$html;" + - " sed -e 's/id=\"current\"/class=\"current\"/' $${html}" + - " | tidy -ascii -q --show-warnings no --fix-uri no " + - " | xsltproc --nonet --html --stringparam topdir %s -o $${html}.new %s - 2>&1" + - " | grep '^-'" + - " | grep -v 'ID .* already defined';" + - " mv $${html}.new $${html}; " + - "done") + " mv $${html} $${html}.orig;" + + " sed -e 's/id=\"current\"/class=\"current\"/' $${html}.orig" + + " | tidy -ascii -q --wrap 0 --show-warnings no --fix-uri no " + + " | sed -e 's/name=\"\([^\"]*\)\"\([^>]*\) id=\"\\1\"/name=\"\\1\"\\2/g'" + + " | xsltproc --novalid --nonet --html --stringparam topdir %s -o $${html} %s -;" + "done; true") % (htmlnode.dir.abspath, reltopdir, xslfile.abspath))) for doc in docs: env.Depends(doc, xslfile) @@ -470,7 +518,7 @@ def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []): for type in env.get("DOXY_XREF_TYPES",[ "bug", "todo" ]): xref = os.path.join(xmlnode.dir.abspath,type+".xml") xref_pp = env.Command(xref+'i', [ xref, os.path.join(basedir,'xrefxtract.xslt'), xmlnode ], - [ "test -s $SOURCE && xsltproc -o $TARGET" + + [ "test -s $SOURCE && xsltproc --nonet -o $TARGET" + " --stringparam module $MODULE" + " --stringparam type $TYPE" + " ${SOURCES[1]} $SOURCE || touch $TARGET" ], @@ -592,8 +640,7 @@ def Lib(env, library, sources, testSources = None, LIBS = [], OBJECTS = [], no_i env.Default(lib) env.Append(ALLLIBS = library) env.Alias('default', lib) - install = InstallWithSources(env, lib, '$LIBINSTALLDIR', sources, testSources, no_includes) - env.Alias('install_all', install) + InstallWithSources(env, lib, '$LIBINSTALLDIR', sources, testSources, no_includes) return lib ## \brief Build Object from multiple sources @@ -601,11 +648,10 @@ def Object(env, target, sources, testSources = None, LIBS = [], OBJECTS = [], no objects = Objects(env,sources,testSources,LIBS=LIBS,OBJECTS=OBJECTS) ob = None if objects: - ob = env.Command(target+".o", objects, "ld -r -o $TARGET $SOURCES") + ob = env.Command(target+"${OBJADDSUFFIX}${OBJSUFFIX}", objects, "ld -r -o $TARGET $SOURCES") env.Default(ob) env.Alias('default', ob) - install = InstallWithSources(env, ob, '$OBJINSTALLDIR', sources, testSources, no_includes) - env.Alias('install_all', install) + InstallWithSources(env, ob, '$OBJINSTALLDIR', sources, testSources, no_includes) return ob ## \brief Build executable @@ -622,15 +668,13 @@ def Binary(env, binary, sources, testSources = None, LIBS = [], OBJECTS = [], no objects = Objects(env,sources,testSources,LIBS=LIBS,OBJECTS=OBJECTS) program = None if objects: - progEnv = env.Copy() - progEnv.Prepend(LIBS = LIBS) + progEnv = env.Clone() + progEnv.Prepend(LIBS = [ x + '$LIBADDSUFFIX' for x in LIBS ]) program = progEnv.ProgramNoScan(target=binary,source=objects+OBJECTS) env.Default(program) env.Depends(program, [ env.File(LibPath(x)) for x in LIBS ]) env.Alias('default', program) - install = InstallWithSources(env, program, '$BININSTALLDIR', sources, testSources, - no_includes) - env.Alias('install_all', install) + InstallWithSources(env, program, '$BININSTALLDIR', sources, testSources, no_includes) return program def AllIncludesHH(env, headers):