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
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