Ticket #13887: 13887_fortran_tmp_dir.patch
File 13887_fortran_tmp_dir.patch, 4.9 KB (added by , 10 years ago) |
---|
-
sage/misc/inline_fortran.py
# HG changeset patch # User Jeroen Demeyer <jdemeyer@cage.ugent.be> # Date 1356860777 -3600 # Node ID 6330cd9fe67b6d236f5756db60734eacbaa2d3f1 # Parent 65b59ae52ccbd75c5f61f2dab1c6634cfc3ea722 In inline_fortran, use a temporary directory instead of the current directory diff --git a/sage/misc/inline_fortran.py b/sage/misc/inline_fortran.py
a b 1 """ 2 Fortran compiler 3 """ 1 4 import __builtin__ 2 5 import os 3 6 4 from sage.misc.temporary_file import tmp_filename 5 6 count=0 7 from sage.misc.temporary_file import tmp_dir 7 8 8 9 9 10 class InlineFortran: … … 34 35 35 36 TESTS:: 36 37 38 sage: os.chdir(SAGE_ROOT) 37 39 sage: fortran.eval("SYNTAX ERROR !@#$") 38 40 Traceback (most recent call last): 39 41 ... 40 42 RuntimeError: failed to compile Fortran code:... 43 sage: os.getcwd() == SAGE_ROOT 44 True 41 45 """ 42 46 if len(x.splitlines()) == 1 and os.path.exists(x): 43 47 filename = x 44 48 x = open(x).read() 45 49 if filename.lower().endswith('.f90'): 46 50 x = '!f90\n' + x 47 global count48 51 49 52 from numpy import f2py 50 old_import_path=os.sys.path51 cwd=os.getcwd()52 os.sys.path.append(cwd)53 53 54 #name = tmp_dir() + '/fortran_module_%d'%count 55 name = 'fortran_module_%d'%count 56 if os.path.exists(name): 57 os.unlink(name) 58 s_lib_path="" 59 s_lib="" 60 for s in self.library_paths: 61 s_lib_path=s_lib_path+"-L"+s+" " 54 # Create everything in a temporary directory 55 mytmpdir = tmp_dir() 62 56 63 for s in self.libraries: 64 s_lib=s_lib +"-l"+s + " " 57 try: 58 old_cwd = os.getcwd() 59 os.chdir(mytmpdir) 65 60 66 # if the first line has !f90 as a comment gfortran will treat it as 67 # fortran 90 code 68 if x.startswith('!f90'): 69 fname = tmp_filename(ext='.f90') 70 else: 71 fname = tmp_filename(ext='.f') 72 73 log = tmp_filename() 74 extra_args = '--quiet --f77exec=sage-inline-fortran --f90exec=sage-inline-fortran %s %s >"%s" 2>&1'%( 75 s_lib_path, s_lib, log) 76 77 f2py.compile(x, name, extra_args = extra_args, source_fn=fname) 78 79 log_string = open(log).read() 80 81 os.unlink(log) 82 os.unlink(fname) 83 84 # f2py.compile() doesn't raise any exception if it fails. 85 # So we manually check whether the compiled file exists. 86 # NOTE: the .so extension is used, even on OS X where .dylib 87 # would be expected. 88 soname = name + '.so' 89 if not os.path.isfile(soname): 90 raise RuntimeError("failed to compile Fortran code:\n" + log_string) 91 92 if self.verbose: 93 print log_string 94 95 count += 1 96 try: 97 m=__builtin__.__import__(name) 98 except ImportError: 99 if not self.verbose: 61 old_import_path = os.sys.path 62 os.sys.path.append(mytmpdir) 63 64 name = "fortran_module" # Python module name 65 # if the first line has !f90 as a comment, gfortran will 66 # treat it as Fortran 90 code 67 if x.startswith('!f90'): 68 fortran_file = name + '.f90' 69 else: 70 fortran_file = name + '.f' 71 72 s_lib_path = "" 73 s_lib = "" 74 for s in self.library_paths: 75 s_lib_path = s_lib_path + "-L%s " 76 77 for s in self.libraries: 78 s_lib = s_lib + "-l%s "%s 79 80 log = name + ".log" 81 extra_args = '--quiet --f77exec=sage-inline-fortran --f90exec=sage-inline-fortran %s %s >"%s" 2>&1'%( 82 s_lib_path, s_lib, log) 83 84 f2py.compile(x, name, extra_args = extra_args, source_fn=fortran_file) 85 log_string = open(log).read() 86 87 # f2py.compile() doesn't raise any exception if it fails. 88 # So we manually check whether the compiled file exists. 89 # NOTE: the .so extension is used, even on OS X where .dylib 90 # might be expected. 91 soname = name + '.so' 92 if not os.path.isfile(soname): 93 raise RuntimeError("failed to compile Fortran code:\n" + log_string) 94 95 if self.verbose: 100 96 print log_string 101 return 97 98 m = __builtin__.__import__(name) 102 99 finally: 103 os.sys.path=old_import_path 104 os.unlink(soname) 100 os.sys.path = old_import_path 101 os.chdir(old_cwd) 102 try: 103 import shutil 104 shutil.rmtree(mytmpdir) 105 except OSError: 106 # This can fail for example over NFS 107 pass 105 108 106 109 for k, x in m.__dict__.iteritems(): 107 110 if k[0] != '_':