def show_fcompilers(dist=None): """Print list of available compilers (used by the "--help-fcompiler" option to "config_fc"). """ from numpy.distutils import fcompiler, log if dist is None: from distutils.dist import Distribution from numpy.distutils.command.config_compiler import config_fc dist = Distribution() dist.script_name = os.path.basename(sys.argv[0]) dist.script_args = ['config_fc'] + sys.argv[1:] try: dist.script_args.remove('--help-fcompiler') except ValueError: pass dist.cmdclass['config_fc'] = config_fc dist.parse_config_files() dist.parse_command_line() compilers = {} compilers_na = [] compilers_ni = [] if not fcompiler.fcompiler_class: fcompiler.load_all_fcompiler_classes() platform_compilers = fcompiler.available_fcompilers_for_platform() for compiler in platform_compilers: v = None log.set_verbosity(-2) try: c = fcompiler.new_fcompiler(compiler=compiler, verbose=dist.verbose) c.customize(dist) v = c.get_version() except (fcompiler.DistutilsModuleError, fcompiler.CompilerNotFound), e: log.debug("show_fcompilers: %s not found" % (compiler,)) log.debug(repr(e)) if v is None: compilers_na.append(("fcompiler="+compiler, None, fcompiler.fcompiler_class[compiler][2])) else: c.dump_properties() compilers[compiler] = c
def build_extension(self, ext): from numpy.distutils.command.build_ext import (is_sequence, newer_group, log, filter_sources, get_numpy_include_dirs) sources = ext.sources if sources is None or not is_sequence(sources): raise DistutilsSetupError( ("in 'ext_modules' option (extension '%s'), " + "'sources' must be present and must be " + "a list of source filenames") % ext.name) sources = list(sources) if not sources: return fullname = self.get_ext_fullname(ext.name) if self.inplace: modpath = fullname.split('.') package = '.'.join(modpath[0:-1]) base = modpath[-1] build_py = self.get_finalized_command('build_py') package_dir = build_py.get_package_dir(package) ext_filename = os.path.join(package_dir, self.get_ext_filename(base)) else: ext_filename = os.path.join(self.build_lib, self.get_ext_filename(fullname)) depends = sources + ext.depends if not (self.force or newer_group(depends, ext_filename, 'newer')): log.debug("skipping '%s' extension (up-to-date)", ext.name) return else: log.info("building '%s' extension", ext.name) extra_args = ext.extra_compile_args or [] macros = ext.define_macros[:] for undef in ext.undef_macros: macros.append((undef,)) c_sources, cxx_sources, f_sources, fmodule_sources = \ filter_sources(ext.sources) if self.compiler.compiler_type=='msvc': if cxx_sources: # Needed to compile kiva.agg._agg extension. extra_args.append('/Zm1000') # this hack works around the msvc compiler attributes # problem, msvc uses its own convention :( c_sources += cxx_sources cxx_sources = [] # Set Fortran/C++ compilers for compilation and linking. if ext.language=='f90': fcompiler = self._f90_compiler elif ext.language=='f77': fcompiler = self._f77_compiler else: # in case ext.language is c++, for instance fcompiler = self._f90_compiler or self._f77_compiler cxx_compiler = self._cxx_compiler # check for the availability of required compilers if cxx_sources and cxx_compiler is None: raise DistutilsError, "extension %r has C++ sources" \ "but no C++ compiler found" % (ext.name) if (f_sources or fmodule_sources) and fcompiler is None: raise DistutilsError, "extension %r has Fortran sources " \ "but no Fortran compiler found" % (ext.name) if ext.language in ['f77','f90'] and fcompiler is None: self.warn("extension %r has Fortran libraries " \ "but no Fortran linker " "found, using default linker" % (ext.name)) if ext.language=='c++' and cxx_compiler is None: self.warn("extension %r has C++ libraries " \ "but no C++ linker " "found, using default linker" % (ext.name)) kws = {'depends':ext.depends} output_dir = self.build_temp include_dirs = ext.include_dirs + get_numpy_include_dirs() c_objects = [] if c_sources: log.info("compiling C sources") c_objects = self.compiler.compile(c_sources, output_dir=output_dir, macros=macros, include_dirs=include_dirs, debug=self.debug, extra_postargs=extra_args, **kws) if cxx_sources: log.info("compiling C++ 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) extra_postargs = [] f_objects = [] if fmodule_sources: log.info("compiling Fortran 90 module sources") module_dirs = ext.module_dirs[:] module_build_dir = os.path.join( self.build_temp,os.path.dirname( self.get_ext_filename(fullname))) self.mkpath(module_build_dir) if fcompiler.module_dir_switch is None: existing_modules = glob('*.mod') extra_postargs += fcompiler.module_options( module_dirs,module_build_dir) #----------------------------------------------------------------- #XXX: hack, but the same can be said for this ENTIRE MODULE! # since fwrap only works with F90 compilers, fcompiler.compiler_f77 # is None, so we replace it with fcompiler.compiler_fix, which is # an F90 compiler. #----------------------------------------------------------------- if fcompiler.compiler_f77 is None: fcompiler.compiler_f77 = fcompiler.compiler_fix f_objects += fcompiler.compile(fmodule_sources, output_dir=self.build_temp, macros=macros, include_dirs=include_dirs, debug=self.debug, extra_postargs=extra_postargs, depends=ext.depends) if fcompiler.module_dir_switch is None: 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, depends=ext.depends) objects = c_objects + f_objects if ext.extra_objects: objects.extend(ext.extra_objects) extra_args = ext.extra_link_args or [] libraries = self.get_libraries(ext)[:] library_dirs = ext.library_dirs[:] linker = self.compiler.link_shared_object # Always use system linker when using MSVC compiler. if self.compiler.compiler_type=='msvc': # expand libraries with fcompiler libraries as we are # not using fcompiler linker self._libs_with_msvc_and_fortran(fcompiler, libraries, library_dirs) # elif ext.language in ['f77','f90'] and fcompiler is not None: # linker = fcompiler.link_shared_object if ext.language=='c++' and cxx_compiler is not None: linker = cxx_compiler.link_shared_object if sys.version[:3]>='2.3': kws = {'target_lang':ext.language} else: kws = {} linker(objects, ext_filename, libraries=libraries, library_dirs=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)