summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcookedm <cookedm@localhost>2007-04-22 21:12:57 +0000
committercookedm <cookedm@localhost>2007-04-22 21:12:57 +0000
commit03b278bc04b508e8c48bc2df80113d23b2a039c4 (patch)
tree78bf34a9a9fe2e5d59a7f91e0cd324e553d8f3c6
parent06cc6933dfdae2f9273c3040b2677e2206221647 (diff)
downloadnumpy-03b278bc04b508e8c48bc2df80113d23b2a039c4.tar.gz
Some distutils work:
- Add better support for C++ in numpy.distutils. Instead of munging the C compiler command, build_clib and build_ext call the new Compiler.cxx_compiler() method to get a version of the compiler suitable for C++ (this also takes care of the special needs of AIX). - If config_fc is specified in the Extension definition, merge that info instead of replacing it (otherwise, the name of the Fortran compiler is overwritten). This is done at the key level (ex., compiler options are replaced instead of appended). - clean up compiler.py a bit - clean up linking in build_ext
-rw-r--r--numpy/distutils/ccompiler.py59
-rw-r--r--numpy/distutils/command/build_clib.py38
-rw-r--r--numpy/distutils/command/build_ext.py40
3 files changed, 70 insertions, 67 deletions
diff --git a/numpy/distutils/ccompiler.py b/numpy/distutils/ccompiler.py
index e850569f4..059fd0ec4 100644
--- a/numpy/distutils/ccompiler.py
+++ b/numpy/distutils/ccompiler.py
@@ -21,6 +21,10 @@ def _new_init_posix():
distutils.sysconfig._config_vars['OPT'] = '-Wall -g -O0'
#distutils.sysconfig._init_posix = _new_init_posix
+def replace_method(klass, method_name, func):
+ m = new.instancemethod(func, None, klass)
+ setattr(klass, method_name, m)
+
# Using customized CCompiler.spawn.
def CCompiler_spawn(self, cmd, display=None):
if display is None:
@@ -37,7 +41,8 @@ def CCompiler_spawn(self, cmd, display=None):
print o
raise DistutilsExecError,\
'Command "%s" failed with exit status %d' % (cmd, s)
-CCompiler.spawn = new.instancemethod(CCompiler_spawn,None,CCompiler)
+
+replace_method(CCompiler, 'spawn', CCompiler_spawn)
def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
if output_dir is None:
@@ -63,8 +68,7 @@ def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir='
obj_names.append(obj_name)
return obj_names
-CCompiler.object_filenames = new.instancemethod(CCompiler_object_filenames,
- None,CCompiler)
+replace_method(CCompiler, 'object_filenames', CCompiler_object_filenames)
def CCompiler_compile(self, sources, output_dir=None, macros=None,
include_dirs=None, debug=0, extra_preargs=None,
@@ -114,7 +118,7 @@ def CCompiler_compile(self, sources, output_dir=None, macros=None,
# Return *all* object filenames, not just the ones we just built.
return objects
-CCompiler.compile = new.instancemethod(CCompiler_compile,None,CCompiler)
+replace_method(CCompiler, 'compile', CCompiler_compile)
def CCompiler_customize_cmd(self, cmd):
""" Customize compiler using distutils command.
@@ -139,8 +143,7 @@ def CCompiler_customize_cmd(self, cmd):
self.set_link_objects(cmd.link_objects)
return
-CCompiler.customize_cmd = new.instancemethod(\
- CCompiler_customize_cmd,None,CCompiler)
+replace_method(CCompiler, 'customize_cmd', CCompiler_customize_cmd)
def _compiler_to_string(compiler):
props = []
@@ -179,9 +182,7 @@ def CCompiler_show_customization(self):
print _compiler_to_string(self)
print '*'*80
-CCompiler.show_customization = new.instancemethod(\
- CCompiler_show_customization,None,CCompiler)
-
+replace_method(CCompiler, 'show_customization', CCompiler_show_customization)
def CCompiler_customize(self, dist, need_cxx=0):
# See FCompiler.customize for suggested usage.
@@ -203,7 +204,7 @@ def CCompiler_customize(self, dist, need_cxx=0):
if hasattr(self,'compiler') and self.compiler[0].find('cc')>=0:
if not self.compiler_cxx:
- if self.compiler[0][:3] == 'gcc':
+ if self.compiler[0].startswith('gcc'):
a, b = 'gcc', 'g++'
else:
a, b = 'cc', 'c++'
@@ -215,10 +216,23 @@ def CCompiler_customize(self, dist, need_cxx=0):
log.warn('Missing compiler_cxx fix for '+self.__class__.__name__)
return
-CCompiler.customize = new.instancemethod(\
- CCompiler_customize,None,CCompiler)
+replace_method(CCompiler, 'customize', CCompiler_customize)
-def simple_version_match(pat=r'[-.\d]+', ignore=None, start=''):
+def simple_version_match(pat=r'[-.\d]+', ignore='', start=''):
+ """
+ Simple matching of version numbers, for use in CCompiler and FCompiler
+ classes.
+
+ :Parameters:
+ pat : regex matching version numbers.
+ ignore : false or regex matching expressions to skip over.
+ start : false or regex matching the start of where to start looking
+ for version numbers.
+
+ :Returns:
+ A function that is appropiate to use as the .version_match
+ attribute of a CCompiler class.
+ """
def matcher(self, version_string):
pos = 0
if start:
@@ -271,15 +285,26 @@ def CCompiler_get_version(self, force=0, ok_status=[0]):
self.version = version
return version
-CCompiler.get_version = new.instancemethod(\
- CCompiler_get_version,None,CCompiler)
+replace_method(CCompiler, 'get_version', CCompiler_get_version)
+
+def CCompiler_cxx_compiler(self):
+ cxx = copy(self)
+ cxx.compiler_so = [cxx.compiler_cxx[0]] + cxx.compiler_so[1:]
+ if sys.platform.startswith('aix') and 'ld_so_aix' in cxx.linker_so[0]:
+ # AIX needs the ld_so_aix script included with Python
+ cxx.linker_so = [cxx.linker_so[0]] + cxx.compiler_cxx[0] \
+ + cxx.linker_so[2:]
+ else:
+ cxx.linker_so = [cxx.compiler_cxx[0]] + cxx.linker_so[1:]
+ return cxx
+
+replace_method(CCompiler, 'cxx_compiler', CCompiler_cxx_compiler)
compiler_class['intel'] = ('intelccompiler','IntelCCompiler',
"Intel C Compiler for 32-bit applications")
compiler_class['intele'] = ('intelccompiler','IntelItaniumCCompiler',
"Intel C Itanium Compiler for Itanium-based applications")
-ccompiler._default_compilers = ccompiler._default_compilers \
- + (('linux.*','intel'),('linux.*','intele'))
+ccompiler._default_compilers += (('linux.*','intel'),('linux.*','intele'))
if sys.platform == 'win32':
compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler',
diff --git a/numpy/distutils/command/build_clib.py b/numpy/distutils/command/build_clib.py
index f53c77ffb..51163c729 100644
--- a/numpy/distutils/command/build_clib.py
+++ b/numpy/distutils/command/build_clib.py
@@ -21,13 +21,11 @@ class build_clib(old_build_clib):
def initialize_options(self):
old_build_clib.initialize_options(self)
self.fcompiler = None
- return
def finalize_options(self):
old_build_clib.finalize_options(self)
self.set_undefined_options('build_ext',
('fcompiler', 'fcompiler'))
- return
def have_f_sources(self):
for (lib_name, build_info) in self.libraries:
@@ -84,7 +82,6 @@ class build_clib(old_build_clib):
self.fcompiler.show_customization()
self.build_libraries(self.libraries)
- return
def get_source_files(self):
self.check_library_list(self.libraries)
@@ -94,8 +91,6 @@ class build_clib(old_build_clib):
return filenames
def build_libraries(self, libraries):
-
-
for (lib_name, build_info) in libraries:
# default compilers
compiler = self.compiler
@@ -109,8 +104,6 @@ class build_clib(old_build_clib):
"a list of source filenames") % lib_name
sources = list(sources)
-
-
lib_file = compiler.library_filename(lib_name,
output_dir=self.build_clib)
@@ -124,9 +117,9 @@ class build_clib(old_build_clib):
config_fc = build_info.get('config_fc',{})
if fcompiler is not None and config_fc:
- log.info('using setup script specified config_fc '\
+ log.info('using additional config_fc from setup script '\
'for fortran compiler: %s' \
- % (config_fc))
+ % (config_fc,))
from numpy.distutils.fcompiler import new_fcompiler
requiref90 = build_info.get('language','c')=='f90'
fcompiler = new_fcompiler(compiler=self.fcompiler.compiler_type,
@@ -134,7 +127,10 @@ class build_clib(old_build_clib):
dry_run=self.dry_run,
force=self.force,
requiref90=requiref90)
- fcompiler.customize(config_fc)
+ dist = self.distribution
+ base_config_fc = dist.get_option_dict('config_fc').copy()
+ base_config_fc.update(config_fc)
+ fcompiler.customize(base_config_fc)
macros = build_info.get('macros')
include_dirs = build_info.get('include_dirs')
@@ -165,19 +161,15 @@ class build_clib(old_build_clib):
if cxx_sources:
log.info("compiling C++ sources")
- old_compiler = self.compiler.compiler_so[0]
- self.compiler.compiler_so[0] = self.compiler.compiler_cxx[0]
-
- cxx_objects = compiler.compile(cxx_sources,
- output_dir=self.build_temp,
- macros=macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_postargs)
+ cxx_compiler = compiler.cxx_compiler()
+ cxx_objects = cxx_compiler.compile(cxx_sources,
+ output_dir=self.build_temp,
+ macros=macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_postargs)
objects.extend(cxx_objects)
- self.compiler.compiler_so[0] = old_compiler
-
if f_sources:
log.info("compiling Fortran sources")
f_objects = fcompiler.compile(f_sources,
@@ -193,10 +185,8 @@ class build_clib(old_build_clib):
debug=self.debug)
clib_libraries = build_info.get('libraries',[])
- for lname,binfo in libraries:
+ for lname, binfo in libraries:
if lname in clib_libraries:
clib_libraries.extend(binfo[1].get('libraries',[]))
if clib_libraries:
build_info['libraries'] = clib_libraries
-
- return
diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py
index 0e804e19e..466462c56 100644
--- a/numpy/distutils/command/build_ext.py
+++ b/numpy/distutils/command/build_ext.py
@@ -201,17 +201,15 @@ class build_ext (old_build_ext):
if cxx_sources:
log.info("compiling C++ sources")
- old_compiler = self.compiler.compiler_so[0]
- self.compiler.compiler_so[0] = self.compiler.compiler_cxx[0]
+ cxx_compiler = self.compiler.cxx_compiler()
- c_objects += self.compiler.compile(cxx_sources,
+ c_objects += cxx_compiler.compile(cxx_sources,
output_dir=output_dir,
macros=macros,
include_dirs=include_dirs,
debug=self.debug,
extra_postargs=extra_args,
**kws)
- self.compiler.compiler_so[0] = old_compiler
check_for_f90_modules = not not fmodule_sources
@@ -272,10 +270,7 @@ class build_ext (old_build_ext):
objects.extend(ext.extra_objects)
extra_args = ext.extra_link_args or []
- try:
- old_linker_so_0 = self.compiler.linker_so[0]
- except:
- pass
+ linker = self.compiler.link_shared_object
use_fortran_linker = getattr(ext,'language','c') in ['f77','f90'] \
and self.fcompiler is not None
@@ -308,37 +303,30 @@ class build_ext (old_build_ext):
if cxx_sources:
# XXX: Which linker should be used, Fortran or C++?
log.warn('mixing Fortran and C++ is untested')
- link = self.fcompiler.link_shared_object
+ linker = self.fcompiler.link_shared_object
language = ext.language or self.fcompiler.detect_language(f_sources)
else:
- link = self.compiler.link_shared_object
+ linker = self.compiler.link_shared_object
if sys.version[:3]>='2.3':
language = ext.language or self.compiler.detect_language(sources)
else:
language = ext.language
if cxx_sources:
- self.compiler.linker_so[0] = self.compiler.compiler_cxx[0]
+ linker = self.compiler.cxx_compiler().link_shared_object
if sys.version[:3]>='2.3':
kws = {'target_lang':language}
else:
kws = {}
- link(objects, ext_filename,
- libraries=self.get_libraries(ext) + c_libraries + clib_libraries,
- library_dirs=ext.library_dirs + c_library_dirs + clib_library_dirs,
- runtime_library_dirs=ext.runtime_library_dirs,
- extra_postargs=extra_args,
- export_symbols=self.get_export_symbols(ext),
- debug=self.debug,
- build_temp=self.build_temp,**kws)
-
- try:
- self.compiler.linker_so[0] = old_linker_so_0
- except:
- pass
-
- return
+ linker(objects, ext_filename,
+ libraries=self.get_libraries(ext) + c_libraries + clib_libraries,
+ library_dirs=ext.library_dirs+c_library_dirs+clib_library_dirs,
+ runtime_library_dirs=ext.runtime_library_dirs,
+ extra_postargs=extra_args,
+ export_symbols=self.get_export_symbols(ext),
+ debug=self.debug,
+ build_temp=self.build_temp,**kws)
def _libs_with_msvc_and_fortran(self, c_libraries, c_library_dirs):
# Always use system linker when using MSVC compiler.