diff options
author | cookedm <cookedm@localhost> | 2007-05-25 11:41:16 +0000 |
---|---|---|
committer | cookedm <cookedm@localhost> | 2007-05-25 11:41:16 +0000 |
commit | 5267b3e16654ef326f525fdb9a1287a88396c616 (patch) | |
tree | 9e7137815415c08577f5451266cdc70f7caa3ea7 | |
parent | d11dbc78c0df5055a6ed57285775cc18dbe1721a (diff) | |
download | numpy-5267b3e16654ef326f525fdb9a1287a88396c616.tar.gz |
merge from distutils-revamp branch (step 2)
- fcompiler changes. All flags, executables, etc., should be overridable
by the user with config_fc (either command line or setup.cfg) or by
environment variables
-rw-r--r-- | numpy/distutils/environment.py | 49 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/__init__.py | 654 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/absoft.py | 7 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/compaq.py | 23 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/g95.py | 10 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/gnu.py | 63 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/hpux.py | 5 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/ibm.py | 7 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/intel.py | 79 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/lahey.py | 5 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/mips.py | 7 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/nag.py | 7 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/none.py | 21 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/pg.py | 5 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/sun.py | 7 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/vast.py | 9 | ||||
-rw-r--r-- | numpy/distutils/interactive.py | 2 |
17 files changed, 567 insertions, 393 deletions
diff --git a/numpy/distutils/environment.py b/numpy/distutils/environment.py new file mode 100644 index 000000000..fa4a77905 --- /dev/null +++ b/numpy/distutils/environment.py @@ -0,0 +1,49 @@ +import os +from distutils.dist import Distribution + +__metaclass__ = type + +class EnvironmentConfig: + def __init__(self, distutils_section='DEFAULT', **kw): + self._distutils_section = distutils_section + self._conf_keys = kw + self._conf = None + self._hook_handler = None + + def __getattr__(self, name): + try: + conf_desc = self._conf_keys[name] + except KeyError: + raise AttributeError(name) + return self._get_var(name, conf_desc) + + def get(self, name, default=None): + try: + conf_desc = self._conf_keys[name] + except KeyError: + return default + var = self._get_var(name, conf_desc) + if var is None: + var = default + return var + + def _get_var(self, name, conf_desc): + hook, envvar, confvar = conf_desc + var = self._hook_handler(name, hook) + if envvar is not None: + var = os.environ.get(envvar, var) + if confvar is not None and self._conf: + var = self._conf.get(confvar, (None, var))[1] + return var + + def clone(self, hook_handler): + ec = self.__class__(distutils_section=self._distutils_section, + **self._conf_keys) + ec._hook_handler = hook_handler + return ec + + def use_distribution(self, dist): + if isinstance(dist, Distribution): + self._conf = dist.get_option_dict(self._distutils_section) + else: + self._conf = dist diff --git a/numpy/distutils/fcompiler/__init__.py b/numpy/distutils/fcompiler/__init__.py index 799a36cb6..3821b3e70 100644 --- a/numpy/distutils/fcompiler/__init__.py +++ b/numpy/distutils/fcompiler/__init__.py @@ -10,6 +10,12 @@ __all__ = ['FCompiler','new_fcompiler','show_fcompilers', import os import sys import re +import new +try: + set +except NameError: + from sets import Set as set + from distutils.sysconfig import get_config_var, get_python_lib from distutils.fancy_getopt import FancyGetopt from distutils.errors import DistutilsModuleError,DistutilsArgError,\ @@ -18,12 +24,18 @@ from distutils.util import split_quoted from numpy.distutils.ccompiler import CCompiler, gen_lib_options from numpy.distutils import log -from numpy.distutils.command.config_compiler import config_fc from numpy.distutils.misc_util import is_string, is_sequence +from numpy.distutils.environment import EnvironmentConfig +from numpy.distutils.exec_command import find_executable from distutils.spawn import _nt_quote_args +__metaclass__ = type + +class CompilerNotFound(Exception): + pass + class FCompiler(CCompiler): - """ Abstract base class to define the interface that must be implemented + """Abstract base class to define the interface that must be implemented by real Fortran compiler classes. Methods that subclasses may redefine: @@ -38,7 +50,7 @@ class FCompiler(CCompiler): DON'T call these methods (except get_version) after constructing a compiler instance or inside any other method. All methods, except get_version_cmd() and get_flags_version(), may - call get_version() method. + call the get_version() method. After constructing a compiler instance, always call customize(dist=None) method that finalizes compiler construction and makes the following @@ -53,6 +65,54 @@ class FCompiler(CCompiler): library_dirs """ + # These are the environment variables and distutils keys used. + # Each configuration descripition is + # (<hook name>, <environment variable>, <key in distutils.cfg>) + # The hook names are handled by the self._environment_hook method. + # - names starting with 'self.' call methods in this class + # - names starting with 'exe.' return the key in the executables dict + # - names like'flags.YYY' return self.get_flag_YYY() + + distutils_vars = EnvironmentConfig( + noopt = (None, None, 'noopt'), + noarch = (None, None, 'noarch'), + debug = (None, None, 'debug'), + verbose = (None, None, 'verbose'), + ) + + command_vars = EnvironmentConfig( + distutils_section='config_fc', + compiler_f77 = ('exe.compiler_f77', 'F77', 'f77exec'), + compiler_f90 = ('exe.compiler_f90', 'F90', 'f90exec'), + compiler_fix = ('exe.compiler_fix', 'F90', 'f90exec'), + version_cmd = ('self.get_version_cmd', None, None), + linker_so = ('self.get_linker_so', 'LDSHARED', 'ldshared'), + linker_exe = ('self.get_linker_exe', 'LD', 'ld'), + archiver = (None, 'AR', 'ar'), + ranlib = (None, 'RANLIB', 'ranlib'), + ) + + flag_vars = EnvironmentConfig( + distutils_section='config_fc', + version = ('flags.version', None, None), + f77 = ('flags.f77', 'F77FLAGS', 'f77flags'), + f90 = ('flags.f90', 'F90FLAGS', 'f90flags'), + free = ('flags.free', 'FREEFLAGS', 'freeflags'), + fix = ('flags.fix', None, None), + opt = ('flags.opt', 'FOPT', 'opt'), + opt_f77 = ('flags.opt_f77', None, None), + opt_f90 = ('flags.opt_f90', None, None), + arch = ('flags.arch', 'FARCH', 'arch'), + arch_f77 = ('flags.arch_f77', None, None), + arch_f90 = ('flags.arch_f90', None, None), + debug = ('flags.debug', 'FDEBUG', None, None), + debug_f77 = ('flags.debug_f77', None, None), + debug_f90 = ('flags.debug_f90', None, None), + flags = ('self.get_flags', 'FFLAGS', 'fflags'), + linker_so = ('flags.linker_so', 'LDFLAGS', 'ldflags'), + linker_exe = ('flags.linker_exe', 'LDFLAGS', 'ldflags'), + ar = ('flags.ar', 'ARFLAGS', 'arflags'), + ) language_map = {'.f':'f77', '.for':'f77', @@ -67,14 +127,15 @@ class FCompiler(CCompiler): version_pattern = None + possible_executables = [] executables = { - 'version_cmd' : ["f77","-v"], + 'version_cmd' : ["f77", "-v"], 'compiler_f77' : ["f77"], 'compiler_f90' : ["f90"], - 'compiler_fix' : ["f90","-fixed"], - 'linker_so' : ["f90","-shared"], + 'compiler_fix' : ["f90", "-fixed"], + 'linker_so' : ["f90", "-shared"], 'linker_exe' : ["f90"], - 'archiver' : ["ar","-cr"], + 'archiver' : ["ar", "-cr"], 'ranlib' : None, } @@ -103,6 +164,26 @@ class FCompiler(CCompiler): shared_lib_format = "%s%s" exe_extension = "" + def __init__(self, *args, **kw): + CCompiler.__init__(self, *args, **kw) + self.distutils_vars = self.distutils_vars.clone(self._environment_hook) + self.command_vars = self.command_vars.clone(self._environment_hook) + self.flag_vars = self.flag_vars.clone(self._environment_hook) + self.executables = self.executables.copy() + for e in ['version_cmd', 'compiler_f77', 'compiler_f90', + 'compiler_fix', 'linker_so', 'linker_exe', 'archiver', + 'ranlib']: + if e not in self.executables: + self.executables[e] = None + + def __copy__(self): + obj = new.instance(self.__class__, self.__dict__) + obj.distutils_vars = obj.distutils_vars.clone(obj._environment_hook) + obj.command_vars = obj.command_vars.clone(obj._environment_hook) + obj.flag_vars = obj.flag_vars.clone(obj._environment_hook) + obj.executables = obj.executables.copy() + return obj + # If compiler does not support compiling Fortran 90 then it can # suggest using another compiler. For example, gnu would suggest # gnu95 compiler type when there are F90 sources. @@ -114,12 +195,72 @@ class FCompiler(CCompiler): ## results if used elsewhere. So, you have been warned.. def find_executables(self): - """Modify self.executables to hold found executables, instead of - searching for them at class creation time.""" - pass + """Go through the self.executables dictionary, and attempt to + find and assign appropiate executables. + + Executable names are looked for in the environment (environment + variables, the distutils.cfg, and command line), the 0th-element of + the command list, and the self.possible_executables list. + + Also, if the 0th element is "<F77>" or "<F90>", the Fortran 77 + or the Fortran 90 compiler executable is used, unless overridden + by an environment setting. + """ + exe_cache = {} + def cached_find_executable(exe): + if exe in exe_cache: + return exe_cache[exe] + fc_exe = find_executable(exe) + exe_cache[exe] = fc_exe + return fc_exe + def set_exe(exe_key, f77=None, f90=None): + cmd = self.executables.get(exe_key, None) + if not cmd: + return None + # Note that we get cmd[0] here if the environment doesn't + # have anything set + exe_from_environ = getattr(self.command_vars, exe_key) + if not exe_from_environ: + possibles = [f90, f77] + self.possible_executables + else: + possibles = [exe_from_environ] + self.possible_executables + + seen = set() + unique_possibles = [] + for e in possibles: + if e == '<F77>': + e = f77 + elif e == '<F90>': + e = f90 + if not e or e in seen: + continue + seen.add(e) + unique_possibles.append(e) + + for exe in unique_possibles: + fc_exe = cached_find_executable(exe) + if fc_exe: + cmd[0] = fc_exe + return fc_exe + return None + + f90 = set_exe('compiler_f90') + if not f90: + raise CompilerNotFound('f90') + f77 = set_exe('compiler_f77', f90=f90) + if not f77: + raise CompilerNotFound('f90') + set_exe('compiler_fix', f90=f90) + + set_exe('linker_so', f77=f77, f90=f90) + set_exe('linker_exe', f77=f77, f90=f90) + set_exe('version_cmd', f77=f77, f90=f90) + + set_exe('archiver') + set_exe('ranlib') def get_version_cmd(self): - """ Compiler command to print out version information. """ + """Compiler command to print out version information.""" f77 = self.executables.get('compiler_f77') if f77 is not None: f77 = f77[0] @@ -137,8 +278,8 @@ class FCompiler(CCompiler): return cmd def get_linker_so(self): - """ Linker command to build shared libraries. """ - f77 = self.executables['compiler_f77'] + """Linker command to build shared libraries.""" + f77 = self.executables.get('compiler_f77') if f77 is not None: f77 = f77[0] ln = self.executables.get('linker_so') @@ -155,8 +296,8 @@ class FCompiler(CCompiler): return ln def get_linker_exe(self): - """ Linker command to build shared libraries. """ - f77 = self.executables['compiler_f77'] + """Linker command to build shared libraries.""" + f77 = self.executables.get('compiler_f77') if f77 is not None: f77 = f77[0] ln = self.executables.get('linker_exe') @@ -173,54 +314,47 @@ class FCompiler(CCompiler): return ln def get_flags(self): - """ List of flags common to all compiler types. """ + """List of flags common to all compiler types.""" return [] + self.pic_flags + + def _get_executable_flags(self, key): + cmd = self.executables.get(key, None) + if cmd is None: + return [] + return cmd[1:] + def get_flags_version(self): - """ List of compiler flags to print out version information. """ - if self.executables.get('version_cmd'): - return self.executables['version_cmd'][1:] - return [] + """List of compiler flags to print out version information.""" + return self._get_executable_flags('version_cmd') def get_flags_f77(self): - """ List of Fortran 77 specific flags. """ - if self.executables.get('compiler_f77'): - return self.executables['compiler_f77'][1:] - return [] + """List of Fortran 77 specific flags.""" + return self._get_executable_flags('compiler_f77') def get_flags_f90(self): - """ List of Fortran 90 specific flags. """ - if self.executables.get('compiler_f90'): - return self.executables['compiler_f90'][1:] - return [] + """List of Fortran 90 specific flags.""" + return self._get_executable_flags('compiler_f90') def get_flags_free(self): - """ List of Fortran 90 free format specific flags. """ + """List of Fortran 90 free format specific flags.""" return [] def get_flags_fix(self): - """ List of Fortran 90 fixed format specific flags. """ - if self.executables.get('compiler_fix'): - return self.executables['compiler_fix'][1:] - return [] + """List of Fortran 90 fixed format specific flags.""" + return self._get_executable_flags('compiler_fix') def get_flags_linker_so(self): - """ List of linker flags to build a shared library. """ - if self.executables.get('linker_so'): - return self.executables['linker_so'][1:] - return [] + """List of linker flags to build a shared library.""" + return self._get_executable_flags('linker_so') def get_flags_linker_exe(self): - """ List of linker flags to build an executable. """ - if self.executables.get('linker_exe'): - return self.executables['linker_exe'][1:] - return [] + """List of linker flags to build an executable.""" + return self._get_executable_flags('linker_exe') def get_flags_ar(self): - """ List of archiver flags. """ - if self.executables.get('archiver'): - return self.executables['archiver'][1:] - return [] + """List of archiver flags. """ + return self._get_executable_flags('archiver') def get_flags_opt(self): - """ List of architecture independent compiler flags. """ + """List of architecture independent compiler flags.""" return [] def get_flags_arch(self): - """ List of architecture dependent compiler flags. """ + """List of architecture dependent compiler flags.""" return [] def get_flags_debug(self): - """ List of compiler flags to compile with debugging information. """ + """List of compiler flags to compile with debugging information.""" return [] get_flags_opt_f77 = get_flags_opt_f90 = get_flags_opt @@ -228,18 +362,18 @@ class FCompiler(CCompiler): get_flags_debug_f77 = get_flags_debug_f90 = get_flags_debug def get_libraries(self): - """ List of compiler libraries. """ + """List of compiler libraries.""" return self.libraries[:] def get_library_dirs(self): - """ List of compiler library directories. """ + """List of compiler library directories.""" return self.library_dirs[:] ############################################################ ## Public methods: - def customize(self, dist=None): - """ Customize Fortran compiler. + def customize(self, dist): + """Customize Fortran compiler. This method gets Fortran compiler specific information from (i) class definition, (ii) environment, (iii) distutils config @@ -250,88 +384,71 @@ class FCompiler(CCompiler): instance is needed for (iii) and (iv). """ log.info('customize %s' % (self.__class__.__name__)) - from distutils.dist import Distribution - if dist is None: - # These hooks are for testing only! - dist = Distribution() - dist.script_name = os.path.basename(sys.argv[0]) - dist.script_args = ['config_fc'] + sys.argv[1:] - dist.cmdclass['config_fc'] = config_fc - dist.parse_config_files() - dist.parse_command_line() - if isinstance(dist,Distribution): - conf = dist.get_option_dict('config_fc') - else: - assert isinstance(dist,dict) - conf = dist - noopt = conf.get('noopt',[None,0])[1] + self.distutils_vars.use_distribution(dist) + self.command_vars.use_distribution(dist) + self.flag_vars.use_distribution(dist) + + self.find_executables() + + noopt = self.distutils_vars.get('noopt', False) if 0: # change to `if 1:` when making release. # Don't use architecture dependent compiler flags: - noarch = 1 + noarch = True else: - noarch = conf.get('noarch',[None,noopt])[1] - debug = conf.get('debug',[None,0])[1] + noarch = self.distutils_vars.get('noarch', noopt) + debug = self.distutils_vars.get('debug', False) - self.find_executables() - - f77 = self.__get_cmd('compiler_f77','F77',(conf,'f77exec')) - f90 = self.__get_cmd('compiler_f90','F90',(conf,'f90exec')) - # Temporarily setting f77,f90 compilers so that - # version_cmd can use their executables. - if f77: - self.set_executables(compiler_f77=[f77]) - if f90: - self.set_executables(compiler_f90=[f90]) + f77 = self.command_vars.compiler_f77 + f90 = self.command_vars.compiler_f90 # Must set version_cmd before others as self.get_flags* # methods may call self.get_version. - vers_cmd = self.__get_cmd(self.get_version_cmd) + vers_cmd = self.command_vars.version_cmd if vers_cmd: - vflags = self.__get_flags(self.get_flags_version) + vflags = self.flag_vars.version self.set_executables(version_cmd=[vers_cmd]+vflags) + f77flags = [] + f90flags = [] + freeflags = [] + fixflags = [] + if f77: - f77flags = self.__get_flags(self.get_flags_f77,'F77FLAGS', - (conf,'f77flags')) + f77flags = self.flag_vars.f77 if f90: - f90flags = self.__get_flags(self.get_flags_f90,'F90FLAGS', - (conf,'f90flags')) - freeflags = self.__get_flags(self.get_flags_free,'FREEFLAGS', - (conf,'freeflags')) + f90flags = self.flag_vars.f90 + freeflags = self.flag_vars.free # XXX Assuming that free format is default for f90 compiler. - fix = self.__get_cmd('compiler_fix','F90',(conf,'f90exec')) + fix = self.command_vars.compiler_fix if fix: - fixflags = self.__get_flags(self.get_flags_fix) + f90flags - - oflags,aflags,dflags = [],[],[] + fixflags = self.flag_vars.fix + f90flags + + oflags, aflags, dflags = [], [], [] + def to_list(flags): + if is_string(flags): + return [flags] + return flags + # examine get_flags_<tag>_<compiler> for extra flags + # only add them if the method is different from get_flags_<tag> + def get_flags(tag, flags): + # note that self.flag_vars.<tag> calls self.get_flags_<tag>() + flags.extend(to_list(getattr(self.flag_vars, tag))) + this_get = getattr(self, 'get_flags_' + tag) + for name, c, flagvar in [('f77', f77, f77flags), + ('f90', f90, f90flags), + ('f90', fix, fixflags)]: + t = '%s_%s' % (tag, name) + if c and this_get is not getattr(self, 'get_flags_' + t): + flagvar.extend(to_list(getattr(self.flag_vars, t))) + return oflags if not noopt: - oflags = self.__get_flags(self.get_flags_opt,'FOPT',(conf,'opt')) - if f77 and self.get_flags_opt is not self.get_flags_opt_f77: - f77flags += self.__get_flags(self.get_flags_opt_f77) - if f90 and self.get_flags_opt is not self.get_flags_opt_f90: - f90flags += self.__get_flags(self.get_flags_opt_f90) - if fix and self.get_flags_opt is not self.get_flags_opt_f90: - fixflags += self.__get_flags(self.get_flags_opt_f90) + get_flags('opt', oflags) if not noarch: - aflags = self.__get_flags(self.get_flags_arch,'FARCH', - (conf,'arch')) - if f77 and self.get_flags_arch is not self.get_flags_arch_f77: - f77flags += self.__get_flags(self.get_flags_arch_f77) - if f90 and self.get_flags_arch is not self.get_flags_arch_f90: - f90flags += self.__get_flags(self.get_flags_arch_f90) - if fix and self.get_flags_arch is not self.get_flags_arch_f90: - fixflags += self.__get_flags(self.get_flags_arch_f90) + get_flags('arch', aflags) if debug: - dflags = self.__get_flags(self.get_flags_debug,'FDEBUG') - if f77 and self.get_flags_debug is not self.get_flags_debug_f77: - f77flags += self.__get_flags(self.get_flags_debug_f77) - if f90 and self.get_flags_debug is not self.get_flags_debug_f90: - f90flags += self.__get_flags(self.get_flags_debug_f90) - if fix and self.get_flags_debug is not self.get_flags_debug_f90: - fixflags += self.__get_flags(self.get_flags_debug_f90) + get_flags('debug', dflags) - fflags = self.__get_flags(self.get_flags,'FFLAGS') \ - + dflags + oflags + aflags + fflags = to_list(self.flag_vars.flags) + dflags + oflags + aflags if f77: self.set_executables(compiler_f77=[f77]+f77flags+fflags) @@ -339,10 +456,11 @@ class FCompiler(CCompiler): self.set_executables(compiler_f90=[f90]+freeflags+f90flags+fflags) if fix: self.set_executables(compiler_fix=[fix]+fixflags+fflags) + #XXX: Do we need LDSHARED->SOSHARED, LDFLAGS->SOFLAGS - linker_so = self.__get_cmd(self.get_linker_so,'LDSHARED') + linker_so = self.command_vars.linker_so if linker_so: - linker_so_flags = self.__get_flags(self.get_flags_linker_so,'LDFLAGS') + linker_so_flags = to_list(self.flag_vars.linker_so) if sys.platform.startswith('aix'): python_lib = get_python_lib(standard_lib=1) ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') @@ -352,37 +470,32 @@ class FCompiler(CCompiler): linker_so = [linker_so] self.set_executables(linker_so=linker_so+linker_so_flags) - linker_exe = self.__get_cmd(self.get_linker_exe,'LD') + linker_exe = self.command_vars.linker_exe if linker_exe: - linker_exe_flags = self.__get_flags(self.get_flags_linker_exe,'LDFLAGS') + linker_exe_flags = to_list(self.flag_vars.linker_exe) self.set_executables(linker_exe=[linker_exe]+linker_exe_flags) - ar = self.__get_cmd('archiver','AR') + + ar = self.command_vars.archiver if ar: - arflags = self.__get_flags(self.get_flags_ar,'ARFLAGS') + arflags = to_list(self.flag_vars.ar) self.set_executables(archiver=[ar]+arflags) - ranlib = self.__get_cmd('ranlib','RANLIB') + ranlib = self.command_vars.ranlib if ranlib: self.set_executables(ranlib=[ranlib]) self.set_library_dirs(self.get_library_dirs()) self.set_libraries(self.get_libraries()) - - verbose = conf.get('verbose',[None,0])[1] - if verbose: - self.dump_properties() - return - def dump_properties(self): - """ Print out the attributes of a compiler instance. """ + """Print out the attributes of a compiler instance.""" props = [] for key in self.executables.keys() + \ ['version','libraries','library_dirs', 'object_switch','compile_switch']: if hasattr(self,key): v = getattr(self,key) - props.append((key, None, '= '+`v`)) + props.append((key, None, '= '+repr(v))) props.sort() pretty_printer = FancyGetopt(props) @@ -429,7 +542,8 @@ class FCompiler(CCompiler): if os.name == 'nt': compiler = _nt_quote_args(compiler) - command = compiler + cc_args + extra_flags + s_args + o_args + extra_postargs + command = compiler + cc_args + extra_flags + s_args + o_args \ + + extra_postargs display = '%s: %s' % (os.path.basename(compiler[0]) + flavor, src) @@ -512,167 +626,145 @@ class FCompiler(CCompiler): log.debug("skipping %s (up-to-date)", output_filename) return - - ## Private methods: - - def __get_cmd(self, command, envvar=None, confvar=None): - if command is None: - var = None - elif is_string(command): - var = self.executables[command] - if var is not None: - var = var[0] + def _environment_hook(self, name, hook_name): + if hook_name is None: + return None + if is_string(hook_name): + if hook_name.startswith('self.'): + hook_name = hook_name[5:] + hook = getattr(self, hook_name) + return hook() + elif hook_name.startswith('exe.'): + hook_name = hook_name[4:] + var = self.executables[hook_name] + if var: + return var[0] + else: + return None + elif hook_name.startswith('flags.'): + hook_name = hook_name[6:] + hook = getattr(self, 'get_flags_' + hook_name) + return hook() else: - var = command() - if envvar is not None: - var = os.environ.get(envvar, var) - if confvar is not None: - var = confvar[0].get(confvar[1], [None,var])[1] - return var - - def __get_flags(self, command, envvar=None, confvar=None): - if command is None: - var = [] - elif is_string(command): - var = self.executables[command][1:] - else: - var = command() - if envvar is not None: - var = os.environ.get(envvar, var) - if confvar is not None: - var = confvar[0].get(confvar[1], [None,var])[1] - if is_string(var): - var = split_quoted(var) - return var + return hook_name() ## class FCompiler -fcompiler_class = {'gnu':('gnu','GnuFCompiler', - "GNU Fortran Compiler"), - 'gnu95':('gnu','Gnu95FCompiler', - "GNU 95 Fortran Compiler"), - 'g95':('g95','G95FCompiler', - "G95 Fortran Compiler"), - 'pg':('pg','PGroupFCompiler', - "Portland Group Fortran Compiler"), - 'absoft':('absoft','AbsoftFCompiler', - "Absoft Corp Fortran Compiler"), - 'mips':('mips','MipsFCompiler', - "MIPSpro Fortran Compiler"), - 'sun':('sun','SunFCompiler', - "Sun|Forte Fortran 95 Compiler"), - 'intel':('intel','IntelFCompiler', - "Intel Fortran Compiler for 32-bit apps"), - 'intelv':('intel','IntelVisualFCompiler', - "Intel Visual Fortran Compiler for 32-bit apps"), - 'intele':('intel','IntelItaniumFCompiler', - "Intel Fortran Compiler for Itanium apps"), - 'intelev':('intel','IntelItaniumVisualFCompiler', - "Intel Visual Fortran Compiler for Itanium apps"), - 'intelem':('intel','IntelEM64TFCompiler', - "Intel Fortran Compiler for EM64T-based apps"), - 'nag':('nag','NAGFCompiler', - "NAGWare Fortran 95 Compiler"), - 'compaq':('compaq','CompaqFCompiler', - "Compaq Fortran Compiler"), - 'compaqv':('compaq','CompaqVisualFCompiler', - "DIGITAL|Compaq Visual Fortran Compiler"), - 'vast':('vast','VastFCompiler', - "Pacific-Sierra Research Fortran 90 Compiler"), - 'hpux':('hpux','HPUXFCompiler', - "HP Fortran 90 Compiler"), - 'lahey':('lahey','LaheyFCompiler', - "Lahey/Fujitsu Fortran 95 Compiler"), - 'ibm':('ibm','IbmFCompiler', - "IBM XL Fortran Compiler"), - 'f':('f','FFCompiler', - "Fortran Company/NAG F Compiler"), - 'none':('none','NoneFCompiler',"Fake Fortran compiler") - } - _default_compilers = ( # Platform mappings - ('win32',('gnu','intelv','absoft','compaqv','intelev','gnu95','g95')), - ('cygwin.*',('gnu','intelv','absoft','compaqv','intelev','gnu95','g95')), - ('linux.*',('gnu','intel','lahey','pg','absoft','nag','vast','compaq', + ('win32', ('gnu','intelv','absoft','compaqv','intelev','gnu95','g95')), + ('cygwin.*', ('gnu','intelv','absoft','compaqv','intelev','gnu95','g95')), + ('linux.*', ('gnu','intel','lahey','pg','absoft','nag','vast','compaq', 'intele','intelem','gnu95','g95')), - ('darwin.*',('nag','absoft','ibm','gnu','gnu95','g95')), - ('sunos.*',('sun','gnu','gnu95','g95')), - ('irix.*',('mips','gnu','gnu95',)), - ('aix.*',('ibm','gnu','gnu95',)), + ('darwin.*', ('nag', 'absoft', 'ibm', 'intel', 'gnu', 'gnu95', 'g95')), + ('sunos.*', ('sun','gnu','gnu95','g95')), + ('irix.*', ('mips','gnu','gnu95',)), + ('aix.*', ('ibm','gnu','gnu95',)), # OS mappings - ('posix',('gnu','gnu95',)), - ('nt',('gnu','gnu95',)), - ('mac',('gnu','gnu95',)), + ('posix', ('gnu','gnu95',)), + ('nt', ('gnu','gnu95',)), + ('mac', ('gnu','gnu95',)), ) -def _find_existing_fcompiler(compilers, osname=None, platform=None, requiref90=None): - for compiler in compilers: +fcompiler_class = None + +def load_all_fcompiler_classes(): + """Cache all the FCompiler classes found in modules in the + numpy.distutils.fcompiler package. + """ + from glob import glob + global fcompiler_class + if fcompiler_class is not None: + return + pys = os.path.join(os.path.dirname(__file__), '*.py') + fcompiler_class = {} + for fname in glob(pys): + module_name, ext = os.path.splitext(os.path.basename(fname)) + module_name = 'numpy.distutils.fcompiler.' + module_name + __import__ (module_name) + module = sys.modules[module_name] + if hasattr(module, 'compilers'): + for cname in module.compilers: + klass = getattr(module, cname) + fcompiler_class[klass.compiler_type] = (klass.compiler_type, + klass, + klass.description) + +def _find_existing_fcompiler(compiler_types, osname=None, platform=None, + requiref90=False): + from numpy.distutils.core import get_distribution + dist = get_distribution(always=True) + for compiler_type in compiler_types: v = None try: - c = new_fcompiler(plat=platform, compiler=compiler) - c.customize() + c = new_fcompiler(plat=platform, compiler=compiler_type) + c.customize(dist) v = c.get_version() if requiref90 and c.compiler_f90 is None: v = None new_compiler = c.suggested_f90_compiler if new_compiler: - log.warn('Trying %r compiler as suggested by %r compiler for f90 support.' % (compiler, new_compiler)) + log.warn('Trying %r compiler as suggested by %r ' + 'compiler for f90 support.' % (compiler, + new_compiler)) c = new_fcompiler(plat=platform, compiler=new_compiler) - c.customize() + c.customize(dist) v = c.get_version() if v is not None: - compiler = new_compiler + compiler_type = new_compiler if requiref90 and c.compiler_f90 is None: - raise ValueError,'%s does not support compiling f90 codes, skipping.' \ - % (c.__class__.__name__) + raise ValueError('%s does not support compiling f90 codes, ' + 'skipping.' % (c.__class__.__name__)) except DistutilsModuleError: pass - except Exception, msg: - log.warn(msg) + except CompilerNotFound: + pass if v is not None: - return compiler - return + return compiler_type + return None -def get_default_fcompiler(osname=None, platform=None, requiref90=None): - """ Determine the default Fortran compiler to use for the given platform. """ +def available_fcompilers_for_platform(osname=None, platform=None): if osname is None: osname = os.name if platform is None: platform = sys.platform - matching_compilers = [] - for pattern, compiler in _default_compilers: - if re.match(pattern, platform) is not None or \ - re.match(pattern, osname) is not None: - if is_sequence(compiler): - matching_compilers.extend(list(compiler)) - else: - matching_compilers.append(compiler) - if not matching_compilers: - matching_compilers.append('gnu') - compiler = _find_existing_fcompiler(matching_compilers, - osname=osname, - platform=platform, - requiref90=requiref90) - if compiler is not None: - return compiler - return matching_compilers[0] + matching_compiler_types = [] + for pattern, compiler_type in _default_compilers: + if re.match(pattern, platform) or re.match(pattern, osname): + for ct in compiler_type: + if ct not in matching_compiler_types: + matching_compiler_types.append(ct) + if not matching_compiler_types: + matching_compiler_types.append('gnu') + return matching_compiler_types + +def get_default_fcompiler(osname=None, platform=None, requiref90=False): + """Determine the default Fortran compiler to use for the given + platform.""" + matching_compiler_types = available_fcompilers_for_platform(osname, + platform) + compiler_type = _find_existing_fcompiler(matching_compiler_types, + osname=osname, + platform=platform, + requiref90=requiref90) + return compiler_type def new_fcompiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0, - requiref90=0): - """ Generate an instance of some FCompiler subclass for the supplied + requiref90=False): + """Generate an instance of some FCompiler subclass for the supplied platform/compiler combination. """ + load_all_fcompiler_classes() if plat is None: plat = os.name + if compiler is None: + compiler = get_default_fcompiler(plat, requiref90=requiref90) try: - if compiler is None: - compiler = get_default_fcompiler(plat,requiref90=requiref90) - (module_name, class_name, long_description) = fcompiler_class[compiler] + module_name, klass, long_description = fcompiler_class[compiler] except KeyError: msg = "don't know how to compile Fortran code on platform '%s'" % plat if compiler is not None: @@ -681,69 +773,67 @@ def new_fcompiler(plat=None, % (','.join(fcompiler_class.keys())) raise DistutilsPlatformError, msg - try: - module_name = 'numpy.distutils.fcompiler.'+module_name - __import__ (module_name) - module = sys.modules[module_name] - klass = vars(module)[class_name] - except ImportError: - raise DistutilsModuleError, \ - "can't compile Fortran code: unable to load module '%s'" % \ - module_name - except KeyError: - 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) - log.debug('new_fcompiler returns %s' % (klass)) + compiler = klass(verbose=verbose, dry_run=dry_run, force=force) return compiler -def show_fcompilers(dist = None): - """ Print list of available compilers (used by the "--help-fcompiler" +def show_fcompilers(dist=None): + """Print list of available compilers (used by the "--help-fcompiler" option to "config_fc"). """ 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 = [] - for compiler in fcompiler_class.keys(): - v = 'N/A' + if not fcompiler_class: + load_all_fcompiler_classes() + platform_compilers = available_fcompilers_for_platform() + for compiler in platform_compilers: + v = None + log.set_verbosity(-2) log.set_verbosity(-2) try: - c = new_fcompiler(compiler=compiler) + c = new_fcompiler(compiler=compiler, verbose=dist.verbose) c.customize(dist) v = c.get_version() - except DistutilsModuleError: + except (DistutilsModuleError, CompilerNotFound): pass - except Exception, msg: - log.warn(msg) + if v is None: compilers_na.append(("fcompiler="+compiler, None, fcompiler_class[compiler][2])) - elif v=='N/A': - compilers_ni.append(("fcompiler="+compiler, None, - fcompiler_class[compiler][2])) else: + c.dump_properties() compilers.append(("fcompiler="+compiler, None, fcompiler_class[compiler][2] + ' (%s)' % v)) + compilers_ni = list(set(fcompiler_class.keys()) - set(platform_compilers)) + compilers_ni = [("fcompiler="+fc, None, fcompiler_class[fc][2]) + for fc in compilers_ni] + compilers.sort() compilers_na.sort() + compilers_ni.sort() pretty_printer = FancyGetopt(compilers) - pretty_printer.print_help("List of available Fortran compilers:") + pretty_printer.print_help("Fortran compilers found:") pretty_printer = FancyGetopt(compilers_na) - pretty_printer.print_help("List of unavailable Fortran compilers:") + pretty_printer.print_help("Compilers available for this " + "platform, but not found:") if compilers_ni: pretty_printer = FancyGetopt(compilers_ni) - pretty_printer.print_help("List of unimplemented Fortran compilers:") + pretty_printer.print_help("Compilers not available on this platform:") print "For compiler details, run 'config_fc --verbose' setup command." def dummy_fortran_file(): diff --git a/numpy/distutils/fcompiler/absoft.py b/numpy/distutils/fcompiler/absoft.py index a00ca78b8..3360c7309 100644 --- a/numpy/distutils/fcompiler/absoft.py +++ b/numpy/distutils/fcompiler/absoft.py @@ -13,9 +13,12 @@ from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file from numpy.distutils.misc_util import cyg2win32 +compilers = ['AbsoftFCompiler'] + class AbsoftFCompiler(FCompiler): compiler_type = 'absoft' + description = 'Absoft Corp Fortran Compiler' #version_pattern = r'FORTRAN 77 Compiler (?P<version>[^\s*,]*).*?Absoft Corp' version_pattern = r'(f90:.*?(Absoft Pro FORTRAN Version|FORTRAN 77 Compiler|Absoft Fortran Compiler Version|Copyright Absoft Corporation.*?Version))'+\ r' (?P<version>[^\s*,]*)(.*?Absoft Corp|)' @@ -28,12 +31,12 @@ class AbsoftFCompiler(FCompiler): # Note that fink installs g77 as f77, so need to use f90 for detection. executables = { - 'version_cmd' : ["f90", "-V -c %(fname)s.f -o %(fname)s.o" \ + 'version_cmd' : ["<F90>", "-V -c %(fname)s.f -o %(fname)s.o" \ % {'fname':cyg2win32(dummy_fortran_file())}], 'compiler_f77' : ["f77"], 'compiler_fix' : ["f90"], 'compiler_f90' : ["f90"], - 'linker_so' : ["f90"], + 'linker_so' : ["<F90>"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } diff --git a/numpy/distutils/fcompiler/compaq.py b/numpy/distutils/fcompiler/compaq.py index c2897f5ca..03c8c88ac 100644 --- a/numpy/distutils/fcompiler/compaq.py +++ b/numpy/distutils/fcompiler/compaq.py @@ -7,9 +7,17 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler +compilers = ['CompaqFCompiler'] +if os.name != 'posix': + # Otherwise we'd get a false positive on posix systems with + # case-insensitive filesystems (like darwin), because we'll pick + # up /bin/df + compilers.append('CompaqVisualFCompiler') + class CompaqFCompiler(FCompiler): compiler_type = 'compaq' + description = 'Compaq Fortran Compiler' version_pattern = r'Compaq Fortran (?P<version>[^\s]*).*' if sys.platform[:5]=='linux': @@ -18,11 +26,11 @@ class CompaqFCompiler(FCompiler): fc_exe = 'f90' executables = { - 'version_cmd' : [fc_exe, "-version"], + 'version_cmd' : ['<F90>', "-version"], 'compiler_f77' : [fc_exe, "-f77rtl","-fixed"], 'compiler_fix' : [fc_exe, "-fixed"], 'compiler_f90' : [fc_exe], - 'linker_so' : [fc_exe], + 'linker_so' : ['<F90>'], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } @@ -47,6 +55,7 @@ class CompaqFCompiler(FCompiler): class CompaqVisualFCompiler(FCompiler): compiler_type = 'compaqv' + description = 'DIGITAL or Compaq Visual Fortran Compiler' version_pattern = r'(DIGITAL|Compaq) Visual Fortran Optimizing Compiler'\ ' Version (?P<version>[^\s]*).*' @@ -68,11 +77,11 @@ class CompaqVisualFCompiler(FCompiler): ar_exe = m.lib executables = { - 'version_cmd' : ['DF', "/what"], - 'compiler_f77' : ['DF', "/f77rtl","/fixed"], - 'compiler_fix' : ['DF', "/fixed"], - 'compiler_f90' : ['DF'], - 'linker_so' : ['DF'], + 'version_cmd' : ['<F90>', "/what"], + 'compiler_f77' : [fc_exe, "/f77rtl","/fixed"], + 'compiler_fix' : [fc_exe, "/fixed"], + 'compiler_f90' : [fc_exe], + 'linker_so' : ['<F90>'], 'archiver' : [ar_exe, "/OUT:"], 'ranlib' : None } diff --git a/numpy/distutils/fcompiler/g95.py b/numpy/distutils/fcompiler/g95.py index 8fe79bfbb..7871decb5 100644 --- a/numpy/distutils/fcompiler/g95.py +++ b/numpy/distutils/fcompiler/g95.py @@ -6,9 +6,12 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler -class G95FCompiler(FCompiler): +compilers = ['G95FCompiler'] +class G95FCompiler(FCompiler): compiler_type = 'g95' + description = 'G95 Fortran Compiler' + # version_pattern = r'G95 \((GCC (?P<gccversion>[\d.]+)|.*?) \(g95!\) (?P<version>.*)\).*' # $ g95 --version # G95 (GCC 4.0.3 (g95!) May 22 2006) @@ -17,13 +20,12 @@ class G95FCompiler(FCompiler): # $ g95 --version # G95 (GCC 4.0.3 (g95 0.90!) Aug 22 2006) - executables = { - 'version_cmd' : ["g95", "--version"], + 'version_cmd' : ["<F90>", "--version"], 'compiler_f77' : ["g95", "-ffixed-form"], 'compiler_fix' : ["g95", "-ffixed-form"], 'compiler_f90' : ["g95"], - 'linker_so' : ["g95","-shared"], + 'linker_so' : ["<F90>","-shared"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py index 64be7fbfe..1a69aba17 100644 --- a/numpy/distutils/fcompiler/gnu.py +++ b/numpy/distutils/fcompiler/gnu.py @@ -5,12 +5,14 @@ import warnings from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler -from numpy.distutils.exec_command import exec_command, find_executable +from numpy.distutils.exec_command import exec_command from numpy.distutils.misc_util import mingw32, msvc_runtime_library -class GnuFCompiler(FCompiler): +compilers = ['GnuFCompiler', 'Gnu95FCompiler'] +class GnuFCompiler(FCompiler): compiler_type = 'gnu' + description = 'GNU Fortran 77 compiler' def gnu_version_match(self, version_string): """Handle the different versions of GNU fortran compilers""" @@ -44,22 +46,23 @@ class GnuFCompiler(FCompiler): # GNU Fortran 0.5.25 20010319 (prerelease) # Redhat: GNU Fortran (GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) 3.2.2 20030222 (Red Hat Linux 3.2.2-5) + possible_executables = ['g77', 'f77'] executables = { - 'version_cmd' : ["g77", "--version"], - 'compiler_f77' : ["g77", "-g", "-Wall","-fno-second-underscore"], + 'version_cmd' : [None, "--version"], + 'compiler_f77' : [None, "-g", "-Wall", "-fno-second-underscore"], 'compiler_f90' : None, # Use --fcompiler=gnu95 for f90 codes 'compiler_fix' : None, - 'linker_so' : ["g77", "-g", "-Wall"], + 'linker_so' : [None, "-g", "-Wall"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"], - 'linker_exe' : ["g77", "-g", "-Wall"] + 'linker_exe' : [None, "-g", "-Wall"] } module_dir_switch = None module_include_switch = None # Cygwin: f771: warning: -fPIC ignored for target (all code is # position independent) - if os.name != 'nt' and sys.platform!='cygwin': + if os.name != 'nt' and sys.platform != 'cygwin': pic_flags = ['-fPIC'] # use -mno-cygwin for g77 when Python is not Cygwin-Python @@ -71,13 +74,6 @@ class GnuFCompiler(FCompiler): suggested_f90_compiler = 'gnu95' - def find_executables(self): - for fc_exe in [find_executable(c) for c in ['g77','f77']]: - if os.path.isfile(fc_exe): - break - for key in ['version_cmd', 'compiler_f77', 'linker_so', 'linker_exe']: - self.executables[key][0] = fc_exe - #def get_linker_so(self): # # win32 linking should be handled by standard linker # # Darwin g77 cannot be used as a linker. @@ -106,7 +102,7 @@ class GnuFCompiler(FCompiler): opt.extend(['-undefined', 'dynamic_lookup', '-bundle']) else: opt.append("-shared") - if sys.platform[:5]=='sunos': + if sys.platform.startswith('sunos'): # SunOS often has dynamically loaded symbols defined in the # static library libg2c.a The linker doesn't like this. To # ignore the problem, use the -mimpure-text flag. It isn't @@ -178,13 +174,10 @@ class GnuFCompiler(FCompiler): def get_flags_arch(self): opt = [] - if sys.platform=='darwin': - if os.name != 'posix': - # this should presumably correspond to Apple - if cpu.is_ppc(): - opt.append('-arch ppc') - elif cpu.is_i386(): - opt.append('-arch i386') + if sys.platform == 'darwin': + # Since Apple doesn't distribute a GNU Fortran compiler, we + # can't add -arch ppc or -arch i386, as only their version + # of the GNU compilers accepts those. for a in '601 602 603 603e 604 604e 620 630 740 7400 7450 750'\ '403 505 801 821 823 860'.split(): if getattr(cpu,'is_ppc%s'%a)(): @@ -276,8 +269,8 @@ class GnuFCompiler(FCompiler): return opt class Gnu95FCompiler(GnuFCompiler): - compiler_type = 'gnu95' + description = 'GNU Fortran 95 compiler' def version_match(self, version_string): v = self.gnu_version_match(version_string) @@ -293,17 +286,18 @@ class Gnu95FCompiler(GnuFCompiler): # GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental) # GNU Fortran (GCC) 4.3.0 20070316 (experimental) + possible_executables = ['gfortran', 'f95'] executables = { - 'version_cmd' : ["gfortran", "--version"], - 'compiler_f77' : ["gfortran", "-Wall", "-ffixed-form", + 'version_cmd' : ["<F90>", "--version"], + 'compiler_f77' : [None, "-Wall", "-ffixed-form", "-fno-second-underscore"], - 'compiler_f90' : ["gfortran", "-Wall", "-fno-second-underscore"], - 'compiler_fix' : ["gfortran", "-Wall", "-ffixed-form", + 'compiler_f90' : [None, "-Wall", "-fno-second-underscore"], + 'compiler_fix' : [None, "-Wall", "-ffixed-form", "-fno-second-underscore"], - 'linker_so' : ["gfortran", "-Wall"], + 'linker_so' : ["<F90>", "-Wall"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"], - 'linker_exe' : ["gfortran", "-Wall"] + 'linker_exe' : [None,"-Wall"] } # use -mno-cygwin flag for g77 when Python is not Cygwin-Python @@ -317,14 +311,6 @@ class Gnu95FCompiler(GnuFCompiler): g2c = 'gfortran' - def find_executables(self): - for fc_exe in [find_executable(c) for c in ['gfortran','f95']]: - if os.path.isfile(fc_exe): - break - for key in ['version_cmd', 'compiler_f77', 'compiler_f90', - 'compiler_fix', 'linker_so', 'linker_exe']: - self.executables[key][0] = fc_exe - def get_libraries(self): opt = GnuFCompiler.get_libraries(self) if sys.platform == 'darwin': @@ -339,3 +325,6 @@ if __name__ == '__main__': compiler = GnuFCompiler() compiler.customize() print compiler.get_version() + compiler = Gnu95FCompiler() + compiler.customize() + print compiler.get_version() diff --git a/numpy/distutils/fcompiler/hpux.py b/numpy/distutils/fcompiler/hpux.py index 8cab2c611..431583600 100644 --- a/numpy/distutils/fcompiler/hpux.py +++ b/numpy/distutils/fcompiler/hpux.py @@ -4,13 +4,16 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler +compilers = ['HPUXFCompiler'] + class HPUXFCompiler(FCompiler): compiler_type = 'hpux' + description = 'HP Fortran 90 Compiler' version_pattern = r'HP F90 (?P<version>[^\s*,]*)' executables = { - 'version_cmd' : ["f90", "+version"], + 'version_cmd' : ["<F90>", "+version"], 'compiler_f77' : ["f90"], 'compiler_fix' : ["f90"], 'compiler_f90' : ["f90"], diff --git a/numpy/distutils/fcompiler/ibm.py b/numpy/distutils/fcompiler/ibm.py index e4e2cec32..a06618668 100644 --- a/numpy/distutils/fcompiler/ibm.py +++ b/numpy/distutils/fcompiler/ibm.py @@ -7,13 +7,16 @@ from numpy.distutils.exec_command import exec_command, find_executable from distutils import log from distutils.sysconfig import get_python_lib -class IbmFCompiler(FCompiler): +compilers = ['IBMFCompiler'] +class IBMFCompiler(FCompiler): compiler_type = 'ibm' + description = 'IBM XL Fortran Compiler' version_pattern = r'(xlf\(1\)\s*|)IBM XL Fortran ((Advanced Edition |)Version |Enterprise Edition V)(?P<version>[^\s*]*)' #IBM XL Fortran Enterprise Edition V10.1 for AIX \nVersion: 10.01.0000.0004 + executables = { - 'version_cmd' : ["xlf","-qversion"], + 'version_cmd' : ["<F77>", "-qversion"], 'compiler_f77' : ["xlf"], 'compiler_fix' : ["xlf90", "-qfixed"], 'compiler_f90' : ["xlf90"], diff --git a/numpy/distutils/fcompiler/intel.py b/numpy/distutils/fcompiler/intel.py index f5e57dda2..6256dd953 100644 --- a/numpy/distutils/fcompiler/intel.py +++ b/numpy/distutils/fcompiler/intel.py @@ -9,7 +9,10 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.ccompiler import simple_version_match from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file -from numpy.distutils.exec_command import find_executable + +compilers = ['IntelFCompiler', 'IntelVisualFCompiler', + 'IntelItaniumFCompiler', 'IntelItaniumVisualFCompiler', + 'IntelEM64TFCompiler'] def intel_version_match(type): # Match against the important stuff in the version string @@ -18,19 +21,18 @@ def intel_version_match(type): class IntelFCompiler(FCompiler): compiler_type = 'intel' + description = 'Intel Fortran Compiler for 32-bit apps' version_match = intel_version_match('32-bit') - for fc_exe in map(find_executable,['ifort','ifc']): - if os.path.isfile(fc_exe): - break + possible_executables = ['ifort', 'ifc'] executables = { - 'version_cmd' : [fc_exe, "-FI -V -c %(fname)s.f -o %(fname)s.o" \ + 'version_cmd' : ["<F77>", "-FI -V -c %(fname)s.f -o %(fname)s.o" \ % {'fname':dummy_fortran_file()}], - 'compiler_f77' : [fc_exe,"-72","-w90","-w95"], - 'compiler_fix' : [fc_exe,"-FI"], - 'compiler_f90' : [fc_exe], - 'linker_so' : [fc_exe,"-shared"], + 'compiler_f77' : [None,"-72","-w90","-w95"], + 'compiler_f90' : [None], + 'compiler_fix' : [None,"-FI"], + 'linker_so' : ["<F90>","-shared"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } @@ -80,6 +82,7 @@ class IntelFCompiler(FCompiler): class IntelItaniumFCompiler(IntelFCompiler): compiler_type = 'intele' + description = 'Intel Fortran Compiler for Itanium apps' version_match = intel_version_match('Itanium') @@ -88,37 +91,34 @@ class IntelItaniumFCompiler(IntelFCompiler): #Copyright (C) 1985-2006 Intel Corporation. All rights reserved. #30 DAY EVALUATION LICENSE - for fc_exe in map(find_executable,['ifort','efort','efc']): - if os.path.isfile(fc_exe): - break + possible_executables = ['ifort', 'efort', 'efc'] executables = { - 'version_cmd' : [fc_exe, "-FI -V -c %(fname)s.f -o %(fname)s.o" \ + 'version_cmd' : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \ % {'fname':dummy_fortran_file()}], - 'compiler_f77' : [fc_exe,"-FI","-w90","-w95"], - 'compiler_fix' : [fc_exe,"-FI"], - 'compiler_f90' : [fc_exe], - 'linker_so' : [fc_exe,"-shared"], + 'compiler_f77' : [None,"-FI","-w90","-w95"], + 'compiler_fix' : [None,"-FI"], + 'compiler_f90' : [None], + 'linker_so' : ['<F90>', "-shared"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } class IntelEM64TFCompiler(IntelFCompiler): compiler_type = 'intelem' + description = 'Intel Fortran Compiler for EM64T-based apps' version_match = intel_version_match('EM64T-based') - for fc_exe in map(find_executable,['ifort','efort','efc']): - if os.path.isfile(fc_exe): - break + possible_executables = ['ifort', 'efort', 'efc'] executables = { - 'version_cmd' : [fc_exe, "-FI -V -c %(fname)s.f -o %(fname)s.o" \ + 'version_cmd' : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \ % {'fname':dummy_fortran_file()}], - 'compiler_f77' : [fc_exe,"-FI","-w90","-w95"], - 'compiler_fix' : [fc_exe,"-FI"], - 'compiler_f90' : [fc_exe], - 'linker_so' : [fc_exe,"-shared"], + 'compiler_f77' : [None, "-FI", "-w90", "-w95"], + 'compiler_fix' : [None, "-FI"], + 'compiler_f90' : [None], + 'linker_so' : ['<F90>', "-shared"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } @@ -133,20 +133,20 @@ class IntelEM64TFCompiler(IntelFCompiler): # and the Visual compilers? class IntelVisualFCompiler(FCompiler): - compiler_type = 'intelv' + description = 'Intel Visual Fortran Compiler for 32-bit apps' version_match = intel_version_match('32-bit') ar_exe = 'lib.exe' - fc_exe = 'ifl' + possible_executables = ['ifl'] executables = { - 'version_cmd' : [fc_exe, "-FI -V -c %(fname)s.f -o %(fname)s.o" \ + 'version_cmd' : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \ % {'fname':dummy_fortran_file()}], - 'compiler_f77' : [fc_exe,"-FI","-w90","-w95"], - 'compiler_fix' : [fc_exe,"-FI","-4L72","-w"], - 'compiler_f90' : [fc_exe], - 'linker_so' : [fc_exe,"-shared"], + 'compiler_f77' : [None,"-FI","-w90","-w95"], + 'compiler_fix' : [None,"-FI","-4L72","-w"], + 'compiler_f90' : [None], + 'linker_so' : ['<F90>', "-shared"], 'archiver' : [ar_exe, "/verbose", "/OUT:"], 'ranlib' : None } @@ -185,20 +185,21 @@ class IntelVisualFCompiler(FCompiler): return opt class IntelItaniumVisualFCompiler(IntelVisualFCompiler): - compiler_type = 'intelev' + description = 'Intel Visual Fortran Compiler for Itanium apps' + version_match = intel_version_match('Itanium') - fc_exe = 'efl' # XXX this is a wild guess + possible_executables = ['efl'] # XXX this is a wild guess ar_exe = IntelVisualFCompiler.ar_exe executables = { - 'version_cmd' : [fc_exe, "-FI -V -c %(fname)s.f -o %(fname)s.o" \ + 'version_cmd' : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \ % {'fname':dummy_fortran_file()}], - 'compiler_f77' : [fc_exe,"-FI","-w90","-w95"], - 'compiler_fix' : [fc_exe,"-FI","-4L72","-w"], - 'compiler_f90' : [fc_exe], - 'linker_so' : [fc_exe,"-shared"], + 'compiler_f77' : [None,"-FI","-w90","-w95"], + 'compiler_fix' : [None,"-FI","-4L72","-w"], + 'compiler_f90' : [None], + 'linker_so' : ['<F90>',"-shared"], 'archiver' : [ar_exe, "/verbose", "/OUT:"], 'ranlib' : None } diff --git a/numpy/distutils/fcompiler/lahey.py b/numpy/distutils/fcompiler/lahey.py index eaa577b62..2fef4a212 100644 --- a/numpy/distutils/fcompiler/lahey.py +++ b/numpy/distutils/fcompiler/lahey.py @@ -4,13 +4,16 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler +compilers = ['LaheyFCompiler'] + class LaheyFCompiler(FCompiler): compiler_type = 'lahey' + description = 'Lahey/Fujitsu Fortran 95 Compiler' version_pattern = r'Lahey/Fujitsu Fortran 95 Compiler Release (?P<version>[^\s*]*)' executables = { - 'version_cmd' : ["lf95", "--version"], + 'version_cmd' : ["<F90>", "--version"], 'compiler_f77' : ["lf95", "--fix"], 'compiler_fix' : ["lf95", "--fix"], 'compiler_f90' : ["lf95"], diff --git a/numpy/distutils/fcompiler/mips.py b/numpy/distutils/fcompiler/mips.py index 915cbead9..4079c6e59 100644 --- a/numpy/distutils/fcompiler/mips.py +++ b/numpy/distutils/fcompiler/mips.py @@ -4,13 +4,16 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler -class MipsFCompiler(FCompiler): +compilers = ['MIPSFCompiler'] + +class MIPSFCompiler(FCompiler): compiler_type = 'mips' + description = 'MIPSpro Fortran Compiler' version_pattern = r'MIPSpro Compilers: Version (?P<version>[^\s*,]*)' executables = { - 'version_cmd' : ["f90", "-version"], + 'version_cmd' : ["<F90>", "-version"], 'compiler_f77' : ["f77", "-f77"], 'compiler_fix' : ["f90", "-fixedform"], 'compiler_f90' : ["f90"], diff --git a/numpy/distutils/fcompiler/nag.py b/numpy/distutils/fcompiler/nag.py index 79413dfc1..328e4074f 100644 --- a/numpy/distutils/fcompiler/nag.py +++ b/numpy/distutils/fcompiler/nag.py @@ -4,17 +4,20 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler +compilers = ['NAGFCompiler'] + class NAGFCompiler(FCompiler): compiler_type = 'nag' + description = 'NAGWare Fortran 95 Compiler' version_pattern = r'NAGWare Fortran 95 compiler Release (?P<version>[^\s]*)' executables = { - 'version_cmd' : ["f95", "-V"], + 'version_cmd' : ["<F90>", "-V"], 'compiler_f77' : ["f95", "-fixed"], 'compiler_fix' : ["f95", "-fixed"], 'compiler_f90' : ["f95"], - 'linker_so' : ["f95"], + 'linker_so' : ["<F90>"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } diff --git a/numpy/distutils/fcompiler/none.py b/numpy/distutils/fcompiler/none.py index c38b9f1ac..e80613883 100644 --- a/numpy/distutils/fcompiler/none.py +++ b/numpy/distutils/fcompiler/none.py @@ -1,19 +1,26 @@ from numpy.distutils.fcompiler import FCompiler +compilers = ['NoneFCompiler'] + class NoneFCompiler(FCompiler): compiler_type = 'none' + description = 'Fake Fortran compiler' - executables = {'compiler_f77':['/path/to/nowhere/none'], - 'compiler_f90':['/path/to/nowhere/none'], - 'compiler_fix':['/path/to/nowhere/none'], - 'linker_so':['/path/to/nowhere/none'], - 'archiver':['/path/to/nowhere/none'], - 'ranlib':['/path/to/nowhere/none'], - 'version_cmd':['/path/to/nowhere/none'], + executables = {'compiler_f77' : None, + 'compiler_f90' : None, + 'compiler_fix' : None, + 'linker_so' : None, + 'linker_exe' : None, + 'archiver' : None, + 'ranlib' : None, + 'version_cmd' : None, } + def find_executables(self): + pass + if __name__ == '__main__': from distutils import log diff --git a/numpy/distutils/fcompiler/pg.py b/numpy/distutils/fcompiler/pg.py index 94aefa244..9152bab15 100644 --- a/numpy/distutils/fcompiler/pg.py +++ b/numpy/distutils/fcompiler/pg.py @@ -7,13 +7,16 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler import FCompiler +compilers = ['PGroupFCompiler'] + class PGroupFCompiler(FCompiler): compiler_type = 'pg' + description = 'Portland Group Fortran Compiler' version_pattern = r'\s*pg(f77|f90|hpf) (?P<version>[\d.-]+).*' executables = { - 'version_cmd' : ["pgf77", "-V 2>/dev/null"], + 'version_cmd' : ["<F77>", "-V 2>/dev/null"], 'compiler_f77' : ["pgf77"], 'compiler_fix' : ["pgf90", "-Mfixed"], 'compiler_f90' : ["pgf90"], diff --git a/numpy/distutils/fcompiler/sun.py b/numpy/distutils/fcompiler/sun.py index a0eaa3da0..0ff051453 100644 --- a/numpy/distutils/fcompiler/sun.py +++ b/numpy/distutils/fcompiler/sun.py @@ -5,20 +5,23 @@ from numpy.distutils.cpuinfo import cpu from numpy.distutils.ccompiler import simple_version_match from numpy.distutils.fcompiler import FCompiler +compilers = ['SunFCompiler'] + class SunFCompiler(FCompiler): compiler_type = 'sun' + description = 'Sun or Forte Fortran 95 Compiler' # ex: # f90: Sun WorkShop 6 update 2 Fortran 95 6.2 Patch 111690-10 2003/08/28 version_match = simple_version_match( start=r'f9[05]: (Sun|Forte|WorkShop).*Fortran 95') executables = { - 'version_cmd' : ["f90", "-V"], + 'version_cmd' : ["<F90>", "-V"], 'compiler_f77' : ["f90"], 'compiler_fix' : ["f90", "-fixed"], 'compiler_f90' : ["f90"], - 'linker_so' : ["f90","-Bdynamic","-G"], + 'linker_so' : ["<F90>","-Bdynamic","-G"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } diff --git a/numpy/distutils/fcompiler/vast.py b/numpy/distutils/fcompiler/vast.py index 30472d893..f5582c66b 100644 --- a/numpy/distutils/fcompiler/vast.py +++ b/numpy/distutils/fcompiler/vast.py @@ -4,9 +4,12 @@ import sys from numpy.distutils.cpuinfo import cpu from numpy.distutils.fcompiler.gnu import GnuFCompiler +compilers = ['VastFCompiler'] + class VastFCompiler(GnuFCompiler): compiler_type = 'vast' + description = 'Pacific-Sierra Research Fortran 90 Compiler' version_pattern = r'\s*Pacific-Sierra Research vf90 '\ '(Personal|Professional)\s+(?P<version>[^\s]*)' @@ -19,7 +22,7 @@ class VastFCompiler(GnuFCompiler): 'compiler_f77' : ["g77"], 'compiler_fix' : ["f90", "-Wv,-ya"], 'compiler_f90' : ["f90"], - 'linker_so' : ["f90"], + 'linker_so' : ["<F90>"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"] } @@ -31,8 +34,8 @@ class VastFCompiler(GnuFCompiler): def get_version_cmd(self): f90 = self.compiler_f90[0] - d,b = os.path.split(f90) - vf90 = os.path.join(d,'v'+b) + d, b = os.path.split(f90) + vf90 = os.path.join(d, 'v'+b) return vf90 def get_flags_arch(self): diff --git a/numpy/distutils/interactive.py b/numpy/distutils/interactive.py index 46bc6eeca..bc741254d 100644 --- a/numpy/distutils/interactive.py +++ b/numpy/distutils/interactive.py @@ -19,7 +19,7 @@ def show_environ(*args): def show_fortran_compilers(*args): from fcompiler import show_fcompilers - show_fcompilers({}) + show_fcompilers() def show_compilers(*args): from distutils.ccompiler import show_compilers |