diff options
author | David Cournapeau <cournape@gmail.com> | 2009-02-21 17:25:09 +0000 |
---|---|---|
committer | David Cournapeau <cournape@gmail.com> | 2009-02-21 17:25:09 +0000 |
commit | b4d0366abcec1ea1c2a1946167d1b9873f372a51 (patch) | |
tree | 09e567210dda33fcf95434de560ac688b8804917 /numpy/distutils/mingw32ccompiler.py | |
parent | 16287f8545397ea651658b878040eab249e84b6d (diff) | |
parent | da364a18e447c334dfa2ca5083b08e1b6a7c0d10 (diff) | |
download | numpy-b4d0366abcec1ea1c2a1946167d1b9873f372a51.tar.gz |
Merged revisions 6153-6173,6176-6178,6184 via svnmerge from
http://svn.scipy.org/svn/numpy/branches/numpy-mingw-w64
........
r6153 | cdavid | 2008-12-19 17:06:06 +0900 (Fri, 19 Dec 2008) | 1 line
Add a function to find python dll on windows.
........
r6154 | cdavid | 2008-12-19 17:28:49 +0900 (Fri, 19 Dec 2008) | 1 line
Fix typo when getting system32 location.
........
r6155 | cdavid | 2008-12-19 17:37:19 +0900 (Fri, 19 Dec 2008) | 1 line
Add a function to get a dump of private headers from dll.
........
r6156 | cdavid | 2008-12-19 17:41:39 +0900 (Fri, 19 Dec 2008) | 1 line
Add a function to generate a .def file from a dll.
........
r6157 | cdavid | 2008-12-19 17:43:56 +0900 (Fri, 19 Dec 2008) | 1 line
Forgot to add the regex for the generate_def function.
........
r6158 | cdavid | 2008-12-19 17:53:49 +0900 (Fri, 19 Dec 2008) | 1 line
Fix .def file generation.
........
r6159 | cdavid | 2008-12-19 17:56:54 +0900 (Fri, 19 Dec 2008) | 1 line
Add a warning if no symbols found in the dll (if stripped, for example).
........
r6160 | cdavid | 2008-12-19 18:02:24 +0900 (Fri, 19 Dec 2008) | 1 line
Refactor build_import_library to take into account multi arch.
........
r6161 | cdavid | 2008-12-19 18:10:03 +0900 (Fri, 19 Dec 2008) | 1 line
Do not generate manifest when built with msver 8.*, it does not look like it is needed, and we dont support it anyway ATM.
........
r6162 | cdavid | 2008-12-19 18:18:08 +0900 (Fri, 19 Dec 2008) | 1 line
Show arch in the log when building import library.
........
r6163 | cdavid | 2008-12-19 18:22:18 +0900 (Fri, 19 Dec 2008) | 1 line
Fix missing out filename.
........
r6164 | cdavid | 2008-12-19 18:32:46 +0900 (Fri, 19 Dec 2008) | 1 line
Actually build the import library for mingw on amd64.
........
r6165 | cdavid | 2008-12-19 18:46:30 +0900 (Fri, 19 Dec 2008) | 1 line
Do not generate ordinal, and use the basename of the dll instead of the full path in the def.file.
........
r6166 | cdavid | 2008-12-19 18:48:01 +0900 (Fri, 19 Dec 2008) | 1 line
Trailing spaces.
........
r6167 | cdavid | 2008-12-19 18:55:16 +0900 (Fri, 19 Dec 2008) | 1 line
Add MS_WIN64 macro when built on amd64 + mingw.
........
r6168 | cdavid | 2008-12-19 18:57:06 +0900 (Fri, 19 Dec 2008) | 1 line
Forgot to import get_build_architecture.
........
r6169 | cdavid | 2008-12-19 18:57:52 +0900 (Fri, 19 Dec 2008) | 1 line
Use a tuple when defining the MS_WIN64 macro.
........
r6170 | cdavid | 2008-12-19 19:05:03 +0900 (Fri, 19 Dec 2008) | 1 line
Fix macro def.
........
r6171 | cdavid | 2008-12-19 19:21:54 +0900 (Fri, 19 Dec 2008) | 2 lines
Do not use g++ for linking on amd64.
........
r6172 | cdavid | 2008-12-19 19:25:18 +0900 (Fri, 19 Dec 2008) | 1 line
do not regenerate the import library if already there.
........
r6173 | cdavid | 2008-12-19 19:28:39 +0900 (Fri, 19 Dec 2008) | 1 line
Add one full msvcrt version for 80 (for manifest generation).
........
r6176 | cdavid | 2008-12-21 02:31:48 +0900 (Sun, 21 Dec 2008) | 1 line
Remove optimization flags for now, to speed up builds.
........
r6177 | cdavid | 2008-12-21 02:32:11 +0900 (Sun, 21 Dec 2008) | 1 line
Add MS_WIN64 for every compile command.
........
r6178 | cdavid | 2008-12-21 02:32:33 +0900 (Sun, 21 Dec 2008) | 1 line
Remove handling of MS_WIN64 in commands: deal with it in mingw tool only.
........
r6184 | cdavid | 2008-12-21 16:46:28 +0900 (Sun, 21 Dec 2008) | 1 line
Hardcode size of long double, because it is broken with mingw.
........
Diffstat (limited to 'numpy/distutils/mingw32ccompiler.py')
-rw-r--r-- | numpy/distutils/mingw32ccompiler.py | 142 |
1 files changed, 127 insertions, 15 deletions
diff --git a/numpy/distutils/mingw32ccompiler.py b/numpy/distutils/mingw32ccompiler.py index 3c7bd2fdc..b3918fa55 100644 --- a/numpy/distutils/mingw32ccompiler.py +++ b/numpy/distutils/mingw32ccompiler.py @@ -12,6 +12,8 @@ import os import subprocess import sys import log +import subprocess +import re # Overwrite certain distutils.ccompiler functions: import numpy.distutils.ccompiler @@ -29,7 +31,11 @@ from distutils.errors import DistutilsExecError, CompileError, UnknownFileError from distutils.unixccompiler import UnixCCompiler from distutils.msvccompiler import get_build_version as get_build_msvc_version -from numpy.distutils.misc_util import msvc_runtime_library +from numpy.distutils.misc_util import msvc_runtime_library, get_build_architecture + +# Useful to generate table of symbols from a dll +_START = re.compile(r'\[Ordinal/Name Pointer\] Table') +_TABLE = re.compile(r'^\s+\[([\s*[0-9]*)\] ([a-zA-Z0-9_]*)') # the same as cygwin plus some additional parameters class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): @@ -89,17 +95,29 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): # linker_exe='gcc -mno-cygwin', # linker_so='%s --driver-name g++ -mno-cygwin -mdll -static %s' # % (self.linker, entry_point)) - if self.gcc_version <= "3.0.0": - self.set_executables(compiler='gcc -mno-cygwin -O2 -w', - compiler_so='gcc -mno-cygwin -mdll -O2 -w -Wstrict-prototypes', - linker_exe='g++ -mno-cygwin', - linker_so='%s -mno-cygwin -mdll -static %s' - % (self.linker, entry_point)) + + # MS_WIN64 should be defined when building for amd64 on windows, but + # python headers define it only for MS compilers, which has all kind of + # bad consequences, like using Py_ModuleInit4 instead of + # Py_ModuleInit4_64, etc... So we add it here + if get_build_architecture() == 'AMD64': + self.set_executables( + compiler='gcc -DMS_WIN64 -mno-cygwin -O0 -Wall', + compiler_so='gcc -DMS_WIN64 -mno-cygwin -O0 -Wall -Wstrict-prototypes', + linker_exe='gcc -mno-cygwin', + linker_so='gcc -mno-cygwin -shared') else: - self.set_executables(compiler='gcc -mno-cygwin -O2 -Wall', - compiler_so='gcc -mno-cygwin -O2 -Wall -Wstrict-prototypes', - linker_exe='g++ -mno-cygwin', - linker_so='g++ -mno-cygwin -shared') + if self.gcc_version <= "3.0.0": + self.set_executables(compiler='gcc -mno-cygwin -O2 -w', + compiler_so='gcc -mno-cygwin -mdll -O2 -w -Wstrict-prototypes', + linker_exe='g++ -mno-cygwin', + linker_so='%s -mno-cygwin -mdll -static %s' + % (self.linker, entry_point)) + else: + self.set_executables(compiler='gcc -mno-cygwin -O2 -Wall', + compiler_so='gcc -mno-cygwin -O2 -Wall -Wstrict-prototypes', + linker_exe='g++ -mno-cygwin', + linker_so='g++ -mno-cygwin -shared') # added for python2.3 support # we can't pass it through set_executables because pre 2.2 would fail self.compiler_cxx = ['g++'] @@ -191,11 +209,102 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): # object_filenames () +def find_python_dll(): + maj, min, micro = [int(i) for i in sys.version_info[:3]] + dllname = 'python%d%d.dll' % (maj, min) + print "Looking for %s" % dllname + + # We can't do much here: + # - find it in python main dir + # - in system32, + # - ortherwise (Sxs), I don't know how to get it. + lib_dirs = [] + lib_dirs.append(os.path.join(sys.prefix, 'lib')) + try: + lib_dirs.append(os.path.join(os.environ['SYSTEMROOT'], 'system32')) + except KeyError: + pass + + for d in lib_dirs: + dll = os.path.join(d, dllname) + if os.path.exists(dll): + return dll + + raise ValueError("%s not found in %s" % (dllname, lib_dirs)) + +def dump_table(dll): + st = subprocess.Popen(["objdump.exe", "-p", dll], stdout=subprocess.PIPE) + return st.stdout.readlines() + +def generate_def(dll, dfile): + """Given a dll file location, get all its exported symbols and dump them + into the given def file. + + The .def file will be overwritten""" + dump = dump_table(dll) + for i in range(len(dump)): + if _START.match(dump[i]): + break + + if i == len(dump): + raise ValueError("Symbol table not found") + + syms = [] + for j in range(i+1, len(dump)): + m = _TABLE.match(dump[j]) + if m: + syms.append((int(m.group(1).strip()), m.group(2))) + else: + break + + if len(syms) == 0: + log.warn('No symbols found in %s' % dll) + + d = open(dfile, 'w') + d.write('LIBRARY %s\n' % os.path.basename(dll)) + d.write(';CODE PRELOAD MOVEABLE DISCARDABLE\n') + d.write(';DATA PRELOAD SINGLE\n') + d.write('\nEXPORTS\n') + for s in syms: + #d.write('@%d %s\n' % (s[0], s[1])) + d.write('%s\n' % s[1]) + d.close() + def build_import_library(): - """ Build the import libraries for Mingw32-gcc on Windows - """ if os.name != 'nt': return + + arch = get_build_architecture() + if arch == 'AMD64': + return _build_import_library_amd64() + elif arch == 'Intel': + return _build_import_library_x86() + else: + raise ValueError("Unhandled arch %s" % arch) + +def _build_import_library_amd64(): + dll_file = find_python_dll() + + out_name = "libpython%d%d.a" % tuple(sys.version_info[:2]) + out_file = os.path.join(sys.prefix, 'libs', out_name) + if os.path.isfile(out_file): + log.debug('Skip building import library: "%s" exists' % (out_file)) + return + + def_name = "python%d%d.def" % tuple(sys.version_info[:2]) + def_file = os.path.join(sys.prefix,'libs',def_name) + + log.info('Building import library (arch=AMD64): "%s" (from %s)' \ + % (out_file, dll_file)) + + generate_def(dll_file, def_file) + + cmd = ['dlltool', '-d', def_file, '-l', out_file] + subprocess.Popen(cmd) + +def _build_import_library_x86(): + """ Build the import libraries for Mingw32-gcc on Windows + """ lib_name = "python%d%d.lib" % tuple(sys.version_info[:2]) lib_file = os.path.join(sys.prefix,'libs',lib_name) out_name = "libpython%d%d.a" % tuple(sys.version_info[:2]) @@ -206,7 +315,7 @@ def build_import_library(): if os.path.isfile(out_file): log.debug('Skip building import library: "%s" exists' % (out_file)) return - log.info('Building import library: "%s"' % (out_file)) + log.info('Building import library (ARCH=x86): "%s"' % (out_file)) from numpy.distutils import lib2def @@ -254,6 +363,9 @@ if sys.platform == 'win32': _MSVCRVER_TO_FULLVER['90'] = msvcrt.CRT_ASSEMBLY_VERSION else: _MSVCRVER_TO_FULLVER['90'] = "9.0.21022.8" + # I took one version in my SxS directory: no idea if it is the good + # one, and we can't retrieve it from python + _MSVCRVER_TO_FULLVER['90'] = "8.0.50727.42" except ImportError: # If we are here, means python was not built with MSVC. Not sure what to do # in that case: manifest building will fail, but it should not be used in @@ -344,7 +456,7 @@ def rc_name(config): def generate_manifest(config): msver = get_build_msvc_version() if msver is not None: - if msver >= 8: + if msver >= 9: check_embedded_msvcr_match_linked(msver) ma = int(msver) mi = int((msver - ma) * 10) |