示例#1
0
    def compile_irbempy(self):
        fcompiler = self.fcompiler
        if fcompiler in ['none', 'None']:
            warnings.warn('Fortran compiler specified was "none."\n'
                          'IRBEM will not be available.')
            return
        # 64 bit or 32 bit?
        bit = len('%x' % sys.maxsize) * 4
        irbemdir = 'irbem-lib-20210630-a4759c0'
        srcdir = os.path.join('spacepy', 'irbempy', irbemdir, 'source')
        outdir = os.path.join(os.path.abspath(self.build_lib), 'spacepy',
                              'irbempy')
        #Possible names of the output library. Unfortunately this seems
        #to depend on Python version, f2py version, and phase of the moon
        libfiles = get_irbem_libfiles()
        #Delete any irbem extension modules from other versions
        for f in glob.glob(os.path.join(outdir, 'irbempylib*')):
            if not os.path.basename(f) in libfiles:
                os.remove(f)
        #Does a matching one exist?
        existing_libfiles = [
            f for f in libfiles if os.path.exists(os.path.join(outdir, f))
        ]
        #Can we import it?
        importable = []
        for f in existing_libfiles:
            fspec = os.path.join(outdir, f)
            if imp:  #old-style imports
                suffixes = imp.get_suffixes()
                desc = next(
                    (s for s in imp.get_suffixes() if f.endswith(s[0])), None)
                if not desc:  #apparently not loadable
                    os.remove(fspec)
                    continue
                fp = open(fspec, 'rb')
                try:
                    imp.load_module('irbempylib', fp, fspec, desc)
                except ImportError:
                    fp.close()
                    os.remove(fspec)
                else:
                    fp.close()
                    importable.append(f)
            else:  #Py3.3 and later imports, not tested
                loader = importlib.machinery.ExtensionFileLoader(
                    'irbempylib', fspec)
                try:
                    loader.load_module('irbempylib')
                except ImportError:
                    os.remove(fspec)
                else:
                    importable.append(f)
        existing_libfiles = importable
        #if MORE THAN ONE matching output library file, delete all;
        #no way of knowing which is the correct one or if it's up to date
        if len(existing_libfiles) > 1:
            for f in existing_libfiles:
                os.remove(os.path.join(outdir, f))
            existing_libfiles = []
        #If there's still one left, check up to date
        if existing_libfiles:
            sources = glob.glob(os.path.join(srcdir, '*.f')) + \
                      glob.glob(os.path.join(srcdir, '*.inc'))
            if not distutils.dep_util.newer_group(
                    sources, os.path.join(outdir, existing_libfiles[0])):
                return

        if not sys.platform in ('darwin', 'linux2', 'linux', 'win32'):
            warnings.warn('%s not supported at this time. ' % sys.platform +
                          'IRBEM will not be available')
            return
        if fcompiler == 'pg' and sys.platform == 'darwin':
            warnings.warn(
                'Portland Group compiler "pg" not supported on Mac OS\n'
                'IRBEM will not be available.')
            return
        if fcompiler != 'gnu95' and sys.platform == 'win32':
            warnings.warn('Only supported compiler on Win32 is gnu95\n'
                          'IRBEM will not be available.')
            return

        if not os.path.exists(outdir):
            os.makedirs(outdir)
        builddir = os.path.join(self.build_temp, 'irbem')
        if os.path.exists(builddir):
            shutil.rmtree(builddir)
        shutil.copytree(os.path.join('spacepy', 'irbempy', irbemdir), builddir)
        shutil.copy(
            os.path.join(builddir, 'source', 'wrappers_{0}.inc'.format(bit)),
            os.path.join(builddir, 'source', 'wrappers.inc'.format(bit)))

        f2py_env, fcompexec = f2py_options(fcompiler, self.distribution)

        # compile irbemlib
        olddir = os.getcwd()
        os.chdir(builddir)
        F90files = ['source/onera_desp_lib.f', 'source/CoordTrans.f', 'source/AE8_AP8.f', 'source/find_foot.f',\
                    'source/LAndI2Lstar.f', 'source/drift_bounce_orbit.f']
        functions = ['make_lstar1', 'make_lstar_shell_splitting1', 'find_foot_point1',\
                     'coord_trans1','find_magequator1', 'find_mirror_point1',
                     'get_field1', 'get_ae8_ap8_flux', 'fly_in_nasa_aeap1',
                     'trace_field_line2_1', 'trace_field_line_towards_earth1', 'trace_drift_bounce_orbit',
                     'landi2lstar1', 'landi2lstar_shell_splitting1']

        # call f2py
        cmd = self.f2py + [
            '--overwrite-signature', '-m', 'irbempylib', '-h', 'irbempylib.pyf'
        ] + F90files + ['only:'] + functions + [':']
        subprocess.check_call(cmd)
        # intent(out) substitute list
        outlist = ['lm', 'lstar', 'blocal', 'bmin', 'xj', 'mlt', 'xout', 'bmin', 'posit', \
                   'xgeo', 'bmir', 'bl', 'bxgeo', 'flux', 'ind', 'xfoot', 'bfoot', 'bfootmag',\
                   'leI0', 'Bposit', 'Nposit', 'hmin', 'hmin_lon']

        inlist = ['sysaxesin', 'sysaxesout', 'iyr', 'idoy', 'secs', 'xin', 'kext', 'options',
                  'sysaxes', 'UT', 'xIN1', 'xIN2', 'xIN3', 'stop_alt', 'hemi_flag', 'maginput',\
                  't_resol', 'r_resol', 'lati', 'longi', 'alti', 'R0','xx0']
        fln = 'irbempylib.pyf'
        if not os.path.isfile(fln):
            warnings.warn('f2py failed; ' 'IRBEM will not be available.')
            os.chdir(olddir)
            return
        print('Substituting fortran intent(in/out) statements')
        with open(fln, 'r') as f:
            filestr = f.read()
        for item in inlist:
            filestr = subst(':: ' + item, ', intent(in) :: ' + item, filestr)
        for item in outlist:
            filestr = subst(':: ' + item, ', intent(out) :: ' + item, filestr)
        with open(fln, 'w') as f:
            f.write(filestr)

        print('Building irbem library...')
        # compile (platform dependent)
        os.chdir('source')
        comppath = {
            'pg': 'pgf77',
            'gnu': 'g77',
            'gnu95': 'gfortran',
            'intel': 'ifort',
            'intelem': 'ifort',
        }[fcompiler]
        compflags = {
            'pg': ['-Mnosecond_underscore', '-w', '-fastsse', '-fPIC'],
            'gnu': ['-w', '-O2', '-fPIC', '-fno-second-underscore'],
            'gnu95':
            ['-w', '-O2', '-fPIC', '-ffixed-line-length-none', '-std=legacy'],
            'intel': ['-Bstatic', '-assume', '2underscores', '-O2', '-fPIC'],
            'intelem': ['-Bdynamic', '-O2', '-fPIC'],
        }[fcompiler]
        if fcompiler == 'gnu':
            if bit == 64:
                compflags = ['-m64'] + compflags
        if not sys.platform.startswith('win') and fcompiler == 'gnu95' \
           and not os.uname()[4].startswith('arm'):
            # Raspberry Pi doesn't have this switch and assumes 32-bit
            compflags = ['-m{0}'.format(bit)] + compflags
        if fcompiler.startswith('intel'):
            if bit == 32:
                compflags = ['-Bstatic', '-assume', '2underscores'] + compflags
            else:
                compflags = ['-Bdynamic'] + compflags
        comp_candidates = [comppath]
        if fcompexec is not None and 'compiler_f77' in fcompexec:
            comp_candidates.insert(0, fcompexec['compiler_f77'][0])
        for fc in comp_candidates:
            retval = subprocess.call([fc, '-c'] + compflags +
                                     list(glob.glob('*.f')))
            if retval == 0:
                break
            else:
                warnings.warn('Compiler {0} failed, trying another'.format(fc))
        else:
            warnings.warn('irbemlib compile failed. '
                          'Try a different Fortran compiler? (--fcompiler)')
            os.chdir(olddir)
            return
        retval = -1
        if 'archiver' in fcompexec:
            retval = subprocess.check_call(fcompexec['archiver'] +
                                           ['libBL2.a'] +
                                           list(glob.glob('*.o')))
            if (retval == 0) and 'ranlib' in fcompexec:
                retval = subprocess.call(fcompexec['ranlib'] + ['libBL2.a'])
            if retval != 0:
                warnings.warn(
                    'irbemlib linking failed, trying with default linker.')
        if retval != 0:  #Try again with defaults
            archiver = {
                'darwin': ['libtool', '-static', '-o'],
                'linux': ['ar', '-r '],
                'linux2': ['ar', '-r '],
                'win32': ['ar', '-r '],
            }[sys.platform]
            ranlib = {
                'darwin': None,
                'linux': 'ranlib',
                'linux2': 'ranlib',
                'win32': 'ranlib',
            }[sys.platform]
            try:
                subprocess.check_call(archiver + ['libBL2.a'] +
                                      list(glob.glob('*.o')))
                if ranlib:
                    subprocess.check_call([ranlib, 'libBL2.a'])
            except:
                warnings.warn(
                    'irbemlib linking failed. '
                    'Try a different Fortran compiler? (--fcompiler)')
                os.chdir(olddir)
                return
        os.chdir('..')

        f2py_flags = ['--fcompiler={0}'.format(fcompiler)]
        if fcompiler == 'gnu':
            f2py_flags.append(
                '--f77flags=-fno-second-underscore,-mno-align-double')
            if bit == 64:
                f2py_flags[-1] += ',-m64'
        if fcompiler == 'gnu95':
            f2py_flags.extend(
                ['--f77flags=-std=legacy', '--f90flags=-std=legacy'])
        if self.compiler:
            f2py_flags.append('--compiler={0}'.format(self.compiler))
        if self.f77exec:
            f2py_flags.append('--f77exec={0}'.format(self.f77exec))
        if self.f90exec:
            f2py_flags.append('--f90exec={0}'.format(self.f90exec))
        try:
            subprocess.check_call(self.f2py + [
                '-c', 'irbempylib.pyf', 'source/onera_desp_lib.f', '-Lsource',
                '-lBL2'
            ] + f2py_flags,
                                  env=f2py_env)
        except:
            warnings.warn('irbemlib module failed. '
                          'Try a different Fortran compiler? (--fcompiler)')

        #All matching outputs
        created_libfiles = [f for f in libfiles if os.path.exists(f)]
        if len(created_libfiles) == 0:  #no matches
            warnings.warn('irbemlib build produced no recognizable module. '
                          'Try a different Fortran compiler? (--fcompiler)')
        elif len(created_libfiles) == 1:  #only one, no ambiguity
            shutil.move(created_libfiles[0],
                        os.path.join(outdir, created_libfiles[0]))
        elif len(created_libfiles) == 2 and \
                len(existing_libfiles) == 1: #two, so one is old and one new
            for f in created_libfiles:
                if f == existing_libfiles[0]:  #delete the old one
                    os.remove(f)
                else:  #and move the new one to its place in build
                    shutil.move(f, os.path.join(outdir, f))
        else:
            warnings.warn(
                'irbem build failed: multiple build outputs ({0}).'.format(
                    ', '.join(created_libfiles)))
        os.chdir(olddir)
        return
