diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2007-05-18 16:41:44 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2007-05-18 16:41:44 +0000 |
commit | b3caec68294618d217bdb26872b3c9d235c6ade6 (patch) | |
tree | af56df505e0cbb0ba2a4b29ebdb85024d9f2e5df /numpy/distutils/command/build_clib.py | |
parent | 5fcecff23893db08dd325501cdfa61cccd55688d (diff) | |
download | numpy-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.py | 108 |
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 |