diff options
-rw-r--r-- | ccompiler.py | 69 | ||||
-rw-r--r-- | command/build_clib.py | 29 | ||||
-rw-r--r-- | command/build_ext.py | 45 | ||||
-rw-r--r-- | command/build_src.py | 7 | ||||
-rw-r--r-- | command/config_compiler.py | 1 | ||||
-rw-r--r-- | cpuinfo.py | 9 | ||||
-rw-r--r-- | fcompiler/__init__.py | 13 | ||||
-rw-r--r-- | fcompiler/gnu.py | 64 | ||||
-rw-r--r-- | fcompiler/ibm.py | 24 | ||||
-rw-r--r-- | fcompiler/intel.py | 33 | ||||
-rw-r--r-- | interactive.py | 8 | ||||
-rw-r--r-- | misc_util.py | 63 | ||||
-rw-r--r-- | system_info.py | 21 | ||||
-rw-r--r-- | tests/test_fcompiler_gnu.py | 52 |
14 files changed, 291 insertions, 147 deletions
diff --git a/ccompiler.py b/ccompiler.py index 621efdfed..ca3da7f24 100644 --- a/ccompiler.py +++ b/ccompiler.py @@ -8,9 +8,9 @@ from distutils import ccompiler from distutils.sysconfig import customize_compiler from distutils.version import LooseVersion -import log -from exec_command import exec_command -from misc_util import cyg2win32, is_sequence, mingw32 +from numpy.distutils import log +from numpy.distutils.exec_command import exec_command +from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32 from distutils.spawn import _nt_quote_args # hack to set compiler optimizing options. Needs to integrated with something. @@ -21,6 +21,10 @@ def _new_init_posix(): distutils.sysconfig._config_vars['OPT'] = '-Wall -g -O0' #distutils.sysconfig._init_posix = _new_init_posix +def replace_method(klass, method_name, func): + m = new.instancemethod(func, None, klass) + setattr(klass, method_name, m) + # Using customized CCompiler.spawn. def CCompiler_spawn(self, cmd, display=None): if display is None: @@ -37,7 +41,8 @@ def CCompiler_spawn(self, cmd, display=None): print o raise DistutilsExecError,\ 'Command "%s" failed with exit status %d' % (cmd, s) -CCompiler.spawn = new.instancemethod(CCompiler_spawn,None,CCompiler) + +replace_method(CCompiler, 'spawn', CCompiler_spawn) def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=''): if output_dir is None: @@ -63,8 +68,7 @@ def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=' obj_names.append(obj_name) return obj_names -CCompiler.object_filenames = new.instancemethod(CCompiler_object_filenames, - None,CCompiler) +replace_method(CCompiler, 'object_filenames', CCompiler_object_filenames) def CCompiler_compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, @@ -114,7 +118,7 @@ def CCompiler_compile(self, sources, output_dir=None, macros=None, # Return *all* object filenames, not just the ones we just built. return objects -CCompiler.compile = new.instancemethod(CCompiler_compile,None,CCompiler) +replace_method(CCompiler, 'compile', CCompiler_compile) def CCompiler_customize_cmd(self, cmd): """ Customize compiler using distutils command. @@ -139,8 +143,7 @@ def CCompiler_customize_cmd(self, cmd): self.set_link_objects(cmd.link_objects) return -CCompiler.customize_cmd = new.instancemethod(\ - CCompiler_customize_cmd,None,CCompiler) +replace_method(CCompiler, 'customize_cmd', CCompiler_customize_cmd) def _compiler_to_string(compiler): props = [] @@ -179,9 +182,7 @@ def CCompiler_show_customization(self): print _compiler_to_string(self) print '*'*80 -CCompiler.show_customization = new.instancemethod(\ - CCompiler_show_customization,None,CCompiler) - +replace_method(CCompiler, 'show_customization', CCompiler_show_customization) def CCompiler_customize(self, dist, need_cxx=0): # See FCompiler.customize for suggested usage. @@ -192,7 +193,7 @@ def CCompiler_customize(self, dist, need_cxx=0): # not valid for C++ code, only for C. Remove it if it's there to # avoid a spurious warning on every compilation. All the default # options used by distutils can be extracted with: - + # from distutils import sysconfig # sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS', # 'CCSHARED', 'LDSHARED', 'SO') @@ -200,10 +201,10 @@ def CCompiler_customize(self, dist, need_cxx=0): self.compiler_so.remove('-Wstrict-prototypes') except (AttributeError, ValueError): pass - + if hasattr(self,'compiler') and self.compiler[0].find('cc')>=0: if not self.compiler_cxx: - if self.compiler[0][:3] == 'gcc': + if self.compiler[0].startswith('gcc'): a, b = 'gcc', 'g++' else: a, b = 'cc', 'c++' @@ -215,10 +216,23 @@ def CCompiler_customize(self, dist, need_cxx=0): log.warn('Missing compiler_cxx fix for '+self.__class__.__name__) return -CCompiler.customize = new.instancemethod(\ - CCompiler_customize,None,CCompiler) +replace_method(CCompiler, 'customize', CCompiler_customize) -def simple_version_match(pat=r'[-.\d]+', ignore=None, start=''): +def simple_version_match(pat=r'[-.\d]+', ignore='', start=''): + """ + Simple matching of version numbers, for use in CCompiler and FCompiler + classes. + + :Parameters: + pat : regex matching version numbers. + ignore : false or regex matching expressions to skip over. + start : false or regex matching the start of where to start looking + for version numbers. + + :Returns: + A function that is appropiate to use as the .version_match + attribute of a CCompiler class. + """ def matcher(self, version_string): pos = 0 if start: @@ -271,15 +285,26 @@ def CCompiler_get_version(self, force=0, ok_status=[0]): self.version = version return version -CCompiler.get_version = new.instancemethod(\ - CCompiler_get_version,None,CCompiler) +replace_method(CCompiler, 'get_version', CCompiler_get_version) + +def CCompiler_cxx_compiler(self): + cxx = copy(self) + cxx.compiler_so = [cxx.compiler_cxx[0]] + cxx.compiler_so[1:] + if sys.platform.startswith('aix') and 'ld_so_aix' in cxx.linker_so[0]: + # AIX needs the ld_so_aix script included with Python + cxx.linker_so = [cxx.linker_so[0]] + cxx.compiler_cxx[0] \ + + cxx.linker_so[2:] + else: + cxx.linker_so = [cxx.compiler_cxx[0]] + cxx.linker_so[1:] + return cxx + +replace_method(CCompiler, 'cxx_compiler', CCompiler_cxx_compiler) compiler_class['intel'] = ('intelccompiler','IntelCCompiler', "Intel C Compiler for 32-bit applications") compiler_class['intele'] = ('intelccompiler','IntelItaniumCCompiler', "Intel C Itanium Compiler for Itanium-based applications") -ccompiler._default_compilers = ccompiler._default_compilers \ - + (('linux.*','intel'),('linux.*','intele')) +ccompiler._default_compilers += (('linux.*','intel'),('linux.*','intele')) if sys.platform == 'win32': compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler', diff --git a/command/build_clib.py b/command/build_clib.py index ee7d8b5f4..e254b54f4 100644 --- a/command/build_clib.py +++ b/command/build_clib.py @@ -129,10 +129,13 @@ class build_clib(old_build_clib): config_fc = build_info.get('config_fc',{}) if fcompiler is not None and config_fc: - log.info('using setup script specified config_fc '\ + log.info('using additional config_fc from setup script '\ 'for fortran compiler: %s' \ - % (config_fc)) - fcompiler.customize(config_fc) + % (config_fc,)) + dist = self.distribution + base_config_fc = dist.get_option_dict('config_fc').copy() + base_config_fc.update(config_fc) + fcompiler.customize(base_config_fc) macros = build_info.get('macros') include_dirs = build_info.get('include_dirs') @@ -163,19 +166,15 @@ class build_clib(old_build_clib): if cxx_sources: log.info("compiling C++ sources") - old_compiler = self.compiler.compiler_so[0] - self.compiler.compiler_so[0] = self.compiler.compiler_cxx[0] - - cxx_objects = compiler.compile(cxx_sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=include_dirs, - debug=self.debug, - extra_postargs=extra_postargs) + cxx_compiler = compiler.cxx_compiler() + cxx_objects = cxx_compiler.compile(cxx_sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs) objects.extend(cxx_objects) - self.compiler.compiler_so[0] = old_compiler - if f_sources: log.info("compiling Fortran sources") f_objects = fcompiler.compile(f_sources, @@ -191,7 +190,7 @@ class build_clib(old_build_clib): debug=self.debug) clib_libraries = build_info.get('libraries',[]) - for lname,binfo in libraries: + for lname, binfo in libraries: if lname in clib_libraries: clib_libraries.extend(binfo[1].get('libraries',[])) if clib_libraries: diff --git a/command/build_ext.py b/command/build_ext.py index bdcccdbda..729f383c6 100644 --- a/command/build_ext.py +++ b/command/build_ext.py @@ -137,7 +137,7 @@ class build_ext (old_build_ext): macros = [] - if check_for_f90_modules: + if fmodule_sources: module_build_dir = os.path.join( self.build_temp,os.path.dirname( self.get_ext_filename(fullname))) @@ -159,8 +159,7 @@ class build_ext (old_build_ext): extra_postargs=extra_postargs, depends=ext.depends) - if check_for_f90_modules \ - and fcompiler.module_dir_switch is None: + if fmodule_sources and fcompiler.module_dir_switch is None: for f in glob('*.mod'): if f in existing_modules: continue @@ -258,17 +257,15 @@ class build_ext (old_build_ext): if cxx_sources: log.info("compiling C++ sources") - old_compiler = self.compiler.compiler_so[0] - self.compiler.compiler_so[0] = self.compiler.compiler_cxx[0] + cxx_compiler = self.compiler.cxx_compiler() - c_objects += self.compiler.compile(cxx_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) - self.compiler.compiler_so[0] = old_compiler fcompiler, f_objects = self.get_fortran_objects(ext, f_sources, @@ -281,10 +278,7 @@ class build_ext (old_build_ext): objects.extend(ext.extra_objects) extra_args = ext.extra_link_args or [] - try: - old_linker_so_0 = self.compiler.linker_so[0] - except: - pass + linker = self.compiler.link_shared_object use_fortran_linker = getattr(ext,'language','c') in ['f77','f90'] c_libraries = [] @@ -318,37 +312,30 @@ class build_ext (old_build_ext): if cxx_sources: # XXX: Which linker should be used, Fortran or C++? log.warn('mixing Fortran and C++ is untested') - link = fcompiler.link_shared_object + linker = fcompiler.link_shared_object language = ext.language or fcompiler.detect_language(f_sources) else: - link = self.compiler.link_shared_object + linker = self.compiler.link_shared_object if sys.version[:3]>='2.3': language = ext.language or self.compiler.detect_language(sources) else: language = ext.language if cxx_sources: - self.compiler.linker_so[0] = self.compiler.compiler_cxx[0] + linker = self.compiler.cxx_compiler().link_shared_object if sys.version[:3]>='2.3': kws = {'target_lang':language} else: kws = {} - link(objects, ext_filename, - libraries=self.get_libraries(ext) + c_libraries + clib_libraries, - library_dirs=ext.library_dirs + c_library_dirs + clib_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) - - try: - self.compiler.linker_so[0] = old_linker_so_0 - except: - pass - - return + linker(objects, ext_filename, + libraries=self.get_libraries(ext) + c_libraries + clib_libraries, + library_dirs=ext.library_dirs+c_library_dirs+clib_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) def _libs_with_msvc_and_fortran(self, c_libraries, c_library_dirs): # Always use system linker when using MSVC compiler. diff --git a/command/build_src.py b/command/build_src.py index 12d19402e..d697bdf16 100644 --- a/command/build_src.py +++ b/command/build_src.py @@ -15,7 +15,9 @@ try: except ImportError: have_pyrex = False -import numpy.f2py +# this import can't be done here, as it uses numpy stuff only available +# after it's installed +#import numpy.f2py from numpy.distutils import log from numpy.distutils.misc_util import fortran_ext_match, \ appendpath, is_string, is_sequence @@ -438,6 +440,7 @@ class build_src(build_ext.build_ext): if (self.force or newer_group(depends, target_file,'newer')) \ and not skip_f2py: log.info("f2py: %s" % (source)) + import numpy.f2py numpy.f2py.run_main(f2py_options + ['--build-dir',target_dir,source]) else: @@ -456,6 +459,7 @@ class build_src(build_ext.build_ext): and not skip_f2py: log.info("f2py:> %s" % (target_file)) self.mkpath(target_dir) + import numpy.f2py numpy.f2py.run_main(f2py_options + ['--lower', '--build-dir',target_dir]+\ ['-m',ext_name]+f_sources) @@ -476,6 +480,7 @@ class build_src(build_ext.build_ext): extension.include_dirs.append(self.build_src) if not skip_f2py: + import numpy.f2py d = os.path.dirname(numpy.f2py.__file__) source_c = os.path.join(d,'src','fortranobject.c') source_h = os.path.join(d,'src','fortranobject.h') diff --git a/command/config_compiler.py b/command/config_compiler.py index 817a07a17..611527dea 100644 --- a/command/config_compiler.py +++ b/command/config_compiler.py @@ -1,4 +1,3 @@ - import sys import copy import distutils.core diff --git a/cpuinfo.py b/cpuinfo.py index 692876f95..1a182eace 100644 --- a/cpuinfo.py +++ b/cpuinfo.py @@ -5,7 +5,7 @@ cpuinfo Copyright 2002 Pearu Peterson all rights reserved, Pearu Peterson <pearu@cens.ioc.ee> Permission to use, modify, and distribute this software is given under the -terms of the SciPy (BSD style) license. See LICENSE.txt that came with +terms of the NumPy (BSD style) license. See LICENSE.txt that came with this distribution for specifics. Note: This should be merged into proc at some point. Perhaps proc should @@ -185,7 +185,12 @@ class linux_cpuinfo(cpuinfo_base): return self.is_PentiumIV() and self.has_sse3() def _is_Nocona(self): - return self.is_PentiumIV() and self.is_64bit() + return self.is_64bit() and self.is_PentiumIV() + + def _is_Core2(self): + return self.is_64bit() and self.is_Intel() and \ + re.match(r'.*?Core\(TM\)2\b', \ + self.info[0]['model name']) is not None def _is_Itanium(self): return re.match(r'.*?Itanium\b', diff --git a/fcompiler/__init__.py b/fcompiler/__init__.py index 7d22219d9..0b2c38a95 100644 --- a/fcompiler/__init__.py +++ b/fcompiler/__init__.py @@ -16,7 +16,7 @@ try: except NameError: from sets import Set as set -from distutils.sysconfig import get_config_var +from distutils.sysconfig import get_config_var, get_python_lib from distutils.fancy_getopt import FancyGetopt from distutils.errors import DistutilsModuleError,DistutilsArgError,\ DistutilsExecError,CompileError,LinkError,DistutilsPlatformError @@ -40,7 +40,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(), @@ -438,7 +438,14 @@ class FCompiler(CCompiler): linker_so = self.command_vars.linker_so if linker_so: linker_so_flags = to_list(self.flag_vars.linker_so) - self.set_executables(linker_so=[linker_so]+linker_so_flags) + 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') + python_exp = os.path.join(python_lib, 'config', 'python.exp') + linker_so = [ld_so_aix, linker_so, '-bI:'+python_exp] + else: + linker_so = [linker_so] + self.set_executables(linker_so=linker_so+linker_so_flags) linker_exe = self.command_vars.linker_exe if linker_exe: diff --git a/fcompiler/gnu.py b/fcompiler/gnu.py index 2475f61f7..c1353379c 100644 --- a/fcompiler/gnu.py +++ b/fcompiler/gnu.py @@ -1,11 +1,9 @@ - import re import os 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 from numpy.distutils.misc_util import mingw32, msvc_runtime_library @@ -13,10 +11,33 @@ from numpy.distutils.misc_util import mingw32, msvc_runtime_library compilers = ['GnuFCompiler', 'Gnu95FCompiler'] class GnuFCompiler(FCompiler): - compiler_type = 'gnu' description = 'GNU Fortran 77 compiler' - 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) @@ -62,13 +83,19 @@ class GnuFCompiler(FCompiler): def get_flags_linker_so(self): opt = self.linker_so[1:] - if sys.platform == 'darwin': - target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', '10.3') + if sys.platform=='darwin': + # MACOSX_DEPLOYMENT_TARGET must be at least 10.3. This is + # a reasonable default value even when building on 10.4 when using + # the official Python distribution and those derived from it (when + # not broken). + target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None) + if target is None or target == '': + target = '10.3' major, minor = target.split('.') if int(minor) < 3: minor = '3' warnings.warn('Environment variable ' - 'MACOSX_DEPLOYMENT_TARGET reset to 10.3') + 'MACOSX_DEPLOYMENT_TARGET reset to %s.%s' % (major, minor)) os.environ['MACOSX_DEPLOYMENT_TARGET'] = '%s.%s' % (major, minor) @@ -189,6 +216,8 @@ class GnuFCompiler(FCompiler): # there's also: athlon-tbird, athlon-4, athlon-xp elif cpu.is_Nocona(): march_opt = '-march=nocona' + elif cpu.is_Core2(): + march_opt = '-march=nocona' elif cpu.is_Prescott(): march_opt = '-march=prescott' elif cpu.is_PentiumIV(): @@ -209,6 +238,10 @@ 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': @@ -234,22 +267,31 @@ class GnuFCompiler(FCompiler): return opt class Gnu95FCompiler(GnuFCompiler): - compiler_type = 'gnu95' description = 'GNU Fortran 95 compiler' - version_match = simple_version_match(start='GNU Fortran 95') + + 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) possible_executables = ['gfortran', 'f95'] executables = { 'version_cmd' : ["<F90>", "--version"], - 'compiler_f77' : [None, "-Wall", "-ffixed-form", "-fno-second-underscore"], + 'compiler_f77' : [None, "-Wall", "-ffixed-form", + "-fno-second-underscore"], 'compiler_f90' : [None, "-Wall", "-fno-second-underscore"], - 'compiler_fix' : [None, "-Wall", "-ffixed-form", "-fno-second-underscore"], + 'compiler_fix' : [None, "-Wall", "-ffixed-form", + "-fno-second-underscore"], 'linker_so' : ["<F90>", "-Wall"], 'archiver' : ["ar", "-cr"], 'ranlib' : ["ranlib"], diff --git a/fcompiler/ibm.py b/fcompiler/ibm.py index 25ec58128..fd6a8e84a 100644 --- a/fcompiler/ibm.py +++ b/fcompiler/ibm.py @@ -3,7 +3,9 @@ import re import sys from numpy.distutils.fcompiler import FCompiler +from numpy.distutils.exec_command import exec_command, find_executable from distutils import log +from distutils.sysconfig import get_python_lib compilers = ['IBMFCompiler'] @@ -11,10 +13,10 @@ class IBMFCompiler(FCompiler): compiler_type = 'ibm' description = 'IBM XL Fortran Compiler' - version_pattern = r'xlf\(1\)\s*IBM XL Fortran (Advanced Edition |)Version (?P<version>[^\s*]*)' - + 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' : ["<F77>"], + 'version_cmd' : ["<F77>", "-qversion"], 'compiler_f77' : ["xlf"], 'compiler_fix' : ["xlf90", "-qfixed"], 'compiler_f90' : ["xlf90"], @@ -25,8 +27,19 @@ class IBMFCompiler(FCompiler): def get_version(self,*args,**kwds): version = FCompiler.get_version(self,*args,**kwds) + + if version is None and sys.platform.startswith('aix'): + # use lslpp to find out xlf version + lslpp = find_executable('lslpp') + xlf = find_executable('xlf') + if os.path.exists(xlf) and os.path.exists(lslpp): + s,o = exec_command(lslpp + ' -Lc xlfcmp') + m = re.search('xlfcmp:(?P<version>\d+([.]\d+)+)', o) + if m: version = m.group('version') + xlf_dir = '/etc/opt/ibmcmp/xlf' if version is None and os.path.isdir(xlf_dir): + # linux: # If the output of xlf does not contain version info # (that's the case with xlf 8.1, for instance) then # let's try another method: @@ -54,7 +67,10 @@ class IBMFCompiler(FCompiler): version = self.get_version(ok_status=[0,40]) if version is not None: import tempfile - xlf_cfg = '/etc/opt/ibmcmp/xlf/%s/xlf.cfg' % version + if sys.platform.startswith('aix'): + xlf_cfg = '/etc/xlf.cfg' + else: + xlf_cfg = '/etc/opt/ibmcmp/xlf/%s/xlf.cfg' % version new_cfg = tempfile.mktemp()+'_xlf.cfg' log.info('Creating '+new_cfg) fi = open(xlf_cfg,'r') diff --git a/fcompiler/intel.py b/fcompiler/intel.py index bc7a15bb6..2c34d69ed 100644 --- a/fcompiler/intel.py +++ b/fcompiler/intel.py @@ -1,21 +1,28 @@ +# -*- 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 compilers = ['IntelFCompiler', 'IntelVisualFCompiler', 'IntelItaniumFCompiler', 'IntelItaniumVisualFCompiler', 'IntelEM64TFCompiler'] +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' description = 'Intel Fortran Compiler for 32-bit apps' - version_pattern = r'Intel\(R\) Fortran Compiler for 32-bit '\ - 'applications, Version (?P<version>[^\s*]*)' + version_match = intel_version_match('32-bit') possible_executables = ['ifort', 'ifc'] @@ -78,9 +85,8 @@ class IntelFCompiler(FCompiler): class IntelItaniumFCompiler(IntelFCompiler): compiler_type = 'intele' description = 'Intel Fortran Compiler for Itanium apps' - 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 @@ -104,8 +110,7 @@ class IntelEM64TFCompiler(IntelFCompiler): compiler_type = 'intelem' description = 'Intel Fortran Compiler for EM64T-based apps' - version_pattern = r'Intel\(R\) Fortran Compiler for Intel\(R\) EM64T-based '\ - 'applications, Version (?P<version>[^\s*]*)' + version_match = intel_version_match('EM64T-based') possible_executables = ['ifort', 'efort', 'efc'] @@ -126,12 +131,14 @@ class IntelEM64TFCompiler(IntelFCompiler): opt.extend(['-tpp7', '-xW']) return opt -class IntelVisualFCompiler(FCompiler): +# Is there no difference in the version string between the above compilers +# and the Visual compilers? +class IntelVisualFCompiler(FCompiler): compiler_type = 'intelv' description = 'Intel Visual Fortran Compiler for 32-bit apps' - 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,12 +188,10 @@ class IntelVisualFCompiler(FCompiler): return opt class IntelItaniumVisualFCompiler(IntelVisualFCompiler): - compiler_type = 'intelev' description = 'Intel Visual Fortran Compiler for Itanium apps' - 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/interactive.py b/interactive.py index 69587dbe1..bc741254d 100644 --- a/interactive.py +++ b/interactive.py @@ -1,4 +1,3 @@ - import os import sys from pprint import pformat @@ -12,7 +11,7 @@ def show_information(*args): for a in ['name']: print 'os.%s = %s' % (a,pformat(getattr(os,a))) if hasattr(os,'uname'): - print 'system,node,release,version,machine = ',os.uname() + print 'system,node,release,version,machine = ',os.uname() def show_environ(*args): for k,i in os.environ.items(): @@ -29,7 +28,7 @@ def show_compilers(*args): def show_tasks(argv,ccompiler,fcompiler): print """\ -Tasks: +Tasks: i - Show python/platform/machine information ie - Show environment information c - Show C compilers information @@ -65,7 +64,7 @@ def edit_argv(*args): if s: argv[1:] = splitcmdline(s) return - + def interactive_sys_argv(argv): print '='*72 print 'Starting interactive session' @@ -186,4 +185,3 @@ def interactive_sys_argv(argv): print '-'*72 return argv - diff --git a/misc_util.py b/misc_util.py index f840264c1..b843f675e 100644 --- a/misc_util.py +++ b/misc_util.py @@ -962,9 +962,9 @@ class Configuration(object): return def add_numarray_include_dirs(self): - import numpy.numarray.util as nnu - self.add_include_dirs(*nnu.get_numarray_include_dirs()) - + import numpy.numarray.util as nnu + self.add_include_dirs(*nnu.get_numarray_include_dirs()) + def add_headers(self,*files): """ Add installable headers to configuration. Argument(s) can be either @@ -1294,7 +1294,7 @@ class Configuration(object): return version - def make_svn_version_py(self): + def make_svn_version_py(self, delete=True): """ Generate package __svn_version__.py file from SVN revision number, it will be removed after python exits but will be available when sdist, etc commands are executed. @@ -1302,29 +1302,31 @@ class Configuration(object): If __svn_version__.py existed before, nothing is done. """ target = njoin(self.local_path,'__svn_version__.py') - if os.path.isfile(target): + revision = self._get_svn_revision(self.local_path) + if os.path.isfile(target) or revision is None: return - def generate_svn_version_py(): - if not os.path.isfile(target): - revision = self._get_svn_revision(self.local_path) - assert revision is not None,'hmm, why I am not inside SVN tree???' - version = str(revision) - self.info('Creating %s (version=%r)' % (target,version)) - f = open(target,'w') - f.write('version = %r\n' % (version)) - f.close() - - import atexit - def rm_file(f=target,p=self.info): - try: os.remove(f); p('removed '+f) - except OSError: pass - try: os.remove(f+'c'); p('removed '+f+'c') - except OSError: pass - atexit.register(rm_file) - - return target - - self.add_data_files(('', generate_svn_version_py())) + else: + def generate_svn_version_py(): + if not os.path.isfile(target): + version = str(revision) + self.info('Creating %s (version=%r)' % (target,version)) + f = open(target,'w') + f.write('version = %r\n' % (version)) + f.close() + + import atexit + def rm_file(f=target,p=self.info): + if delete: + try: os.remove(f); p('removed '+f) + except OSError: pass + try: os.remove(f+'c'); p('removed '+f+'c') + except OSError: pass + + atexit.register(rm_file) + + return target + + self.add_data_files(('', generate_svn_version_py())) def make_config_py(self,name='__config__'): """ Generate package __config__.py file containing system_info @@ -1360,14 +1362,7 @@ def get_numpy_include_dirs(): include_dirs = Configuration.numpy_include_dirs[:] if not include_dirs: import numpy - if numpy.show_config is None: - # running from numpy_core source directory - include_dirs.append(njoin(os.path.dirname(numpy.__file__), - 'core', 'include')) - else: - # using installed numpy core headers - import numpy.core as core - include_dirs.append(njoin(os.path.dirname(core.__file__), 'include')) + include_dirs = [ numpy.get_include() ] # else running numpy/core/setup.py return include_dirs diff --git a/system_info.py b/system_info.py index 0e9914640..641e23bcf 100644 --- a/system_info.py +++ b/system_info.py @@ -58,7 +58,7 @@ Global parameters: The file 'site.cfg' is looked for in 1) Directory of main setup.py file being run. -2) Home directory of user running the setup.py file (Not implemented yet) +2) Home directory of user running the setup.py file as ~/.numpy-site.cfg 3) System wide directory (location of this file...) The first one found is used to get system configuration options The @@ -104,7 +104,7 @@ Authors: Copyright 2002 Pearu Peterson all rights reserved, Pearu Peterson <pearu@cens.ioc.ee> Permission to use, modify, and distribute this software is given under the -terms of the SciPy (BSD style) license. See LICENSE.txt that came with +terms of the NumPy (BSD style) license. See LICENSE.txt that came with this distribution for specifics. NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. @@ -349,7 +349,9 @@ class system_info: defaults['src_dirs'] = os.pathsep.join(default_src_dirs) defaults['search_static_first'] = str(self.search_static_first) self.cp = ConfigParser.ConfigParser(defaults) - self.files = get_standard_file('site.cfg') + self.files = [] + self.files.extend(get_standard_file('.numpy-site.cfg')) + self.files.extend(get_standard_file('site.cfg')) self.parse_config_files() self.search_static_first = self.cp.getboolean(self.section, 'search_static_first') @@ -809,9 +811,12 @@ class mkl_info(system_info): info = {} dict_append(info,**mkl) dict_append(info, - libraries = ['pthread'], define_macros=[('SCIPY_MKL_H',None)], include_dirs = incl_dirs) + if sys.platform == 'win32': + pass # win32 has no pthread library + else: + dict_append(info, libraries=['pthread']) self.set_info(**info) class lapack_mkl_info(mkl_info): @@ -820,7 +825,11 @@ class lapack_mkl_info(mkl_info): mkl = get_info('mkl') if not mkl: return - lapack_libs = self.get_libs('lapack_libs',['mkl_lapack32','mkl_lapack64']) + if sys.platform == 'win32': + lapack_libs = self.get_libs('lapack_libs',['mkl_lapack']) + else: + lapack_libs = self.get_libs('lapack_libs',['mkl_lapack32','mkl_lapack64']) + info = {'libraries': lapack_libs} dict_append(info,**mkl) self.set_info(**info) @@ -1114,7 +1123,7 @@ def get_atlas_version(**config): if _cached_atlas_version.has_key(key): return _cached_atlas_version[key] c = cmd_config(Distribution()) - atlas_version = None + atlas_version = None try: s, o = c.get_output(atlas_version_c_text, libraries=libraries, library_dirs=library_dirs) diff --git a/tests/test_fcompiler_gnu.py b/tests/test_fcompiler_gnu.py new file mode 100644 index 000000000..c6ccea054 --- /dev/null +++ b/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() |