diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2004-01-19 09:00:01 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2004-01-19 09:00:01 +0000 |
commit | c879ef7d77eb19cb4d795e4550573de9c58955b4 (patch) | |
tree | 1f4fefca21b78e13a10f133a5df586faa799347a | |
parent | 60612a648d3b108daf597dfbaee57c316fb0775f (diff) | |
download | numpy-c879ef7d77eb19cb4d795e4550573de9c58955b4.tar.gz |
Refactoring build_flib.py (to follow and use standard distutils conventions and tools). It's work in-progress. Sending the output of 'python fcompiler.py --verbose' would be a great help if you have other than intel and gnu compilers installed.
-rw-r--r-- | scipy_distutils/absoftfcompiler.py | 84 | ||||
-rw-r--r-- | scipy_distutils/compaqfcompiler.py | 88 | ||||
-rw-r--r-- | scipy_distutils/cpuinfo.py | 646 | ||||
-rw-r--r-- | scipy_distutils/fcompiler.py | 679 | ||||
-rw-r--r-- | scipy_distutils/fortefcompiler.py | 37 | ||||
-rw-r--r-- | scipy_distutils/gnufcompiler.py | 166 | ||||
-rw-r--r-- | scipy_distutils/hpuxfcompiler.py | 39 | ||||
-rw-r--r-- | scipy_distutils/intelfcompiler.py | 119 | ||||
-rw-r--r-- | scipy_distutils/mipsfcompiler.py | 53 | ||||
-rw-r--r-- | scipy_distutils/nagfcompiler.py | 35 | ||||
-rw-r--r-- | scipy_distutils/vastfcompiler.py | 49 |
11 files changed, 1995 insertions, 0 deletions
diff --git a/scipy_distutils/absoftfcompiler.py b/scipy_distutils/absoftfcompiler.py new file mode 100644 index 000000000..a79701ec4 --- /dev/null +++ b/scipy_distutils/absoftfcompiler.py @@ -0,0 +1,84 @@ + +# http://www.absoft.com/literature/osxuserguide.pdf + +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler, dummy_fortran_file + +class AbsoftFCompiler(FCompiler): + + compiler_type = 'absoft' + version_pattern = r'FORTRAN 77 Compiler (?P<version>[^\s*,]*).*?Absoft Corp' + + executables = { + 'version_cmd' : ["f77", "-V -c %(fname)s.f -o %(fname)s.o" \ + % {'fname':dummy_fortran_file()}], + 'compiler_f77' : ["f77"], + 'compiler_fix' : ["f90"], + 'compiler_f90' : ["f90"], + 'linker_so' : ["f77","-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + + def get_library_dirs(self): + opt = FCompiler.get_library_dirs(self) + d = os.environ.get('ABSOFT') + if d: + opt.append(d) + return opt + + def get_libraries(self): + opt = FCompiler.get_libraries(self) + opt.extend(['fio','f77math','f90math']) + if os.name =='nt': + opt.append('COMDLG32') + return opt + + def get_flags(self): + opt = FCompiler.get_flags(self) + if os.name != 'nt': + opt.extend(['-s']) + return opt + + def get_flags_f77(self): + opt = FCompiler.get_flags_f77(self) + opt.extend(['-N22','-N90','-N110']) + if os.name != 'nt': + opt.append('-f') + if self.get_version(): + if self.get_version()<='4.6': + opt.append('-B108') + else: + # Though -N15 is undocumented, it works with + # Absoft 8.0 on Linux + opt.append('-N15') + return opt + + def get_flags_f90(self): + opt = FCompiler.get_flags_f90(self) + opt.extend(["-YCFRL=1","-YCOM_NAMES=LCS","-YCOM_PFX","-YEXT_PFX", + "-YCOM_SFX=_","-YEXT_SFX=_","-YEXT_NAMES=LCS"]) + return opt + + def get_flags_fix(self): + opt = FCompiler.get_flags_fix(self) + opt.extend(["-YCFRL=1","-YCOM_NAMES=LCS","-YCOM_PFX","-YEXT_PFX", + "-YCOM_SFX=_","-YEXT_SFX=_","-YEXT_NAMES=LCS"]) + opt.extend(["-f","fixed"]) + return opt + + def get_flags_opt(self): + opt = ['-O'] + return opt + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='absoft') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/compaqfcompiler.py b/scipy_distutils/compaqfcompiler.py new file mode 100644 index 000000000..c80574a75 --- /dev/null +++ b/scipy_distutils/compaqfcompiler.py @@ -0,0 +1,88 @@ + +#http://www.compaq.com/fortran/docs/ + +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler + +class CompaqFCompiler(FCompiler): + + compiler_type = 'compaq' + version_pattern = r'Compaq Fortran (?P<version>[^\s]*).*' + + if sys.platform[:5]=='linux': + fc_exe = 'fort' + else: + fc_exe = 'f90' + + executables = { + 'version_cmd' : [fc_exe, "-version"], + 'compiler_f77' : [fc_exe, "-f77rtl","-fixed"], + 'compiler_fix' : [fc_exe, "-fixed"], + 'compiler_f90' : [fc_exe], + 'linker_so' : [fc_exe], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags(self): + return ['-assume no2underscore','-nomixed_str_len_arg'] + def get_flags_debug(self): + return ['-g','-check bounds'] + def get_flags_opt(self): + return ['-O4','-align dcommons','-assume bigarrays', + '-assume nozsize','-math_library fast'] + def get_flags_arch(self): + return ['-arch host', '-tune host'] + def get_flags_linker_so(self): + if sys.platform[:5]=='linux': + return ['-shared'] + return ['-shared','-Wl,-expect_unresolved,*'] + +class CompaqVisualFCompiler(FCompiler): + + compiler_type = 'compaqv' + version_pattern = r'(DIGITAL|Compaq) Visual Fortran Optimizing Compiler'\ + ' Version (?P<version>[^\s]*).*' + + compile_switch = '/c ' + object_switch = '/object:' + + static_lib_extension = ".lib" + static_lib_format = "%s%s" + + ar_exe = 'lib.exe' + fc_exe = 'DF' + if sys.platform=='win32': + from distutils.msvccompiler import MSVCCompiler + ar_exe = MSVCCompiler().lib + + executables = { + 'version_cmd' : ['DF', "/what"], + 'compiler_f77' : ['DF', "/f77rtl","/fixed"], + 'compiler_fix' : ['DF', "/fixed"], + 'compiler_f90' : ['DF'], + 'linker_so' : ['DF'], + 'archiver' : [ar_exe, "/OUT:"], + 'ranlib' : None + } + + def get_flags(self): + return ['/nologo','/MD','/WX','/iface=(cref,nomixed_str_len_arg)', + '/names:lowercase','/assume:underscore'] + def get_flags_opt(self): + return ['/Ox','/fast','/optimize:5','/unroll:0','/math_library:fast'] + def get_flags_arch(self): + return ['/threads'] + def get_flags_debug(self): + return ['/debug'] + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='compaq') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/cpuinfo.py b/scipy_distutils/cpuinfo.py new file mode 100644 index 000000000..625525e7b --- /dev/null +++ b/scipy_distutils/cpuinfo.py @@ -0,0 +1,646 @@ +#!/usr/bin/env python +""" +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 +this distribution for specifics. + +Note: This should be merged into proc at some point. Perhaps proc should +be returning classes like this instead of using dictionaries. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Revision$ +$Date$ +Pearu Peterson +""" + +__version__ = "$Id$" + +__all__ = ['cpu'] + +import sys,string,re,types + +class cpuinfo_base: + """Holds CPU information and provides methods for requiring + the availability of various CPU features. + """ + + def _try_call(self,func): + try: + return func() + except: + pass + + def __getattr__(self,name): + if name[0]!='_': + if hasattr(self,'_'+name): + attr = getattr(self,'_'+name) + if type(attr) is types.MethodType: + return lambda func=self._try_call,attr=attr : func(attr) + else: + return lambda : None + raise AttributeError,name + + def _getNCPUs(self): + return 1 + +class linux_cpuinfo(cpuinfo_base): + + info = None + + def __init__(self): + if self.info is not None: + return + info = [] + try: + for line in open('/proc/cpuinfo').readlines(): + name_value = map(string.strip,string.split(line,':',1)) + if len(name_value)!=2: + continue + name,value = name_value + if not info or info[-1].has_key(name): # next processor + info.append({}) + info[-1][name] = value + except: + print sys.exc_value,'(ignoring)' + self.__class__.info = info + + def _not_impl(self): pass + + # Athlon + + def _is_AMD(self): + return self.info[0]['vendor_id']=='AuthenticAMD' + + def _is_AthlonK6_2(self): + return self._is_AMD() and self.info[0]['model'] == '2' + + def _is_AthlonK6_3(self): + return self._is_AMD() and self.info[0]['model'] == '3' + + def _is_AthlonK6(self): + return re.match(r'.*?AMD-K6',self.info[0]['model name']) is not None + + def _is_AthlonK7(self): + return re.match(r'.*?AMD-K7',self.info[0]['model name']) is not None + + def _is_AthlonMP(self): + return re.match(r'.*?Athlon\(tm\) MP\b', + self.info[0]['model name']) is not None + + def _is_AthlonHX(self): + return re.match(r'.*?Athlon HX\b', + self.info[0]['model name']) is not None + + def _is_Opteron(self): + return re.match(r'.*?Opteron\b', + self.info[0]['model name']) is not None + + def _is_Hammer(self): + return re.match(r'.*?Hammer\b', + self.info[0]['model name']) is not None + + # Alpha + + def _is_Alpha(self): + return self.info[0]['cpu']=='Alpha' + + def _is_EV4(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'EV4' + + def _is_EV5(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'EV5' + + def _is_EV56(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'EV56' + + def _is_PCA56(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'PCA56' + + # Intel + + #XXX + _is_i386 = _not_impl + + def _is_Intel(self): + return self.info[0]['vendor_id']=='GenuineIntel' + + def _is_i486(self): + return self.info[0]['cpu']=='i486' + + def _is_i586(self): + return self.is_Intel() and self.info[0]['cpu family'] == '5' + + def _is_i686(self): + return self.is_Intel() and self.info[0]['cpu family'] == '6' + + def _is_Celeron(self): + return re.match(r'.*?Celeron', + self.info[0]['model name']) is not None + + def _is_Pentium(self): + return re.match(r'.*?Pentium', + self.info[0]['model name']) is not None + + def _is_PentiumII(self): + return re.match(r'.*?Pentium.*?II\b', + self.info[0]['model name']) is not None + + def _is_PentiumPro(self): + return re.match(r'.*?PentiumPro\b', + self.info[0]['model name']) is not None + + def _is_PentiumMMX(self): + return re.match(r'.*?Pentium.*?MMX\b', + self.info[0]['model name']) is not None + + def _is_PentiumIII(self): + return re.match(r'.*?Pentium.*?III\b', + self.info[0]['model name']) is not None + + def _is_PentiumIV(self): + return re.match(r'.*?Pentium.*?(IV|4)\b', + self.info[0]['model name']) is not None + + def _is_Itanium(self): + return re.match(r'.*?Itanium\b', + self.info[0]['model name']) is not None + + + + # Varia + + def _is_singleCPU(self): + return len(self.info) == 1 + + def _getNCPUs(self): + return len(self.info) + + def _has_fdiv_bug(self): + return self.info[0]['fdiv_bug']=='yes' + + def _has_f00f_bug(self): + return self.info[0]['f00f_bug']=='yes' + + def _has_mmx(self): + return re.match(r'.*?\bmmx\b',self.info[0]['flags']) is not None + + def _has_sse(self): + return re.match(r'.*?\bsse\b',self.info[0]['flags']) is not None + + def _has_sse2(self): + return re.match(r'.*?\bsse2\b',self.info[0]['flags']) is not None + + def _has_3dnow(self): + return re.match(r'.*?\b3dnow\b',self.info[0]['flags']) is not None + + def _has_3dnowext(self): + return re.match(r'.*?\b3dnowext\b',self.info[0]['flags']) is not None + +class irix_cpuinfo(cpuinfo_base): + + info = None + + def __init__(self): + if self.info is not None: + return + info = [] + try: + import commands + status,output = commands.getstatusoutput('sysconf') + if status not in [0,256]: + return + for line in output.split('\n'): + name_value = map(string.strip,string.split(line,' ',1)) + if len(name_value)!=2: + continue + name,value = name_value + if not info: + info.append({}) + info[-1][name] = value + except: + print sys.exc_value,'(ignoring)' + self.__class__.info = info + + #print info + def _not_impl(self): pass + + def _is_singleCPU(self): + return self.info[0].get('NUM_PROCESSORS') == '1' + + def _getNCPUs(self): + return int(self.info[0].get('NUM_PROCESSORS')) + + def __cputype(self,n): + return self.info[0].get('PROCESSORS').split()[0].lower() == 'r%s' % (n) + def _is_r2000(self): return self.__cputype(2000) + def _is_r3000(self): return self.__cputype(3000) + def _is_r3900(self): return self.__cputype(3900) + def _is_r4000(self): return self.__cputype(4000) + def _is_r4100(self): return self.__cputype(4100) + def _is_r4300(self): return self.__cputype(4300) + def _is_r4400(self): return self.__cputype(4400) + def _is_r4600(self): return self.__cputype(4600) + def _is_r4650(self): return self.__cputype(4650) + def _is_r5000(self): return self.__cputype(5000) + def _is_r6000(self): return self.__cputype(6000) + def _is_r8000(self): return self.__cputype(8000) + def _is_r10000(self): return self.__cputype(10000) + def _is_r12000(self): return self.__cputype(12000) + def _is_rorion(self): return self.__cputype('orion') + + def get_ip(self): + try: return self.info[0].get('MACHINE') + except: pass + def __machine(self,n): + return self.info[0].get('MACHINE').lower() == 'ip%s' % (n) + def _is_IP19(self): return self.__machine(19) + def _is_IP20(self): return self.__machine(20) + def _is_IP21(self): return self.__machine(21) + def _is_IP22(self): return self.__machine(22) + def _is_IP22_4k(self): return self.__machine(22) and self._is_r4000() + def _is_IP22_5k(self): return self.__machine(22) and self._is_r5000() + def _is_IP24(self): return self.__machine(24) + def _is_IP25(self): return self.__machine(25) + def _is_IP26(self): return self.__machine(26) + def _is_IP27(self): return self.__machine(27) + def _is_IP28(self): return self.__machine(28) + def _is_IP30(self): return self.__machine(30) + def _is_IP32(self): return self.__machine(32) + def _is_IP32_5k(self): return self.__machine(32) and self._is_r5000() + def _is_IP32_10k(self): return self.__machine(32) and self._is_r10000() + +class darwin_cpuinfo(cpuinfo_base): + + info = None + + def __init__(self): + if self.info is not None: + return + info = [] + try: + import commands + status,output = commands.getstatusoutput('arch') + if not status: + if not info: info.append({}) + info[-1]['arch'] = string.strip(output) + status,output = commands.getstatusoutput('machine') + if not status: + if not info: info.append({}) + info[-1]['machine'] = string.strip(output) + status,output = commands.getstatusoutput('sysctl hw') + if not status: + if not info: info.append({}) + d = {} + for l in string.split(output,'\n'): + l = map(string.strip,string.split(l, '=')) + if len(l)==2: + d[l[0]]=l[1] + info[-1]['sysctl_hw'] = d + except: + print sys.exc_value,'(ignoring)' + self.__class__.info = info + + def _not_impl(self): pass + + def _getNCPUs(self): + try: return int(self.info[0]['sysctl_hw']['hw.ncpu']) + except: return 1 + + def _is_Power_Macintosh(self): + return self.info[0]['sysctl_hw']['hw.machine']=='Power Macintosh' + + def _is_i386(self): + return self.info[0]['arch']=='i386' + def _is_ppc(self): + return self.info[0]['arch']=='ppc' + + def __machine(self,n): + return self.info[0]['machine'] == 'ppc%s'%n + def _is_ppc601(self): return self.__machine(601) + def _is_ppc602(self): return self.__machine(602) + def _is_ppc603(self): return self.__machine(603) + def _is_ppc603e(self): return self.__machine('603e') + def _is_ppc604(self): return self.__machine(604) + def _is_ppc604e(self): return self.__machine('604e') + def _is_ppc620(self): return self.__machine(620) + def _is_ppc630(self): return self.__machine(630) + def _is_ppc740(self): return self.__machine(740) + def _is_ppc7400(self): return self.__machine(7400) + def _is_ppc7450(self): return self.__machine(7450) + def _is_ppc750(self): return self.__machine(750) + def _is_ppc403(self): return self.__machine(403) + def _is_ppc505(self): return self.__machine(505) + def _is_ppc801(self): return self.__machine(801) + def _is_ppc821(self): return self.__machine(821) + def _is_ppc823(self): return self.__machine(823) + def _is_ppc860(self): return self.__machine(860) + +class sunos_cpuinfo(cpuinfo_base): + + info = None + + def __init__(self): + if self.info is not None: + return + info = [] + try: + import commands + status,output = commands.getstatusoutput('arch') + if not status: + if not info: info.append({}) + info[-1]['arch'] = string.strip(output) + status,output = commands.getstatusoutput('mach') + if not status: + if not info: info.append({}) + info[-1]['mach'] = string.strip(output) + status,output = commands.getstatusoutput('uname -i') + if not status: + if not info: info.append({}) + info[-1]['uname_i'] = string.strip(output) + status,output = commands.getstatusoutput('uname -X') + if not status: + if not info: info.append({}) + d = {} + for l in string.split(output,'\n'): + l = map(string.strip,string.split(l, '=')) + if len(l)==2: + d[l[0]]=l[1] + info[-1]['uname_X'] = d + status,output = commands.getstatusoutput('isainfo -b') + if not status: + if not info: info.append({}) + info[-1]['isainfo_b'] = string.strip(output) + status,output = commands.getstatusoutput('isainfo -n') + if not status: + if not info: info.append({}) + info[-1]['isainfo_n'] = string.strip(output) + status,output = commands.getstatusoutput('psrinfo -v 0') + if not status: + if not info: info.append({}) + for l in string.split(output,'\n'): + m = re.match(r'\s*The (?P<p>[\w\d]+) processor operates at',l) + if m: + info[-1]['processor'] = m.group('p') + break + except: + print sys.exc_value,'(ignoring)' + self.__class__.info = info + + def _not_impl(self): pass + + def _is_32bit(self): + return self.info[0]['isainfo_b']=='32' + def _is_64bit(self): + return self.info[0]['isainfo_b']=='64' + + def _is_i386(self): + return self.info[0]['isainfo_n']=='i386' + def _is_sparc(self): + return self.info[0]['isainfo_n']=='sparc' + def _is_sparcv9(self): + return self.info[0]['isainfo_n']=='sparcv9' + + def _getNCPUs(self): + try: return int(self.info[0]['uname_X']['NumCPU']) + except: return 1 + + def _is_sun4(self): + return self.info[0]['arch']=='sun4' + + def _is_SUNW(self): + return re.match(r'SUNW',self.info[0]['uname_i']) is not None + def _is_sparcstation5(self): + return re.match(r'.*SPARCstation-5',self.info[0]['uname_i']) is not None + def _is_ultra1(self): + return re.match(r'.*Ultra-1',self.info[0]['uname_i']) is not None + def _is_ultra250(self): + return re.match(r'.*Ultra-250',self.info[0]['uname_i']) is not None + def _is_ultra2(self): + return re.match(r'.*Ultra-2',self.info[0]['uname_i']) is not None + def _is_ultra30(self): + return re.match(r'.*Ultra-30',self.info[0]['uname_i']) is not None + def _is_ultra4(self): + return re.match(r'.*Ultra-4',self.info[0]['uname_i']) is not None + def _is_ultra5_10(self): + return re.match(r'.*Ultra-5_10',self.info[0]['uname_i']) is not None + def _is_ultra5(self): + return re.match(r'.*Ultra-5',self.info[0]['uname_i']) is not None + def _is_ultra60(self): + return re.match(r'.*Ultra-60',self.info[0]['uname_i']) is not None + def _is_ultra80(self): + return re.match(r'.*Ultra-80',self.info[0]['uname_i']) is not None + def _is_ultraenterprice(self): + return re.match(r'.*Ultra-Enterprise',self.info[0]['uname_i']) is not None + def _is_ultraenterprice10k(self): + return re.match(r'.*Ultra-Enterprise-10000',self.info[0]['uname_i']) is not None + def _is_sunfire(self): + return re.match(r'.*Sun-Fire',self.info[0]['uname_i']) is not None + def _is_ultra(self): + return re.match(r'.*Ultra',self.info[0]['uname_i']) is not None + + def _is_cpusparcv7(self): + return self.info[0]['processor']=='sparcv7' + def _is_cpusparcv8(self): + return self.info[0]['processor']=='sparcv8' + def _is_cpusparcv9(self): + return self.info[0]['processor']=='sparcv9' + +class win32_cpuinfo(cpuinfo_base): + + info = None + pkey = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor" + # XXX: what does the value of + # HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0 + # mean? + + def __init__(self): + if self.info is not None: + return + info = [] + try: + #XXX: Bad style to use so long `try:...except:...`. Fix it! + import _winreg + pkey = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor" + prgx = re.compile(r"family\s+(?P<FML>\d+)\s+model\s+(?P<MDL>\d+)"\ + "\s+stepping\s+(?P<STP>\d+)",re.IGNORECASE) + chnd=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,pkey) + pnum=0 + while 1: + try: + proc=_winreg.EnumKey(chnd,pnum) + except _winreg.error: + break + else: + pnum+=1 + print proc + info.append({"Processor":proc}) + phnd=_winreg.OpenKey(chnd,proc) + pidx=0 + while True: + try: + name,value,vtpe=_winreg.EnumValue(phnd,pidx) + except _winreg.error: + break + else: + pidx=pidx+1 + info[-1][name]=value + if name=="Identifier": + srch=prgx.search(value) + if srch: + info[-1]["Family"]=int(srch.group("FML")) + info[-1]["Model"]=int(srch.group("MDL")) + info[-1]["Stepping"]=int(srch.group("STP")) + except: + print sys.exc_value,'(ignoring)' + self.__class__.info = info + + def _not_impl(self): pass + + # Athlon + + def _is_AMD(self): + return self.info[0]['VendorIdentifier']=='AuthenticAMD' + + def _is_Am486(self): + return self.is_AMD() and self.info[0]['Family']==4 + + def _is_Am5x86(self): + return self.is_AMD() and self.info[0]['Family']==4 + + def _is_AMDK5(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model'] in [0,1,2,3] + + def _is_AMDK6(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model'] in [6,7] + + def _is_AMDK6_2(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model']==8 + + def _is_AMDK6_3(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model']==9 + + def _is_Athlon(self): + return self.is_AMD() and self.info[0]['Family']==6 + + def _is_Athlon64(self): + return self.is_AMD() and self.info[0]['Family']==15 \ + and self.info[0]['Model']==4 + + def _is_Opteron(self): + return self.is_AMD() and self.info[0]['Family']==15 \ + and self.info[0]['Model']==5 + + # Intel + + def _is_Intel(self): + return self.info[0]['VendorIdentifier']=='GenuineIntel' + + def _is_i386(self): + return self.info[0]['Family']==3 + + def _is_i486(self): + return self.info[0]['Family']==4 + + def _is_i586(self): + return self.is_Intel() and self.info[0]['Family']==5 + + def _is_i686(self): + return self.is_Intel() and self.info[0]['Family']==6 + + def _is_Pentium(self): + return self.is_Intel() and self.info[0]['Family']==5 + + def _is_PentiumMMX(self): + return self.is_Intel() and self.info[0]['Family']==5 \ + and self.info[0]['Model']==4 + + def _is_PentiumPro(self): + return self.is_Intel() and self.info[0]['Family']==6 \ + and self.info[0]['Model']==1 + + def _is_PentiumII(self): + return self.is_Intel() and self.info[0]['Family']==6 \ + and self.info[0]['Model'] in [3,5,6] + + def _is_PentiumIII(self): + return self.is_Intel() and self.info[0]['Family']==6 \ + and self.info[0]['Model'] in [7,8,9,10,11] + + def _is_PentiumIV(self): + return self.is_Intel() and self.info[0]['Family']==15 + + # Varia + + def _is_singleCPU(self): + return len(self.info) == 1 + + def _getNCPUs(self): + return len(self.info) + + def _has_mmx(self): + if self.is_Intel(): + return (self.info[0]['Family']==5 and self.info[0]['Model']==4) \ + or (self.info[0]['Family'] in [6,15]) + elif self.is_AMD(): + return self.info[0]['Family'] in [5,6,15] + + def _has_sse(self): + if self.is_Intel(): + return (self.info[0]['Family']==6 and \ + self.info[0]['Model'] in [7,8,9,10,11]) \ + or self.info[0]['Family']==15 + elif self.is_AMD(): + return (self.info[0]['Family']==6 and \ + self.info[0]['Model'] in [6,7,8,10]) \ + or self.info[0]['Family']==15 + + def _has_sse2(self): + return self.info[0]['Family']==15 + + def _has_3dnow(self): + # XXX: does only AMD have 3dnow?? + return self.is_AMD() and self.info[0]['Family'] in [5,6,15] + + def _has_3dnowext(self): + return self.is_AMD() and self.info[0]['Family'] in [6,15] + +if sys.platform[:5] == 'linux': # variations: linux2,linux-i386 (any others?) + cpuinfo = linux_cpuinfo +elif sys.platform[:4] == 'irix': + cpuinfo = irix_cpuinfo +elif sys.platform == 'darwin': + cpuinfo = darwin_cpuinfo +elif sys.platform[:5] == 'sunos': + cpuinfo = sunos_cpuinfo +elif sys.platform[:5] == 'win32': + cpuinfo = win32_cpuinfo +#XXX: other OS's. Eg. use _winreg on Win32. Or os.uname on unices. +else: + cpuinfo = cpuinfo_base + +cpu = cpuinfo() + +if __name__ == "__main__": + + cpu.is_blaa() + cpu.is_Intel() + cpu.is_Alpha() + + print 'CPU information:', + for name in dir(cpuinfo): + if name[0]=='_' and name[1]!='_': + r = getattr(cpu,name[1:])() + if r: + if r!=1: + print '%s=%s' %(name[1:],r), + else: + print name[1:], + print diff --git a/scipy_distutils/fcompiler.py b/scipy_distutils/fcompiler.py new file mode 100644 index 000000000..b4bf950c8 --- /dev/null +++ b/scipy_distutils/fcompiler.py @@ -0,0 +1,679 @@ +"""scipy_distutils.fcompiler + +Contains FCompiler, an abstract base class that defines the interface +for the Scipy_istutils Fortran compiler abstraction model. + +""" + +import re +import os +import sys + +from distutils.version import StrictVersion +from distutils.ccompiler import CCompiler +# distutils.ccompiler provides the following functions: +# gen_preprocess_options(macros, include_dirs) +# gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries) +from distutils.errors import DistutilsModuleError,DistutilsArgError +from distutils.core import Command +from distutils.util import split_quoted +from distutils.fancy_getopt import FancyGetopt +from distutils.version import LooseVersion +from distutils import log +from distutils.sysconfig import get_config_var + +from exec_command import find_executable, exec_command + + +class FCompiler(CCompiler): + """ Abstract base class to define the interface that must be implemented + by real Fortran compiler classes. + + Methods that subclasses may redefine: + + 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(), + get_flags_arch_f90(), get_flags_debug_f90(), + get_flags_fix(), get_flags_linker_so(), get_flags_version() + + 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. + + After constructing a compiler instance, always call customize(dist=None) + method that finalizes compiler construction and makes the following + attributes available: + compiler_f77 + compiler_f90 + compiler_fix + linker_so + archiver + ranlib + libraries + library_dirs + """ + # CCompiler defines the following attributes: + # compiler_type + # src_extensions + # obj_extension + # static_lib_extension + # shared_lib_extension + # static_lib_format + # shared_lib_format + # exe_extension + # language_map ### REDEFINED + # language_order ### REDEFINED + # and the following public methods: + # set_executables(**args) + # set_executable(key,value) + # define_macro(name, value=None) + # undefine_macro(name) + # add_include_dir(dir) + # set_include_dirs(dirs) + # add_library(libname) + # set_libraries(libnames) + # add_library_dir(dir) + # set_library_dirs(dirs) + # add_runtime_library_dir(dir) + # set_runtime_library_dirs(dirs) + # add_link_object(object) + # set_link_objects(objects) + # + # detect_language(sources) ### USABLE + # + # preprocess(source,output_file=None,macros=None,include_dirs=None, + # extra_preargs=None,extra_postargs=None) + # compile(sources, output_dir=None, macros=None, + # include_dirs=None, debug=0, extra_preargs=None, + # extra_postargs=None, depends=None) + # create_static_lib(objects,output_libname,output_dir=None,debug=0,target_lang=None): + # link(target_desc, objects, output_filename, output_dir=None, + # libraries=None, library_dirs=None, runtime_library_dirs=None, + # export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, + # build_temp=None, target_lang=None) + # link_shared_lib(objects, output_libname, output_dir=None, + # libraries=None, library_dirs=None, runtime_library_dirs=None, + # export_symbols=None, debug=0, extra_preargs=None, + # extra_postargs=None, build_temp=None, target_lang=None) + # link_shared_object(objects,output_filename,output_dir=None, + # libraries=None,library_dirs=None,runtime_library_dirs=None, + # export_symbols=None,debug=0,extra_preargs=None, + # extra_postargs=None,build_temp=None,target_lang=None) + # link_executable(objects,output_progname,output_dir=None, + # libraries=None,library_dirs=None,runtime_library_dirs=None, + # debug=0,extra_preargs=None,extra_postargs=None,target_lang=None) + # + # library_dir_option(dir) + # runtime_library_dir_option(dir) + # library_option(lib) + # has_function(funcname,includes=None,include_dirs=None, + # libraries=None,library_dirs=None) + # find_library_file(dirs, lib, debug=0) + # + # object_filenames(source_filenames, strip_dir=0, output_dir='') + # shared_object_filename(basename, strip_dir=0, output_dir='') + # executable_filenamee(basename, strip_dir=0, output_dir='') + # library_filename(libname, lib_type='static',strip_dir=0, output_dir=''): + # + # announce(msg, level=1) + # debug_print(msg) + # warn(msg) + # execute(func, args, msg=None, level=1) + # spawn(cmd) + # move_file(src,dst) + # mkpath(name, mode=0777) + # + + src_extensions = ['.for','.ftn','.f77','.f','.f90','.f95'] + + language_map = {'.f':'f77', + '.for':'f77', + '.ftn':'f77', + '.f77':'f77', + '.f90':'f90', + '.f95':'f90'} + language_order = ['f90','f77'] + + version_pattern = None + + executables = { + 'version_cmd' : ["f77","-v"], + 'compiler_f77' : ["f77"], + 'compiler_f90' : ["f90"], + 'compiler_fix' : ["f90","-fixed"], + 'linker_so' : ["f90","-shared"], + 'archiver' : ["ar","-cr"], + 'ranlib' : None, + } + + compile_switch = "-c " # Ending space matters! + object_switch = "-o " # Ending space matters! + object_extension = ".o" + shared_lib_extension = get_config_var('SO') + static_lib_extension = ".a" + static_lib_format = "lib%s%s" + shared_lib_format = "%s%s" + + def __init__(self,verbose=0,dry_run=0,force=0): + # Set the following attributes (see ccompiler.py for explanations): + # output_dir + # macros + # include_dirs + # libraries + # library_dirs + # runtime_library_dirs + # objects + # and call set_executables. + CCompiler.__init__(self,verbose,dry_run,force) + + ## Methods that subclasses may redefine. But don't call these methods! + ## They are private to FCompiler class and may return unexpected + ## results if used elsewhere. So, you have been warned.. + + def get_version_cmd(self): + """ Compiler command to print out version information. """ + f77 = self.executables['compiler_f77'] + if f77 is not None: + f77 = f77[0] + cmd = self.executables['version_cmd'] + if cmd is not None: + cmd = cmd[0] + if cmd==f77: + cmd = self.compiler_f77[0] + else: + f90 = self.executables['compiler_f90'] + if f90 is not None: + f90 = f90[0] + if cmd==f90: + cmd = self.compiler_f90[0] + return cmd + + def get_linker_so(self): + """ Linker command to build shared libraries. """ + f77 = self.executables['compiler_f77'] + if f77 is not None: + f77 = f77[0] + ln = self.executables['linker_so'] + if ln is not None: + ln = ln[0] + if ln==f77: + ln = self.compiler_f77[0] + else: + f90 = self.executables['compiler_f90'] + if f90 is not None: + f90 = f90[0] + if ln==f90: + ln = self.compiler_f90[0] + return ln + + def get_flags(self): + """ List of flags common to all compiler types. """ + return [] + def get_flags_version(self): + """ List of compiler flags to print out version information. """ + if self.executables['version_cmd']: + return self.executables['version_cmd'][1:] + return [] + def get_flags_f77(self): + """ List of Fortran 77 specific flags. """ + if self.executables['compiler_f77']: + return self.executables['compiler_f77'][1:] + return [] + def get_flags_f90(self): + """ List of Fortran 90 specific flags. """ + if self.executables['compiler_f90']: + return self.executables['compiler_f90'][1:] + return [] + def get_flags_fix(self): + """ List of Fortran 90 fixed format specific flags. """ + if self.executables['compiler_fix']: + return self.executables['compiler_fix'][1:] + return [] + def get_flags_linker_so(self): + """ List of linker flags to build a shared library. """ + if self.executables['linker_so']: + return self.executables['linker_so'][1:] + return [] + def get_flags_ar(self): + """ List of archiver flags. """ + if self.executables['archiver']: + return self.executables['archiver'][1:] + return [] + def get_flags_opt(self): + """ List of architecture independent compiler flags. """ + return [] + def get_flags_arch(self): + """ List of architecture dependent compiler flags. """ + return [] + def get_flags_debug(self): + """ List of compiler flags to compile with debugging information. """ + return [] + get_flags_opt_f77 = get_flags_opt_f90 = get_flags_opt + get_flags_arch_f77 = get_flags_arch_f90 = get_flags_arch + get_flags_debug_f77 = get_flags_debug_f90 = get_flags_debug + + def get_libraries(self): + """ List of compiler libraries. """ + return self.libraries[:] + def get_library_dirs(self): + """ List of compiler library directories. """ + return self.library_dirs[:] + + def get_version(self, force=0, ok_status=[0]): + """ Compiler version. Returns None if compiler is not available. """ + if not force and hasattr(self,'version'): + return self.version + + cmd = ' '.join(self.version_cmd) + status, output = self.exec_command(cmd,use_tee=0) + version = None + if status in ok_status: + m = re.match(self.version_pattern,output) + if m: + version = m.group('version') + assert version,`version` + version = LooseVersion(version) + self.version = version + return version + + ############################################################ + + ## Public methods: + + def customize(self, dist=None): + """ Customize Fortran compiler. + + This method gets Fortran compiler specific information from + (i) class definition, (ii) environment, (iii) distutils config + files, and (iv) command line. + + This method should be always called after constructing a + compiler instance. But not in __init__ because Distribution + instance is needed for (iii) and (iv). + """ + if dist is None: + # These hooks are for testing only! + from dist import Distribution + 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() + + conf = dist.get_option_dict('config_fc') + + noopt = conf.get('noopt',[None,0])[1] + noarch = conf.get('noarch',[None,noopt])[1] + debug = conf.get('debug',[None,0])[1] + + f77 = self.__get_cmd('compiler_f77','F77',(conf,'f77_exec')) + f90 = self.__get_cmd('compiler_f90','F90',(conf,'f90_exec')) + # 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]) + + # 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) + if vers_cmd: + vflags = self.__get_flags(self.get_flags_version) + self.set_executables(version_cmd=[vers_cmd]+vflags) + + if f77: + f77flags = self.__get_flags(self.get_flags_f77,'F77FLAGS', + (conf,'f77flags')) + if f90: + f90flags = self.__get_flags(self.get_flags_f90,'F90FLAGS', + (conf,'f90flags')) + + # XXX Assuming that free format is default for f90 compiler. + fix = self.__get_cmd('compiler_fix','F90',(conf,'f90_exec')) + if fix: + fixflags = self.__get_flags(self.get_flags_fix) + f90flags + + oflags,aflags,dflags = [],[],[] + 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) + 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) + 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) + + fflags = self.__get_flags(self.get_flags,'FFLAGS') \ + + dflags + oflags + aflags + + if f77: + self.set_executables(compiler_f77=[f77]+f77flags+fflags) + if f90: + self.set_executables(compiler_f90=[f90]+f90flags+fflags) + if fix: + self.set_executables(compiler_fix=[fix]+fixflags+fflags) + + linker_so = self.__get_cmd(self.get_linker_so,'LDSHARED') + if linker_so: + linker_so_flags = self.__get_flags(self.get_flags_linker_so,'LDFLAGS') + self.set_executables(linker_so=[linker_so]+linker_so_flags) + + ar = self.__get_cmd('archiver','AR') + if ar: + arflags = self.__get_flags(self.get_flags_ar,'ARFLAGS') + self.set_executables(archiver=[ar]+arflags) + + ranlib = self.__get_cmd('ranlib','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() + + def dump_properties(self): + """ 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.sort() + + pretty_printer = FancyGetopt(props) + for l in pretty_printer.generate_help("%s instance properties:" \ + % (self.__class__.__name__)): + if l[:4]==' --': + l = ' ' + l[4:] + print l + + def exec_command(self,*args,**kws): + """ Return status,output of a command. """ + log.info('%s.exec_command(*%s,**%s)' % (self.__class__.__name__,args,kws)) + status, output = exec_command(*args,**kws) + log.info('*****status:%s\n*****output:\n%s\n*****' % (status,output)) + return status, output + + ############################################################ + + ## Private methods: + + def __get_cmd(self, command, envvar=None, confvar=None): + if command is None: + var = None + elif type(command) is type(''): + var = self.executables[command] + if var is not None: + var = var[0] + 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 type(command) is type(''): + 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 type(var) is type(''): + var = split_quoted(var) + return var + + ## class FCompiler + +fcompiler_class = {'gnu':('gnufcompiler','GnuFCompiler', + "GNU Fortran Compiler"), + 'pg':('pgfcompiler','PGroupFCompiler', + "Portland Group Fortran Compiler"), + 'absoft':('absoftfcompiler','AbsoftFCompiler', + "Absoft Corp Fortran Compiler"), + 'mips':('mipsfcompiler','MipsFCompiler', + "MIPSpro Fortran Compiler"), + 'forte':('fortefcompiler','ForteFCompiler', + "Forte Fortran 95 Compiler"), + 'sun':('sunfcompiler','SunFCompiler', + "Sun Fortran Compiler"), + 'intel':('intelfcompiler','IntelFCompiler', + "Intel Fortran Compiler for 32-bit apps"), + 'intelv':('intelfcompiler','IntelVisualFCompiler', + "Intel Visual Fortran Compiler for 32-bit apps"), + 'intelitanium':('intelfcompiler','IntelItaniumFCompiler', + "Intel Fortran Compiler for Itanium apps"), + 'nag':('nagfcompiler','NAGFCompiler', + "NAGWare Fortran 95 Compiler"), + 'compaq':('compaqfcompiler','CompaqFCompiler', + "Compaq Fortran Compiler"), + 'compaqv':('compaqfcompiler','CompaqVisualFCompiler', + "DIGITAL|Compaq Visual Fortran Compiler"), + 'vast':('vastfcompiler','VastFCompiler', + "Pacific-Sierra Research Fortran 90 Compiler"), + 'hpux':('hpuxfcompiler','HPUXFCompiler', + "HP Fortran 90 Compiler"), + 'lahey':('laheyfcompiler','LaheyFCompiler', + "Lahey/Fujitsu Fortran 95 Compiler"), + 'f':('fcompiler','FFCompiler', + "Fortran Company/NAG F Compiler"), + } + +_default_compilers = ( + # Platform mappings + ('win32',('gnu','intelv','absoft','compaqv','intelitanium')), + ('cygwin.*',('gnu','intelv','absoft','compaqv','intelitanium')), + ('linux.*',('gnu','intel','lahey','pg','absoft','nag','vast','compaq', + 'intelitanium')), + ('sunos.*',('forte','gnu','sun')), + ('irix',('mips','gnu')), + # OS mappings + ('posix',('gnu',)), + ('nt',('gnu',)), + ('mac',('gnu',)), + ) + +def get_default_fcompiler(osname=None, platform=None): + """ Determine the default Fortran compiler to use for the given platform. """ + if osname is None: + osname = os.name + if platform is None: + platform = sys.platform + for pattern, compiler in _default_compilers: + if re.match(pattern, platform) is not None or \ + re.match(pattern, osname) is not None: + if type(compiler) is type(()): + return compiler[0] + return compiler + return 'gnu' + +def new_fcompiler(plat=None, + compiler=None, + verbose=0, + dry_run=0, + force=0): + """ Generate an instance of some FCompiler subclass for the supplied + platform/compiler combination. + """ + if plat is None: + plat = os.name + try: + if compiler is None: + compiler = get_default_fcompiler(plat) + (module_name, class_name, 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: + msg = msg + " with '%s' compiler" % compiler + raise DistutilsPlatformError, msg + + try: + module_name = 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) + + return klass(None, dry_run, force) + + +def show_fcompilers(dist = None): + """ Print list of available compilers (used by the "--help-fcompiler" + option to "config_fc"). + """ + if dist is None: + from dist import Distribution + 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() + + compilers = [] + compilers_na = [] + compilers_ni = [] + for compiler in fcompiler_class.keys(): + v = 'N/A' + try: + c = new_fcompiler(compiler=compiler) + c.customize(dist) + v = c.get_version() + except DistutilsModuleError: + pass + except: + print sys.exc_info()[0],sys.exc_info()[1] + 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: + compilers.append(("fcompiler="+compiler, None, + fcompiler_class[compiler][2] + ' (%s)' % v)) + compilers.sort() + compilers_na.sort() + pretty_printer = FancyGetopt(compilers) + pretty_printer.print_help("List of available Fortran compilers:") + pretty_printer = FancyGetopt(compilers_na) + pretty_printer.print_help("List of unavailable Fortran compilers:") + if compilers_ni: + pretty_printer = FancyGetopt(compilers_ni) + pretty_printer.print_help("List of unimplemented Fortran compilers:") + print "For compiler details, run 'config_fc --verbose' setup command." + +class config_fc(Command): + """ Distutils command to hold user specified options + to Fortran compilers. + + This is used in FCompiler.customize() method. + """ + + user_options = [ + ('fcompiler=',None,"specify Fortran compiler type"), + ('f77-exec=', None, "specify F77 compiler command"), + ('f90-exec=', None, "specify F90 compiler command"), + ('f77flags=',None,"specify F77 compiler flags"), + ('f90flags=',None,"specify F90 compiler flags"), + ('opt=',None,"specify optimization flags"), + ('arch=',None,"specify architecture specific optimization flags"), + ('debug','g',"compile with debugging information"), + ('noopt',None,"compile without optimization"), + ('noarch',None,"compile without arch-dependent optimization"), + ] + + boolean_options = ['debug','noopt','noarch'] + + help_options = [ + ('help-fcompiler', None, + "list available Fortran compilers", show_fcompilers), + ] + +def dummy_fortran_file(): + import tempfile + dummy_name = tempfile.mktemp()+'__dummy' + dummy = open(dummy_name+'.f','w') + dummy.write(" subroutine dummy()\n end\n") + dummy.close() + import atexit + from distutils import log + def rm_file(name=dummy_name,log_threshold=log._global_log.threshold): + save_th = log._global_log.threshold + log.set_threshold(log_threshold) + try: os.remove(name+'.f'); log.debug('removed '+name+'.f') + except OSError: pass + try: os.remove(name+'.o'); log.debug('removed '+name+'.o') + except OSError: pass + log.set_threshold(save_th) + atexit.register(rm_file) + return dummy_name + +is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z',re.I).match +_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-',re.I).search +_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-',re.I).search +_free_f90_start = re.compile(r'[^c*][^\s\d\t]',re.I).match +def is_free_format(file): + """Check if file is in free format Fortran.""" + # f90 allows both fixed and free format, assuming fixed unless + # signs of free format are detected. + result = 0 + f = open(file,'r') + line = f.readline() + n = 15 # the number of non-comment lines to scan for hints + if _has_f_header(line): + n = 0 + elif _has_f90_header(line): + n = 0 + result = 1 + while n>0 and line: + if line[0]!='!': + n -= 1 + if _free_f90_start(line[:5]) or line[-2:-1]=='&': + result = 1 + break + line = f.readline() + f.close() + return result + +if __name__ == '__main__': + show_fcompilers() diff --git a/scipy_distutils/fortefcompiler.py b/scipy_distutils/fortefcompiler.py new file mode 100644 index 000000000..37b736c29 --- /dev/null +++ b/scipy_distutils/fortefcompiler.py @@ -0,0 +1,37 @@ +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler + +class ForteFCompiler(FCompiler): + + compiler_type = 'forte' + version_pattern = r'(f90|f95): Forte Developer 7 Fortran 95 (?P<version>[^\s]+).*' + + executables = { + 'version_cmd' : ["f90", "-V"], + 'compiler_f77' : ["f90", "-f77", "-ftrap=%none"], + 'compiler_fix' : ["f90", "-fixed"], + 'compiler_f90' : ["f90"], + 'linker_so' : ["f90","-Bdynamic","-G"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags(self): + return ['-xcode=pic32'] + def get_opt(self): + return ['-fast','-dalign'] + def get_arch(self): + return ['-xtarget=generic'] + def get_libraries(self): + opt = FCompiler.get_libraries(self) + opt.extend(['fsu','sunmath','mvec','f77compat']) + return opt + +if __name__ == '__main__': + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='forte') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/gnufcompiler.py b/scipy_distutils/gnufcompiler.py new file mode 100644 index 000000000..11a2ac28f --- /dev/null +++ b/scipy_distutils/gnufcompiler.py @@ -0,0 +1,166 @@ + +import re +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler +from exec_command import find_executable + +class GnuFCompiler(FCompiler): + + compiler_type = 'gnu' + version_pattern = r'GNU Fortran (\(GCC\)|\(GCC.*\)\)|)\s*'\ + '(?P<version>[^\s*\)]+)' + + 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,"-Wall","-fno-second-underscore"], + 'compiler_f90' : None, + 'compiler_fix' : None, + 'linker_so' : [fc_exe], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"], + } + + + def get_flags(self): + opt = FCompiler.get_flags(self) + if os.name != 'nt': + opt.append('-fPIC') + return opt + + def get_linker_so(self): + # win32 linking should be handled by standard linker + # Darwin g77 cannot be used as a linker. + if re.match(r'(win32|cygwin.*|darwin)', sys.platform): + return + return FCompiler.get_linker_so(self) + + def get_flags_linker_so(self): + opt = FCompiler.get_flags_linker_so(self) + if not re.match(r'(win32|cygwin.*|darwin)', sys.platform): + opt.append("-shared") + if sys.platform[:5]=='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 + # the safest thing, but seems to work. 'man gcc' says: + # ".. Instead of using -mimpure-text, you should compile all + # source code with -fpic or -fPIC." + opt.append('-mimpure-text') + return opt + + def get_libgcc_dir(self): + status, output = self.exec_command('%s -print-libgcc-file-name' \ + % (self.compiler_f77[0]),use_tee=0) + if not status: + return os.path.dirname(output) + return + + def get_library_dirs(self): + opt = FCompiler.get_library_dirs(self) + if sys.platform[:5] != 'linux': + d = self.get_libgcc_dir() + if d: + opt.append(d) + return opt + + def get_libraries(self): + opt = FCompiler.get_library_dirs(self) + d = self.get_libgcc_dir() + if d is not None: + for g2c in ['g2c-pic','g2c']: + f = self.static_lib_format % (g2c, self.static_lib_extension) + if os.path.isfile(os.path.join(d,f)): + break + else: + g2c = 'g2c' + if sys.platform=='win32': + opt.extend(['gcc',g2c]) + else: + opt.append(g2c) + return opt + + def get_flags_debug(self): + return ['-g'] + + def get_flags_opt(self): + opt = ['-O3','-funroll-loops'] + return opt + + 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') + 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)(): + opt.append('-mcpu='+a) + opt.append('-mtune='+a) + break + return opt + march_flag = 1 + if self.get_version() == '0.5.26': # gcc 3.0 + if cpu.is_AthlonK6(): + opt.append('-march=k6') + elif cpu.is_AthlonK7(): + opt.append('-march=athlon') + else: + march_flag = 0 + elif self.get_version() >= '3.1.1': # gcc >= 3.1.1 + if cpu.is_AthlonK6(): + opt.append('-march=k6') + elif cpu.is_AthlonK6_2(): + opt.append('-march=k6-2') + elif cpu.is_AthlonK6_3(): + opt.append('-march=k6-3') + elif cpu.is_AthlonK7(): + opt.append('-march=athlon') + elif cpu.is_AthlonMP(): + opt.append('-march=athlon-mp') + # there's also: athlon-tbird, athlon-4, athlon-xp + elif cpu.is_PentiumIV(): + opt.append('-march=pentium4') + elif cpu.is_PentiumIII(): + opt.append('-march=pentium3') + elif cpu.is_PentiumII(): + opt.append('-march=pentium2') + else: + march_flag = 0 + if cpu.has_mmx(): opt.append('-mmmx') + if self.get_version() > '3.2.2': + if cpu.has_sse2(): opt.append('-msse2') + if cpu.has_sse(): opt.append('-msse') + if cpu.has_3dnow(): opt.append('-m3dnow') + else: + march_flag = 0 + if march_flag: + pass + elif cpu.is_i686(): + opt.append('-march=i686') + elif cpu.is_i586(): + opt.append('-march=i586') + elif cpu.is_i486(): + opt.append('-march=i486') + elif cpu.is_i386(): + opt.append('-march=i386') + if cpu.is_Intel(): + opt.extend(['-malign-double','-fomit-frame-pointer']) + return opt + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='gnu') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/hpuxfcompiler.py b/scipy_distutils/hpuxfcompiler.py new file mode 100644 index 000000000..60682a81e --- /dev/null +++ b/scipy_distutils/hpuxfcompiler.py @@ -0,0 +1,39 @@ +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler + +class HPUXFCompiler(FCompiler): + + compiler_type = 'hpux' + version_pattern = r'HP F90 (?P<version>[^\s*,]*)' + + executables = { + 'version_cmd' : ["f90", "+version"], + 'compiler_f77' : ["f90"], + 'compiler_fix' : ["f90"], + 'compiler_f90' : ["f90"], + 'linker_so' : None, + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags(self): + return ['+pic=long','+ppu'] + def get_flags_opt(self): + return ['-O3'] + def get_libraries(self): + return ['m'] + def get_version(self, force=0, ok_status=[256,0]): + # XXX status==256 may indicate 'unrecognized option' or + # 'no input file'. So, version_cmd needs more work. + return FCompiler.get_version(self,force,ok_status) + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(10) + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='hpux') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/intelfcompiler.py b/scipy_distutils/intelfcompiler.py new file mode 100644 index 000000000..df91f5ce3 --- /dev/null +++ b/scipy_distutils/intelfcompiler.py @@ -0,0 +1,119 @@ +# http://developer.intel.com/software/products/compilers/flin/ + +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler, dummy_fortran_file +from exec_command import find_executable + +class IntelFCompiler(FCompiler): + + compiler_type = 'intel' + version_pattern = r'Intel\(R\) Fortran Compiler for 32-bit '\ + 'applications, Version (?P<version>[^\s*]*)' + + for fc_exe in map(find_executable,['ifort','ifc']): + if os.path.isfile(fc_exe): + break + + executables = { + 'version_cmd' : [fc_exe, "-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","-72"], + 'compiler_f90' : [fc_exe], + 'linker_so' : [fc_exe,"-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags(self): + opt = ["-KPIC","-cm"] + return opt + + def get_flags_opt(self): + return ['-O3','-unroll'] + + def get_flags_arch(self): + opt = [] + if cpu.has_fdiv_bug(): + opt.append('-fdiv_check') + if cpu.has_f00f_bug(): + opt.append('-0f_check') + if cpu.is_PentiumPro() or cpu.is_PentiumII(): + opt.extend(['-tpp6','-xi']) + elif cpu.is_PentiumIII(): + opt.append('-tpp6') + elif cpu.is_Pentium(): + opt.append('-tpp5') + elif cpu.is_PentiumIV(): + opt.extend(['-tpp7','-xW']) + if cpu.has_mmx(): + opt.append('-xM') + return opt + + def get_flags_linker_so(self): + opt = FCompiler.get_flags_linker_so(self) + v = self.get_version() + if v and v >= '8.0': + opt.append('-nofor_main') + return opt + +class IntelVisualFCompiler(FCompiler): + + compiler_type = 'intelv' + version_pattern = r'Intel\(R\) Fortran Compiler for 32-bit applications, '\ + 'Version (?P<version>[^\s*]*)' + + ar_exe = 'lib.exe' + fc_exe = 'ifl' + if sys.platform=='win32': + from distutils.msvccompiler import MSVCCompiler + ar_exe = MSVCCompiler().lib + + executables = { + 'version_cmd' : [fc_exe, "-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"], + 'archiver' : [ar_exe, "/verbose", "/OUT:"], + 'ranlib' : None + } + + compile_switch = '/c ' + object_switch = '/Fo' #No space after /Fo! + + def get_flags(self): + opt = ['/nologo','/MD','/nbs','/Qlowercase','/us'] + return opt + + def get_flags_debug(self): + return ['/4Yb','/d2'] + + def get_flags_opt(self): + return ['/O3','/Qip','/Qipo','/Qipo_obj'] + + def get_flags_arch(self): + opt = [] + if cpu.is_PentiumPro() or cpu.is_PentiumII(): + opt.extend(['/G6','/Qaxi']) + elif cpu.is_PentiumIII(): + opt.extend(['/G6','/QaxK']) + elif cpu.is_Pentium(): + opt.append('/G5') + elif cpu.is_PentiumIV(): + opt.extend(['/G7','/QaxW']) + if cpu.has_mmx(): + opt.append('/QaxM') + return opt + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='intel') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/mipsfcompiler.py b/scipy_distutils/mipsfcompiler.py new file mode 100644 index 000000000..daa4468ec --- /dev/null +++ b/scipy_distutils/mipsfcompiler.py @@ -0,0 +1,53 @@ +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler + +class MipsFCompiler(FCompiler): + + compiler_type = 'mips' + version_pattern = r'MIPSpro Compilers: Version (?P<version>[^\s*,]*)' + + executables = { + 'version_cmd' : ["f90", "-version"], + 'compiler_f77' : ["f77", "-f77"], + 'compiler_fix' : ["f90", "-fixedform"], + 'compiler_f90' : ["f90"], + 'linker_so' : ["f90","-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : None + } + + def get_flags(self): + return ['-KPIC','-n32'] + def get_flags_opt(self): + return ['-O3'] + def get_flags_arch(self): + opt = [] + for a in '19 20 21 22_4k 22_5k 24 25 26 27 28 30 32_5k 32_10k'.split(): + if getattr(cpu,'is_IP%s'%a)(): + opt.append('-TARG:platform=IP%s' % a) + break + return opt + def get_flags_arch_f77(self): + r = None + if cpu.is_r10000(): r = 10000 + elif cpu.is_r12000(): r = 12000 + elif cpu.is_r8000(): r = 8000 + elif cpu.is_r5000(): r = 5000 + elif cpu.is_r4000(): r = 4000 + if r is not None: + return ['r%s' % (r)] + return [] + def get_flags_arch_f90(self): + r = self.get_flags_arch_f77() + if r: + r[0] = '-' + r[0] + return r + +if __name__ == '__main__': + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='mips') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/nagfcompiler.py b/scipy_distutils/nagfcompiler.py new file mode 100644 index 000000000..b9c1f354d --- /dev/null +++ b/scipy_distutils/nagfcompiler.py @@ -0,0 +1,35 @@ +import os +import sys + +from cpuinfo import cpu +from fcompiler import FCompiler + +class NAGFCompiler(FCompiler): + + compiler_type = 'nag' + version_pattern = r'NAGWare Fortran 95 compiler Release (?P<version>[^\s]*)' + + executables = { + 'version_cmd' : ["f95", "-V"], + 'compiler_f77' : ["f95", "-fixed"], + 'compiler_fix' : ["f95", "-fixed"], + 'compiler_f90' : ["f95"], + 'linker_so' : ["f95","-Wl,shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags_opt(self): + return ['-O4'] + def get_flags_arch(self): + return ['-target=native'] + def get_flags_debug(self): + return ['-g','-gline','-g90','-nan','-C'] + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='nag') + compiler.customize() + print compiler.get_version() diff --git a/scipy_distutils/vastfcompiler.py b/scipy_distutils/vastfcompiler.py new file mode 100644 index 000000000..125195dac --- /dev/null +++ b/scipy_distutils/vastfcompiler.py @@ -0,0 +1,49 @@ +import os +import sys + +from cpuinfo import cpu +from gnufcompiler import GnuFCompiler +#from fcompiler import FCompiler + +class VastFCompiler(GnuFCompiler): + + compiler_type = 'vast' + version_pattern = r'\s*Pacific-Sierra Research vf90 '\ + '(Personal|Professional)\s+(?P<version>[^\s]*)' + + # VAST f90 does not support -o with -c. So, object files are created + # to the current directory and then moved to build directory + object_switch = ' && function _mvfile { mv -v `basename $1` $1 ; } && _mvfile ' + + executables = { + 'version_cmd' : ["vf90", "-v"], + 'compiler_f77' : ["g77"], + 'compiler_fix' : ["f90", "-Wv,-ya"], + 'compiler_f90' : ["f90"], + 'linker_so' : ["f90"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_version_cmd(self): + f90 = self.compiler_f90[0] + d,b = os.path.split(f90) + vf90 = os.path.join(d,'v'+b) + return vf90 + + def get_flags_arch(self): + vast_version = self.get_version() + gnu = GnuFCompiler() + gnu.customize() + self.version = gnu.get_version() + opt = GnuFCompiler.get_flags_arch(self) + self.version = vast_version + return opt + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from fcompiler import new_fcompiler + compiler = new_fcompiler(compiler='vast') + compiler.customize() + print compiler.get_version() |