#! /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=<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_<machine>_gnu_<version>.a
#		For Intel ifc it is libgen_intel_<version>
#		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

if __name__ == '__main__':
	say = 'olb, '

	argv = sys.argv
	all = len( args( argv ) ) == 1

	argv.append('-obj')

	verbose = is_there( '-verbose', argv )
	lib_dir = start   ( '-dir='   , argv )

	hostname = os.environ['HOSTNAME']
	if hostname == 'cass185.ucsd.edu':
		hostname = 'ips.ucsd.edu'
	is_master = os.environ['SMEI_MASTER'].find(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()
