summaryrefslogtreecommitdiff
path: root/numpy/distutils/command/build_clib.py
diff options
context:
space:
mode:
authorPearu Peterson <pearu.peterson@gmail.com>2007-05-18 16:41:44 +0000
committerPearu Peterson <pearu.peterson@gmail.com>2007-05-18 16:41:44 +0000
commitb3caec68294618d217bdb26872b3c9d235c6ade6 (patch)
treeaf56df505e0cbb0ba2a4b29ebdb85024d9f2e5df /numpy/distutils/command/build_clib.py
parent5fcecff23893db08dd325501cdfa61cccd55688d (diff)
downloadnumpy-b3caec68294618d217bdb26872b3c9d235c6ade6.tar.gz
Extension modules and libraries are built with suitable compilers/linkers. Improved failure handling.
Diffstat (limited to 'numpy/distutils/command/build_clib.py')
-rw-r--r--numpy/distutils/command/build_clib.py108
1 files changed, 83 insertions, 25 deletions
diff --git a/numpy/distutils/command/build_clib.py b/numpy/distutils/command/build_clib.py
index 427b52dc3..fd4d41cde 100644
--- a/numpy/distutils/command/build_clib.py
+++ b/numpy/distutils/command/build_clib.py
@@ -1,8 +1,9 @@
""" Modified version of build_clib that handles fortran source files.
"""
+import os
from distutils.command.build_clib import build_clib as old_build_clib
-from distutils.errors import DistutilsSetupError
+from distutils.errors import DistutilsSetupError, DistutilsError
from numpy.distutils import log
from distutils.dep_util import newer_group
@@ -89,6 +90,7 @@ 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)
@@ -111,9 +113,21 @@ class build_clib(old_build_clib):
"a list of source filenames") % lib_name
sources = list(sources)
+ c_sources, cxx_sources, f_sources, fmodule_sources \
+ = filter_sources(sources)
+ requiref90 = not not fmodule_sources or \
+ build_info.get('language','c')=='f90'
+
+ # save source type information so that build_ext can use it.
+ source_languages = []
+ if c_sources: source_languages.append('c')
+ if cxx_sources: source_languages.append('c++')
+ if requiref90: source_languages.append('f90')
+ elif f_sources: source_languages.append('f77')
+ build_info['source_languages'] = source_languages
+
lib_file = compiler.library_filename(lib_name,
output_dir=self.build_clib)
-
depends = sources + build_info.get('depends',[])
if not (self.force or newer_group(depends, lib_file, 'newer')):
log.debug("skipping '%s' library (up-to-date)", lib_name)
@@ -121,15 +135,13 @@ class build_clib(old_build_clib):
else:
log.info("building '%s' library", lib_name)
-
config_fc = build_info.get('config_fc',{})
if fcompiler is not None and config_fc:
log.info('using additional config_fc from setup script '\
'for fortran compiler: %s' \
% (config_fc,))
from numpy.distutils.fcompiler import new_fcompiler
- requiref90 = build_info.get('language','c')=='f90'
- fcompiler = new_fcompiler(compiler=self.fcompiler.compiler_type,
+ fcompiler = new_fcompiler(compiler=fcompiler.compiler_type,
verbose=self.verbose,
dry_run=self.dry_run,
force=self.force,
@@ -139,23 +151,26 @@ class build_clib(old_build_clib):
base_config_fc.update(config_fc)
fcompiler.customize(base_config_fc)
+ # check availability of Fortran compilers
+ if (f_sources or fmodule_sources) and fcompiler is None:
+ raise DistutilsError, "library %s has Fortran sources"\
+ " but no Fortran compiler found" % (lib_name)
+
macros = build_info.get('macros')
include_dirs = build_info.get('include_dirs')
extra_postargs = build_info.get('extra_compiler_args') or []
- c_sources, cxx_sources, f_sources, fmodule_sources \
- = filter_sources(sources)
-
- if self.compiler.compiler_type=='msvc':
+ # where compiled F90 module files are:
+ module_dirs = build_info.get('module_dirs') or []
+ module_build_dir = os.path.dirname(lib_file)
+ if requiref90: self.mkpath(module_build_dir)
+
+ if compiler.compiler_type=='msvc':
# this hack works around the msvc compiler attributes
# problem, msvc uses its own convention :(
c_sources += cxx_sources
cxx_sources = []
- if fmodule_sources:
- print 'XXX: Fortran 90 module support not implemented or tested'
- f_sources.extend(fmodule_sources)
-
objects = []
if c_sources:
log.info("compiling C sources")
@@ -176,24 +191,67 @@ class build_clib(old_build_clib):
debug=self.debug,
extra_postargs=extra_postargs)
objects.extend(cxx_objects)
+
+ if f_sources or fmodule_sources:
+ extra_postargs = []
+ f_objects = []
+
+ if requiref90:
+ if fcompiler.module_dir_switch is None:
+ existing_modules = glob('*.mod')
+ extra_postargs += fcompiler.module_options(\
+ module_dirs,module_build_dir)
+
+ if fmodule_sources:
+ log.info("compiling Fortran 90 module sources")
+ f_objects += fcompiler.compile(fmodule_sources,
+ output_dir=self.build_temp,
+ macros=macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_postargs)
+
+ if requiref90 and self.fcompiler.module_dir_switch is None:
+ # move new compiled F90 module files to module_build_dir
+ for f in glob('*.mod'):
+ if f in existing_modules:
+ continue
+ t = os.path.join(module_build_dir, f)
+ if os.path.abspath(f)==os.path.abspath(t):
+ continue
+ if os.path.isfile(t):
+ os.remove(t)
+ try:
+ self.move_file(f, module_build_dir)
+ except DistutilsFileError:
+ log.warn('failed to move %r to %r' \
+ % (f, module_build_dir))
+
+ if f_sources:
+ log.info("compiling Fortran sources")
+ f_objects += fcompiler.compile(f_sources,
+ output_dir=self.build_temp,
+ macros=macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_postargs)
+ else:
+ f_objects = []
- if f_sources:
- log.info("compiling Fortran sources")
- f_objects = fcompiler.compile(f_sources,
- output_dir=self.build_temp,
- macros=macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=[])
- objects.extend(f_objects)
+ objects.extend(f_objects)
- self.compiler.create_static_lib(objects, lib_name,
- output_dir=self.build_clib,
- debug=self.debug)
+ # assume that default linker is suitable for
+ # linking Fortran object files
+ compiler.create_static_lib(objects, lib_name,
+ output_dir=self.build_clib,
+ debug=self.debug)
+ # fix library dependencies
clib_libraries = build_info.get('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
+#EOF