diff options
| author | cookedm <cookedm@localhost> | 2006-07-28 20:02:07 +0000 |
|---|---|---|
| committer | cookedm <cookedm@localhost> | 2006-07-28 20:02:07 +0000 |
| commit | b8783285fe67338ef11ba0a40d80ce62172d8ba1 (patch) | |
| tree | 2b4fe4e9cec986a229a484b8b7ef1d591a94fb73 /numpy | |
| parent | 471419fc4edca27993f8970306115e4c55a2c8a1 (diff) | |
| download | numpy-b8783285fe67338ef11ba0a40d80ce62172d8ba1.tar.gz | |
Fix #114: Problems with building with MSVC and GCC under Cygwin
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/distutils/ccompiler.py | 2 | ||||
| -rw-r--r-- | numpy/distutils/command/build_ext.py | 37 | ||||
| -rw-r--r-- | numpy/distutils/fcompiler/gnu.py | 45 | ||||
| -rw-r--r-- | numpy/distutils/mingw32ccompiler.py | 21 | ||||
| -rw-r--r-- | numpy/distutils/misc_util.py | 13 | ||||
| -rw-r--r-- | numpy/distutils/system_info.py | 69 |
6 files changed, 139 insertions, 48 deletions
diff --git a/numpy/distutils/ccompiler.py b/numpy/distutils/ccompiler.py index 1c417f9a2..736a691e9 100644 --- a/numpy/distutils/ccompiler.py +++ b/numpy/distutils/ccompiler.py @@ -18,7 +18,7 @@ import distutils.sysconfig _old_init_posix = distutils.sysconfig._init_posix def _new_init_posix(): _old_init_posix() - distutils.sysconfig._config_vars['OPT'] = '-Wall -g -O2' + distutils.sysconfig._config_vars['OPT'] = '-Wall -g -O0' #distutils.sysconfig._init_posix = _new_init_posix # Using customized CCompiler.spawn. diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py index 8d4accde3..9958f5d8b 100644 --- a/numpy/distutils/command/build_ext.py +++ b/numpy/distutils/command/build_ext.py @@ -8,12 +8,16 @@ from glob import glob from distutils.dep_util import newer_group from distutils.command.build_ext import build_ext as old_build_ext +from distutils.errors import DistutilsFileError, DistutilsSetupError +from distutils.file_util import copy_file from numpy.distutils import log +from numpy.distutils.exec_command import exec_command +from numpy.distutils.system_info import combine_paths from numpy.distutils.misc_util import filter_sources, has_f_sources, \ has_cxx_sources, get_ext_source_files, all_strings, \ get_numpy_include_dirs, is_sequence -from distutils.errors import DistutilsFileError, DistutilsSetupError + class build_ext (old_build_ext): @@ -290,9 +294,8 @@ class build_ext (old_build_ext): # Always use system linker when using MSVC compiler. if self.compiler.compiler_type=='msvc' and use_fortran_linker: - c_libraries.extend(self.fcompiler.libraries) - c_library_dirs.extend(self.fcompiler.library_dirs) - use_fortran_linker = 0 + self._libs_with_msvc_and_fortran(c_libraries, c_library_dirs) + use_fortran_linker = False if use_fortran_linker: if cxx_sources: @@ -330,6 +333,32 @@ class build_ext (old_build_ext): return + def _libs_with_msvc_and_fortran(self, c_libraries, c_library_dirs): + # Always use system linker when using MSVC compiler. + f_lib_dirs = [] + for dir in self.fcompiler.library_dirs: + # correct path when compiling in Cygwin but with normal Win + # Python + if dir.startswith('/usr/lib'): + s,o = exec_command(['cygpath', '-w', dir], use_tee=False) + if not s: + dir = o + f_lib_dirs.append(dir) + c_library_dirs.extend(f_lib_dirs) + + # make g77-compiled static libs available to MSVC + lib_added = False + for lib in self.fcompiler.libraries: + if not lib.startswtih('msvcr'): + c_libraries.append(lib) + p = combine_paths(f_lib_dirs, 'lib' + lib + '.a') + if p: + dst_name = os.path.join(self.build_temp, lib + '.lib') + copy_file(p[0], dst_name) + if not lib_added: + c_library_dirs.append(self.build_temp) + lib_added = True + def get_source_files (self): self.check_extensions_list(self.extensions) filenames = [] diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py index e56e0303d..e8a09d47b 100644 --- a/numpy/distutils/fcompiler/gnu.py +++ b/numpy/distutils/fcompiler/gnu.py @@ -8,7 +8,7 @@ from numpy.distutils.cpuinfo import cpu from numpy.distutils.ccompiler import simple_version_match from numpy.distutils.fcompiler import FCompiler from numpy.distutils.exec_command import exec_command, find_executable -from numpy.distutils.misc_util import mingw32 +from numpy.distutils.misc_util import mingw32, msvc_runtime_library class GnuFCompiler(FCompiler): @@ -38,10 +38,16 @@ class GnuFCompiler(FCompiler): module_dir_switch = None module_include_switch = None - # Cygwin: f771: warning: -fPIC ignored for target (all code is position independent) + # Cygwin: f771: warning: -fPIC ignored for target (all code is + # position independent) if os.name != 'nt' and sys.platform!='cygwin': pic_flags = ['-fPIC'] + # use -mno-cygwin for g77 when Python is not Cygwin-Python + if sys.platform == 'win32': + for key in ['version_cmd', 'compiler_f77', 'linker_so', 'linker_exe']: + executables[key].append('-mno-cygwin') + g2c = 'g2c' #def get_linker_so(self): @@ -52,7 +58,7 @@ class GnuFCompiler(FCompiler): # return FCompiler.get_linker_so(self) def get_flags_linker_so(self): - opt = [] + opt = self.linker_so[1:] if sys.platform=='darwin': target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None) if target is None: @@ -79,17 +85,26 @@ class GnuFCompiler(FCompiler): return opt def get_libgcc_dir(self): - status, output = exec_command('%s -print-libgcc-file-name' \ - % (self.compiler_f77[0]),use_tee=0) + status, output = exec_command(self.compiler_f77 + + '-print-libgcc-file-name', + use_tee=0) if not status: return os.path.dirname(output) - return + return None def get_library_dirs(self): opt = [] if sys.platform[:5] != 'linux': d = self.get_libgcc_dir() if d: + # if windows and not cygwin, libg2c lies in a different folder + if sys.platform == 'win32' and not d.startswith('/usr/lib'): + d = os.path.normpath(d) + if not os.path.exists(os.path.join(d, 'libg2c.a')): + d2 = os.path.abspath(os.path.join(d, + '../../../../lib')) + if os.path.exists(os.path.join(d2, 'libg2c.a')): + opt.append(d2) opt.append(d) return opt @@ -104,13 +119,14 @@ class GnuFCompiler(FCompiler): else: g2c = self.g2c - if sys.platform=='win32': - # To avoid undefined reference __EH_FRAME_BEGIN__ linker error, - # don't use -lgcc option for mingw32 g77 linker. - if not mingw32(): - opt.append('gcc') if g2c is not None: opt.append(g2c) + if sys.platform == 'win32': + # in case want to link F77 compiled code with MSVC + opt.append('gcc') + runtime_lib = msvc_runtime_library() + if runtime_lib: + opt.append(runtime_lib) if sys.platform == 'darwin': opt.append('cc_dynamic') return opt @@ -242,6 +258,13 @@ class Gnu95FCompiler(GnuFCompiler): 'ranlib' : ["ranlib"], 'linker_exe' : [fc_exe,"-Wall"] } + + # use -mno-cygwin flag for g77 when Python is not Cygwin-Python + if sys.platform == 'win32': + for key in ['version_cmd', 'compiler_f77', 'compiler_f90', + 'compiler_fix', 'linker_so', 'linker_exe']: + executables[key].append('-mno-cygwin') + module_dir_switch = '-J' module_include_switch = '-I' diff --git a/numpy/distutils/mingw32ccompiler.py b/numpy/distutils/mingw32ccompiler.py index eee6ed2db..91a80a626 100644 --- a/numpy/distutils/mingw32ccompiler.py +++ b/numpy/distutils/mingw32ccompiler.py @@ -27,6 +27,7 @@ from numpy.distutils.ccompiler import gen_preprocess_options, gen_lib_options from distutils.errors import DistutilsExecError, CompileError, UnknownFileError from distutils.unixccompiler import UnixCCompiler +from numpy.distutils.misc_util import msvc_runtime_library # the same as cygwin plus some additional parameters class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): @@ -93,9 +94,9 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): % (self.linker, entry_point)) else: self.set_executables(compiler='gcc -mno-cygwin -O2 -Wall', - compiler_so='gcc -O2 -Wall -Wstrict-prototypes', - linker_exe='g++ ', - linker_so='g++ -shared') + 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++'] @@ -104,7 +105,7 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): # dlls need another dll (mingwm10.dll see Mingw32 docs) # (-mthreads: Support thread-safe exception handling on `Mingw32') - # no additional libraries needed -- maybe need msvcr71 + # no additional libraries needed #self.dll_libraries=[] return @@ -124,11 +125,13 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): extra_postargs=None, build_temp=None, target_lang=None): - if sys.version[:3] > '2.3': - if libraries: - libraries.append('msvcr71') - else: - libraries = ['msvcr71'] + # Include the appropiate MSVC runtime library if Python was built + # with MSVC >= 7.0 (MinGW standard is msvcrt) + runtime_library = msvc_runtime_library() + if runtime_library: + if not libraries: + libraries = [] + libraries.append(runtime_library) args = (self, target_desc, objects, diff --git a/numpy/distutils/misc_util.py b/numpy/distutils/misc_util.py index f45d2d0ef..49adffb2f 100644 --- a/numpy/distutils/misc_util.py +++ b/numpy/distutils/misc_util.py @@ -242,6 +242,19 @@ def mingw32(): return True return False +def msvc_runtime_library(): + "return name of MSVC runtime library if Python was built with MSVC >= 7" + msc_pos = sys.version.find('MSC v.') + if msc_pos != -1: + msc_ver = sys.version[msc_pos+6:msc_pos+10] + lib = {'1300' : 'msvcr70', # MSVC 7.0 + '1310' : 'msvcr71', # MSVC 7.1 + '1400' : 'msvcr80', # MSVC 8 + }.get(msc_ver, None) + else: + lib = None + return lib + ######################### #XXX need support for .C that is also C++ diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py index 6cd6cc84b..56b5baccd 100644 --- a/numpy/distutils/system_info.py +++ b/numpy/distutils/system_info.py @@ -492,6 +492,18 @@ class system_info: def get_libraries(self, key='libraries'): return self.get_libs(key,'') + def library_extensions(self): + static_exts = ['.a'] + if sys.platform == 'win32': + static_exts.append('.lib') # .lib is used by MSVC + if self.search_static_first: + exts = static_exts + [so_ext] + else: + exts = [so_ext] + static_exts + if sys.platform == 'cygwin': + exts.append('.dll.a') + return exts + def check_libs(self,lib_dir,libs,opt_libs =[]): """If static or shared libraries are available then return their info dictionary. @@ -499,12 +511,7 @@ class system_info: Checks for all libraries as shared libraries first, then static (or vice versa if self.search_static_first is True). """ - if self.search_static_first: - exts = ['.a', so_ext] - else: - exts = [so_ext, '.a'] - if sys.platform == 'cygwin': - exts.append('.dll.a') + exts = self.library_extensions() info = None for ext in exts: info = self._check_libs(lib_dir,libs,opt_libs,[ext]) @@ -520,12 +527,7 @@ class system_info: Checks each library for shared or static. """ - if self.search_static_first: - exts = ['.a', so_ext] - else: - exts = [so_ext, '.a'] - if sys.platform=='cygwin': - exts.append('.dll.a') + exts = self.library_extensions() info = self._check_libs(lib_dir,libs,opt_libs,exts) if not info: log.info(' libraries %s not found in %s', ','.join(libs), lib_dir) @@ -534,17 +536,29 @@ class system_info: def _lib_list(self, lib_dir, libs, exts): assert is_string(lib_dir) liblist = [] + # under windows first try without 'lib' prefix + if sys.platform == 'win32': + lib_prefixes = ['', 'lib'] + else: + lib_prefixes = ['lib'] # for each library name, see if we can find a file for it. for l in libs: for ext in exts: - p = self.combine_paths(lib_dir, 'lib'+l+ext) + for prefix in lib_prefixes: + p = self.combine_paths(lib_dir, prefix+l+ext) + if p: + break if p: assert len(p)==1 + # ??? splitext on p[0] would do this for cygwin + # doesn't seem correct + if ext == '.dll.a': + l += '.dll' liblist.append(l) break return liblist - def _check_libs(self,lib_dir,libs, opt_libs, exts): + def _check_libs(self, lib_dir, libs, opt_libs, exts): found_libs = self._lib_list(lib_dir, libs, exts) if len(found_libs) == len(libs): info = {'libraries' : found_libs, 'library_dirs' : [lib_dir]} @@ -556,6 +570,9 @@ class system_info: return None def combine_paths(self,*args): + """Return a list of existing paths composed by all combinations + of items from the arguments. + """ return combine_paths(*args,**{'verbosity':self.verbosity}) @@ -837,12 +854,12 @@ class atlas_info(system_info): lapack = None atlas_1 = None for d in lib_dirs: - atlas = self.check_libs(d,atlas_libs,[]) - lapack_atlas = self.check_libs(d,['lapack_atlas'],[]) + atlas = self.check_libs2(d,atlas_libs,[]) + lapack_atlas = self.check_libs2(d,['lapack_atlas'],[]) if atlas is not None: - lib_dirs2 = self.combine_paths(d,['atlas*','ATLAS*'])+[d] + lib_dirs2 = [d] + self.combine_paths(d,['atlas*','ATLAS*']) for d2 in lib_dirs2: - lapack = self.check_libs(d2,lapack_libs,[]) + lapack = self.check_libs2(d2,lapack_libs,[]) if lapack is not None: break else: @@ -886,10 +903,16 @@ class atlas_info(system_info): lapack_dir = lapack['library_dirs'][0] lapack_name = lapack['libraries'][0] lapack_lib = None - for e in ['.a',so_ext]: - fn = os.path.join(lapack_dir,'lib'+lapack_name+e) - if os.path.exists(fn): - lapack_lib = fn + lib_prefixes = ['lib'] + if sys.platform == 'win32': + lib_prefixes.append('') + for e in self.library_extensions(): + for prefix in lib_prefixes: + fn = os.path.join(lapack_dir,prefix+lapack_name+e) + if os.path.exists(fn): + lapack_lib = fn + break + if lapack_lib: break if lapack_lib is not None: sz = os.stat(lapack_lib)[6] @@ -919,7 +942,7 @@ class atlas_blas_info(atlas_info): self._lib_names + self._lib_atlas) atlas = None for d in lib_dirs: - atlas = self.check_libs(d,atlas_libs,[]) + atlas = self.check_libs2(d,atlas_libs,[]) if atlas is not None: break if atlas is None: |
