summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scipy_distutils/__init__.py15
-rw-r--r--scipy_distutils/ccompiler.py103
-rw-r--r--scipy_distutils/command/build_clib.py30
-rw-r--r--scipy_distutils/command/build_ext.py26
-rw-r--r--scipy_distutils/exec_command.py2
-rw-r--r--scipy_distutils/extension.py2
-rw-r--r--scipy_distutils/fcompiler.py59
-rw-r--r--scipy_distutils/mingw32ccompiler.py1
-rw-r--r--scipy_distutils/unixccompiler.py136
9 files changed, 201 insertions, 173 deletions
diff --git a/scipy_distutils/__init__.py b/scipy_distutils/__init__.py
index 50169952e..ce4c2d287 100644
--- a/scipy_distutils/__init__.py
+++ b/scipy_distutils/__init__.py
@@ -10,14 +10,7 @@ from scipy_distutils_version import scipy_distutils_version as __version__
import sys
-if not sys.modules.has_key('distutils'):
- # Replace distutils.ccompiler with scipy_distutils.ccompiler
- assert not sys.modules.has_key('distutils.ccompiler'),\
- 'distutils has been imported before scipy_distutils'
- import ccompiler
- sys.modules['distutils.ccompiler'] = ccompiler
-
- assert not sys.modules.has_key('distutils.unixccompiler'),\
- 'cannot override distutils.unixccompiler'
- import unixccompiler
- sys.modules['distutils.unixccompiler'] = unixccompiler
+# Must import local ccompiler ASAP in order to get
+# customized CCompiler.spawn effective.
+import ccompiler
+import unixccompiler
diff --git a/scipy_distutils/ccompiler.py b/scipy_distutils/ccompiler.py
index 7d148a138..288e92c1f 100644
--- a/scipy_distutils/ccompiler.py
+++ b/scipy_distutils/ccompiler.py
@@ -2,12 +2,110 @@
import re
import os
import sys
+import new
from distutils.ccompiler import *
from distutils import ccompiler
+from distutils.sysconfig import customize_compiler
import log
from exec_command import exec_command
+from misc_util import compiler_to_string
+
+# Using customized CCompiler.spawn.
+def CCompiler_spawn(self, cmd, display=None):
+ if display is None:
+ display = cmd
+ if type(display) is type([]): display = ' '.join(display)
+ log.info(display)
+ s,o = exec_command(cmd)
+ if s:
+ if type(cmd) is type([]):
+ cmd = ' '.join(cmd)
+ raise DistutilsExecError,\
+ 'Command "%s" failed with exit status %d' % (cmd, s)
+CCompiler.spawn = new.instancemethod(CCompiler_spawn,None,CCompiler)
+
+def CCompiler_compile(self, sources, output_dir=None, macros=None,
+ include_dirs=None, debug=0, extra_preargs=None,
+ extra_postargs=None, depends=None):
+ from fcompiler import FCompiler
+ if isinstance(self, FCompiler):
+ display = []
+ for fcomp in ['f77','f90','fix']:
+ fcomp = getattr(self,'compiler_'+fcomp)
+ if fcomp is None:
+ continue
+ display.append('%s options: "%s"' % (os.path.basename(fcomp[0]),
+ ' '.join(fcomp[1:])))
+ display = '\n'.join(display)
+ else:
+ ccomp = self.compiler_so
+ display = '%s options: "%s"' % (os.path.basename(ccomp[0]),
+ ' '.join(ccomp[1:]))
+ log.info(display)
+ macros, objects, extra_postargs, pp_opts, build = \
+ self._setup_compile(output_dir, macros, include_dirs, sources,
+ depends, extra_postargs)
+ cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
+ display = "compile options: '%s'" % (' '.join(cc_args))
+ if extra_postargs:
+ display += "extra: '%s'" % (' '.join(extra_postargs))
+ log.info(display)
+ for obj, (src, ext) in build.items():
+ self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
+
+ # Return *all* object filenames, not just the ones we just built.
+ return objects
+
+CCompiler.compile = new.instancemethod(CCompiler_compile,None,CCompiler)
+
+def CCompiler_customize_cmd(self, cmd):
+ """ Customize compiler using distutils command.
+ """
+ log.info('customize %s using %s' % (self.__class__.__name__,
+ cmd.__class__.__name__))
+ if getattr(cmd,'include_dirs',None) is not None:
+ self.set_include_dirs(cmd.include_dirs)
+ if getattr(cmd,'define',None) is not None:
+ for (name,value) in cmd.define:
+ self.define_macro(name, value)
+ if getattr(cmd,'undef',None) is not None:
+ for macro in cmd.undef:
+ self.undefine_macro(macro)
+ if getattr(cmd,'libraries',None) is not None:
+ self.set_libraries(self.libraries + cmd.libraries)
+ if getattr(cmd,'library_dirs',None) is not None:
+ self.set_library_dirs(self.library_dirs + cmd.library_dirs)
+ if getattr(cmd,'rpath',None) is not None:
+ self.set_runtime_library_dirs(cmd.rpath)
+ if getattr(cmd,'link_objects',None) is not None:
+ self.set_link_objects(cmd.link_objects)
+ self.show_customization()
+ return
+CCompiler.customize_cmd = new.instancemethod(\
+ CCompiler_customize_cmd,None,CCompiler)
+
+def CCompiler_show_customization(self):
+ for attrname in ['include_dirs','libraries','library_dirs',
+ 'rpath','link_objects']:
+ attr = getattr(self,attrname,None)
+ if not attr:
+ continue
+ log.info("compiler '%s' is set to %s" % (attrname,attr))
+
+CCompiler.show_customization = new.instancemethod(\
+ CCompiler_show_customization,None,CCompiler)
+
+
+def CCompiler_customize(self, dist):
+ # See FCompiler.customize for suggested usage.
+ log.info('customize %s' % (self.__class__.__name__))
+ customize_compiler(self)
+ return
+CCompiler.customize = new.instancemethod(\
+ CCompiler_customize,None,CCompiler)
+
if sys.platform == 'win32':
compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler',
@@ -21,6 +119,7 @@ if sys.platform == 'win32':
ccompiler._default_compilers = (('nt', 'mingw32'),) \
+ ccompiler._default_compilers
+
_distutils_new_compiler = new_compiler
def new_compiler (plat=None,
compiler=None,
@@ -59,8 +158,10 @@ def new_compiler (plat=None,
raise DistutilsModuleError, \
("can't compile C/C++ code: unable to find class '%s' " +
"in module '%s'") % (class_name, module_name)
+ compiler = klass(None, dry_run, force)
print '*'*80
print klass
+ print compiler_to_string(compiler)
print '*'*80
- return klass(None, dry_run, force)
+ return compiler
diff --git a/scipy_distutils/command/build_clib.py b/scipy_distutils/command/build_clib.py
index 0d22fb685..2ddbfc315 100644
--- a/scipy_distutils/command/build_clib.py
+++ b/scipy_distutils/command/build_clib.py
@@ -81,8 +81,16 @@ class build_clib(old_build_clib):
raise TypeError,'Library "%s" sources contains unresolved'\
' items (call build_src before built_clib).' % (lib_name)
- old_build_clib.run(self) # sets self.compiler
- log.info(misc_util.compiler_to_string(self.compiler))
+ from distutils.ccompiler import new_compiler
+ self.compiler = new_compiler(compiler=self.compiler,
+ dry_run=self.dry_run,
+ force=self.force)
+ self.compiler.customize(self.distribution)
+
+ libraries = self.libraries
+ self.libraries = None
+ self.compiler.customize_cmd(self)
+ self.libraries = libraries
if self.have_f_sources():
from scipy_distutils.fcompiler import new_fcompiler
@@ -91,17 +99,14 @@ class build_clib(old_build_clib):
dry_run=self.dry_run,
force=self.force)
self.fcompiler.customize(self.distribution)
- log.info(misc_util.compiler_to_string(self.fcompiler))
-
- #XXX: C++ linker support, see build_ext.py
- self.build_libraries2(self.libraries)
- return
+ libraries = self.libraries
+ self.libraries = None
+ self.fcompiler.customize_cmd(self)
+ self.libraries = libraries
- def build_libraries(self, libraries):
- # Hold on building libraries in old_build_clib.run()
- # until Fortran/C++ compilers are set. Building will be
- # carried out in build_libraries2()
+ #XXX: C++ linker support, see build_ext.py
+ self.build_libraries(self.libraries)
return
def get_source_files(self):
@@ -113,7 +118,7 @@ class build_clib(old_build_clib):
filenames.extend(get_headers(get_directories(filenames)))
return filenames
- def build_libraries2(self, libraries):
+ def build_libraries(self, libraries):
compiler = self.compiler
fcompiler = self.fcompiler
@@ -149,6 +154,7 @@ class build_clib(old_build_clib):
if cxx_sources:
print 'XXX: C++ linker support not implemented or tested'
+
objects = compiler.compile(c_sources+cxx_sources,
output_dir=self.build_temp,
macros=macros,
diff --git a/scipy_distutils/command/build_ext.py b/scipy_distutils/command/build_ext.py
index 62c247f8f..c989acc1c 100644
--- a/scipy_distutils/command/build_ext.py
+++ b/scipy_distutils/command/build_ext.py
@@ -50,11 +50,13 @@ class build_ext (old_build_ext):
# bogus linking commands. Extensions must
# explicitly specify the C libraries that they use.
- save_mth = self.distribution.has_c_libraries
- self.distribution.has_c_libraries = self.distribution.return_false
- old_build_ext.run(self) # sets self.compiler
- log.info(misc_util.compiler_to_string(self.compiler))
- self.distribution.has_c_libraries = save_mth
+ from distutils.ccompiler import new_compiler
+ self.compiler = new_compiler(compiler=self.compiler,
+ verbose=self.verbose,
+ dry_run=self.dry_run,
+ force=self.force)
+ self.compiler.customize(self.distribution)
+ self.compiler.customize_cmd(self)
# Determine if Fortran compiler is needed.
if build_clib and build_clib.fcompiler is not None:
@@ -88,7 +90,6 @@ class build_ext (old_build_ext):
force=self.force)
self.fcompiler.customize(self.distribution)
self.fcompiler.customize_cmd(self)
- log.info(misc_util.compiler_to_string(self.fcompiler))
if need_cxx_compiler:
c = self.compiler
if c.compiler[0].find('gcc')>=0:
@@ -103,17 +104,7 @@ class build_ext (old_build_ext):
print 'XXX: Fix compiler_cxx for',c.__class__.__name__
# Build extensions
- self.build_extensions2()
- return
-
- def build_extensions(self):
- # Hold on building extensions in old_build_ext.run()
- # until Fortran/C++ compilers are set. Building will be
- # carried out in build_extensions2()
- return
-
- def build_extensions2(self):
- old_build_ext.build_extensions(self)
+ self.build_extensions()
return
def swig_sources(self, sources):
@@ -172,6 +163,7 @@ class build_ext (old_build_ext):
if cxx_sources:
old_compiler = self.compiler.compiler_so[0]
self.compiler.compiler_so[0] = self.compiler.compiler_cxx[0]
+
c_objects += self.compiler.compile(cxx_sources,
output_dir=self.build_temp,
macros=macros,
diff --git a/scipy_distutils/exec_command.py b/scipy_distutils/exec_command.py
index b2fd0e05c..54d47fecd 100644
--- a/scipy_distutils/exec_command.py
+++ b/scipy_distutils/exec_command.py
@@ -115,7 +115,7 @@ def test_splitcmdline():
def find_executable(exe, path=None):
""" Return full path of a executable.
"""
- log.info('find_executable(%r)' % exe)
+ log.debug('find_executable(%r)' % exe)
if path is None:
path = os.environ.get('PATH',os.defpath)
suffices = ['']
diff --git a/scipy_distutils/extension.py b/scipy_distutils/extension.py
index b0ab92ec9..4f9a6df4d 100644
--- a/scipy_distutils/extension.py
+++ b/scipy_distutils/extension.py
@@ -6,8 +6,6 @@ modules in setup scripts.
Overridden to support f2py and SourceGenerator.
"""
-# created 2000/05/30, Greg Ward
-
__revision__ = "$Id$"
from distutils.extension import Extension as old_Extension
diff --git a/scipy_distutils/fcompiler.py b/scipy_distutils/fcompiler.py
index f9ca23ab9..7ef04a0c5 100644
--- a/scipy_distutils/fcompiler.py
+++ b/scipy_distutils/fcompiler.py
@@ -28,6 +28,7 @@ from distutils.sysconfig import get_config_var
from scipy_distutils.command.config_compiler import config_fc
import log
+from misc_util import compiler_to_string
from exec_command import find_executable, exec_command
class FCompiler(CCompiler):
@@ -304,6 +305,7 @@ class FCompiler(CCompiler):
compiler instance. But not in __init__ because Distribution
instance is needed for (iii) and (iv).
"""
+ log.info('customize %s' % (self.__class__.__name__))
if dist is None:
# These hooks are for testing only!
from dist import Distribution
@@ -408,25 +410,6 @@ class FCompiler(CCompiler):
self.dump_properties()
return
- def customize_cmd(self, cmd):
- if cmd.include_dirs is not None:
- self.set_include_dirs(cmd.include_dirs)
- if cmd.define is not None:
- for (name,value) in cmd.define:
- self.define_macro(name, value)
- if cmd.undef is not None:
- for macro in cmd.undef:
- self.undefine_macro(macro)
- if cmd.libraries is not None:
- self.set_libraries(self.get_libraries() + cmd.libraries)
- if cmd.library_dirs is not None:
- self.set_library_dirs(self.get_library_dirs() + cmd.library_dirs)
- if cmd.rpath is not None:
- self.set_runtime_library_dirs(cmd.rpath)
- if cmd.link_objects is not None:
- self.set_link_objects(cmd.link_objects)
- return
-
def dump_properties(self):
""" Print out the attributes of a compiler instance. """
props = []
@@ -446,21 +429,8 @@ class FCompiler(CCompiler):
print l
return
- def spawn(self, cmd):
- s,o = exec_command(cmd)
- if s:
- if type(cmd) is type([]):
- cmd = ' '.join(cmd)
- raise DistutilsExecError,\
- 'Command "%s" failed with exit status %d' % (cmd, s)
-
###################
- def _get_cc_args(self, pp_opts, debug, before):
- #XXX
- #print self.__class__.__name__ + '._get_cc_args:',pp_opts, debug, before
- return []
-
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
"""Compile 'src' to product 'obj'."""
if is_f_file(src):
@@ -483,12 +453,13 @@ class FCompiler(CCompiler):
assert self.compile_switch.strip()
s_args = [self.compile_switch, src]
- command = compiler + cc_args + pp_opts + s_args + o_args + extra_postargs
- log.info('%s: %s' % (os.path.basename(compiler[0]) \
- + (compiler is self.compiler_fix and ':fix' or ''),
- src))
+ command = compiler + cc_args + s_args + o_args + extra_postargs
+
+ display = '%s: %s' % (os.path.basename(compiler[0]) \
+ + (compiler is self.compiler_fix and ':fix' or ''),
+ src)
try:
- self.spawn(command)
+ self.spawn(command,display=display)
except DistutilsExecError, msg:
raise CompileError, msg
@@ -517,6 +488,9 @@ class FCompiler(CCompiler):
def library_dir_option(self, dir):
return "-L" + dir
+ def _get_cc_args(self, pp_opts, debug, extra_preargs):
+ return []
+
if sys.version[:3]<'2.3':
def compile(self, sources, output_dir=None, macros=None,
include_dirs=None, debug=0, extra_preargs=None,
@@ -569,8 +543,8 @@ class FCompiler(CCompiler):
o_args = [self.library_switch.strip()+output_filename]
ld_args = (objects + self.objects +
lib_opts + o_args)
- #if debug:
- # ld_args[:0] = ['-g']
+ if debug:
+ ld_args[:0] = ['-g']
if extra_preargs:
ld_args[:0] = extra_preargs
if extra_postargs:
@@ -581,8 +555,7 @@ class FCompiler(CCompiler):
else:
linker = self.linker_so[:]
command = linker + ld_args
- log.info('%s:> %s' % (os.path.basename(linker[0]),
- output_filename))
+
try:
self.spawn(command)
except DistutilsExecError, msg:
@@ -726,10 +699,12 @@ def new_fcompiler(plat=None,
raise DistutilsModuleError, \
("can't compile Fortran code: unable to find class '%s' " +
"in module '%s'") % (class_name, module_name)
+ compiler = klass(None, dry_run, force)
print '*'*80
print klass
+ print compiler_to_string(compiler)
print '*'*80
- return klass(None, dry_run, force)
+ return compiler
def show_fcompilers(dist = None):
diff --git a/scipy_distutils/mingw32ccompiler.py b/scipy_distutils/mingw32ccompiler.py
index deef2f998..df7d6a74e 100644
--- a/scipy_distutils/mingw32ccompiler.py
+++ b/scipy_distutils/mingw32ccompiler.py
@@ -144,7 +144,6 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler):
strip_dir=0,
output_dir=''):
if output_dir is None: output_dir = ''
- print 'cygiwn_output_dir:', output_dir
obj_names = []
for src_name in source_filenames:
# use normcase to make sure '.rc' is really '.rc' and not '.RC'
diff --git a/scipy_distutils/unixccompiler.py b/scipy_distutils/unixccompiler.py
index fa6a2931a..214763cef 100644
--- a/scipy_distutils/unixccompiler.py
+++ b/scipy_distutils/unixccompiler.py
@@ -3,99 +3,63 @@ unixccompiler - can handle very long argument lists for ar.
"""
import os
-from distutils import unixccompiler
-from distutils.errors import DistutilsExecError, LinkError
-from types import StringType, NoneType
+import sys
+import new
-from ccompiler import gen_lib_options, CCompiler
-import log
-from exec_command import exec_command
+from distutils.errors import DistutilsExecError, LinkError, CompileError
+from distutils.unixccompiler import *
-class UnixCCompiler(unixccompiler.UnixCCompiler):
- def _compile(self, obj, src, *args):
- log.info('%s: %s' % (os.path.basename(self.compiler_so[0]),src))
- return unixccompiler.UnixCCompiler._compile(self, obj, src, *args)
+import log
- def spawn(self, cmd):
- s,o = exec_command(cmd)
- if s:
- if type(cmd) is type([]):
- cmd = ' '.join(cmd)
- raise DistutilsExecError,\
- 'Command "%s" failed with exit status %d' % (cmd, s)
+# Note that UnixCCompiler._compile appeared in Python 2.3
+def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+ display = '%s: %s' % (os.path.basename(self.compiler_so[0]),src)
+ try:
+ self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
+ extra_postargs, display = display)
+ except DistutilsExecError, msg:
+ raise CompileError, msg
+UnixCCompiler._compile = new.instancemethod(UnixCCompiler__compile,
+ None,
+ UnixCCompiler)
- def create_static_lib(self, objects, output_libname,
- output_dir=None, debug=0, target_lang=None):
- objects, output_dir = self._fix_object_args(objects, output_dir)
-
- output_filename = \
- self.library_filename(output_libname, output_dir=output_dir)
-
- if self._need_link(objects, output_filename):
- self.mkpath(os.path.dirname(output_filename))
- tmp_objects = objects + self.objects
- log.info('%s:> %s' % (os.path.basename(self.archiver[0]),
- output_filename))
- while tmp_objects:
- objects = tmp_objects[:50]
- tmp_objects = tmp_objects[50:]
- self.spawn(self.archiver +
- [output_filename] +
- objects)
-
- # Not many Unices required ranlib anymore -- SunOS 4.x is, I
- # think the only major Unix that does. Maybe we need some
- # platform intelligence here to skip ranlib if it's not
- # needed -- or maybe Python's configure script took care of
- # it for us, hence the check for leading colon.
- if self.ranlib:
- log.info('%s:@ %s' % (os.path.basename(self.ranlib[0]),
- output_filename))
- try:
- self.spawn(self.ranlib + [output_filename])
- except DistutilsExecError, msg:
- raise LibError, msg
- else:
- log.debug("skipping %s (up-to-date)", output_filename)
- def link(self, target_desc, objects,
- output_filename, output_dir=None, libraries=None,
- library_dirs=None, runtime_library_dirs=None,
- export_symbols=None, debug=0, extra_preargs=None,
- extra_postargs=None, build_temp=None, target_lang=None):
- objects, output_dir = self._fix_object_args(objects, output_dir)
- libraries, library_dirs, runtime_library_dirs = \
- self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
+def UnixCCompile_create_static_lib(self, objects, output_libname,
+ output_dir=None, debug=0, target_lang=None):
+ objects, output_dir = self._fix_object_args(objects, output_dir)
- lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
- libraries)
- if type(output_dir) not in (StringType, NoneType):
- raise TypeError, "'output_dir' must be a string or None"
- if output_dir is not None:
- output_filename = os.path.join(output_dir, output_filename)
+ output_filename = \
+ self.library_filename(output_libname, output_dir=output_dir)
+
+ if self._need_link(objects, output_filename):
+ self.mkpath(os.path.dirname(output_filename))
+ tmp_objects = objects + self.objects
+ while tmp_objects:
+ objects = tmp_objects[:50]
+ tmp_objects = tmp_objects[50:]
+ display = '%s: adding %d object files to %s' % (os.path.basename(self.archiver[0]),
+ len(objects),output_filename)
+ self.spawn(self.archiver + [output_filename] + objects,
+ display = display)
- if self._need_link(objects, output_filename):
- ld_args = (objects + self.objects +
- lib_opts + ['-o', output_filename])
- if debug:
- ld_args[:0] = ['-g']
- if extra_preargs:
- ld_args[:0] = extra_preargs
- if extra_postargs:
- ld_args.extend(extra_postargs)
- self.mkpath(os.path.dirname(output_filename))
+ # Not many Unices required ranlib anymore -- SunOS 4.x is, I
+ # think the only major Unix that does. Maybe we need some
+ # platform intelligence here to skip ranlib if it's not
+ # needed -- or maybe Python's configure script took care of
+ # it for us, hence the check for leading colon.
+ if self.ranlib:
+ display = '%s:@ %s' % (os.path.basename(self.ranlib[0]),
+ output_filename)
try:
- if target_desc == CCompiler.EXECUTABLE:
- linker = self.linker_exe[:]
- else:
- linker = self.linker_so[:]
- if target_lang == "c++" and self.compiler_cxx:
- linker[0] = self.compiler_cxx[0]
- log.info('%s:> %s' % (os.path.basename(linker[0]),
- output_filename))
- self.spawn(linker + ld_args)
+ self.spawn(self.ranlib + [output_filename],
+ display = display)
except DistutilsExecError, msg:
- raise LinkError, msg
- else:
- log.debug("skipping %s (up-to-date)", output_filename)
+ raise LibError, msg
+ else:
+ log.debug("skipping %s (up-to-date)", output_filename)
+ return
+
+UnixCCompiler.create_static_lib = \
+ new.instancemethod(UnixCCompile_create_static_lib,
+ None,UnixCCompiler)