#! /usr/bin/python #+ # NAME: # olb # PURPOSE: # Recompile all F77 subroutines and functions, and create object library # libgen.a from the object files # CALLING SEQUENCE: # olb # olb module (where 'module' is an F77 module, e.g. forgen) # INPUTS: # Fortran files selected from a number of subdirectories (see PROCEDURE). # OPTIONAL INPUTS: # -g77 use g77 compiler # -intel use Intel Fortran compiler # -pgi use Portland compiler # -absoft or $ABSOFT set # use Absoft compiler # -dir= destination directory for static library # If neither keyword or environment variable is set then g77 or Intel # compiler is used (whichever is found first using 'which') # OUTPUTS: # New or updated object library libgen.a in $for (when executed on # the '$SMEI_ACCOUNT' software account) or $myfor (when executed on a # user account). # CALLS: # mk, tiny.is_there, tiny.args, tine.run_cmd # SIDE EFFECTS: # A compilation status line is added to $sys/olb.log # RESTRICTIONS: # Can only be executed from the software account (i.e. $USER=$SMEI_ACCOUNT). # A line is added to $sys/olb.log with the time of compilation and # the module updated (if present) # PROCEDURE: # > If no explicit module is specified then a hardcoded list of # Fortran files is used from $for and $SMEI_FOR, mostly from # subdirectories 'lib' and 'os' (containing OS-dependent files) # > If an explicit module with name 'module' is specified then the # file 'module.f' is processed after looking for it in directories # $myfor, $for and $SMEI_FOR, respectively. # > Object files are created in $temp and deleted after use # > The library is created in $for (on the software account) or $myfor # (on a user account). # > The compilation command looks for include files in the directories # $for/h, $SMEI_FOR/h and $SMEI_FOR/h/linux. # > Two other switches are included: # -ffixed-line-length-none -> extended fortran # -c -> suppresses linking into executable # # Some of the fortran files are compiled with the -w switch added to # suppress warning messages, mostly about unimplemented intrinsics such # as cosd, sind, etc. # # An earlier version also used switches to be able to use our old # 'signal' subroutine (signal is a unix function included in the # badu77 group and the unix group of intrinsics): # -fbadu77-intrinsic-hide # -funix-intrinsic-hide # Since 'signal' has been renamed 'say' we don't need these anymore. # # > For gcc the machine type is determined with gcc -dumpmachine and # the version number with gcc -dumpversion. # For the Intel compilers -dumpmachine doesn't work, and -dumpversion # only works for version 8.0. ifc -dumpversion is used to determine # the version number. If it doesn't work version 6.0 is assumed (this # is the only version of ifc prior to 8.0 that we used). # MODIFICATION HISTORY: # FEB-2001, Paul Hick (UCSD/CASS) # SEP-2002, Paul Hick (UCSD/CASS) # Removed -fdollar-ok option from g77 compilations (all dollar # signs in variable names should have been removed by now). # SEP-2004, Paul Hick (UCSD/CASS) # The name of the libgen library now tries to code # compiler information into the file name. # For g77 the name now is libgen__gnu_.a # For Intel ifc it is libgen_intel_ # On the software account the library is now created in # $SMEI_LIB instead of $for. # OCT-2004, Paul Hick (UCSD/CASS) # Added Portland compiler. # JAN-2004, Paul Hick (UCSD/CASS) # Converted from bash to Python. # SEP-2007, Paul Hick (UCSD/CASS; pphick@ucsd.edu) # Added get_compiler_intel.f and get_compiler_gnu.f # to list of files to be skipped. #- import sys, os from mk import mk from tiny import is_there, start, args, run_cmd, hide_env say = 'olb, ' argv = sys.argv all = len( args( argv ) ) == 1 argv.append('-obj') verbose = is_there( '-verbose', argv ) lib_dir = start ( '-dir=' , argv ) is_master = os.environ['SMEI_MASTER'].find(os.environ['HOSTNAME']) != -1 if all: # Pick up all *.f files in the all_fdir directories # (recursively) all_fdir = [ os.path.join( os.environ['SMEI_FOR'], 'lib' ), os.path.join( os.environ['SMEI_FOR'], 'os' ,'fnc' ), os.path.join( os.environ['SMEI_FOR'], 'os' ,'linux'), os.path.join( os.environ['SMEI'], 'for' ,'lib' ), os.path.join( os.environ['SMEI'], 'for' ,'tdlib' ) ] skip_files = ['forfits.f','arrinfo.f','get_compiler_intel.f','get_compiler_gnu.f'] f77 = [] for fdir in all_fdir: for root, dirs, files in os.walk( fdir, topdown=False ): for one in files: if one not in skip_files: tmp = os.path.splitext(one) if tmp[1] == '.f': f77.append(tmp[0]) argv[len(argv):] = f77 # Add explicit list of other source code #argv[len(argv):] = [ \ # '' , \ # '' ] # Compile all functions/subroutines results = mk( argv ) f77 = results['f77'] obj = results['obj'] if len(f77) == 0: print say+'no objects files created' sys.exit() f77id = f77[2] f77 = f77[0] if all and (f77 == 'g77' or f77 == 'gfortran'): argv = argv[0:argv.index('-obj')+1] argv.append( 'goniod' ) results = mk( argv ) results = results['obj'] if len(results) > 0: obj.append( (results)[0] ) if lib_dir != '': if not os.path.isdir(lib_dir): print say+'directory does not exist, '+lib_dir sys.exit() log_file = '' elif os.environ['USER'] == os.environ['SMEI_ACCOUNT']: if is_master: log_file = os.path.join(os.environ['SYS'],'olb.log') if not os.path.isfile(log_file): log_file = '' lib_dir = os.environ['SMEI_LIB'] else: log_file = '' lib_dir = os.environ['TUB'] else: log_file = os.path.join(os.environ['FOR'],'olb.log') lib_dir = os.environ['FOR'] libgen = os.path.join( lib_dir,'libgen'+f77id+'.a' ) if all: if os.path.isfile( libgen ): os.remove( libgen ) run_cmd( 'ar -rcsv '+libgen+' '+' '.join(obj), verbose) else: run_cmd( 'ar -rsv '+libgen+' '+' '.join(obj), verbose) for tmp in obj: os.remove(tmp) if not is_master: # If compiling on one of the subnet members, copy # the library to the SMEI master tree. if (os.environ['HOSTNAME']).find('.ucsd.edu') != -1: run_cmd( 'scp '+libgen+' '+os.path.join(os.environ['SMEI_MASTER'],'ucsd','gen','lib','linux'), True ) os.remove(libgen) print say+hide_env(libgen) if log_file != '': log_string = (os.popen('date +"%Y-%m-%d %H:%M:%S"')).read() log_string = (log_string.split('\n'))[0] log_string += ' '+os.path.split(libgen)[1] if all: log_string += ' all' else: log_string += ' '.join( (args( argv ))[1:] ) tmp = (open(log_file, 'r')).read() tmp += log_string+'\n' (open(log_file, 'w')).write(tmp) sys.exit()