X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senfscons%2FBoost.py;fp=senfscons%2FBoost.py;h=4e07ac3ac7f6bdb85f925e4e25bf5b326ffd418d;hb=6b43243d9b1a3b9720efdacc6f02364877ebe2aa;hp=058efc5dcbc909094535d6ac1ff01a95eab59bf1;hpb=2c5ee014ddfed45406e238029600346c99870229;p=senf.git diff --git a/senfscons/Boost.py b/senfscons/Boost.py index 058efc5..4e07ac3 100644 --- a/senfscons/Boost.py +++ b/senfscons/Boost.py @@ -1,4 +1,113 @@ -# Provide environment variables for boost libraries +import SCons.Script +import SCons.Script.SConscript +import SCons.Defaults +import os.path +import os +import sys +import tempfile +import SCons.Scanner.C + +# ARGH ... Why do they put a '+' in the module name ???????? +SCons.Tool.cplusplus=getattr(__import__('SCons.Tool.c++', globals(), locals(), []).Tool, 'c++') + +_ALL_TESTS = [] + +def scanTests(f): + tests = {} + name = start = None + linenr= 0 + for line in f: + linenr += 1 + if line.startswith('COMPILE_FAIL(') and ')' in line: + name = line.split('(',1)[-1].split(')',1)[0] + start = linenr + elif line.startswith('}') and name and start: + tests[name] = (start, linenr) + return tests + +def CompileCheck(target, source, env): + tests = scanTests(file(source[0].abspath)) + cenv = env.Clone() + cenv.Append( CPPDEFINES = [ 'COMPILE_CHECK' ] ) + out = tempfile.TemporaryFile() + cenv['SPAWN'] = lambda sh, escape, cmd, args, env, pspawn=cenv['PSPAWN'], out=out: \ + pspawn(sh, escape, cmd, args, env, out, out) + SCons.Script.Action('$CXXCOM').execute(target, source, cenv) + passedTests = {} + delay_name = None + out.seek(0) + for error in out.read().splitlines(): + elts = error.split(':',2) + if len(elts) != 3 : continue + filename, line, message = elts + if not os.path.exists(filename) : continue + try: line = int(line) + except ValueError : continue + message = message.strip() + + if delay_name and not message.startswith('instantiated from '): + print "Passed test '%s': %s" % (delay_name, message) + delay_name = None + continue + + filename = os.path.abspath(filename) + if filename != source[0].abspath : continue + + for name,lines in tests.iteritems(): + if line >= lines[0] and line <= lines[1]: + passedTests[name] = 1 + if message.startswith('instantiated from '): + delay_name = name + else: + print "Passed test '%s': %s" % (name, message) + if delay_name: + print "Passed test '%s': " % delay_name + failedTests = set(tests.iterkeys()) - set(passedTests.iterkeys()) + if failedTests: + for test in failedTests: + print "Test '%s' FAILED" % test + print + print "*** %d tests FAILED" % len(failedTests) + if os.path.exists(target[0].abspath): + os.unlink(target[0].abspath) + return 1 + file(target[0].abspath,"w").close() + return 0 + +CompileCheck = SCons.Script.Action(CompileCheck) + +def BoostUnitTest(env, target=None, source=None, **kw): + target = env.arg2nodes(target)[0] + source = env.arg2nodes(source) + + binnode = target.dir.File('.' + target.name + '.bin') + stampnode = target.dir.File('.' + target.name + '.stamp') + + bin = env.Program(binnode, source, + LIBS = env['LIBS'] + [ '$TEST_EXTRA_LIBS' ], + _LIBFLAGS = ' -Wl,-Bstatic -l$BOOSTTESTLIB -Wl,-Bdynamic ' + env['_LIBFLAGS'], + **kw) + + stamp = env.Command(stampnode, bin, + [ '$SOURCE $BOOSTTESTARGS', + 'touch $TARGET' ], + **kw) + + alias = env.Command(env.File(target), stamp, []) + + 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() ] + if compileTests: + env.Depends(alias, env.CompileCheck(source = compileTests)) + + _ALL_TESTS.append(alias) + + return alias + +def FindAllBoostUnitTests(env, target, source): + return _ALL_TESTS def generate(env): env.SetDefault( @@ -9,7 +118,19 @@ def generate(env): BOOSTFSLIB = 'boost_filesystem$BOOST_VARIANT', BOOSTIOSTREAMSLIB = 'boost_iostreams$BOOST_VARIANT', BOOSTSIGNALSLIB = 'boost_signals$BOOST_VARIANT', + + BOOSTTESTARGS = [ '--build_info=yes', '--log_level=test_suite' ], ) + env['BUILDERS']['BoostUnitTest'] = BoostUnitTest + env['BUILDERS']['FindAllBoostUnitTests'] = FindAllBoostUnitTests + env['BUILDERS']['CompileCheck'] = env.Builder( + action = CompileCheck, + suffix = '.checked', + src_suffix = '.cc', + source_scanner = SCons.Scanner.C.CScanner(), + single_source=1 + ) + def exists(env): return True