summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--QMTest/TestRuntest.py2
-rw-r--r--src/CHANGES.txt14
-rw-r--r--src/engine/SCons/Platform/__init__.py17
-rw-r--r--src/engine/SCons/Tool/__init__.py27
-rw-r--r--src/engine/SCons/Tool/swig.py54
-rw-r--r--test/SWIG/SWIG.py50
6 files changed, 154 insertions, 10 deletions
diff --git a/QMTest/TestRuntest.py b/QMTest/TestRuntest.py
index 6fd423a..a4bcd05 100644
--- a/QMTest/TestRuntest.py
+++ b/QMTest/TestRuntest.py
@@ -99,7 +99,7 @@ class TestRuntest(TestCommon):
'QMTest',
]
- dirs = []
+ dirs = [orig_cwd]
spe = os.environ.get('SCONS_SOURCE_PATH_EXECUTABLE', orig_cwd)
for d in string.split(spe, os.pathsep):
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index b3eb484..ccbc3af 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -47,6 +47,16 @@ RELEASE 0.97 - XXX
This will become the default behavior as we add more functionality
to the QMTest side.
+ From Arve Knudsen:
+
+ - Support cleaning and scanning SWIG-generated files.
+
+ From Baptiste Lepilleur:
+
+ - Try using zipimport if we can't import Tool or Platform modules
+ using the normal "imp" module. This allows SCons to be packaged
+ using py2exe's all-in-one-zip-file approach.
+
From Sanjoy Mahajan:
- Change use of $SOURCES to $SOURCE in all TeX-related Tool modules.
@@ -99,6 +109,10 @@ RELEASE 0.97 - XXX
- Fix detection of Visual C++ Express Edition.
+ From Johan Zander:
+
+ - Fix missing os.path.join() when constructing the $FRAMEWORKSDKDIR/bin.
+
RELEASE 0.96.92 - Mon, 10 Apr 2006 21:08:22 -0400
diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py
index b1a0a67..0a47059 100644
--- a/src/engine/SCons/Platform/__init__.py
+++ b/src/engine/SCons/Platform/__init__.py
@@ -98,12 +98,19 @@ def platform_module(name = platform_default()):
try:
file, path, desc = imp.find_module(name,
sys.modules['SCons.Platform'].__path__)
- mod = imp.load_module(full_name, file, path, desc)
- setattr(SCons.Platform, name, mod)
+ try:
+ mod = imp.load_module(full_name, file, path, desc)
+ finally:
+ if file:
+ file.close()
except ImportError:
- raise SCons.Errors.UserError, "No platform named '%s'" % name
- if file:
- file.close()
+ try:
+ import zipimport
+ importer = zipimport.zipimporter( sys.modules['SCons.Platform'].__path__[0] )
+ mod = importer.load_module(full_name)
+ except ImportError:
+ raise SCons.Errors.UserError, "No platform named '%s'" % name
+ setattr(SCons.Platform, name, mod)
return sys.modules[full_name]
def DefaultToolList(platform, env):
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 77da0c7..d36478d 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -99,7 +99,17 @@ class Tool:
if file:
file.close()
except ImportError, e:
- pass
+ try:
+ import zipimport
+ except ImportError:
+ pass
+ else:
+ for aPath in self.toolpath:
+ try:
+ importer = zipimport.zipimporter(aPath)
+ return importer.load_module(self.name)
+ except ImportError, e:
+ pass
finally:
sys.path = oldpythonpath
@@ -109,14 +119,23 @@ class Tool:
except KeyError:
try:
smpath = sys.modules['SCons.Tool'].__path__
- file, path, desc = imp.find_module(self.name, smpath)
try:
+ file, path, desc = imp.find_module(self.name, smpath)
module = imp.load_module(full_name, file, path, desc)
setattr(SCons.Tool, self.name, module)
- return module
- finally:
if file:
file.close()
+ return module
+ except ImportError, e:
+ try:
+ import zipimport
+ importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] )
+ module = importer.load_module(full_name)
+ setattr(SCons.Tool, self.name, module)
+ return module
+ except ImportError, e:
+ m = "No tool named '%s': %s" % (self.name, e)
+ raise SCons.Errors.UserError, m
except ImportError, e:
m = "No tool named '%s': %s" % (self.name, e)
raise SCons.Errors.UserError, m
diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py
index 449e3aa..ed066a7 100644
--- a/src/engine/SCons/Tool/swig.py
+++ b/src/engine/SCons/Tool/swig.py
@@ -37,6 +37,9 @@ import SCons.Action
import SCons.Defaults
import SCons.Tool
import SCons.Util
+from SCons.Scanner import Scanner
+import os
+import re
SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR')
@@ -46,6 +49,54 @@ def swigSuffixEmitter(env, source):
else:
return '$SWIGCFILESUFFIX'
+_reSwig = re.compile(r"%include\s+(\S+)")
+
+def recurse(path, searchPath):
+ global _reSwig
+ f = open(path)
+ try: contents = f.read()
+ finally: f.close()
+
+ found = []
+ # Better code for when we drop Python 1.5.2.
+ #for m in _reSwig.finditer(contents):
+ # fname = m.group(1)
+ for fname in _reSwig.findall(contents):
+ for dpath in searchPath:
+ absPath = os.path.join(dpath, fname)
+ if os.path.isfile(absPath):
+ found.append(absPath)
+ break
+
+ # Equivalent code for when we drop Python 1.5.2.
+ #for f in [f for f in found if os.path.splitext(f)[1] == ".i"]:
+ # found += recurse(f, searchPath)
+ for f in filter(lambda f: os.path.splitext(f)[1] == ".i", found):
+ found = found + recurse(f, searchPath)
+ return found
+
+def _scanSwig(node, env, path):
+ import sys
+ r = recurse(str(node), [os.path.abspath(os.path.dirname(str(node))), os.path.abspath(os.path.join("include", "swig"))])
+ return r
+
+def _swigEmitter(target, source, env):
+ for src in source:
+ src = str(src)
+ mname = None
+ if "-python" in SCons.Util.CLVar(env.subst("$SWIGFLAGS")):
+ f = open(src)
+ try:
+ for l in f.readlines():
+ m = re.match("%module (.+)", l)
+ if m:
+ mname = m.group(1)
+ finally:
+ f.close()
+ if mname is not None:
+ target.append(mname + ".py")
+ return (target, source)
+
def generate(env):
"""Add Builders and construction variables for swig to an Environment."""
c_file, cxx_file = SCons.Tool.createCFileBuilders(env)
@@ -54,13 +105,16 @@ def generate(env):
cxx_file.suffix['.i'] = swigSuffixEmitter
c_file.add_action('.i', SwigAction)
+ c_file.add_emitter('.i', _swigEmitter)
cxx_file.add_action('.i', SwigAction)
+ cxx_file.add_emitter('.i', _swigEmitter)
env['SWIG'] = 'swig'
env['SWIGFLAGS'] = SCons.Util.CLVar('')
env['SWIGCFILESUFFIX'] = '_wrap$CFILESUFFIX'
env['SWIGCXXFILESUFFIX'] = '_wrap$CXXFILESUFFIX'
env['SWIGCOM'] = '$SWIG $SWIGFLAGS -o $TARGET $SOURCES'
+ env.Append(SCANNERS=Scanner(function=_scanSwig, skeys=[".i"]))
def exists(env):
return env.Detect(['swig'])
diff --git a/test/SWIG/SWIG.py b/test/SWIG/SWIG.py
index 753d0b9..65ecf2b 100644
--- a/test/SWIG/SWIG.py
+++ b/test/SWIG/SWIG.py
@@ -218,6 +218,56 @@ This is bar.c!
test.up_to_date(arguments = '.')
+ # Test that swig-generated modules are removed
+ # The %module directive specifies the module name
+ test.write("module.i", """\
+%module modulename
+""")
+ test.write('SConstruct', """
+foo = Environment(SWIGFLAGS='-python',
+ CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/',
+ SHCCFLAGS='',
+ LDMODULEPREFIX='%(ldmodule_prefix)s',
+ LDMODULESUFFIX='%(_dll)s',
+ FRAMEWORKSFLAGS='%(frameworks)s',
+ )
+
+foo.LoadableModule(target = 'modulename', source = ['module.i'])
+""" % locals())
+ test.run()
+ test.must_exist(test.workpath("modulename.py"))
+ test.run(arguments = "-c")
+ test.must_not_exist(test.workpath("modulename.py"))
+
+ # Test that implicit dependencies are caught
+
+ test.write("dependency.i", """\
+%module dependency
+""")
+ test.write("dependent.i", """\
+%module dependent
+
+%include dependency.i
+""")
+ test.write('SConstruct', """
+foo = Environment(SWIGFLAGS='-python',
+ CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/',
+ SHCCFLAGS='',
+ LDMODULEPREFIX='%(ldmodule_prefix)s',
+ LDMODULESUFFIX='%(_dll)s',
+ FRAMEWORKSFLAGS='%(frameworks)s',
+ )
+swig = foo.Dictionary('SWIG')
+bar = foo.Copy(SWIG = r'%(python)s wrapper.py ' + swig)
+foo.CFile(target = 'dependent', source = ['dependent.i'])
+""" % locals())
+
+ test.run()
+ test.write("dependency.i", """%module dependency
+
+extern char *dependency_string();
+""")
+ test.not_up_to_date(arguments = "dependent_wrap.c")
test.pass_test()