From 79a086c22c6964a04ab88a382aaba3626c216b5a Mon Sep 17 00:00:00 2001 From: Greg Noel Date: Sat, 17 Jan 2009 19:56:55 +0000 Subject: Issue 2278: Emit header name when using SWIG directors (Ben Webb) --- src/CHANGES.txt | 2 ++ src/engine/SCons/Tool/swig.py | 29 +++++++++++++++++++++++++---- test/SWIG/module-parens.py | 14 +++++--------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index cbdda51..2e9b20f 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -78,6 +78,8 @@ RELEASE 1.X - XXX - Handle quoted module names in SWIG source files. + - Emit *_wrap.h when SWIG generates header file for directors + From Matthew Wesley: - Copy file attributes so we identify, and can link a shared library diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index 08f8cd4..eff8806 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -35,6 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os.path import re +import string import SCons.Action import SCons.Defaults @@ -56,12 +57,27 @@ _reModule = re.compile(r'%module(\s*\(.*\))?\s+("?)(.+)\2') def _find_modules(src): """Find all modules referenced by %module lines in `src`, a SWIG .i file. - Returns a list of all modules.""" + Returns a list of all modules, and a flag set if SWIG directors have + been requested (SWIG will generate an additional header file in this + case.)""" + directors = 0 mnames = [] matches = _reModule.findall(open(src).read()) for m in matches: mnames.append(m[2]) - return mnames + directors = directors or string.find(m[0], 'directors') >= 0 + return mnames, directors + +def _add_director_header_targets(target, env): + # Directors only work with C++ code, not C + suffix = env.subst(env['SWIGCXXFILESUFFIX']) + # For each file ending in SWIGCXXFILESUFFIX, add a new target director + # header by replacing the ending with SWIGDIRECTORSUFFIX. + for x in target[:]: + n = x.name + d = x.dir + if n[-len(suffix):] == suffix: + target.append(d.File(n[:-len(suffix)] + env['SWIGDIRECTORSUFFIX'])) def _swigEmitter(target, source, env): swigflags = env.subst("$SWIGFLAGS", target=target, source=source) @@ -71,12 +87,16 @@ def _swigEmitter(target, source, env): mnames = None if "-python" in flags and "-noproxy" not in flags: if mnames is None: - mnames = _find_modules(src) + mnames, directors = _find_modules(src) + if directors: + _add_director_header_targets(target, env) target.extend(map(lambda m, d=target[0].dir: d.File(m + ".py"), mnames)) if "-java" in flags: if mnames is None: - mnames = _find_modules(src) + mnames, directors = _find_modules(src) + if directors: + _add_director_header_targets(target, env) java_files = map(lambda m: [m + ".java", m + "JNI.java"], mnames) java_files = SCons.Util.flatten(java_files) outdir = env.subst('$SWIGOUTDIR', target=target, source=source) @@ -110,6 +130,7 @@ def generate(env): env['SWIG'] = 'swig' env['SWIGFLAGS'] = SCons.Util.CLVar('') + env['SWIGDIRECTORSUFFIX'] = '_wrap.h' env['SWIGCFILESUFFIX'] = '_wrap$CFILESUFFIX' env['SWIGCXXFILESUFFIX'] = '_wrap$CXXFILESUFFIX' env['_SWIGOUTDIR'] = r'${"-outdir \"%s\"" % SWIGOUTDIR}' diff --git a/test/SWIG/module-parens.py b/test/SWIG/module-parens.py index e30b93e..7b48a76 100644 --- a/test/SWIG/module-parens.py +++ b/test/SWIG/module-parens.py @@ -61,16 +61,7 @@ if sys.version[0] == '1': env.LoadableModule('test1.so', ['test1.i', 'test1.cc']) env.LoadableModule('test2.so', ['test2.i', 'test2.cc']) -env.Clean('.', ['test1_wrap.h', 'test2_wrap.h']) ### SEE NOTE BELOW """ % locals()) -# NOTE: For some reason, this test on OS X is unstable. The first time 'scons' -# is run, it works as expected. However, when 'scons' is run again, the -# 'test?_wrap.os' files are rebuilt. (When run a third time, it correctly -# determines that nothing is to be rebuilt.) When 'scons -c' is run, the -# 'test?_wrap.h' files are not removed, meaning that they are not identified -# by the emitter. Mentioning the two files in the SConscript file stabilizes -# the runs and makes the test reliable. When whatever that is causing this -# instability is chased down and cured, this hack should be removed. test.write(['test1.cc'], """\ int test1func() @@ -116,6 +107,11 @@ test.write(['test2.i'], """\ test.run(arguments = '.') +# Note that both tests use directors, so a file *_wrap.h should be generated +# in each case. If the emitter does not correctly allow for this, the test will +# not be up to date. +test.must_exist('test1_wrap.h') +test.must_exist('test2_wrap.h') test.up_to_date(arguments = '.') test.pass_test() -- cgit v0.12