#! /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()