diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/distutils/fcompiler/__init__.py | 8 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/gnu.py | 82 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/intel.py | 29 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/vast.py | 3 | ||||
-rw-r--r-- | numpy/distutils/tests/test_fcompiler_gnu.py | 52 |
5 files changed, 140 insertions, 34 deletions
diff --git a/numpy/distutils/fcompiler/__init__.py b/numpy/distutils/fcompiler/__init__.py index c88faf59f..1bc0ab2e7 100644 --- a/numpy/distutils/fcompiler/__init__.py +++ b/numpy/distutils/fcompiler/__init__.py @@ -28,7 +28,7 @@ class FCompiler(CCompiler): Methods that subclasses may redefine: - get_version_cmd(), get_linker_so(), get_version() + find_executables(), get_version_cmd(), get_linker_so(), get_version() get_flags(), get_flags_opt(), get_flags_arch(), get_flags_debug() get_flags_f77(), get_flags_opt_f77(), get_flags_arch_f77(), get_flags_debug_f77(), get_flags_f90(), get_flags_opt_f90(), @@ -113,6 +113,11 @@ class FCompiler(CCompiler): ## They are private to FCompiler class and may return unexpected ## 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 + def get_version_cmd(self): """ Compiler command to print out version information. """ f77 = self.executables['compiler_f77'] @@ -267,6 +272,7 @@ class FCompiler(CCompiler): noarch = conf.get('noarch',[None,noopt])[1] debug = conf.get('debug',[None,0])[1] + self.find_executables() f77 = self.__get_cmd('compiler_f77','F77',(conf,'f77exec')) f90 = self.__get_cmd('compiler_f90','F90',(conf,'f90exec')) diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py index 47fa2b856..b38369c75 100644 --- a/numpy/distutils/fcompiler/gnu.py +++ b/numpy/distutils/fcompiler/gnu.py @@ -4,7 +4,6 @@ import sys import warnings from numpy.distutils.cpuinfo import cpu -from numpy.distutils.ccompiler import simple_version_match from numpy.distutils.fcompiler import FCompiler from numpy.distutils.exec_command import exec_command, find_executable from numpy.distutils.misc_util import mingw32, msvc_runtime_library @@ -12,7 +11,31 @@ from numpy.distutils.misc_util import mingw32, msvc_runtime_library class GnuFCompiler(FCompiler): compiler_type = 'gnu' - version_match = simple_version_match(start=r'GNU Fortran (?!95)') + + def gnu_version_match(self, version_string): + """Handle the different versions of GNU fortran compilers""" + m = re.match(r'GNU Fortran', version_string) + if not m: + return None + m = re.match(r'GNU Fortran\s+95.*?([0-9-.]+)', version_string) + if m: + return ('gfortran', m.group(1)) + m = re.match(r'GNU Fortran.*?([0-9-.]+)', version_string) + if m: + v = m.group(1) + if v.startswith('0') or v.startswith('2') or v.startswith('3'): + # the '0' is for early g77's + return ('g77', v) + else: + # at some point in the 4.x series, the ' 95' was dropped + # from the version string + return ('gfortran', v) + + def version_match(self, version_string): + v = self.gnu_version_match(version_string) + if not v or v[0] != 'g77': + return None + return v[1] # 'g77 --version' results # SunOS: GNU Fortran (GCC 3.2) 3.2 20020814 (release) @@ -21,18 +44,15 @@ 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) - for fc_exe in map(find_executable,['g77','f77']): - if os.path.isfile(fc_exe): - break executables = { - 'version_cmd' : [fc_exe,"--version"], - 'compiler_f77' : [fc_exe, "-g", "-Wall","-fno-second-underscore"], + 'version_cmd' : ["g77", "--version"], + 'compiler_f77' : ["g77", "-g", "-Wall","-fno-second-underscore"], 'compiler_f90' : None, # Use --fcompiler=gnu95 for f90 codes 'compiler_fix' : None, - 'linker_so' : [fc_exe, "-g", "-Wall"], + 'linker_so' : ["g77", "-g", "-Wall"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"], - 'linker_exe' : [fc_exe, "-g", "-Wall"] + 'linker_exe' : ["g77", "-g", "-Wall"] } module_dir_switch = None module_include_switch = None @@ -51,6 +71,13 @@ 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. @@ -218,12 +245,11 @@ class GnuFCompiler(FCompiler): if gnu_ver >= '3.4.4': if cpu.is_PentiumM(): march_opt = '-march=pentium-m' - # Future: # if gnu_ver >= '4.3': # if cpu.is_Core2(): # march_opt = '-march=core2' - + # Note: gcc 3.2 on win32 has breakage with -march specified if '3.1.1' <= gnu_ver <= '3.4' and sys.platform=='win32': march_opt = '' @@ -250,26 +276,32 @@ class GnuFCompiler(FCompiler): class Gnu95FCompiler(GnuFCompiler): compiler_type = 'gnu95' - version_match = simple_version_match(start='GNU Fortran (95|\(GCC\))') + + def version_match(self, version_string): + v = self.gnu_version_match(version_string) + if not v or v[0] != 'gfortran': + return None + return v[1] # 'gfortran --version' results: + # XXX is the below right? # Debian: GNU Fortran 95 (GCC 4.0.3 20051023 (prerelease) (Debian 4.0.2-3)) + # GNU Fortran 95 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) # OS X: GNU Fortran 95 (GCC) 4.1.0 # GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental) # GNU Fortran (GCC) 4.3.0 20070316 (experimental) - for fc_exe in map(find_executable,['gfortran','f95']): - if os.path.isfile(fc_exe): - break executables = { - 'version_cmd' : [fc_exe,"--version"], - 'compiler_f77' : [fc_exe,"-Wall","-ffixed-form","-fno-second-underscore"], - 'compiler_f90' : [fc_exe,"-Wall","-fno-second-underscore"], - 'compiler_fix' : [fc_exe,"-Wall","-ffixed-form","-fno-second-underscore"], - 'linker_so' : [fc_exe,"-Wall"], + 'version_cmd' : ["gfortran", "--version"], + 'compiler_f77' : ["gfortran", "-Wall", "-ffixed-form", + "-fno-second-underscore"], + 'compiler_f90' : ["gfortran", "-Wall", "-fno-second-underscore"], + 'compiler_fix' : ["gfortran", "-Wall", "-ffixed-form", + "-fno-second-underscore"], + 'linker_so' : ["gfortran", "-Wall"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"], - 'linker_exe' : [fc_exe,"-Wall"] + 'linker_exe' : ["gfortran", "-Wall"] } # use -mno-cygwin flag for g77 when Python is not Cygwin-Python @@ -283,6 +315,14 @@ 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': diff --git a/numpy/distutils/fcompiler/intel.py b/numpy/distutils/fcompiler/intel.py index 57e83be9f..b4ae833bf 100644 --- a/numpy/distutils/fcompiler/intel.py +++ b/numpy/distutils/fcompiler/intel.py @@ -1,17 +1,24 @@ +# -*- encoding: iso-8859-1 -*- +# above encoding b/c there's a non-ASCII character in the sample output +# of intele # http://developer.intel.com/software/products/compilers/flin/ import os 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 +def intel_version_match(type): + # Match against the important stuff in the version string + return simple_version_match(start=r'Intel.*?Fortran.*?%s.*?Version' % (type,)) + class IntelFCompiler(FCompiler): compiler_type = 'intel' - version_pattern = r'Intel\(R\) Fortran Compiler for 32-bit '\ - 'applications, Version (?P<version>[^\s*]*)' + version_match = intel_version_match('32-bit') for fc_exe in map(find_executable,['ifort','ifc']): if os.path.isfile(fc_exe): @@ -74,9 +81,8 @@ class IntelFCompiler(FCompiler): class IntelItaniumFCompiler(IntelFCompiler): compiler_type = 'intele' - version_pattern = r'Intel\(R\) Fortran (90 Compiler Itanium\(TM\)|Itanium\(R\)) Compiler'\ - ' for (the Itanium\(TM\)|Itanium\(R\))-based applications(,|)'\ - '\s+Version (?P<version>[^\s*]*)' + + version_match = intel_version_match('Itanium') #Intel(R) Fortran Itanium(R) Compiler for Itanium(R)-based applications #Version 9.1 Build 20060928 Package ID: l_fc_c_9.1.039 @@ -101,8 +107,7 @@ class IntelItaniumFCompiler(IntelFCompiler): class IntelEM64TFCompiler(IntelFCompiler): compiler_type = 'intelem' - version_pattern = r'Intel\(R\) Fortran Compiler for Intel\(R\) EM64T-based '\ - 'applications, Version (?P<version>[^\s*]*)' + version_match = intel_version_match('EM64T-based') for fc_exe in map(find_executable,['ifort','efort','efc']): if os.path.isfile(fc_exe): @@ -125,11 +130,13 @@ class IntelEM64TFCompiler(IntelFCompiler): opt.extend(['-tpp7', '-xW']) return opt +# Is there no difference in the version string between the above compilers +# and the Visual compilers? + class IntelVisualFCompiler(FCompiler): compiler_type = 'intelv' - version_pattern = r'Intel\(R\) Fortran Compiler for 32-bit applications, '\ - 'Version (?P<version>[^\s*]*)' + version_match = intel_version_match('32-bit') ar_exe = 'lib.exe' fc_exe = 'ifl' @@ -181,9 +188,7 @@ class IntelVisualFCompiler(FCompiler): class IntelItaniumVisualFCompiler(IntelVisualFCompiler): compiler_type = 'intelev' - version_pattern = r'Intel\(R\) Fortran (90 Compiler Itanium\(TM\)|Itanium\(R\)) Compiler'\ - ' for (the Itanium\(TM\)|Itanium\(R\))-based applications(,|)'\ - '\s+Version (?P<version>[^\s*]*)' + version_match = intel_version_match('Itanium') fc_exe = 'efl' # XXX this is a wild guess ar_exe = IntelVisualFCompiler.ar_exe diff --git a/numpy/distutils/fcompiler/vast.py b/numpy/distutils/fcompiler/vast.py index cf9d32b27..30472d893 100644 --- a/numpy/distutils/fcompiler/vast.py +++ b/numpy/distutils/fcompiler/vast.py @@ -26,6 +26,9 @@ class VastFCompiler(GnuFCompiler): module_dir_switch = None #XXX Fix me module_include_switch = None #XXX Fix me + def find_executables(self): + pass + def get_version_cmd(self): f90 = self.compiler_f90[0] d,b = os.path.split(f90) diff --git a/numpy/distutils/tests/test_fcompiler_gnu.py b/numpy/distutils/tests/test_fcompiler_gnu.py new file mode 100644 index 000000000..c6ccea054 --- /dev/null +++ b/numpy/distutils/tests/test_fcompiler_gnu.py @@ -0,0 +1,52 @@ +from numpy.testing import * + +set_package_path() +import numpy.distutils.fcompiler +restore_path() + +g77_version_strings = [ + ('GNU Fortran 0.5.25 20010319 (prerelease)', '0.5.25'), + ('GNU Fortran (GCC 3.2) 3.2 20020814 (release)', '3.2'), + ('GNU Fortran (GCC) 3.3.3 20040110 (prerelease) (Debian)', '3.3.3'), + ('GNU Fortran (GCC) 3.3.3 (Debian 20040401)', '3.3.3'), + ('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)', '3.2.2'), +] + +gfortran_version_strings = [ + ('GNU Fortran 95 (GCC 4.0.3 20051023 (prerelease) (Debian 4.0.2-3))', + '4.0.3'), + ('GNU Fortran 95 (GCC) 4.1.0', '4.1.0'), + ('GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental)', '4.2.0'), + ('GNU Fortran (GCC) 4.3.0 20070316 (experimental)', '4.3.0'), +] + +class test_g77_versions(NumpyTestCase): + def test_g77_version(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu') + for vs, version in g77_version_strings: + v = fc.version_match(vs) + assert v == version, (vs, v) + + def test_not_g77(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu') + for vs, _ in gfortran_version_strings: + v = fc.version_match(vs) + assert v is None, (vs, v) + +class test_gortran_versions(NumpyTestCase): + def test_gfortran_version(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95') + for vs, version in gfortran_version_strings: + v = fc.version_match(vs) + assert v == version, (vs, v) + + def test_not_gfortran(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95') + for vs, _ in g77_version_strings: + v = fc.version_match(vs) + assert v is None, (vs, v) + + +if __name__ == '__main__': + NumpyTest.run() |