[Numpy-svn] r2919 - in trunk/numpy/distutils: . command fcompiler
numpy-svn at scipy.org
numpy-svn at scipy.org
Fri Jul 28 16:02:11 EDT 2006
Author: cookedm
Date: 2006-07-28 15:02:07 -0500 (Fri, 28 Jul 2006)
New Revision: 2919
Modified:
trunk/numpy/distutils/ccompiler.py
trunk/numpy/distutils/command/build_ext.py
trunk/numpy/distutils/fcompiler/gnu.py
trunk/numpy/distutils/mingw32ccompiler.py
trunk/numpy/distutils/misc_util.py
trunk/numpy/distutils/system_info.py
Log:
Fix #114: Problems with building with MSVC and GCC under Cygwin
Modified: trunk/numpy/distutils/ccompiler.py
===================================================================
--- trunk/numpy/distutils/ccompiler.py 2006-07-28 16:27:18 UTC (rev 2918)
+++ trunk/numpy/distutils/ccompiler.py 2006-07-28 20:02:07 UTC (rev 2919)
@@ -18,7 +18,7 @@
_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.
Modified: trunk/numpy/distutils/command/build_ext.py
===================================================================
--- trunk/numpy/distutils/command/build_ext.py 2006-07-28 16:27:18 UTC (rev 2918)
+++ trunk/numpy/distutils/command/build_ext.py 2006-07-28 20:02:07 UTC (rev 2919)
@@ -8,13 +8,17 @@
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):
description = "build C/C++/F extensions (compile/link to build directory)"
@@ -290,9 +294,8 @@
# 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 @@
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 = []
Modified: trunk/numpy/distutils/fcompiler/gnu.py
===================================================================
--- trunk/numpy/distutils/fcompiler/gnu.py 2006-07-28 16:27:18 UTC (rev 2918)
+++ trunk/numpy/distutils/fcompiler/gnu.py 2006-07-28 20:02:07 UTC (rev 2919)
@@ -8,7 +8,7 @@
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 @@
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 @@
# 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 @@
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 @@
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 @@
'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'
Modified: trunk/numpy/distutils/mingw32ccompiler.py
===================================================================
--- trunk/numpy/distutils/mingw32ccompiler.py 2006-07-28 16:27:18 UTC (rev 2918)
+++ trunk/numpy/distutils/mingw32ccompiler.py 2006-07-28 20:02:07 UTC (rev 2919)
@@ -27,6 +27,7 @@
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 @@
% (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 @@
# 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 @@
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,
Modified: trunk/numpy/distutils/misc_util.py
===================================================================
--- trunk/numpy/distutils/misc_util.py 2006-07-28 16:27:18 UTC (rev 2918)
+++ trunk/numpy/distutils/misc_util.py 2006-07-28 20:02:07 UTC (rev 2919)
@@ -242,6 +242,19 @@
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++
Modified: trunk/numpy/distutils/system_info.py
===================================================================
--- trunk/numpy/distutils/system_info.py 2006-07-28 16:27:18 UTC (rev 2918)
+++ trunk/numpy/distutils/system_info.py 2006-07-28 20:02:07 UTC (rev 2919)
@@ -492,6 +492,18 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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:
More information about the Numpy-svn
mailing list