示例#2
0
    def compile_irbempy(self):
        fcompiler = self.fcompiler
        if fcompiler in ['none', 'None']:
            warnings.warn(
                'Fortran compiler specified was "none."\n'
                'IRBEM will not be available.')
            return
        # 64 bit or 32 bit?
        bit = len('%x' % sys.maxsize)*4
        irbemdir = 'irbem-lib-2016-03-21-rev546'
        srcdir = os.path.join('spacepy', 'irbempy', irbemdir, 'source')
        outdir = os.path.join(os.path.abspath(self.build_lib),
                              'spacepy', 'irbempy')
        #Possible names of the output library. Unfortunately this seems
        #to depend on Python version, f2py version, and phase of the moon
        libfiles = get_irbem_libfiles()
        #Delete any irbem extension modules from other versions
        for f in glob.glob(os.path.join(outdir, 'irbempylib*')):
            if not os.path.basename(f) in libfiles:
                os.remove(f)
        #Does a matching one exist?
        existing_libfiles = [f for f in libfiles
                             if os.path.exists(os.path.join(outdir, f))]
        #Can we import it?
        importable = []
        for f in existing_libfiles:
            fspec = os.path.join(outdir, f)
            if imp: #old-style imports
                suffixes = imp.get_suffixes()
                desc = next(
                    (s for s in imp.get_suffixes() if f.endswith(s[0])), None)
                if not desc: #apparently not loadable
                    os.remove(fspec)
                    continue
                fp = open(fspec, 'rb')
                try:
                    imp.load_module('irbempylib', fp, fspec, desc)
                except ImportError:
                    fp.close()
                    os.remove(fspec)
                else:
                    fp.close()
                    importable.append(f)
            else: #Py3.3 and later imports, not tested
                loader = importlib.machinery.ExtensionFileLoader(
                    'irbempylib', fspec)
                try:
                    loader.load_module('irbempylib')
                except ImportError:
                    os.remove(fspec)
                else:
                    importable.append(f)
        existing_libfiles = importable
        #if MORE THAN ONE matching output library file, delete all;
        #no way of knowing which is the correct one or if it's up to date
        if len(existing_libfiles) > 1:
            for f in existing_libfiles:
                os.remove(os.path.join(outdir, f))
            existing_libfiles = []
        #If there's still one left, check up to date
        if existing_libfiles:
            sources = glob.glob(os.path.join(srcdir, '*.f')) + \
                      glob.glob(os.path.join(srcdir, '*.inc'))
            if not distutils.dep_util.newer_group(
                sources, os.path.join(outdir, existing_libfiles[0])):
                return

        if not sys.platform in ('darwin', 'linux2', 'linux', 'win32'):
            warnings.warn(
                '%s not supported at this time. ' % sys.platform +
                'IRBEM will not be available')
            return
        if fcompiler == 'pg' and sys.platform == 'darwin':
            warnings.warn(
                'Portland Group compiler "pg" not supported on Mac OS\n'
                'IRBEM will not be available.')
            return
        if fcompiler != 'gnu95' and sys.platform == 'win32':
            warnings.warn(
                'Only supported compiler on Win32 is gnu95\n'
                'IRBEM will not be available.')
            return

        if not os.path.exists(outdir):
            os.makedirs(outdir)
        builddir = os.path.join(self.build_temp, 'irbem')
        if os.path.exists(builddir):
            shutil.rmtree(builddir)
        shutil.copytree(os.path.join('spacepy', 'irbempy', irbemdir),
                        builddir)
        shutil.copy(
            os.path.join(builddir, 'source', 'wrappers_{0}.inc'.format(bit)),
            os.path.join(builddir, 'source', 'wrappers.inc'.format(bit)))

        f2py_env, fcompexec = f2py_options(fcompiler, self.distribution)

        # compile irbemlib
        olddir = os.getcwd()
        os.chdir(builddir)
        F90files = ['source/onera_desp_lib.f', 'source/CoordTrans.f', 'source/AE8_AP8.f', 'source/find_foot.f',\
                    'source/drift_bounce_orbit.f']
        functions = ['make_lstar1', 'make_lstar_shell_splitting1', 'find_foot_point1',\
                     'coord_trans1','find_magequator1', 'find_mirror_point1',
                     'get_field1', 'get_ae8_ap8_flux', 'fly_in_nasa_aeap1',
                     'trace_field_line2_1', 'trace_field_line_towards_earth1', 'trace_drift_bounce_orbit']

        # call f2py
        cmd = [self.f2py, '--overwrite-signature', '-m', 'irbempylib', '-h',
               'irbempylib.pyf'] + F90files + ['only:'] + functions + [':']
        subprocess.check_call(cmd)
        # intent(out) substitute list
        outlist = ['lm', 'lstar', 'blocal', 'bmin', 'xj', 'mlt', 'xout', 'bmin', 'posit', \
                   'xgeo', 'bmir', 'bl', 'bxgeo', 'flux', 'ind', 'xfoot', 'bfoot', 'bfootmag',\
                   'leI0', 'Bposit', 'Nposit', 'hmin', 'hmin_lon']

        inlist = ['sysaxesin', 'sysaxesout', 'iyr', 'idoy', 'secs', 'xin', 'kext', 'options', 
                  'sysaxes', 'UT', 'xIN1', 'xIN2', 'xIN3', 'stop_alt', 'hemi_flag', 'maginput',\
                  't_resol', 'r_resol', 'lati', 'longi', 'alti', 'R0','xx0']
        fln = 'irbempylib.pyf'
        if not os.path.isfile(fln):
            warnings.warn(
                'f2py failed; '
                'IRBEM will not be available.')
            os.chdir(olddir)
            return
        print('Substituting fortran intent(in/out) statements')
        with open(fln, 'r') as f:
            filestr = f.read()
        for item in inlist:
            filestr = subst( ':: '+item, ', intent(in) :: '+item, filestr)
        for item in outlist:
            filestr = subst( ':: '+item, ', intent(out) :: '+item, filestr)
        with open(fln, 'w') as f:
            f.write(filestr)

        # compile (platform dependent)
        os.chdir('source')
        comppath = {
            'pg': 'pgf77',
            'gnu': 'g77',
            'gnu95': 'gfortran',
            'intel': 'ifort',
            'intelem': 'ifort',
            }[fcompiler]
        compflags = {
            'pg': '-Mnosecond_underscore -w -fastsse -fPIC',
            'gnu': '-w -O2 -fPIC -fno-second-underscore',
            'gnu95': '-w -O2 -fPIC -ffixed-line-length-none',
            'intel': '-Bstatic -assume 2underscores -O2 -fPIC',
            'intelem': '-Bdynamic -O2 -fPIC',
            }[fcompiler]
        if fcompiler == 'gnu':
            if bit == 64:
                compflags = '-m64 ' + compflags
        if fcompiler == 'gnu95':
            compflags = '-m{0} '.format(bit) + compflags
        if fcompiler.startswith('intel'):
            if bit == 32:
                compflags = '-Bstatic -assume 2underscores ' + compflags
            else:
                compflags = '-Bdynamic ' + compflags
        comp_candidates = [comppath]
        if fcompexec is not None and 'compiler_f77' in fcompexec:
            comp_candidates.insert(0, fcompexec['compiler_f77'][0])
        for fc in comp_candidates:
            retval = subprocess.call(fc + ' -c ' + compflags + ' *.f',
                                     shell=True)
            if retval == 0:
                break
            else:
                warnings.warn('Compiler {0} failed, trying another'.format(fc))
        else:
            warnings.warn('irbemlib compile failed. '
                          'Try a different Fortran compiler? (--fcompiler)')
            os.chdir(olddir)
            return
        retval = -1
        if 'archiver' in fcompexec:
            archiver = ' '.join(fcompexec['archiver']) + ' '
            ranlib = None
            if 'ranlib' in fcompexec:
                ranlib = ' '.join(fcompexec['ranlib']) + ' '
            retval = subprocess.check_call(archiver + 'libBL2.a *.o', shell=True)
            if (retval == 0) and ranlib:
                retval = subprocess.call(ranlib + 'libBL2.a', shell=True)
            if retval != 0:
                warnings.warn(
                    'irbemlib linking failed, trying with default linker.')
        if retval != 0: #Try again with defaults
            archiver = {
                'darwin': 'libtool -static -o ',
                'linux': 'ar -r ',
                'linux2': 'ar -r ',
                'win32': 'ar - r',
                }[sys.platform]
            ranlib = {
                'darwin': None,
                'linux': 'ranlib ',
                'linux2': 'ranlib ',
                'win32': 'ranlib ',
                }[sys.platform]
            try:
                subprocess.check_call(archiver + 'libBL2.a *.o', shell=True)
                if ranlib:
                    subprocess.check_call(ranlib + 'libBL2.a', shell=True)
            except:
                warnings.warn(
                    'irbemlib linking failed. '
                    'Try a different Fortran compiler? (--fcompiler)')
                os.chdir(olddir)
                return
        os.chdir('..')

        f2py_flags = ['--fcompiler={0}'.format(fcompiler)]
        if fcompiler == 'gnu':
            f2py_flags.append('--f77flags=-fno-second-underscore,-mno-align-double')
            if bit == 64:
                f2py_flags[-1] += ',-m64'
        if self.compiler:
            f2py_flags.append('--compiler={0}'.format(self.compiler))
        if self.f77exec:
            f2py_flags.append('--f77exec={0}'.format(self.f77exec))
        if self.f90exec:
            f2py_flags.append('--f90exec={0}'.format(self.f90exec))
        try:
            subprocess.check_call(
                [self.f2py, '-c', 'irbempylib.pyf', 'source/onera_desp_lib.f',
                 '-Lsource', '-lBL2'] + f2py_flags, env=f2py_env)
        except:
            warnings.warn(
                'irbemlib module failed. '
                'Try a different Fortran compiler? (--fcompiler)')

        #All matching outputs
        created_libfiles = [f for f in libfiles if os.path.exists(f)]
        if len(created_libfiles) == 0: #no matches
            warnings.warn(
                'irbemlib build produced no recognizable module. '
                'Try a different Fortran compiler? (--fcompiler)')
        elif len(created_libfiles) == 1: #only one, no ambiguity
            shutil.move(created_libfiles[0],
                        os.path.join(outdir, created_libfiles[0]))
        elif len(created_libfiles) == 2 and \
                len(existing_libfiles) == 1: #two, so one is old and one new
            for f in created_libfiles:
                if f == existing_libfiles[0]: #delete the old one
                    os.remove(f)
                else: #and move the new one to its place in build
                    shutil.move(f,
                                os.path.join(outdir, f))
        else:
             warnings.warn(
                'irbem build failed: multiple build outputs ({0}).'.format(
                     ', '.join(created_libfiles)))
        os.chdir(olddir)
        return