From 678c769bc6189b5b7c301fbecfb37496725f6aee Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Wed, 20 Aug 2014 21:52:38 -0400 Subject: SWIG: improve tool detection, and update SWIG tests to run on Windows. The tool detection is improved by checking for swig in env['SWIG'], where it is commonly set, as well as env['ENV']['PATH']. The tests mostly didn't work on Windows. I updated them all. Mostly to build 32-bit extensions when using 32-bit python on Windows, and use .pyd as the python extension on Windows. --- QMTest/TestSCons.py | 17 ++++++++++++++--- src/engine/SCons/Tool/swig.py | 3 ++- test/SWIG/SWIGFLAGS.py | 6 ++++-- test/SWIG/SWIGOUTDIR-python.py | 14 +++++++++++--- test/SWIG/SWIGPATH.py | 1 + test/SWIG/build-dir.py | 12 +++++++++--- test/SWIG/generated_swigfile.py | 14 +++++++------- test/SWIG/implicit-dependencies.py | 2 +- test/SWIG/live.py | 11 +++++++++-- test/SWIG/module-deduced-name.py | 8 ++++++++ test/SWIG/module-parens.py | 20 ++++++++++++++++++-- test/SWIG/module-quoted.py | 18 +++++++++++++++++- test/SWIG/module-spaces.py | 20 ++++++++++++++++++-- test/SWIG/remove-modules.py | 6 ++++++ test/SWIG/subdir.py | 11 +++++++++-- 15 files changed, 134 insertions(+), 29 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 4b2b5a4..ae6e9c5 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -1129,14 +1129,25 @@ SConscript( sconscript ) self.run(program = python, stdin = """\ import os, sys try: - py_ver = 'python%d.%d' % sys.version_info[:2] + if sys.platform == 'win32': + py_ver = 'python%d%d' % sys.version_info[:2] + else: + py_ver = 'python%d.%d' % sys.version_info[:2] except AttributeError: py_ver = 'python' + sys.version[:3] -print os.path.join(sys.prefix, 'include', py_ver) -print os.path.join(sys.prefix, 'lib', py_ver, 'config') +# print include and lib path +try: + import distutils.sysconfig + exec_prefix = distutils.sysconfig.EXEC_PREFIX + print distutils.sysconfig.get_python_inc() + print os.path.join(exec_prefix, 'libs') +except: + print os.path.join(sys.prefix, 'include', py_ver) + print os.path.join(sys.prefix, 'lib', py_ver, 'config') print py_ver """) + # print "get_platform_python_info(): "+self.stdout() return [python] + self.stdout().strip().split('\n') def start(self, *args, **kw): diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index d51a386..f166174 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -174,7 +174,8 @@ def generate(env): env.Append(SCANNERS = scanner) def exists(env): - return env.Detect(['swig']) + swig = env.get('SWIG') or env.Detect(['swig']) + return swig # Local Variables: # tab-width:4 diff --git a/test/SWIG/SWIGFLAGS.py b/test/SWIG/SWIGFLAGS.py index 88f5184..cb91699 100644 --- a/test/SWIG/SWIGFLAGS.py +++ b/test/SWIG/SWIGFLAGS.py @@ -28,6 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Verify that we can use ${SOURCE} expansions in $SWIGFLAGS. """ +import sys import TestSCons test = TestSCons.TestSCons() @@ -54,9 +55,10 @@ test.write(['src', 'bar.i'], """\ test.write('SConstruct', """ # Note that setting the -I option in $SWIGFLAGS is not good and the # documentation says to use $SWIGPATH. This is just for testing. -env = Environment(SWIGFLAGS='-python -I${SOURCE.dir}') +env = Environment(SWIGFLAGS='-python -I${SOURCE.dir}', + SWIG=r'%(swig)s') env.CFile(target = 'foo', source = ['src/foo.i']) -""") +""" % locals()) test.run() diff --git a/test/SWIG/SWIGOUTDIR-python.py b/test/SWIG/SWIGOUTDIR-python.py index c94e509..db0cc95 100644 --- a/test/SWIG/SWIGOUTDIR-python.py +++ b/test/SWIG/SWIGOUTDIR-python.py @@ -31,6 +31,7 @@ that Python files are created in the specified output directory. import TestSCons import os +import sys test = TestSCons.TestSCons() @@ -44,8 +45,15 @@ Python_h = os.path.join(python_include, 'Python.h') if not os.path.exists(Python_h): test.skip_test('Can not find %s, skipping test.\n' % Python_h) +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write(['SConstruct'], """\ env = Environment(SWIGFLAGS = '-python -c++', + %(swig_arch_var)s CPPPATH=[r"%(python_include)s"], SWIG=[r'%(swig)s'], SWIGOUTDIR='python/build dir', @@ -64,17 +72,17 @@ test.write('python_foo_interface.i', """\ # subdirectory to hold the generated .py files. test.run(arguments = '.') -test.must_exist('python/build dir/foopack.py') +test.must_exist('python/build dir/foopack.py') # SCons should remove the built .py files. test.run(arguments = '-c') -test.must_not_exist('python/build dir/foopack.py') +test.must_not_exist('python/build dir/foopack.py') # SCons should realize it needs to rebuild the removed .py files. test.not_up_to_date(arguments = '.') -test.must_exist('python/build dir/foopack.py') +test.must_exist('python/build dir/foopack.py') test.pass_test() diff --git a/test/SWIG/SWIGPATH.py b/test/SWIG/SWIGPATH.py index 30426da..55e8d7e 100644 --- a/test/SWIG/SWIGPATH.py +++ b/test/SWIG/SWIGPATH.py @@ -55,6 +55,7 @@ test.write("dependent.i", """\ test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', + SWIG='%(swig)s', SWIGPATH=['inc1', 'inc2']) swig = foo.Dictionary('SWIG') bar = foo.Clone(SWIG = [r'%(python)s', 'wrapper.py', swig]) diff --git a/test/SWIG/build-dir.py b/test/SWIG/build-dir.py index 4e5bfe9..304932f 100644 --- a/test/SWIG/build-dir.py +++ b/test/SWIG/build-dir.py @@ -45,7 +45,7 @@ if not swig: if sys.platform == 'win32': _dll = '.dll' else: - _dll = '.so' + _dll = '.so' test.subdir(['source']) @@ -55,11 +55,17 @@ Python_h = os.path.join(python_include, 'Python.h') if not os.path.exists(Python_h): test.skip_test('Can not find %s, skipping test.\n' % Python_h) +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write(['SConstruct'], """\ # # Create the build environment. # env = Environment(CPPPATH = [".", r'%(python_include)s'], + %(swig_arch_var)s CPPDEFINES = "NDEBUG", SWIG = [r'%(swig)s'], SWIGFLAGS = ["-python", "-c++"], @@ -123,11 +129,11 @@ class Vector public: Vector(int n = 0); ~Vector(); - + %extend { const char* __str__() { return "linalg.Vector()"; } - + %pythoncode %{ def __iter__(self): for i in range(len(self)): diff --git a/test/SWIG/generated_swigfile.py b/test/SWIG/generated_swigfile.py index 1187df2..d09b473 100644 --- a/test/SWIG/generated_swigfile.py +++ b/test/SWIG/generated_swigfile.py @@ -39,14 +39,14 @@ import TestSCons if sys.platform == 'win32': _dll = '.dll' else: - _dll = '.so' + _dll = '.so' # swig-python expects specific filenames. # the platform specific suffix won't necessarily work. if sys.platform == 'win32': _dll = '.dll' else: - _dll = '.so' + _dll = '.so' test = TestSCons.TestSCons() @@ -69,17 +69,17 @@ foo = Environment(CPPPATH=[r'%(python_include)s'], SWIG=[r'%(swig)s'], LIBPATH=[r'%(python_libpath)s'], ) -python_interface = foo.Command( 'test_py_swig.i', Value(1), "echo '%%module test_py_swig' > test_py_swig.i" ) +python_interface = foo.Command( 'test_py_swig.i', Value(1), 'echo %%module test_py_swig > test_py_swig.i' ) python_c_file = foo.CFile( target='python_swig_test',source=python_interface, SWIGFLAGS = '-python -c++' ) -java_interface = foo.Command( 'test_java_swig.i', Value(1),"echo '%%module test_java_swig' > test_java_swig.i" ) -java_c_file = foo.CFile( target='java_swig_test' ,source=java_interface, SWIGFLAGS = '-java -c++' ) +java_interface = foo.Command( 'test_java_swig.i', Value(1),'echo %%module test_java_swig > test_java_swig.i' ) +java_c_file = foo.CFile( target='java_swig_test' ,source=java_interface, SWIGFLAGS = '-java -c++' ) """ % locals()) expected_stdout = """\ -echo '%%module test_java_swig' > test_java_swig.i +echo %%module test_java_swig > test_java_swig.i %(swig)s -o java_swig_test_wrap.cc -java -c++ test_java_swig.i -echo '%%module test_py_swig' > test_py_swig.i +echo %%module test_py_swig > test_py_swig.i %(swig)s -o python_swig_test_wrap.cc -python -c++ test_py_swig.i """ % locals() test.run(arguments = '.',stdout=test.wrap_stdout(expected_stdout)) diff --git a/test/SWIG/implicit-dependencies.py b/test/SWIG/implicit-dependencies.py index 6d40216..465a0d6 100644 --- a/test/SWIG/implicit-dependencies.py +++ b/test/SWIG/implicit-dependencies.py @@ -52,7 +52,7 @@ test.write("dependent.i", """\ """) test.write('SConstruct', """ -foo = Environment(SWIGFLAGS='-python') +foo = Environment(SWIGFLAGS='-python', SWIG='%(swig)s') swig = foo.Dictionary('SWIG') bar = foo.Clone(SWIG = [r'%(python)s', r'wrapper.py', swig]) foo.CFile(target = 'dependent', source = ['dependent.i']) diff --git a/test/SWIG/live.py b/test/SWIG/live.py index 4d4369e..7d79bae 100644 --- a/test/SWIG/live.py +++ b/test/SWIG/live.py @@ -36,7 +36,7 @@ import TestSCons # swig-python expects specific filenames. # the platform specific suffix won't necessarily work. if sys.platform == 'win32': - _dll = '.dll' + _dll = '.pyd' else: _dll = '.so' @@ -55,6 +55,12 @@ if not os.path.exists(Python_h): # handle testing on other platforms: ldmodule_prefix = '_' +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write("wrapper.py", """import os import sys @@ -64,11 +70,12 @@ os.system(" ".join(sys.argv[1:])) test.write('SConstruct', """\ foo = Environment(SWIGFLAGS='-python', + LIBPATH=[r'%(python_libpath)s'], CPPPATH=[r'%(python_include)s'], LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', SWIG=[r'%(swig)s'], - LIBPATH=[r'%(python_libpath)s'], + %(swig_arch_var)s LIBS='%(python_lib)s', ) diff --git a/test/SWIG/module-deduced-name.py b/test/SWIG/module-deduced-name.py index 733b6c1..bdaef4f 100644 --- a/test/SWIG/module-deduced-name.py +++ b/test/SWIG/module-deduced-name.py @@ -32,6 +32,7 @@ emitter should return the basename of the module only. import TestSCons import os +import sys test = TestSCons.TestSCons() @@ -45,8 +46,15 @@ Python_h = os.path.join(python_include, 'Python.h') if not os.path.exists(Python_h): test.skip_test('Cannot find %s, skipping test.\n' % Python_h) +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write(['SConstruct'], """\ env = Environment(SWIGFLAGS = '-python -c++', + %(swig_arch_var)s CPPPATH=[r"%(python_include)s"], SWIG=[r'%(swig)s'], SWIGOUTDIR='python/build dir', diff --git a/test/SWIG/module-parens.py b/test/SWIG/module-parens.py index 6ae4924..d8c1744 100644 --- a/test/SWIG/module-parens.py +++ b/test/SWIG/module-parens.py @@ -30,6 +30,7 @@ without white space before the opening parenthesis. """ import os.path +import sys import TestSCons test = TestSCons.TestSCons() @@ -44,16 +45,31 @@ Python_h = os.path.join(python_include, 'Python.h') if not os.path.exists(Python_h): test.skip_test('Can not find %s, skipping test.\n' % Python_h) +# swig-python expects specific filenames. +# the platform specific suffix won't necessarily work. +if sys.platform == 'win32': + _dll = '.pyd' +else: + _dll = '.so' + +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write(['SConstruct'], """\ env = Environment(SWIGFLAGS = '-python -c++', + %(swig_arch_var)s CPPPATH=[r'%(python_include)s'], SWIG=[r'%(swig)s'], LIBPATH=[r'%(python_libpath)s'], LIBS='%(python_lib)s', + LDMODULESUFFIX='%(_dll)s', ) -env.LoadableModule('test1.so', ['test1.i', 'test1.cc']) -env.LoadableModule('test2.so', ['test2.i', 'test2.cc']) +env.LoadableModule('test1', ['test1.i', 'test1.cc']) +env.LoadableModule('test2', ['test2.i', 'test2.cc']) """ % locals()) test.write(['test1.cc'], """\ diff --git a/test/SWIG/module-quoted.py b/test/SWIG/module-quoted.py index ec7a132..6f4b891 100644 --- a/test/SWIG/module-quoted.py +++ b/test/SWIG/module-quoted.py @@ -30,6 +30,7 @@ Verify that we correctly parse quoted module names; e.g. %module "test" """ import os.path +import sys import TestSCons test = TestSCons.TestSCons() @@ -44,15 +45,30 @@ Python_h = os.path.join(python_include, 'Python.h') if not os.path.exists(Python_h): test.skip_test('Can not find %s, skipping test.\n' % Python_h) +# swig-python expects specific filenames. +# the platform specific suffix won't necessarily work. +if sys.platform == 'win32': + _dll = '.pyd' +else: + _dll = '.so' + +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write(['SConstruct'], """\ env = Environment(SWIGFLAGS = '-python -c++', + %(swig_arch_var)s CPPPATH=[r'%(python_include)s'], SWIG=[r'%(swig)s'], LIBPATH=[r'%(python_libpath)s'], LIBS='%(python_lib)s', + LDMODULESUFFIX='%(_dll)s', ) -env.LoadableModule('test1.so', ['test1.i', 'test1.cc']) +env.LoadableModule('test1', ['test1.i', 'test1.cc']) """ % locals()) test.write(['test1.cc'], """\ diff --git a/test/SWIG/module-spaces.py b/test/SWIG/module-spaces.py index a0056f0..2833dff 100644 --- a/test/SWIG/module-spaces.py +++ b/test/SWIG/module-spaces.py @@ -30,6 +30,7 @@ the module name ; e.g. "%module test " """ import os.path +import sys import TestSCons test = TestSCons.TestSCons() @@ -44,15 +45,30 @@ Python_h = os.path.join(python_include, 'Python.h') if not os.path.exists(Python_h): test.skip_test('Can not find %s, skipping test.\n' % Python_h) +# swig-python expects specific filenames. +# the platform specific suffix won't necessarily work. +if sys.platform == 'win32': + _dll = '.pyd' +else: + _dll = '.so' + +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write(['SConstruct'], """\ env = Environment(SWIGFLAGS = '-python -c++', + %(swig_arch_var)s CPPPATH=[r'%(python_include)s'], SWIG=[r'%(swig)s'], LIBPATH=[r'%(python_libpath)s'], LIBS='%(python_lib)s', + LDMODULESUFFIX='%(_dll)s', ) -env.LoadableModule('test1.so', ['test1.i', 'test1.cc']) +env.LoadableModule('test1', ['test1.i', 'test1.cc']) """ % locals()) test.write(['test1.cc'], """\ @@ -67,7 +83,7 @@ int test1func(); """) test.write(['test1.i'], """\ -%module test1 +%module test1 %{ #include "test1.h" diff --git a/test/SWIG/remove-modules.py b/test/SWIG/remove-modules.py index 964970b..f5ce60d 100644 --- a/test/SWIG/remove-modules.py +++ b/test/SWIG/remove-modules.py @@ -56,6 +56,11 @@ if not os.path.exists(Python_h): # handle testing on other platforms: ldmodule_prefix = '_' +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" test.write("module.i", """\ %module modulename @@ -63,6 +68,7 @@ test.write("module.i", """\ test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', + %(swig_arch_var)s CPPPATH=['%(python_include)s'], LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', diff --git a/test/SWIG/subdir.py b/test/SWIG/subdir.py index 0b9f24d..e23b858 100644 --- a/test/SWIG/subdir.py +++ b/test/SWIG/subdir.py @@ -39,7 +39,7 @@ import TestSCons if sys.platform == 'win32': _dll = '.dll' else: - _dll = '.so' + _dll = '.so' test = TestSCons.TestSCons() @@ -58,14 +58,21 @@ if not os.path.exists(Python_h): # handle testing on other platforms: ldmodule_prefix = '_' +# On Windows, build a 32-bit exe if on 32-bit python. +if sys.platform == 'win32' and sys.maxsize <= 2**32: + swig_arch_var="TARGET_ARCH='x86'," +else: + swig_arch_var="" + test.write('SConstruct', """ env = Environment(SWIGFLAGS='-python', + %(swig_arch_var)s CPPPATH=['%(python_include)s/'], LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', SWIG=r'%(swig)s', LIBPATH=[r'%(python_libpath)s'], - LIBS='%(python_lib)s', + LIBS='%(python_lib)s' ) env.LoadableModule('sub/_foo', -- cgit v0.12 From 4d4029a77e986d64153b3de0ece5177dbaed5cd9 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Thu, 21 Aug 2014 06:41:26 -0400 Subject: Remove extra print stmt in TestSCons.py, per review. --- QMTest/TestSCons.py | 1 - 1 file changed, 1 deletion(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index ae6e9c5..9434bb1 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -1147,7 +1147,6 @@ except: print py_ver """) - # print "get_platform_python_info(): "+self.stdout() return [python] + self.stdout().strip().split('\n') def start(self, *args, **kw): -- cgit v0.12