Issue 2278: Emit header name when using SWIG directors (Ben Webb)
authorGregNoel <GregNoel@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 17 Jan 2009 19:56:55 +0000 (19:56 +0000)
committerGregNoel <GregNoel@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 17 Jan 2009 19:56:55 +0000 (19:56 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@3904 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Tool/swig.py
test/SWIG/module-parens.py

index cbdda51cf3a16e10f7a6044e7c97df9af8709cd4..2e9b20f9d41e8057f2535edfb41d0a73521c62d8 100644 (file)
@@ -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
index 08f8cd494201a0e8938abeb8112bf446c658b981..eff88062ef54c136887af484b802c0840448a1fc 100644 (file)
@@ -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}'
index e30b93e66ba1c84e819737a9f7ed92e9f92c48db..7b48a76422dfab72c9ae8526bc0d2717525fc9fa 100644 (file)
@@ -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()