#! /usr/bin/env bash
#
# Makefile generator for MITgcm UV codes
#   created  by cnh 03/98
#   adapted  by aja 06/98
#   modified by aja 01/00
#   rewritten in bash by eh3 08/03

#  Explain usage
usage()  {
cat <<EOF

Usage: "$0" [OPTIONS]
  where [OPTIONS] can be:

    -help | --help | -h | --h
	  Print this help message and exit.

    -tap | --tap
          Generate a Makefile for a Tapenade build

    -oad | --oad
	  Generate a Makefile for an OpenAD built

    -oadsingularity NAME | --oadsingularity NAME | -oadsngl NAME | --oadsngl NAME
      -oadsingularity=NAME | --oadsingularity=NAME | -oadsngl=NAME | --oadsngl=NAME
	  Here, "NAME" specifies the singularity file
	  that contains the OpenAD execulable.

    -nocat4ad | -dog4ad | -ncad | -dad
	  do not concatenate (cat) source code sent to TAF
	  resulting in compilation of multiple files

    -adoptfile NAME | --adoptfile NAME | -adof NAME | --adof NAME
      -adoptfile=NAME | --adoptfile=NAME | -adof=NAME | --adof=NAME
	  Use "NAME" as the adoptfile.  By default, the file at
	  "tools/adjoint_options/adjoint_oad" (for OpenAD built) or
	  "tools/adjoint_options/adjoint_default" will be used.

    -optfile NAME | --optfile NAME | -of NAME | --of NAME
      -optfile=NAME | --optfile=NAME | -of=NAME | --of=NAME
	  Use "NAME" as the optfile.  By default, an attempt will be
	  made to find an appropriate "standard" optfile in the
	  tools/build_options/ directory.

    -pdepend NAME | --pdepend NAME
      -pdepend=NAME | --pdepend=NAME
	  Get package dependency information from "NAME".

    -pgroups NAME | --pgroups NAME
      -pgroups=NAME | --pgroups=NAME
	  Get the package groups information from "NAME".

    -bash NAME
	  Explicitly specify the Bourne or BASH shell to use

    -make NAME | -m NAME
      --make=NAME | -m=NAME
	  Use "NAME" for the MAKE program. The default is "make" but
	  many platforms, "gmake" is the preferred choice.

    -makefile NAME | -mf NAME
      --makefile=NAME | -mf=NAME
	  Call the makefile "NAME".  The default is "Makefile".

    -makedepend NAME | -md NAME
      --makedepend=NAME | -md=NAME
	  Use "NAME" for the MAKEDEPEND program.

    -rootdir NAME | --rootdir NAME | -rd NAME | --rd NAME
      -rootdir=NAME | --rootdir=NAME | -rd=NAME | --rd=NAME
	  Specify the location of the MITgcm root directory as 'NAME'.
	  By default, genmake will try to find the location by
	  looking in parent directories (up to the 5th parent).

    -mods NAME | --mods NAME | -mo NAME | --mo NAME
      -mods=NAME | --mods=NAME | -mo=NAME | --mo=NAME
	  Here, "NAME" specifies a list of directories that are
	  used for additional source code.  Files found in the
	  "mods list" are given preference over files of the same
	  name found elsewhere.

    -disable NAME | --disable NAME
      -disable=NAME | --disable=NAME
	  Here "NAME" specifies a list of packages that we don't
	  want to use.  If this violates package dependencies,
	  genmake will exit with an error message.

    -enable NAME | --enable NAME
      -enable=NAME | --enable=NAME
	  Here "NAME" specifies a list of packages that we wish
	  to specifically enable.  If this violates package
	  dependencies, genmake will exit with an error message.

    -standarddirs NAME | --standarddirs NAME
      -standarddirs=NAME | --standarddirs=NAME
	  Here, "NAME" specifies a list of directories to be
	  used as the "standard" code.

    -fortran NAME | --fortran NAME | -fc NAME | --fc NAME
      -fc=NAME | --fc=NAME
	  Use "NAME" as the fortran compiler.  By default, genmake
	  will search for a working compiler by trying a list of
	  "usual suspects" such as g77, f77, etc.

    -cc NAME | --cc NAME | -cc=NAME | --cc=NAME
	  Use "NAME" as the C compiler.  By default, genmake
	  will search for a working compiler by trying a list of
	  "usual suspects" such as gcc, c89, cc, etc.

    -use_real4 | -use_r4 | -ur4 | --use_real4 | --use_r4 | --ur4
	  Use "real*4" type for _RS variable (#undef REAL4_IS_SLOW)
	  *only* works if CPP_EEOPTIONS.h allows this.

    -ignoretime | -ignore_time | --ignoretime | --ignore_time
	  Ignore all the "wall clock" routines entirely.  This will
	  not in any way hurt the model results -- it simply means
	  that the code that checks how long the model spends in
	  various routines will give junk values.

    -ts | --ts
	  Produce timing information per timestep
    -papis | --papis
	  Produce summary MFlop/s (and IPC) with PAPI per timestep
    -pcls | --pcls
	  Produce summary MFlop/s etc. with PCL per timestep
    -foolad | --foolad
	  Fool the AD code generator
    -papi | --papi
	  Performance analysis with PAPI
    -pcl | --pcl
	  Performance analysis with PCL
    -hpmt | --hpmt
	  Performance analysis with the HPM Toolkit

    -ieee | --ieee
	  use IEEE numerics.  Note that this option *only* works
	  if it is supported by the OPTFILE that is being used.
    -devel | --devel
	  Add additional warning and debugging flags for development
	  (if supported by the OPTFILE); also switch to IEEE numerics.
    -gsl | --gsl
	  Use GSL to control floating point rounding and precision

    -mpi | --mpi
	  Include MPI header files and link to MPI libraries
    -mpi=PATH | --mpi=PATH
	  Include MPI header files and link to MPI libraries using MPI_ROOT
	  set to PATH. i.e. Include files from \$PATH/include, link to libraries
	  from \$PATH/lib and use binaries from \$PATH/bin.

    -omp | --omp
	  Activate OpenMP code
    -omp=OMPFLAG | --omp=OMPFLAG
	  Activate OpenMP code + use Compiler option OMPFLAG

    -es | --es | -embed-source | --embed-source
	  Embed a tarball containing the full source code
	  (including the Makefile, etc.) used to build the
	  executable [off by default]

    -ds | --ds
	  Report genmake internal variables status (DUMPSTATE)
	  to file "genmake_state" (for debug purpose)

  While it is most often a single word, the "NAME" variables specified
  above can in many cases be a space-delimited string such as:

    --enable pkg1   --enable 'pkg1 pkg2'   --enable 'pkg1 pkg2 pkg3'
    -mods=dir1   -mods='dir1'   -mods='dir1 dir2 dir3'
    -foptim='-Mvect=cachesize:512000,transform -xtypemap=real:64,double:64,integer:32'

  which, depending upon your shell, may need to be single-quoted.

  For more detailed genmake documentation, please see section "Building the model"
    (under "Getting Started") at:  https://mitgcm.readthedocs.io/

EOF
#- full link directly to section 3.5:
#https://mitgcm.readthedocs.io/en/latest/getting_started/getting_started.html#building-the-model

    exit 1
}

# Search for particular CPP #cmds associated with packages
# usage: test_for_package_in_cpp_options CPP_file package_name
test_for_package_in_cpp_options() {
    cpp_options=$1
    pkg=$2
    test_for_string_in_file $cpp_options "^ *# *define *\<ALLOW_$pkg\>"
    test_for_string_in_file $cpp_options "^ *# *undef *\<ALLOW_$pkg\>"
    test_for_string_in_file $cpp_options "^ *# *define *\<DISABLE_$pkg\>"
    test_for_string_in_file $cpp_options "^ *# *undef *\<DISABLE_$pkg\>"
}

# Search for particular CPP #cmds associated with MPI
# usage: test_for_mpi_in_cpp_eeoptions CPP_file
test_for_mpi_in_cpp_eeoptions() {
    cpp_options=$1
    test_for_string_in_file $cpp_options "^ *# *define *\<ALLOW_USE_MPI\>"
    test_for_string_in_file $cpp_options "^ *# *undef *\<ALLOW_USE_MPI\>"
}

# Search for particular string in a file. Return 1 if detected, 0 if not
# usage: test_for_string_in_file file string
test_for_string_in_file() {
    file=$1
    strng=$2
    grep "$strng" $file > /dev/null 2>&1
    RETVAL=$?
    if test "x${RETVAL}" = x0 ; then
	printf "Error: In $file there is an illegal line: "
	grep -i "$strng" $file
	exit 99
    fi
    return 0
}

# Read the $ROOTDIR/pkg/pkg_groups file and expand any references to
# the package list.
expand_pkg_groups() {
    new_packages=
    if test -r $PKG_GROUPS ; then
	cat $PKG_GROUPS | sed -e 's/#.*$//g' | sed -e 's/:/ : /g' > $TMP.p1
	cat $TMP.p1 | $AWK '(NF>2 && $2==":"){ print $0 }' > $TMP.p2
	matched=0
	for i in $PACKAGES ; do
	    line=`grep "^ *$i" $TMP.p2`
	    RETVAL=$?
	    if test "x$RETVAL" = x0 ; then
		matched=1
		replace=`echo $line | $AWK '{ $1=""; $2=""; print $0 }'`
		echo "    replacing \"$i\" with:$replace"
		new_packages="$new_packages $replace"
	    else
		new_packages="$new_packages $i"
	    fi
	done
	PACKAGES=$new_packages
	rm -f $TMP.p[1,2]
	return $matched
    else
	echo "Warning: can't read package groups definition file: $PKG_GROUPS"
    fi
}

#  Check for broken environments (eg. cygwin, MacOSX w/HFS+) that
#  cannot distinguish [*.F/*.F90] from [*.f/*.f90] files.
check_for_broken_Ff()  {
    #  Do we have defaults for $FS and/or $FS90 ?
    tfs=f
    tfs9=f90
    if test "x$FS" != x ; then
	tfs="$FS"
    fi
    if test "x$FS90" != x ; then
	tfs9="$FS90"
    fi

    #  First check the ability to create a *.F/.f pair.
    cat <<EOF >> genmake_hello.F
      program hello
      write(*,*) 'hi'
      stop
      end
EOF
    cp genmake_hello.F "genmake_hello."$tfs > /dev/null 2>&1
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	if test "x$FS" = x ; then
	    FS='for'
	    FS90='fr9'
	    check_for_broken_Ff
	else
	    cat <<EOF 2>&1
ERROR: Your file system cannot distinguish between *.F and *.f files
  (fails the "cp" test) and this program cannot find a suitable
  replacement extension.  Please try a different build environment or
  contact the <MITgcm-support@mitgcm.org> list for help.

EOF
	    exit -1
	fi
	return
    fi
    rm -f genmake_hello.*

    #  Check the ability of ${MAKE} and ${LN} to use the current set
    #  of extensions.
    cat <<EOF >> genmake_hello.F
      program hello
      write(*,*) 'hi'
      stop
      end
EOF
    test -f $MAKEFILE  &&  mv -f $MAKEFILE $MAKEFILE".tst"
    cat <<EOF >> $MAKEFILE
.SUFFIXES:
.SUFFIXES: .$tfs .F
.F.$tfs:
	$LN \$< \$@
EOF
    $MAKE -f $MAKEFILE "genmake_hello."$tfs > /dev/null 2>&1
    RETVAL=$?
    if test "x$RETVAL" != x0 -o ! -f "genmake_hello."$tfs ; then
	if test "x$FS" = x ; then
	    FS='for'
	    FS90='fr9'
	    check_for_broken_Ff
	else
	    echo "ERROR: test: '$MAKE -f $MAKEFILE genmake_hello.$tfs' Failed"
	    echo "       see simple makefile: '$MAKEFILE' (left here)"
	    echo "  Please check (1) your '$MAKE' command, (2) your '$LN' command"
	    echo "           and (3) the allowed sufix '.F' and '.$tfs' in makefile"
	    echo "  or contact the <MITgcm-support@mitgcm.org> list for help."
	    echo ""
	    exit -1
	    return
	fi
    fi
    rm -f genmake_hello.* $MAKEFILE
    test -f $MAKEFILE".tst"  &&  mv -f $MAKEFILE".tst" $MAKEFILE

    #  If we make it here, use the extensions
    FS=$tfs
    FS90=$tfs9
    return
}

look_for_makedepend()  {

    #  The "original" makedepend is part of the Imake system that is
    #  most often distributed with XFree86 or with an XFree86 source
    #  package.  As a result, many machines (eg. generic Linux) do not
    #  have a system-default "makedepend" available.  For those
    #  systems, we have two fall-back options:
    #
    #    1) a makedepend implementation shipped with the cyrus-imapd
    #       package:  ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
    #    2) a local tools/xmakedepend shell script
    #
    #  So the choices are, in order:
    #    1) use the user-specified program
    #    2) use the local xmakedepend script (get all dependencies, but slower)
    #    3) use a system-wide default
    #    4) locally build and use the cyrus makedepend
    #             (faster, but can miss some dependencies)
    #
    echo >> $LOGFILE
    echo "running: look_for_makedepend()" >> $LOGFILE
    if test "x${MAKEDEPEND}" != x ; then
	echo "${MAKEDEPEND}" | grep -i cyrus > /dev/null 2>&1
	RETVAL=$?
	if test x"$RETVAL" = x0 ; then
	    build_cyrus_makedepend
	    RETVAL=$?
	    if test "x$RETVAL" != x0 ; then
		echo "WARNING: unable to build cyrus-makedepend. Try other 'makedepend'"
		MAKEDEPEND=
	    fi
	else
	    echo "${MAKEDEPEND}" | grep 'tools.xmakedepend' > /dev/null 2>&1
	    RETVAL=$?
	    if test "x$RETVAL" = x0 ; then
		MAKEDEPEND='$(TOOLSDIR)/xmakedepend'
	    fi
	    echo " -->     MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
	fi
    fi
    if test "x${MAKEDEPEND}" = x ; then
	test -f $MAKEFILE  &&  mv -f $MAKEFILE $MAKEFILE".tst"
	#  echo 'MAKEFILE="'$MAKEFILE'"'
	cat <<EOF >> $MAKEFILE
#   THIS IS A TEST MAKEFILE GENERATED BY "genmake2"
#
#   Some "makedepend" implementations will die if they cannot
#   find a Makefile -- so this file is here to gives them an
#   empty one to find and parse.
EOF
	cat <<EOF >> genmake_tc.f
      program test
      write(*,*) 'test'
      stop
      end
EOF
	$ROOTDIR/tools/xmakedepend -f $MAKEFILE genmake_tc.f > /dev/null 2>&1
	RV1=$?
	which makedepend > /dev/null 2>&1
	RV2=$?
	if test "x${RV2}" = x0 ; then
	    makedepend -f $MAKEFILE genmake_tc.f > /dev/null 2>&1
	    RV3=$? ; loc_msg='not working.'
	else RV3=$RV2 ; loc_msg='not found.'
	fi
	test -f $MAKEFILE  &&  rm -f $MAKEFILE
	test -f $MAKEFILE".tst"  &&  mv -f $MAKEFILE".tst" $MAKEFILE
	echo "  check makedepend (local: $RV1, system: $RV2, $RV3)"
	if test "x${RV1}" = x0 ; then
	    MAKEDEPEND='$(TOOLSDIR)/xmakedepend'
	    echo " --> set MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
	elif test "x${RV3}" = x0 ; then
	    echo "    local tools/xmakedepend not working. Use system-default makedepend"
	    MAKEDEPEND=makedepend
	    echo " --> set MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
	else
	    echo "    local tools/xmakedepend not working; system-default makedepend $loc_msg"
	    echo -n "    Try to build cyrus-makedepend ..."
	    #  Try to build the cyrus implementation
	    build_cyrus_makedepend
	    RETVAL=$?
	    if test "x$RETVAL" = x0 ; then
		echo "  Works"
	    else
		echo "  Fails" ; echo "" >> $LOGFILE
		echo "ERROR: no working makedepend found ; look_for_makedepend FAILED" | tee -a $LOGFILE
		echo ""
		exit -1
		return
	    fi
	fi
    fi
}

build_cyrus_makedepend()  {
    echo >> $LOGFILE
    echo "running: build_cyrus_makedepend()" >> $LOGFILE
    rm -f ./genmake_cy_md
    (
	cd $ROOTDIR/tools/cyrus-imapd-makedepend  \
	    &&  ./configure > /dev/null 2>&1  \
	    &&  $MAKE > /dev/null 2>&1
	if test -x ./makedepend.exe ; then
	    $LN ./makedepend.exe ./makedepend
	fi
	./makedepend ifparser.c > /dev/null 2>&1  \
	    &&  echo "true"
    ) > ./genmake_cy_md
    grep true ./genmake_cy_md > /dev/null 2>&1
    RETVAL=$?
    rm -f ./genmake_cy_md
    if test "x$RETVAL" = x0 ; then
	MAKEDEPEND='$(TOOLSDIR)/cyrus-imapd-makedepend/makedepend'
 	echo " --> set MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
	return 0
    else
	echo "WARNING: fail to build cyrus-imapd-makedepend" >> $LOGFILE
	return 1
    fi
}

build_embed_encode()
{
    printf "  building the embed-encode utility...  "
    if test ! -e "$ROOTDIR/tools/embed_encode/encode_files" ; then
	if test ! -d "$ROOTDIR/tools/embed_encode" ; then
	    echo
	    echo "    Error: can't locate \"$ROOTDIR/tools/embed_encode\""
	    echo
	    EMBED_SRC=f
	    return 1
	fi
	clist="cc gcc c89 $CC"
	for ic in $clist ; do
	    comm="$ic -o encode_files encode_files.c"
	    ( cd $ROOTDIR/tools/embed_encode && $comm ) > /dev/null 2>&1
	    RETVAL=$?
	    if test "x$RETVAL" = x0 ; then
		echo "OK"
		return 0
	    fi
	done
	echo
	echo "    Error: unable to build $ROOTDIR/embed_encode/encode_files"
	echo "      so it has been disabled"
	echo
	EMBED_SRC=f
	return 1
    fi
    echo "OK"
}

#  look for possible C compilers
look_for_C_compilers() {
    echo >> $LOGFILE
    echo "running: look_for_C_compilers()" >> $LOGFILE
    rm -f ./genmake_hello.c  ./genmake_hello
    cat >> genmake_hello.c << EOF
#include <stdio.h>
int main(int argc, char **argv) {
  printf("Hello!\n");
  return 0;
}
EOF
    tmp="$MITGCM_CC $CC gcc c89 cc c99 mpicc icc"
    p_CC=
    for c in $tmp ; do
	COMM="$c $CFLAGS -o genmake_hello genmake_hello.c"
	echo $COMM >> $LOGFILE
	$COMM >> $LOGFILE 2>&1
	RETVAL=$?
	if test "x${RETVAL}" = x0 ; then
	    echo " $c test successful" >> $LOGFILE
	    p_CC="$p_CC $c"
	fi
    done
    rm -f ./genmake_hello.c ./genmake_hello
    if test "x${p_CC}" = x ; then
	cat 1>&2 <<EOF

Error: No C compilers were found in your path.  Please specify one using:

    1) an "optfile" on (eg. "-optfile=path/to/OPTFILE"),
    2) the CC or MITGCM_CC environment variables.

EOF
	exit 1
    else
	echo "  The possible C compilers found in your path are: $p_CC" | tee -a $LOGFILE
	if test "x$CC" = x ; then
	    CC=`echo $p_CC | $AWK '{print $1}'`
	    echo "  Setting C compiler to: "$CC
	fi
    fi
    echo " --> set CC='$CC'" >> $LOGFILE
}

#  Guess possible config options for this host
find_possible_optfile()  {

    echo >> $LOGFILE
    echo "running: find_possible_optfile()" >> $LOGFILE
    tmp1=`uname`"_"`uname -m`
    tmp2=`echo $tmp1 | sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
    tmp3=`echo $tmp2 | sed -e 's/power macintosh/ppc/'`
    tmp1=`echo $tmp3 | sed -e 's|x86_64|amd64|' | sed -e 's|aarch64|arm64|'`
    tmp2=`echo $tmp1 | sed -e 's/i[3-6]86/ia32/' | sed -e 's/athlon/ia32/'`
    tmp3=`echo $tmp2 | sed -e 's/cray sv1/craysv1/'`
    PLATFORM=$tmp3
    echo $PLATFORM | grep cygwin > /dev/null 2>&1  &&  PLATFORM=cygwin_ia32
    OFLIST=`(cd $ROOTDIR/tools/build_options; ls | grep "^$PLATFORM")`
    echo "  The platform appears to be:  $PLATFORM" | tee -a $LOGFILE

    #================================================================
    #  look for possible FORTRAN compilers
    echo "  look for possible FORTRAN compilers" >> $LOGFILE
    tmp="$MITGCM_FC $FC efc gfortran g77 f77 pgf77 pgf95 ifc ifort f90 f95 mpif77 mpf77 mpxlf95 g95"
    p_FC=
    rm -f ./genmake_hello.f
    cat >> genmake_hello.f <<EOF
      program hello
      do i=1,3
        print *, 'hello world : ', i
      enddo
      end
EOF
    for f in $tmp ; do
	COMM="$f -o genmake_hello genmake_hello.f"
	echo $COMM >> $LOGFILE
	$COMM >> $LOGFILE 2>&1
	RETVAL=$?
	if test "x${RETVAL}" = x0 ; then
	    echo " $f test successful" >> $LOGFILE
	    p_FC="$p_FC $f"
	fi
    done
    rm -f ./genmake_hello.f ./genmake_hello
    if test "x${p_FC}" = x ; then
	cat 1>&2 <<EOF

Error: No Fortran compilers were found in your path.  Please specify one using:

    1) an "optfile" on (eg. "-optfile=path/to/OPTFILE"),
    2) a command-line option (eg. "-fc NAME"), or
    3) the FC or MITGCM_FC environment variables.

EOF
	exit 1
    else
	echo "  The possible FORTRAN compilers found in your path are: $p_FC" | tee -a $LOGFILE
    fi

    #  Use the first of the compilers found in the current PATH
    #  that has a correctly-named optfile
    if test "x$OPTFILE" = x  -a  "x$FC" = x ; then
	for i in $p_FC ; do
	    OPTFILE=$ROOTDIR"/tools/build_options/"$PLATFORM"_"$i
	    if test -r $OPTFILE ; then
		echo "  Setting OPTFILE to: "$OPTFILE | tee -a $LOGFILE
		break
	    fi
	done
    fi

    if test "x$OPTFILE" = x ; then
	OPTFILE=$ROOTDIR"/tools/build_options/"$PLATFORM"_"$FC
	if test ! -r $OPTFILE ; then
	     echo "  I looked for the file "$OPTFILE" but did not find it"
	fi
    fi

    if test "x$OPTFILE" = x ; then
	cat 1>&2 <<EOF

Error: No options file was found in:  $ROOTDIR/tools/build_options/
  that matches this platform ("$PLATFORM") and the compilers found in
  your path.  Please specify an "optfile" using:

    1) the command line (eg. "-optfile=path/to/OPTFILE"), or
    2) the MITGCM_OF environment variable.

  If you need help, please contact the <MITgcm-support@mitgcm.org> list.

EOF
	exit 1
    fi
}
#---- keep this line unchanged after the end of find_possible_optfile -----

#  Just try to use FC, report failed attempt as a Warning
check_fortran_compiler() {
    echo -n "  check Fortran Compiler... "
    echo "" >> $LOGFILE
    echo "running: check_fortran_compiler" >> $LOGFILE
    FC_CHECK=-1
    rm -f ./genmake_tcomp.f
    cat >> genmake_tcomp.f <<EOF
      program hello
      integer i
      do i=1,3
        print *, 'hello world : ', i
      enddo
      end
EOF
    COMM="$FC $FFLAGS $FOPTIM -c genmake_tcomp.f"
    echo ' '$COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	FC_CHECK=0
	echo "" >> $LOGFILE
	echo " Warning: FORTRAN compiler test fails to compile" >> $LOGFILE
	echo -n " fail to compile"
    fi
    if test $FC_CHECK = '-1' ; then
	COMM="$LINK $FFLAGS $FOPTIM -o genmake_tcomp genmake_tcomp.o $LIBS"
	echo ' '$COMM >> $LOGFILE
	$COMM >> $LOGFILE 2>&1
	RETVAL=$?
    else RETVAL=0 ; fi
    if test "x$RETVAL" != x0 ; then
	FC_CHECK=1
	echo "" >> $LOGFILE
	echo " Warning: FORTRAN compiler test fails to link" >> $LOGFILE
	echo -n " fail to generate executable"
    fi
    if test $FC_CHECK = '-1' -a -x genmake_tcomp ; then
	if test "x$MPI" = 'xtrue' ; then
	  which mpirun > /dev/null 2>&1
	  RETVAL=$?
	  if test "x${RETVAL}" = x0 ; then
	    COMM="mpirun -np 1 ./genmake_tcomp"
	  else
	    which mpiexec > /dev/null 2>&1
	    RETVAL=$?
	    if test "x${RETVAL}" = x0 ; then
	      COMM="mpiexec -np 1 ./genmake_tcomp"
	    else
	      FC_CHECK=4
	      echo "" >> $LOGFILE
	      echo " Warning: MPI run command not found ==> skip run-test check" >> $LOGFILE
	     #echo -n " fail to generate executable"
	    fi
	  fi
	else
	    COMM="./genmake_tcomp"
	fi
    elif test $FC_CHECK = '-1' ; then
	FC_CHECK=2
	echo 'WARNING: missing executable from FORTRAN compiler test' >> $LOGFILE
	echo -n " fail to generate executable"
    fi
    if test $FC_CHECK = '-1' ; then
	echo ' '$COMM >> $LOGFILE
	$COMM >> $LOGFILE 2>&1
	RETVAL=$?
	if test "x$RETVAL" != x0 ; then
	   FC_CHECK=3
	  #echo -n " fail to run"
	else
	   FC_CHECK=5
	   echo -n " pass"
	fi
    fi
    rm -f genmake_tcomp.* genmake_tcomp
    echo " --> set FC_CHECK= $FC_CHECK /5" >> $LOGFILE
    echo "  (set FC_CHECK=${FC_CHECK}/5)"
}

#  Do a local copy of MPI headers files (in local dir ./mpi_headers/) after
#  checking for additional included headers (in case of chain of included header)
mpi_headers_do_local_copy() {

    dBug=0
    rm -rf ./mpi_headers
    if test -d $MPIINCLUDEDIR ; then

	#----- check for additional headers (chain of included headers)
	echo -n '  Check MPI headers ... '
	listIni=$MPI_HEADER_FILES
	echo $listIni | grep "\<mpif.h\>" > /dev/null 2>&1
	outp=$?
	#- always check mpif.h (the only mpi-header included in standard MITgcm code)
	if test $outp != 0 ; then listIni="mpif.h $listIni" ; fi
	if test $dBug = 1 ; then echo "listIni='$listIni'" ; fi

	doCheck=1 ; list2copy='' ; list2check=$listIni
	while test $doCheck = 1 ; do
	  newList=''
	  for i in $list2check ; do
	    if test -f $MPIINCLUDEDIR/$i ; then
	      newInc=`grep '^ *include ' $MPIINCLUDEDIR/$i | \
		sed -e 's/^ *include //' -e 's/\!.*$//' -e "s/'//g"  -e 's/\"//g'`
	      if test $dBug = 1 ; then echo -n "checking $i : newInc='$newInc'" ; fi
	      for j in $newInc ; do
		echo $listIni $list2copy $newList | grep "\<$j\>" > /dev/null 2>&1
		outp=$?
	        if test $outp != 0 ; then
		  if test $dBug = 1 ; then echo -n " ; adding $j" ; fi
		  newList="$newList $j"
		fi
	      done
	      if test $dBug = 1 ; then echo "" ; fi
	    fi
	  done
	  if test "x$newList" = x ; then doCheck=0
	  else list2check=$newList ; list2copy="$list2copy $newList"
	  fi
	done
	list2copy="$MPI_HEADER_FILES $list2copy"
	if test $dBug = 1 ; then echo "list2copy='$list2copy'" ; fi

	#----- create local mpi_headers dir if we have files to copy
	mkListInc=`echo $list2copy | wc -w`
	if test $mkListInc != 0 ; then
	  echo 'create local "./mpi_headers" dir'
	  mkdir -p ./mpi_headers
	  INCLUDES="-I./mpi_headers $INCLUDES"
	  mkListInc=1
	fi
	if test "x$LOCAL_MPI_HEADERS" != x ; then mkListInc=0 ; fi

	#----- make local copy and update LOCAL_MPI_HEADERS (if not already set)
	for i in $list2copy ; do
	  if test -f $MPIINCLUDEDIR/$i ; then
	    cp -p $MPIINCLUDEDIR/$i ./mpi_headers
	    if test $i = 'mpif.h' ; then
		perl -i -pe 's/MPI_DISPLACEMENT_CURRENT=-1_8/MPI_DISPLACEMENT_CURRENT=-1/g' mpi_headers/mpif.h
	    fi
	    if test $mkListInc = 2 ; then
		LOCAL_MPI_HEADERS="$LOCAL_MPI_HEADERS ./mpi_headers/$i"
	    fi
	    if test $mkListInc = 1 ; then
		LOCAL_MPI_HEADERS="./mpi_headers/$i" ; mkListInc=2
	    fi
	  fi
	done
    else
	echo "WARNING: MPIINCLUDEDIR='$MPIINCLUDEDIR' is not a directory"
	echo "WARNING: => skip checking for MPI headers (no ./mpi_headers dir)"
#	exit -1
    fi
}

#  Re-order file list according to dependencies from used modules
#  usage: sort_file_list_from_used_modules file_list
sort_file_list_from_used_modules()  {
    file_list=$1
    dBug=0
    if test $dBug = 1 ; then
	echo "-- sort_file_list_from_used_modules : file_list=$file_list , TMP=$TMP"
	echo "-> initial list :" ; cat $file_list
    fi
    test -f $TMP.Graph && rm -f $TMP.Graph
    test -f $TMP.noGraph && rm -f $TMP.noGraph
    touch $TMP.Graph $TMP.noGraph
    # Sort the f90 files in topological order
    while IFS= read -r f90file; do
    # List modules used in f90file, ignoring those commented out
	mod_used=$(grep -i "^[^!]*\buse\b" $f90file | $AWK '{print $2}' | tr -d ',')
	if [ -n "$mod_used" ]; then
	    for mod in $mod_used; do
		# Find the file that defines this module
		mod_file=$(grep -li "^module $mod\b" \
				$(grep -v $f90file "$file_list"))
		if [ -n "$mod_file" ]; then
		    echo $mod_file $f90file >> $TMP.Graph
		fi
	    done
	else
	    echo $f90file >> $TMP.noGraph
	fi
    done < $file_list
    # Replace alphabetical with topological file order
    tsort $TMP.Graph | sed 's|.*/||' > $file_list
    # append files without use-statements if they are not already included
    while IFS= read -r f90file; do
	f=$(echo $f90file | sed 's|.*/||' )
	inList=$(grep -i $f $file_list)
	if test -z "$inList" ; then
	    echo $f >> $file_list
	fi
    done < $TMP.noGraph
    # Clean up topological sorting files
    rm -rf $TMP.Graph $TMP.noGraph
    if test $dBug = 1 ; then
	echo "<- re-ordered list :" ; cat $file_list
    fi
}

#  Parse the package dependency information
get_pdepend_list()  {

    #  strip the comments and then convert the dependency file into
    #  two arrays: PNAME, DNAME
    cat $1 | sed -e 's/#.*$//g' \
	| $AWK 'BEGIN{nn=-1;} (NF>0){ for(i=2;i<=NF;i++){nn++; print "PNAME_"nn"="$1"\nDNAME_"nn"="$i}} END{print "nname="nn}' \
	> ./.pd_tmp
    RETVAL=$?
    if test ! "x${RETVAL}" = x0 ; then
      echo "Error: unable to parse package dependencies -- please check PKG_DEPEND=\"$1\""
      exit 1
    fi
    #echo "---- content of tmp file '.pd_tmp' :" ; cat .pd_tmp ; echo "---- end of file"
    . ./.pd_tmp
    rm -f ./.pd_tmp
}

#  Build a CPP macro to automate calling C routines from FORTRAN
get_fortran_c_namemangling()  {

    #echo "FC_NAMEMANGLE = \"$FC_NAMEMANGLE\""
    if test ! "x$FC_NAMEMANGLE" = x ; then
	return 0
    fi
    echo " running: get_fortran_c_namemangling()" >> $LOGFILE

    default_nm="#define FC_NAMEMANGLE(X) X ## _"

    cat > genmake_test.c <<EOF
void tcall( char * string ) { tsub( string ); }
EOF
    COMM="$CC $CFLAGS -c genmake_test.c"
    echo ' '$COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	FC_NAMEMANGLE=$default_nm
	cat <<EOF>> $LOGFILE

 WARNING: C test compile fails
 WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
 WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here
EOF
	return 1
    fi
    c_tcall=`nm genmake_test.o 2>/dev/null | grep 'T ' | grep tcall | cut -d ' ' -f 3`
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	FC_NAMEMANGLE=$default_nm
	cat <<EOF>> $LOGFILE

 WARNING: The "nm" command failed.
 WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
 WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here
EOF
	return 1
    fi
    cat > genmake_tcomp.$FS <<EOF
      subroutine tcall( string )
      character*(*) string
      call tsub( string )
      end
EOF
    COMM="$FC $FFLAGS -c genmake_tcomp.$FS"
    echo ' '$COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	FC_NAMEMANGLE=$default_nm
	cat <<EOF>> $LOGFILE

 WARNING: FORTRAN test compile fails -- please see '$LOGFILE'
 WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
 WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here.
EOF
	return 1
    fi
    f_tcall=`nm genmake_tcomp.o 2>/dev/null | grep 'T ' | grep tcall | cut -d ' ' -f 3`
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	FC_NAMEMANGLE=$default_nm
	cat <<EOF>> $LOGFILE

 WARNING: The "nm" command failed.
 WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
 WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here.
EOF
	return 1
    fi

    c_a=`echo $c_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 1 | sed -e 's|Y||'`
    f_a=`echo $f_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 1 | sed -e 's|Y||'`
    c_b=`echo $c_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 2 | sed -e 's|Y||'`
    f_b=`echo $f_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 2 | sed -e 's|Y||'`

    nmangle="X"
    if test "x$c_a" != "x$f_a" ; then
	comm="echo x$f_a | sed -e 's|x$c_a||'"
	a=`eval $comm`
	nmangle="$a ## $nmangle"
    fi
    if test "x$c_b" != "x$f_b" ; then
	comm="echo x$f_b | sed -e 's|x$c_b||'"
	b=`eval $comm`
	nmangle="$nmangle ## $b"
    fi

    FC_NAMEMANGLE="#define FC_NAMEMANGLE(X)  $nmangle"

    #  cleanup the testing files
    rm -f genmake_tcomp.* genmake_test.*

    echo " --> set FC_NAMEMANGLE='$FC_NAMEMANGLE'" >> $LOGFILE
}

check_HAVE_CLOC()  {
    echo >> $LOGFILE
    echo "running: check_HAVE_CLOC()" >> $LOGFILE
    get_fortran_c_namemangling
    cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/time.h>
void FC_NAMEMANGLE(cloc) ( double *curtim )
{
 struct timeval tv1;
 gettimeofday(&tv1 , (void *)NULL );
 *curtim =  (double)((tv1.tv_usec)+(tv1.tv_sec)*1.E6);
 *curtim = *curtim/1.E6;
}
EOF
    COMM="$CC $CFLAGS -c genmake_tc_1.c"
    echo $COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RET_C=$?
    cat <<EOF > genmake_tc_2.$FS
      program hello
      REAL*8 wtime
      external cloc
      call cloc(wtime)
      print *," HELLO WORLD", wtime
      end
EOF
    COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
    echo $COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RET_F=$?
    test -x ./genmake_tc  &&  ./genmake_tc >> $LOGFILE 2>&1
    RETVAL=$?
    if test "x$RETVAL" = x0 ; then
	HAVE_CLOC=t
    fi
    rm -f genmake_tc*
    echo " --> set HAVE_CLOC='$HAVE_CLOC'" >> $LOGFILE
}

check_HAVE_SIGREG()  {
    if test ! "x$HAVE_SIGREG" = x ; then
	return
    fi
    echo >> $LOGFILE
    echo "running: check_HAVE_SIGREG()" >> $LOGFILE
    get_fortran_c_namemangling
    cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <ucontext.h>

int * ip;

static void killhandler(
    unsigned int sn, siginfo_t  si, struct ucontext *sc )
{
    *ip = *ip + 1;
    return;
}

void FC_NAMEMANGLE(sigreg) (int * aip)
{
    struct sigaction s;
    ip = aip;
    s.sa_flags = SA_SIGINFO;
    s.sa_sigaction = (void *)killhandler;
    if(sigaction (SIGTERM,&s,(struct sigaction *)NULL)) {
	printf("Sigaction returned error = %d\n", errno);
	exit(0);
    }
    return;
}
EOF
    COMM="$CC $CFLAGS -c genmake_tc_1.c"
    echo $COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RET_C=$?
    cat <<EOF > genmake_tc_2.$FS
      program hello
      integer anint
      common /iv/ anint
      external sigreg
      call sigreg(anint)
      end
EOF
    cat genmake_tc_2.$FS >> $LOGFILE
    COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
    echo $COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RETVAL=$?
    if test "x$RETVAL" = x0 ; then
	HAVE_SIGREG=t
    fi
    rm -f genmake_tc*
    echo " --> set HAVE_SIGREG='$HAVE_SIGREG'" >> $LOGFILE
}

check_HAVE_SETRLSTK()  {
    if test ! "x$HAVE_SETRLSTK" = x ; then
	return
    fi
    echo >> $LOGFILE
    echo "running: check_HAVE_SETRLSTK()" >> $LOGFILE
    get_fortran_c_namemangling
    cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
void FC_NAMEMANGLE(setrlstk) ()
{
    struct rlimit rls;
    rls.rlim_cur = RLIM_INFINITY;
    rls.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_STACK, &rls);
    return;
}
EOF
    COMM="$CC $CFLAGS -c genmake_tc_1.c"
    echo $COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RET_C=$?
    cat <<EOF > genmake_tc_2.$FS
      program hello
      external setrlstk
      call setrlstk()
      end
EOF
    cat genmake_tc_2.$FS >> $LOGFILE
    COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
    echo $COMM >> $LOGFILE
    $COMM >> $LOGFILE 2>&1
    RETVAL=$?
    if test "x$RETVAL" = x0 ; then
	HAVE_SETRLSTK=t
    fi
    rm -f genmake_tc*
    echo " --> set HAVE_SETRLSTK='$HAVE_SETRLSTK'" >> $LOGFILE
}

check_HAVE_STAT()  {
    echo >> $LOGFILE
    echo "running: check_HAVE_STAT()" >> $LOGFILE
    get_fortran_c_namemangling
    cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
void FC_NAMEMANGLE(tfsize) ( int *nbyte )
{
    char name[512];
    struct stat astat;

    name[0] = 'a'; name[1] = '\0';
    if (! stat(name, &astat))
        *nbyte = (int)(astat.st_size);
    else
        *nbyte = -1;
}
EOF
    COMM="$CC $CFLAGS -c genmake_tc_1.c"
    echo $COMM >> $LOGFILE
    $COMM >> genmake_tc.log 2>&1
    RET_C=$?
    cat <<EOF > genmake_tc_2.$FS
      program hello
      integer nbyte
      call tfsize(nbyte)
      print *," HELLO WORLD", nbyte
      end
EOF
    cat genmake_tc_2.$FS >> $LOGFILE
    COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
    echo $COMM >> $LOGFILE
    $COMM >> genmake_tc.log 2>&1
    RETVAL=$?
    if test "x$RETVAL" = x0 ; then
	HAVE_STAT=t
    fi
    rm -f genmake_tc*
    echo " --> set HAVE_STAT='$HAVE_STAT'" >> $LOGFILE
}

check_netcdf_libs()  {
    if test ! "x$SKIP_NETCDF_CHECK" = x ; then
	return
    fi
    echo >> $LOGFILE
    echo "running: check_netcdf_libs()" >> $LOGFILE
    cat <<EOF > genmake_tnc.F
      program fgennc
#include "netcdf.inc"
EOF
   #if test ! "x$MPI" = x ; then
   #	echo '#include "mpif.h"' >> genmake_tnc.F
   #fi
    cat <<EOF >> genmake_tnc.F
      integer iret, ncid, xid
      iret = nf_create('genmake_tnc.nc', NF_CLOBBER, ncid)
      IF (iret .NE. NF_NOERR) write(*,*) NF_STRERROR(iret)
      iret = nf_def_dim(ncid, 'X', 11, xid)
      IF (iret .NE. NF_NOERR) write(*,*) NF_STRERROR(iret)
      iret = nf_close(ncid)
      IF (iret .NE. NF_NOERR) write(*,*) NF_STRERROR(iret)
      end
EOF
    echo "===  genmake_tnc.F  >>>" > genmake_tnc.log
    cat genmake_tnc.F >> genmake_tnc.log
    echo "<<<  genmake_tnc.F  ===" >> genmake_tnc.log
    RET_CPP=f
    COMM="cat genmake_tnc.F | $CPP $DEFINES $INCLUDES"
    echo "$COMM" >> genmake_tnc.log
    eval $COMM > genmake_tnc.$FS 2>/dev/null  &&  RET_CPP=t
    if test "x$RET_CPP" = xf ; then
	echo "  WARNING: CPP failed to pre-process the netcdf test." \
	    >> genmake_tnc.log
	echo "    Please check that \$INCLUDES is properly set." \
	    >> genmake_tnc.log
    fi
    echo "$FC $FFLAGS $FOPTIM -c genmake_tnc.$FS  \ " >> genmake_tnc.log
    echo "  &&  $LINK $FFLAGS $FOPTIM -o genmake_tnc genmake_tnc.o $LIBS" >> genmake_tnc.log
    $FC $FFLAGS $FOPTIM -c genmake_tnc.$FS >> genmake_tnc.log 2>&1  \
	&&  $LINK $FFLAGS $FOPTIM -o genmake_tnc genmake_tnc.o $LIBS >> genmake_tnc.log 2>&1
    RET_COMPILE=$?
    cat genmake_tnc.log >> $LOGFILE

    #EH3  Remove test program execution for machines that either disallow
    #EH3  execution or cannot support it (eg. cross-compilers)
    #EH3
    #EH3 test -x ./genmake_tnc  &&  ./genmake_tnc >> genmake_tnc.log 2>&1
    #EH3 RETVAL=$?
    #EH3 if test "x$RET_COMPILE" = x0 -a "x$RETVAL" = x0 ; then

    if test "x$RET_COMPILE" = x0 ; then
	HAVE_NETCDF=t
	echo "check_netcdf: successful" >> $LOGFILE
    else
	# try again with "-lnetcdf" added to the libs
	echo "==> try again with added '-lnetcdf'" > genmake_tnc.log
	echo "cat genmake_tnc.F | $CPP $DEFINES $INCLUDES > genmake_tnc.$FS \ " >> genmake_tnc.log
	echo " &&  $FC $FFLAGS $FOPTIM -c genmake_tnc.$FS \ " >> genmake_tnc.log
	echo " &&  $LINK $FFLAGS $FOPTIM -o genmake_tnc genmake_tnc.o $LIBS -lnetcdf" >> genmake_tnc.log
	cat genmake_tnc.F | $CPP $DEFINES $INCLUDES > genmake_tnc.$FS 2>/dev/null  \
	    &&  $FC $FFLAGS $FOPTIM -c genmake_tnc.$FS >> genmake_tnc.log 2>&1  \
	    &&  $LINK $FFLAGS $FOPTIM -o genmake_tnc genmake_tnc.o $LIBS -lnetcdf >> genmake_tnc.log 2>&1
	RET_COMPILE=$?
	echo >> $LOGFILE
	cat genmake_tnc.log >> $LOGFILE
	if test "x$RET_COMPILE" = x0 ; then
	    LIBS="$LIBS -lnetcdf"
	    HAVE_NETCDF=t
	    echo "check_netcdf: successful" >> $LOGFILE
	else
	# try again with "-lnetcdff -lnetcdf" added to the libs
	    echo "==> try again with added '-lnetcdff -lnetcdf'" > genmake_tnc.log
	    echo "cat genmake_tnc.F | $CPP $DEFINES $INCLUDES > genmake_tnc.$FS \ " >> genmake_tnc.log
	    echo " &&  $FC $FFLAGS $FOPTIM -c genmake_tnc.$FS \ " >> genmake_tnc.log
	    echo " &&  $LINK $FFLAGS $FOPTIM -o genmake_tnc genmake_tnc.o $LIBS -lnetcdff -lnetcdf" >> genmake_tnc.log
	    cat genmake_tnc.F | $CPP $DEFINES $INCLUDES > genmake_tnc.$FS 2>/dev/null  \
		&&  $FC $FFLAGS $FOPTIM -c genmake_tnc.$FS >> genmake_tnc.log 2>&1  \
		&&  $LINK $FFLAGS $FOPTIM -o genmake_tnc genmake_tnc.o $LIBS -lnetcdff -lnetcdf >> genmake_tnc.log 2>&1
	    RET_COMPILE=$?
	    echo >> $LOGFILE
	    cat genmake_tnc.log >> $LOGFILE
	    if test "x$RET_COMPILE" = x0 ; then
		LIBS="$LIBS -lnetcdff -lnetcdf"
		HAVE_NETCDF=t
		echo "check_netcdf: successful" >> $LOGFILE
	    fi
	fi
    fi
    rm -f genmake_tnc*
    echo " --> set HAVE_NETCDF='$HAVE_NETCDF'" >> $LOGFILE
}

check_lapack_libs()  {
    HAVE_LAPACK=f
    echo >> $LOGFILE
    echo "running: check_lapack_libs()" >> $LOGFILE
    cat <<EOF > genmake_tla.F
      program fgenla
      integer info
      integer ipiv( 2 )
      double precision ab( 4, 2 ), b( 2 )
      data ab / 0., 0., 1., 2., 0., 2., 1., 0. /
      data b / 1., 1. /
      call dgbsv( 2, 1, 1, 1, ab, 4, ipiv, b, 2, info )
      IF (info .NE. 0) write(*,*) 'Error:', info
      write(*,*) b
      end
EOF
    echo "===  genmake_tla.F  >>>" > genmake_tla.log
    cat genmake_tla.F >> genmake_tla.log
    echo "<<<  genmake_tla.F  ===" >> genmake_tla.log
    RET_CPP=f
    COMM="cat genmake_tla.F | $CPP $DEFINES $INCLUDES"
    echo "$COMM" >> genmake_tla.log
    eval $COMM > genmake_tla.$FS 2>/dev/null  &&  RET_CPP=t
    if test "x$RET_CPP" = xf ; then
	echo "  WARNING: CPP failed to pre-process the lapack test." \
	    >> genmake_tla.log
	echo "    Please check that \$INCLUDES is properly set." \
	    >> genmake_tla.log
    fi
    echo "$FC $FFLAGS $FOPTIM -c genmake_tla.$FS  \ " >> genmake_tla.log
    echo "  &&  $LINK $FFLAGS $FOPTIM -o genmake_tla.o $LIBS" >> genmake_tla.log
    $FC $FFLAGS $FOPTIM -c genmake_tla.$FS >> genmake_tla.log 2>&1  \
	&&  $LINK $FFLAGS $FOPTIM -o genmake_tla genmake_tla.o $LIBS >> genmake_tla.log 2>&1
    RET_COMPILE=$?
    cat genmake_tla.log >> $LOGFILE

    # test program execution not always possible (see check_netcdf_libs)
    #
    #test -x ./genmake_tla  &&  ./genmake_tla >> genmake_tla.log 2>&1
    #RETVAL=$?
    #if test "x$RET_COMPILE" = x0 -a "x$RETVAL" = x0 ; then

    if test "x$RET_COMPILE" = x0 ; then
	HAVE_LAPACK=t
	echo "check_lapack: successful" >> $LOGFILE
    else
	# try again with "-llapack" added to the libs
	echo "==> try again with added '-llapack'" > genmake_tla.log
	echo "cat genmake_tla.F | $CPP $DEFINES $INCLUDES > genmake_tla.$FS \ " >> genmake_tla.log
	echo " &&  $FC $FFLAGS $FOPTIM -c genmake_tla.$FS \ " >> genmake_tla.log
	echo " &&  $LINK $FFLAGS $FOPTIM -o genmake_tla genmake_tla.o $LIBS -llapack" >> genmake_tla.log
	cat genmake_tla.F | $CPP $DEFINES $INCLUDES > genmake_tla.$FS 2>/dev/null  \
	    &&  $FC $FFLAGS $FOPTIM -c genmake_tla.$FS >> genmake_tla.log 2>&1  \
	    &&  $LINK $FFLAGS $FOPTIM -o genmake_tla genmake_tla.o $LIBS -llapack >> genmake_tla.log 2>&1
	RET_COMPILE=$?
	echo >> $LOGFILE
	cat genmake_tla.log >> $LOGFILE
	if test "x$RET_COMPILE" = x0 ; then
	    LIBS="$LIBS -llapack"
	    HAVE_LAPACK=t
	    echo "check_lapack: successful" >> $LOGFILE
	else
	# try again with "-lf77blas -lcblas" added to the libs
	    echo "==> try again with added '-llapack -lf77blas -lcblas'" > genmake_tla.log
	    echo "cat genmake_tla.F | $CPP $DEFINES $INCLUDES > genmake_tla.$FS \ " >> genmake_tla.log
	    echo " &&  $FC $FFLAGS $FOPTIM -c genmake_tla.$FS \ " >> genmake_tla.log
	    echo " &&  $LINK $FFLAGS $FOPTIM -o genmake_tla genmake_tla.o $LIBS -llapack -lf77blas -lcblas" >> genmake_tla.log
	    cat genmake_tla.F | $CPP $DEFINES $INCLUDES > genmake_tla.$FS 2>/dev/null  \
		&&  $FC $FFLAGS $FOPTIM -c genmake_tla.$FS >> genmake_tla.log 2>&1  \
		&&  $LINK $FFLAGS $FOPTIM -o genmake_tla genmake_tla.o $LIBS -llapack -lf77blas -lcblas >> genmake_tla.log 2>&1
	    RET_COMPILE=$?
	    echo >> $LOGFILE
	    cat genmake_tla.log >> $LOGFILE
	    if test "x$RET_COMPILE" = x0 ; then
		LIBS="$LIBS -llapack -lf77blas -lcblas"
		HAVE_LAPACK=t
		echo "check_lapack: successful" >> $LOGFILE
	    else
	    # try again with "-latlas" added to the libs
		echo "==> try again with added '-llapack -lf77blas -lcblas -latlas'" > genmake_tla.log
		echo "cat genmake_tla.F | $CPP $DEFINES $INCLUDES > genmake_tla.$FS \ " >> genmake_tla.log
		echo " &&  $FC $FFLAGS $FOPTIM -c genmake_tla.$FS \ " >> genmake_tla.log
		echo " &&  $LINK $FFLAGS $FOPTIM -o genmake_tla genmake_tla.o $LIBS -llapack -lf77blas -lcblas -latlas" >> genmake_tla.log
		cat genmake_tla.F | $CPP $DEFINES $INCLUDES > genmake_tla.$FS 2>/dev/null  \
		    &&  $FC $FFLAGS $FOPTIM -c genmake_tla.$FS >> genmake_tla.log 2>&1  \
		    &&  $LINK $FFLAGS $FOPTIM -o genmake_tla genmake_tla.o $LIBS -llapack -lf77blas -lcblas -latlas >> genmake_tla.log 2>&1
		RET_COMPILE=$?
		echo >> $LOGFILE
		cat genmake_tla.log >> $LOGFILE
		if test "x$RET_COMPILE" = x0 ; then
		    LIBS="$LIBS -llapack -lf77blas -lcblas -latlas"
		    HAVE_LAPACK=t
		    echo "check_lapack: successful" >> $LOGFILE
		fi
	    fi
	fi
    fi
    rm -f genmake_tla*
    echo " --> set HAVE_LAPACK='$HAVE_LAPACK'" >> $LOGFILE
}

check_HAVE_FLUSH()  {
    if test ! "x$SKIP_CHECK_FLUSH" = x ; then
	return
    fi
    echo >> $LOGFILE
    echo "running: check_HAVE_FLUSH()" >> $LOGFILE
    cat <<EOF > genmake_tflsh.$FS
      program fgenflsh
      integer iounit
      character*9 fname
      iounit = 26
      fname = 'tmp.tflsh'
      open(iounit,FILE=fname,STATUS='unknown')
      write(iounit,*) 'genmake_tflsh: hello'
      call flush(iounit)
      close(iounit)
      end
EOF
    echo "===  genmake_tflsh.$FS  >>>" > genmake_tflsh.log
    cat genmake_tflsh.$FS >> genmake_tflsh.log
    echo "<<<  genmake_tflsh.$FS  ===" >> genmake_tflsh.log

    echo "$FC $FFLAGS $FOPTIM -c genmake_tflsh.$FS  \ " >> genmake_tflsh.log
    echo "  &&  $LINK $FFLAGS $FOPTIM -o genmake_tflsh.o $LIBS" >> genmake_tflsh.log
    $FC $FFLAGS $FOPTIM -c genmake_tflsh.$FS >> genmake_tflsh.log 2>&1  \
	&&  $LINK $FFLAGS $FOPTIM -o genmake_tflsh genmake_tflsh.o $LIBS >> genmake_tflsh.log 2>&1
    RET_COMPILE=$?

    if test "x$RET_COMPILE" = x0 ; then
	HAVE_FLUSH=t
	#cat genmake_tflsh.log >> $LOGFILE
	echo "  check_HAVE_FLUSH: successful" >> $LOGFILE
    else
	HAVE_FLUSH=f
	cat genmake_tflsh.log >> $LOGFILE
    fi
    rm -f genmake_tflsh*
    echo " --> set HAVE_FLUSH='$HAVE_FLUSH'" >> $LOGFILE
}

###############################################################################
#   Sequential part of script starts here
###############################################################################

#  Set defaults here
COMMANDL="$0 $@"

PLATFORM=
FS=
FS90=
LN=
S64=
KPP=
#FC=
#CC=gcc
#CPP=
LINK=
DEFINES=
PACKAGES=
ENABLE=
DISABLE=
# MAKEFILE=
# MAKEDEPEND=
PKG_DEPEND=
PKG_GROUPS=
DUMPSTATE=f
OPTFILE=
INCLUDES="-I. $INCLUDES"
FFLAGS=
FOPTIM=
FEXTRAFLAGS=
USE_EXTENDED_SRC=
EXTENDED_SRC_FLAG=
GET_FC_VERSION=
CFLAGS=
KFLAGS1=
KFLAGS2=
#LDADD=
LIBS=
KPPFILES=
NOOPTFILES=
NOOPTFLAGS=
MPI=
MPIPATH=
OMP=
OMPFLAG=
USE_R4=
TS=
PAPIS=
PCLS=
FOOLAD=
PAPI=
PCL=
HPMT=
GSL=
DEVEL=
HAVE_TEST_L=

# set this to "t" to enable lapack test
CHECK_FOR_LAPACK=f

# DEFINES checked by test compilation or command-line
HAVE_SYSTEM=
HAVE_FDATE=
FC_CHECK=
FC_NAMEMANGLE=
HAVE_CLOC=
# HAVE_SETRLSTK=
HAVE_STAT=
HAVE_NETCDF=
HAVE_ETIME=
IGNORE_TIME=
HAVE_LAPACK=
HAVE_FLUSH=

MODS=
TOOLSDIR=
SOURCEDIRS=
INCLUDEDIRS=
STANDARDDIRS="USE_THE_DEFAULT"
SINGULARITYFILE=

#- local config file
gm_local="genmake_local"

G2ARGS=
BASH=
PWD=`pwd`
test "x$MAKE" = x  &&  MAKE=make
test "x$AWK" = x   &&  AWK=awk
EMBED_SRC=
THISHOST=`hostname`
THISCWD=`pwd`
THISDATE=`date`
THISUSER=`echo $USER`
THISVER=
MACHINE=`uname -a`
EXECUTABLE=
EXEHOOK=
EXEDIR=
IEEE=
if test "x$MITGCM_IEEE" != x ; then
    IEEE=$MITGCM_IEEE
fi

AUTODIFF_PKG_USED=f
AD_OPTFILE=
TAPENADE=
TAPENADECMD=tapenade
OPENAD=
CAT_SRC_FOR_TAF=1
DEP_TAF_FILE='Makefile_taf.dep'
TAF=
AD_TAF_FLAGS=
FTL_TAF_FLAGS=
SVD_TAF_FLAGS=
TAF_EXTRA=
TAF_F77_FLAGS=
TAF_F90_FLAGS=

DIVA=
MPIINCLUDEDIR=
MPI_HEADER_FILES=
LOCAL_MPI_HEADERS=

#  The following state can be set directly by command-line switches
gm_s1="ROOTDIR STANDARDDIRS MODS PKG_DEPEND PKG_GROUPS DISABLE ENABLE"
gm_s2="PLATFORM OPTFILE MAKE MAKEFILE MAKEDEPEND FS FS90 FC CC MPI OMP USE_R4"
gm_s3="FEXTRAFLAGS IEEE DEVEL GSL TS PAPIS PCLS PAPI PCL HPMT DUMPSTATE"

#  The following state is not directly set by command-line switches
gm_s4="LN S64 LINK PACKAGES INCLUDES FFLAGS FOPTIM"
gm_s5="CFLAGS LIBS KPP KFLAGS1 KFLAGS2 KPPFILES NOOPTFILES NOOPTFLAGS"
gm_s6="PWD TOOLSDIR SOURCEDIRS INCLUDEDIRS EXEDIR EXECUTABLE EXEHOOK"
gm_s7="TMP THISHOST THISUSER THISDATE THISVER MACHINE FC_CHECK FC_NAMEMANGLE"
gm_s8="HAVE_NETCDF HAVE_SYSTEM HAVE_FDATE HAVE_ETIME HAVE_LAPACK HAVE_FLUSH"

#  The following are all related to adjoint/tangent-linear stuff
gm_s10="AUTODIFF_PKG_USED AD_OPTFILE TAPENADE TAPENADECMD OPENAD"
gm_s11="TAF AD_TAF_FLAGS FTL_TAF_FLAGS SVD_TAF_FLAGS TAF_F77_FLAGS TAF_F90_FLAGS"
gm_s12="TAF_EXTRA DIVA MPIINCLUDEDIR MPI_HEADER_FILES"

gm_state="COMMANDL $gm_s1 $gm_s2 $gm_s3 $gm_s4 $gm_s5 $gm_s6 $gm_s7 $gm_s8"
gm_state="$gm_state $gm_s10 $gm_s11 $gm_s12"

cat <<EOF

GENMAKE :

A program for GENerating MAKEfiles for the MITgcm project.
   For a quick list of options, use "genmake2 -h"
or for more detail see the documentation, section "Building the model"
   (under "Getting Started") at:  https://mitgcm.readthedocs.io/

EOF

if test "x$MITGCM_ROOTDIR" = x ; then
  if test "x$ROOTDIR" != x ; then
    echo "WARNING: Environment Variable 'ROOTDIR' no longer recognized"
    echo "WARNING:  use instead 'MITGCM_ROOTDIR'" ; ROOTDIR=
    echo ''
  fi
else
  ROOTDIR=$MITGCM_ROOTDIR
fi

LOGFILE="genmake.log"
#- clean-up previous genmake logfiles:
rm -f genmake_state genmake_*optfile $LOGFILE

echo "===  Processing options files and arguments  ==="

#echo "$0::$1:$2:$3:$4:$5:$6:$7:"
#parse_options
ac_prev=
for ac_option in "$@" ; do

    G2ARGS="$G2ARGS \"$ac_option\""

    # If the previous option needs an argument, assign it.
    if test -n "$ac_prev"; then
	eval "$ac_prev=\$ac_option"
	ac_prev=
	continue
    fi

    ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`

    case $ac_option in

	-help | --help | -h | --h)
	    usage ;;

	-optfile | --optfile | -of | --of)
	    ac_prev=OPTFILE ;;
	-optfile=* | --optfile=* | -of=* | --of=*)
	    OPTFILE=$ac_optarg ;;

	-tap | --tap)
	    TAPENADE="true" ; ALWAYS_USE_F90=1 ;;

	-oad | --oad)
	    OPENAD="true" ; ALWAYS_USE_F90=1 ;;
	-oadsingularity | --oadsingularity | -oadsngl | --oadsngl)
	    ac_prev=SINGULARITYFILE ;;
	-oadsingularity=* | --oadsingularity=* | -oadsngl=* | --oadsngl=*)
	    SINGULARITYFILE=$ac_optarg ;;
	-nocat4ad | -dog4ad | -ncad | -dad)
	    CAT_SRC_FOR_TAF=0 ;;
	-adoptfile | --adoptfile | -adof | --adof)
	    ac_prev=AD_OPTFILE ;;
	-adoptfile=* | --adoptfile=* | -adof=* | --adof=*)
	    AD_OPTFILE=$ac_optarg ;;

	-pdepend | --pdepend)
	    ac_prev=PKG_DEPEND ;;
	-pdepend=* | --pdepend=*)
	    PKG_DEPEND=$ac_optarg ;;

	-pgroups | --pgroups)
	    ac_prev=PKG_GROUPS ;;
	-pgroups=* | --pgroups=*)
	    PKG_GROUPS=$ac_optarg ;;

	-make | --make | -m | --m)
	    ac_prev=MAKE ;;
	-make=* | --make=* | -m=* | --m=*)
	    MAKE=$ac_optarg ;;

	-bash | --bash)
	    ac_prev=BASH ;;
	-bash=* | --bash=*)
	    BASH=$ac_optarg ;;

	-makedepend | --makedepend | -md | --md)
	    ac_prev=MAKEDEPEND ;;
	-makedepend=* | --makedepend=* | -md=* | --md=*)
	    MAKEDEPEND=$ac_optarg ;;

	-makefile | --makefile | -mf | --mf)
	    ac_prev=MAKEFILE ;;
	-makefile=* | --makefile=* | -mf=* | --mf=*)
	    MAKEFILE=$ac_optarg ;;

	-platform | --platform | -pl | --pl | -platform=* | --platform=* | -pl=* | --pl=*)
	    echo "ERROR: The platform option has been removed.  Please specify"
	    echo "  the build options using the \"optfile\" mechanism."
	    echo
	    usage
	    ;;

	-rootdir | --rootdir | -rd | --rd)
	    ac_prev=ROOTDIR ;;
	-rootdir=* | --rootdir=* | -rd=* | --rd=*)
	    ROOTDIR=$ac_optarg ;;

	-mods | --mods | -mo | --mo)
	    ac_prev=MODS ;;
	-mods=* | --mods=* | -mo=* | --mo=*)
	    MODS=$ac_optarg ;;

	-disable | --disable)
	    ac_prev=DISABLE ;;
	-disable=* | --disable=*)
	    DISABLE=$ac_optarg ;;

	-enable | --enable)
	    ac_prev=ENABLE ;;
	-enable=* | --enable=*)
	    ENABLE=$ac_optarg ;;

	-standarddirs | --standarddirs)
	    ac_prev=STANDARDDIRS ;;
	-standarddirs=* | --standarddirs=*)
	    STANDARDDIRS=$ac_optarg ;;

#	    -cpp | --cpp)
#		ac_prev=cpp ;;
#	    -cpp=* | --cpp=*)
#		CPP=$ac_optarg ;;

	-cc | --cc)
	    ac_prev=CC ;;
	-cc=* | --cc=*)
	    CC=$ac_optarg ;;

	-fortran | --fortran | -fc | --fc)
	    ac_prev=FC ;;
	-fc=* | --fc=*)
	    FC=$ac_optarg ;;

	-fs | --fs)
	    ac_prev=FS ;;
	-fs=* | --fs=*)
	    FS=$ac_optarg ;;

	-fs90 | --fs90)
	    ac_prev=FS90 ;;
	-fs90=* | --fs90=*)
	    FS90=$ac_optarg ;;

	-use_real4 | -use_r4 | -ur4 | --use_real4 | --use_r4 | --ur4 )
	    USE_R4=true ;;

	-ieee | --ieee)
	    IEEE=true ;;
	-noieee | --noieee)
	    echo "Warning: ignore option '$ac_option' (default is already without '-ieee')" ;;
	-devel | --devel)
	    IEEE=true ; DEVEL=true ;;
	-gsl | --gsl)
	    GSL=true ;;

	-ts | --ts)
	    TS=true ;;
	-papis | --papis)
	    PAPIS=true ;;
	-pcls | --pcls)
	    PCLS=true ;;
	-foolad | --foolad)
	    FOOLAD=true ;;
	-papi | --papi)
	    PAPI=true ;;
	-pcl | --pcl)
	    PCL=true ;;
	-hpmt | --hpmt)
	    HPMT=true ;;

	-mpi | --mpi)
	    MPI=true ;;
	-mpi=* | --mpi=*)
	    MPIPATH=$ac_optarg
	    MPI=true ;;

	-omp | --omp)
	    OMP=true ;;
	-omp=* | --omp=*)
	    OMPFLAG=$ac_optarg
	    OMP=true ;;

	-ds | --ds)
	    DUMPSTATE=t ;;

	-extra_flag | --extra_flag)
	    ac_prev=FEXTRAFLAGS ;;
	-extra_flag=* | --extra_flag=*)
	    FEXTRAFLAGS=$ac_optarg ;;

	-taf_extra | --taf_extra)
	    ac_prev=TAF_EXTRA ;;
	-taf_extra=* | --taf_extra=*)
	    TAF_EXTRA=$ac_optarg ;;

#	-taf_f77_flags | --taf_f77_flags)
#	    ac_prev=TAF_F77_FLAGS ;;
#	-taf_f77_flags=* | --taf_f77_flags=*)
#	    TAF_F77_FLAGS=$ac_optarg ;;

#	-taf_f90_flags | --taf_f90_flags)
#	    ac_prev=TAF_F90_FLAGS ;;
#	-taf_f90_flags=* | --taf_f90_flags=*)
#	    TAF_F90_FLAGS=$ac_optarg ;;

	-ignoretime | -ignore_time | --ignoretime | --ignore_time)
	    IGNORE_TIME="-DIGNORE_TIME" ;;

	-es | --es | -embed-source | --embed-source)
	    EMBED_SRC=t ;;

	-*)
	    echo "Error: unrecognized option: "$ac_option
	    usage
	    ;;

	*)
	    echo "Error: unrecognized argument: "$ac_option
	    usage
	    ;;

    esac

done

#TMP=./genmk_$$
#- try to put temporary files in system-local /tmp dir
TMP=/tmp/genmk_${USER}_$$
touch $TMP ; retVal=$?
if [ $retVal -eq 0 ] ; then
  if test ! -r $TMP ; then TMP=./genmk_$$ ; fi
else
  TMP=./genmk_$$
fi
rm -f $TMP
#echo "  temp files: $TMP.*"

printf "  getting local config information:  "
if test -f $gm_local ; then
    echo "using $gm_local"
    . $gm_local
else
    echo "none found"
fi

if test -f ./.genmakerc ; then
    echo
    echo "WARNING: genmake2 has detected a copy of the old-style \"./.genmakerc\""
    echo "  file.  This file format is no longer supported."
    echo "  For directions on how to setup and use the new \"genmake2\" script,"
    echo "  please see the User Manual at:  https://mitgcm.readthedocs.io/"
    echo "WARNING: ignore \"./.genmakerc\" and continue."
    echo
fi

#  Find the MITgcm root directory (${ROOTDIR})
if test "x${ROOTDIR}" = x ; then
    tmp=`echo $PWD | sed -e 's/\// /g' | $AWK '{print $NR}'`
    if test "x$tmp" = "xbin" -a -d ../model -a -d ../eesupp -a -d ../pkg ; then
	ROOTDIR=".."
    else
	for d in . .. ../.. ../../.. ../../../.. ../../../../.. ; do
	    if [ -d "$d/model" -a -d "$d/eesupp" -a -d "$d/pkg" ]; then
		ROOTDIR=$d
		printf "Warning: MITgcm root directory was not specified ;"
		echo " try using a local copy of MITgcm found at \"$ROOTDIR\""
		break
	    fi
	done
    fi
fi
if test "x${ROOTDIR}" = x ; then
    echo "Error: Cannot determine MITgcm root directory for MITgcm code."
    echo "  Please specify a root directory using either the command line"
    echo "   option '-rootdir' or the environment variable 'MITGCM_ROOTDIR'."
    exit 1
fi
if test ! -d ${ROOTDIR} ; then
    echo "Error: the specified MITgcm root directory (\"$ROOTDIR\") does not exist!"
    exit 1
fi

#  Find the MITgcm ${THISVER}
version_file="${ROOTDIR}/doc/tag-index"
if test -f $version_file ; then
    THISVER=`$AWK '/^checkpoint/{print $1; exit}' $version_file`
#-  remove ./BUILD_INFO.h file if older than version_file
    if test -f ./BUILD_INFO.h -a ./BUILD_INFO.h -ot $version_file ; then
	echo "  remove ./BUILD_INFO.h (older than ${version_file})"
	rm -f ./BUILD_INFO.h
    fi
fi

if test "x$MAKEFILE" = x ; then
    MAKEFILE="Makefile"
fi

echo "  getting OPTFILE information:"
if test "x${OPTFILE}" = x ; then
    if test "x$MITGCM_OF" = x ; then
	echo "Warning: no OPTFILE specified so we'll look for possible settings"
	printf "\n===  Searching for possible settings for OPTFILE  ===\n"
	find_possible_optfile
    else
	OPTFILE=$MITGCM_OF
    fi
fi
if test "x$OPTFILE" != xNONE ; then
    if test -f "$OPTFILE" -a -r "$OPTFILE" ; then
	echo "    using OPTFILE=\"$OPTFILE\""
	. "$OPTFILE"
	RETVAL=$?
	if test "x$RETVAL" != x0 ; then
	    printf "Error: failed to source OPTFILE \"$OPTFILE\""
	    echo "--please check that variable syntax is bash-compatible"
	    exit 1
	fi
	if test "x$DUMPSTATE" = xt ; then
	    cp -f $OPTFILE "genmake_optfile"
	fi
    else
	echo "Error: can't read OPTFILE=\"$OPTFILE\""
	exit 1
    fi
fi

echo "  getting AD_OPTFILE information:"
if test "x${AD_OPTFILE}" = x ; then
    if test "x$MITGCM_AD_OF" != x ; then
	AD_OPTFILE=$MITGCM_AD_OF
    elif test "x$TAPENADE" != x ; then
	AD_OPTFILE=$ROOTDIR/tools/adjoint_options/adjoint_tap
    elif test "x$OPENAD" != x ; then
	AD_OPTFILE=$ROOTDIR/tools/adjoint_options/adjoint_oad
    else
	AD_OPTFILE=$ROOTDIR/tools/adjoint_options/adjoint_default
    fi
fi
if test "x${AD_OPTFILE}" != xNONE ; then
    if test -f "$AD_OPTFILE" -a -r "$AD_OPTFILE" ; then
	echo "    using AD_OPTFILE=\"$AD_OPTFILE\""
	. "$AD_OPTFILE"
	RETVAL=$?
	if test "x$RETVAL" != x0 ; then
	    printf "Error: failed to source AD_OPTFILE \"$AD_OPTFILE\""
	    echo "--please check that variable syntax is bash-compatible"
	    exit 1
	fi
	if test "x$DUMPSTATE" = xt ; then
	    cp -f $AD_OPTFILE "genmake_ad_optfile"
	fi
    else
	echo "Error: can't read AD_OPTFILE=\"$AD_OPTFILE\""
	exit 1
    fi
fi

#====================================================================
# Initialize INCLUDEDIRSMK from and optfile INCLUDEDIRS
if test "x${INCLUDEDIRS}" != "x" ; then
 INCLUDEDIRSMK=${INCLUDEDIRS}
fi

#====================================================================
#  Set default values if not set by the optfile
#
#  Check that FC, CC, LINK, CPP, S64, LN, and MAKE are defined.  If not,
#  either set defaults or complain and abort!
if test ! "x$BASH" = x ; then
    # add a trailing space so that it works within the Makefile syntax (see below)
    BASH="$BASH "
fi
if test "x$FC" = x ; then
    cat <<EOF 1>&2

Error: no Fortran compiler: please specify using one of the following:
  1) within the options file ("FC=...") as specified by "-of=OPTFILE"
  2) the "-fc=XXX" command-line option
  3) the "./genmake_local" file
EOF
    exit 1
fi
if test "x$GET_FC_VERSION" != x ; then
  echo "Get compiler version using: $FC $GET_FC_VERSION" >> $LOGFILE
  ff=`echo $FC | sed 's/ .*//'` ; xx=`echo $ff | sed 's/^./& /' | sed 's/ .*//'`
  if test $xx != '/' ; then which $ff >> $LOGFILE ; fi
  $FC $GET_FC_VERSION > genmake_fc_vers1 2> genmake_fc_vers2
  if test -s genmake_fc_vers1 ; then
    cat genmake_fc_vers1 >> $LOGFILE
  else
    cat genmake_fc_vers2 >> $LOGFILE
  fi
  echo "<-- compiler version ----" >> $LOGFILE
  rm -f genmake_fc_vers1 genmake_fc_vers2
fi

if test "x$CC" = x ; then
    look_for_C_compilers
fi

if test "x$LINK" = x ; then
    LINK=$FC
fi
if test "x$MAKE" = x ; then
    MAKE="make"
fi

#- check for fortran compiler (for now, just for information, no consequence)
if test "x$FC_CHECK" = x -o "x$FC_CHECK" = xt ; then
    check_fortran_compiler
else FC_CHECK=-2 ; fi

if test "x$CPP" = x ; then
    CPP="cpp -traditional -P"
fi
#EH3 === UGLY ===
#  The following is an ugly little hack to check for $CPP in /lib/ and
#  it should eventually be replaced with a more general function that
#  searches a combo of the user's path and a list of "usual suspects"
#  to find the correct location for binaries such as $CPP.
for i in " " "/lib/" ; do
    echo "#define A a" | $i$CPP > test_cpp 2>&1 && CPP=$i$CPP
done
#EH3 === UGLY ===
echo "#define A a" | $CPP > test_cpp 2>&1
RETVAL=$?
if test "x$RETVAL" != x0 ; then
    cat <<EOF 1>&2

Error: C pre-processor "$CPP" failed the test case: please specify using:

  1) within the options file ("CPP=...") as specified by "-of=OPTFILE"
  2) the "./genmake_local" file
  3) with the CPP environment variable

EOF
    exit 1
else
    rm -f test_cpp
fi

look_for_makedepend

#  Check that soft-link command is set and usable
if test "x$LN" = x ; then
    LN="ln -s"
fi
echo "test" > genmake_test_ln
$LN genmake_test_ln genmake_tlink
RETVAL=$?
if test "x$RETVAL" != x0 ; then
    cat <<EOF 1>&2

Error: The command "$LN" failed -- please specify a working soft-link
  command in the optfile.

EOF
    exit 1
fi
test -L genmake_tlink > /dev/null 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
    HAVE_TEST_L=t
fi
rm -f genmake_test_ln genmake_tlink

#  Check for broken *.F/*.f handling and fix if possible
check_for_broken_Ff

if test ! "x$MPI" = x ; then
      echo "  Turning on MPI cpp macros"
      DEFINES="$DEFINES -DALLOW_USE_MPI"
#- To compile code older than checkpoint63s (2012/09/05), un-comment the following line:
#     DEFINES="$DEFINES -DALWAYS_USE_MPI"
fi
if test ! "x$OMP" = x ; then
      echo "  Add OMPFLAG and turn on OpenMP cpp macros"
      FFLAGS="$FFLAGS $OMPFLAG"
      F90FLAGS="$F90FLAGS $OMPFLAG"
      DEFINES="$DEFINES -DUSE_OMP_THREADING"
fi

if test ! "x$USE_R4" = x ; then
      echo "  Turning on LET_RS_BE_REAL4 cpp flag"
      DEFINES="$DEFINES -DLET_RS_BE_REAL4"
fi

if test ! "x$TS" = x ; then
      echo "  Turning on timing per timestep"
      if test ! "x$FOOLAD" = x ; then
	    DEFINES="$DEFINES -DTIME_PER_TIMESTEP_SFP"
      else
	    DEFINES="$DEFINES -DTIME_PER_TIMESTEP"
      fi
      PACKAGES="$PACKAGES showflops"
fi
if test ! "x$PAPIS" = x ; then
      echo "  Turning on PAPI flop summary per timestep"
      echo "  Please make sure PAPIINC, PAPILIB are defined"
      if test ! "x$FOOLAD" = x ; then
	    DEFINES="$DEFINES -DUSE_PAPI_FLOPS_SFP"
      else
	    DEFINES="$DEFINES -DUSE_PAPI_FLOPS"
      fi
      INCLUDES="$INCLUDES $PAPIINC"
      LIBS="$LIBS $PAPILIB"
      PACKAGES="$PACKAGES showflops"
fi
if test ! "x$PCLS" = x ; then
      echo "  Turning on PCL counter summary per timestep"
      echo "  Please make sure PCLINC, PCLLIB are defined"
      if test ! "x$FOOLAD" = x ; then
	    DEFINES="$DEFINES -DUSE_PCL_FLOPS_SFP"
      else
	    DEFINES="$DEFINES -DUSE_PCL_FLOPS"
      fi
      INCLUDES="$INCLUDES $PCLINC"
      LIBS="$LIBS $PCLLIB"
      PACKAGES="$PACKAGES showflops"
fi
if test ! "x$PAPI" = x ; then
      if test ! "x$PAPIS" = x ; then
	  echo "  PAPI performance analysis and flop summary per timestep cannot co-exist!"
	  echo "  Sticking with PAPI flop summary per timestep!"
      else
	  echo "  Turning on performance analysis with PAPI"
	  echo "  Please make sure PAPIINC, PAPILIB are defined"
	  DEFINES="$DEFINES -DUSE_PAPI"
	  INCLUDES="$INCLUDES $PAPIINC"
	  LIBS="$LIBS $PAPILIB"
      fi
fi
if test ! "x$PCL" = x ; then
      if test ! "x$PCLS" = x ; then
	  echo "  PCL performance analysis and flop summary per timestep cannot co-exist!"
	  echo "  Sticking with PCL flop summary per timestep!"
      else
	  echo "  Turning on performance analysis with PCL"
	  echo "  Please make sure PCLINC, PCLLIB are defined"
	  DEFINES="$DEFINES -DUSE_PCL"
	  INCLUDES="$INCLUDES $PCLINC"
	  LIBS="$LIBS $PCLLIB"
      fi
fi
if test ! "x$HPMT" = x ; then
      if test ! "x$PAPI" = x ; then
	  echo "  PAPI and the HPM Toolkit cannot co-exist!"
	  echo "  Sticking with PAPI!"
      else
	if test ! "x$PCL" = x ; then
	  echo "  PCL and the HPM Toolkit cannot co-exist!"
	  echo "  Sticking with PCL!"
	else
	  echo "  Turning on performance analysis with the HPM Toolkit"
	  echo "  Please make sure HPMTINC, HPMTLIB are defined"
	  DEFINES="$DEFINES -DUSE_LIBHPM"
	  INCLUDES="$INCLUDES $HPMTINC"
	  LIBS="$LIBS $HPMTLIB"
	fi
      fi
fi
if test ! "x$GSL" = x ; then
      echo "  Turning on use of GSL to control floating point calculations"
      echo "  Please make sure GSLINC, GSLLIB are defined"
      DEFINES="$DEFINES -DUSE_GSL_IEEE"
      INCLUDES="$INCLUDES $GSLINC"
      LIBS="$LIBS $GSLLIB"
fi
#- if USE_EXTENDED_SRC is set, add EXTENDED_SRC_FLAG to FFLAGS :
if test ! "x$USE_EXTENDED_SRC" = x ; then
      FFLAGS="$FFLAGS $EXTENDED_SRC_FLAG"
      F90FIXEDFORMAT="$F90FIXEDFORMAT $EXTENDED_SRC_FLAG"
fi

printf "\n===  Checking system libraries  ===\n"
printf "  Do we have the system() command using $FC...  "
cat > genmake_tcomp.$FS <<EOF
      program hello
      call system('echo hi')
      end
EOF
$FC $FFLAGS -o genmake_tcomp genmake_tcomp.$FS > genmake_tcomp.log 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
    HAVE_SYSTEM=t
    DEFINES="$DEFINES -DHAVE_SYSTEM"
    echo "yes"
else
    HAVE_SYSTEM=
    echo "no"
fi
rm -f genmake_tcomp*

printf "  Do we have the fdate() command using $FC...  "
cat > genmake_tcomp.$FS <<EOF
      program hello
      CHARACTER*(128) string
      string = ' '
      call fdate( string )
      print *, string
      end
EOF
$FC $FFLAGS -o genmake_tcomp genmake_tcomp.$FS > genmake_tcomp.log 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
    HAVE_FDATE=t
    DEFINES="$DEFINES -DHAVE_FDATE"
    echo "yes"
else
    HAVE_FDATE=
    echo "no"
fi
rm -f genmake_tcomp*

printf "  Do we have the etime() command using $FC... "
cat > genmake_tcomp_1.$FS <<EOF
      program hello
      REAL*4 actual, tarray(2)
      EXTERNAL ETIME
      REAL*4 ETIME
      actual = ETIME( tarray )
      print *, tarray
      end
EOF
$FC $FFLAGS -o genmake_tcomp_1 genmake_tcomp_1.$FS > genmake_tcomp.log 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
    HAVE_ETIME='Fct'
    DEFINES="$DEFINES -DHAVE_ETIME_FCT"
    echo " yes (${HAVE_ETIME})"
else
  cat > genmake_tcomp_2.$FS <<EOF
      program hello
      REAL*4 actual, tarray(2)
      actual = -999.
      call ETIME( tarray, actual )
      if ( actual.ge.0. ) then
        print *, 0, tarray, actual
      else
        print *, 1, tarray, actual
      endif
      end
EOF
  $FC $FFLAGS -o genmake_tcomp_2 genmake_tcomp_2.$FS >> genmake_tcomp.log 2>&1
  RETVAL=$?
  if test "x$RETVAL" = x0 ; then
    echo -n 'c,'
    ./genmake_tcomp_2 > genmake_tcomp_2.out 2>&1
    RETVAL=$?
  fi
  if test "x$RETVAL" = x0 ; then
    echo -n 'r:'
    RETVAL=`cat genmake_tcomp_2.out | $AWK '{print $1}'`
  fi
  if test "x$RETVAL" = x0 ; then
    HAVE_ETIME='SbR'
    DEFINES="$DEFINES -DHAVE_ETIME_SBR"
    echo " yes (${HAVE_ETIME})"
  else
    HAVE_ETIME=
    echo " no"
  fi
fi
#mkdir chk_etime ; cp -p -f genmake_tcomp* chk_etime
rm -f genmake_tcomp*

printf "  Can we call simple C routines (here, \"cloc()\") using $FC...  "
check_HAVE_CLOC
if test "x$HAVE_CLOC" != x ; then
    DEFINES="$DEFINES -DHAVE_CLOC"
    echo "yes"
else
    echo "no"
    if test "x$EMBED_SRC" = xt ; then
	echo "    WARNING: you requested file embedding but it has"
	echo "      been disabled since C code cannot be called"
	EMBED_SRC=
    fi
fi
rm -f genmake_t*

printf "  Can we unlimit the stack size using $FC...  "
check_HAVE_SETRLSTK
if test "x$HAVE_SETRLSTK" = xt ; then
    DEFINES="$DEFINES -DHAVE_SETRLSTK"
    echo "yes"
else
    echo "no"
fi
rm -f genmake_t*

printf "  Can we register a signal handler using $FC...  "
check_HAVE_SIGREG
if test "x$HAVE_SIGREG" = xt ; then
    DEFINES="$DEFINES -DHAVE_SIGREG"
    echo "yes"
else
    echo "no"
fi
rm -f genmake_t*

printf "  Can we use stat() through C calls...  "
check_HAVE_STAT
if test "x$HAVE_STAT" != x ; then
    DEFINES="$DEFINES -DHAVE_STAT"
    echo "yes"
else
    echo "no"
fi
rm -f genmake_t*

printf "  Can we create NetCDF-enabled binaries...  "
check_netcdf_libs
if test "x$HAVE_NETCDF" != x ; then
    DEFINES="$DEFINES -DHAVE_NETCDF"
    echo "yes"
else
    echo "no"
fi

if test "x$CHECK_FOR_LAPACK" = xf ; then
    echo   "    skip check for LAPACK Libs"
else
    printf "  Can we create LAPACK-enabled binaries...  "
    check_lapack_libs
    if test "x$HAVE_LAPACK" = xt ; then
	echo "yes"
    else
	echo "no"
    fi
fi
if test "x$HAVE_LAPACK" = xt ; then
    DEFINES="$DEFINES -DHAVE_LAPACK"
elif test "x$HAVE_LAPACK" = x ; then
   #- do not report if unset and unchecked:
    gm_state=`echo $gm_state | sed 's/HAVE_LAPACK//'`
fi

printf "  Can we call FLUSH intrinsic subroutine...  "
check_HAVE_FLUSH
if test "x$HAVE_FLUSH" = xt ; then
    DEFINES="$DEFINES -DHAVE_FLUSH"
    echo "yes"
else
    echo "no"
fi

DEFINES="$DEFINES $IGNORE_TIME"
if test "x$EMBED_SRC" = xt ; then
    build_embed_encode
fi
if test "x$EMBED_SRC" = xt ; then
    ENABLE="$ENABLE embed_files"
#   DEFINES="$DEFINES -DHAVE_EMBED_SRC"
fi

printf "\n===  Setting defaults  ===\n"
printf "  Adding MODS directories: "
for d in $MODS ; do
    if test ! -d $d ; then
	echo
	echo "Error: MODS directory \"$d\" not found!"
	exit 1
    else
	printf "$d "
	SOURCEDIRS="$SOURCEDIRS $d"
	INCLUDEDIRS="$INCLUDEDIRS $d"
	SOURCEDIRSMK="$SOURCEDIRSMK $d"
	INCLUDEDIRSMK="$INCLUDEDIRSMK $d"
    fi
done
echo

#if test "x${PLATFORM}" = x ; then
#    PLATFORM=$p_PLATFORM
#fi

if test "x${EXEDIR}" = x ; then
    tmp=`echo $PWD | sed -e 's/\// /g' | $AWK '{print $NR}'`
    if test "x$tmp" = "xbin" -a -d ../exe -a $ROOTDIR = .. ; then
	EXEDIR=../exe
    else
	EXEDIR=.
    fi
fi
if test ! -d ${EXEDIR} ; then
    echo "Error:  the specified EXEDIR (\"$EXEDIR\") does not exist!"
    exit 1
fi

if test "x${TOOLSDIR}" = x ; then
    TOOLSDIR="$ROOTDIR/tools"
    TOOLSDIRMK='$(ROOTDIR)'"/tools"
else
    TOOLSDIRMK=${TOOLSDIR}
fi
if test ! -d ${TOOLSDIR} ; then
    echo "Error: the specified TOOLSDIR (\"$TOOLSDIR\") does not exist!"
    exit 1
fi
if test "x$S64" = x ; then
    echo "3.0 _d 3" | ${TOOLSDIR}/set64bitConst.sh > /dev/null 2>&1
    RETVAL=$?
    if test "x${RETVAL}" = x0 ; then
	S64='$(TOOLSDIR)/set64bitConst.sh'
    else
	echo "3.0 _d 3" | ${TOOLSDIR}/set64bitConst.csh > /dev/null 2>&1
	RETVAL=$?
	if test "x${RETVAL}" = x0 ; then
	    S64='$(TOOLSDIR)/set64bitConst.csh'
	else
	    cat <<EOF

ERROR: neither of the two default scripts:

    ${TOOLSDIR}/set64bitConst.sh
    ${TOOLSDIR}/set64bitConst.csh

  are working so please check paths or specify (with \$S64) a
  working version of this script.

EOF
	    exit 1
	fi
    fi
fi
THIS_SCRIPT=`echo ${0} | sed 's:'$TOOLSDIR':\$(TOOLSDIR):'`

EXECUTABLE=${EXECUTABLE:-mitgcmuv}

#  Set Standard Code Directories:
if test "x$STANDARDDIRS" = xUSE_THE_DEFAULT ; then
    STANDARDDIRS="eesupp model"
fi
#  if model in Standard-Code-Dir, add eesupp (needed to compile model)
echo " $STANDARDDIRS " | grep ' model ' > /dev/null 2>&1
ckM=$?
echo " $STANDARDDIRS " | grep ' eesupp ' > /dev/null 2>&1
ckE=$?
if test $ckM = 0 -a $ckE = 1 ; then
    STANDARDDIRS="$STANDARDDIRS eesupp"
fi

#  We have a special set of source files in eesupp/src which are
#  generated from some template source files. We'll make them first so
#  they appear as regular source code
if test -r $ROOTDIR"/eesupp/src/Makefile" ; then
    echo "  Making source files in eesupp from templates"
    ( cd $ROOTDIR"/eesupp/src/" && $MAKE clean_old && $MAKE \
    ) > make_eesupp.errors 2>&1
    RETVAL=$?
    if test "x${RETVAL}" = x0 ; then
	rm -f make_eesupp.errors
    else
	echo "Error: problem encountered while building source files in eesupp:"
	cat make_eesupp.errors 1>&2
	exit 1
    fi
fi

#same for pkg/exch2 and pkg/regrid
for pdir in exch2 regrid ; do
    if test -r $ROOTDIR"/pkg/${pdir}/Makefile" ; then
	echo "  Making source files in pkg/${pdir} from templates"
	( cd $ROOTDIR"/pkg/"${pdir} && $MAKE clean_old && $MAKE \
	) > make_${pdir}.errors 2>&1
	RETVAL=$?
	if test "x${RETVAL}" = x0 ; then
	    rm -f make_${pdir}.errors
	else
	    echo "Error: problem encountered while building source files in pkg/${pdir}:"
	    cat make_${pdir}.errors 1>&2
	    exit 1
	fi
    fi
done

printf "\n===  Determining package settings  ===\n"
if  test "x${PKG_DEPEND}" = x ; then
    tmp=$ROOTDIR"/pkg/pkg_depend"
    if test -r $tmp ; then PKG_DEPEND=$tmp ; fi
fi
if  test "x${PKG_DEPEND}" = x ; then
	echo "Warning:  No package dependency information was specified."
	echo "  Please check that ROOTDIR/pkg/pkg_depend exists."
else
    if test ! -r ${PKG_DEPEND} ; then
	echo "Error:  can't read package dependency info from PKG_DEPEND=\"$PKG_DEPEND\""
	exit 1
    fi
    echo "  getting package dependency info from  $PKG_DEPEND"
#  Strip the comments and then convert the dependency file into arrays: PNAME, DNAME
    get_pdepend_list $PKG_DEPEND
fi

# A default package groups file "$ROOTDIR/pkg/pkg_groups" is provided
#  to define the "default_pkg_list" and package groups (for convenience, one
#  can specify a group of packages using names like "ocean" and "atmosphere").
if test "x${PKG_GROUPS}" = x ; then
    tmp=$ROOTDIR"/pkg/pkg_groups"
    if test -r $tmp ; then PKG_GROUPS=$tmp ; fi
fi
if test "x${PKG_GROUPS}" = x ; then
	echo "Warning:  No package groups information was specified."
	echo "  Please check that ROOTDIR/pkg/pkg_groups exists."
else
    if test ! -r ${PKG_GROUPS} ; then
	echo "Error:  can't read package groups info from PKG_GROUPS=\"$PKG_GROUPS\""
	exit 1
    fi
    echo "  getting package groups info from      $PKG_GROUPS"
fi

#  Search for packages to compile.
echo "  checking list of packages to compile:"
PKG_LIST=
if test "x${PKG_LIST}" = x ; then
    for i in "." $MODS ; do
	if test -r $i"/packages.conf" ; then
		PKG_LIST=$i"/packages.conf"
		break
	fi
    done
fi
if test "x${PKG_LIST}" = x ; then
    pkg_list='default_pkg_list'
    if test "x${PKG_GROUPS}" = x ; then
	echo "Error:  need package groups info to expand pkg_list=\"$pkg_list\""
	exit 1
    fi
else
    if test ! -r $PKG_LIST ; then
	echo "Error:  can't read package list from PKG_LIST=\"$PKG_LIST\""
	exit 1
    else
	echo "    using PKG_LIST=\"$PKG_LIST\""
	#  Strip the comments and add all the names
	pkg_list=`cat $PKG_LIST | sed -e 's/#.*$//g' | $AWK '(NF>0){print $0}'`
	RETVAL=$?
	if test "x${RETVAL}" != x0 ; then
	    printf "Error: can't parse package list "
	    echo "-- please check PKG_LIST=\"$PKG_LIST\""
	    exit 1
	fi
    fi
fi
for i in $pkg_list ; do
    PACKAGES="$PACKAGES $i"
done
echo     "    before group expansion packages are:$PACKAGES"
if test "x${PKG_GROUPS}" != x ; then
    RET=1
    while test $RET = 1 ; do expand_pkg_groups; RET=$?; done
    echo "    after group expansion packages are: $PACKAGES"
fi

echo "  applying DISABLE settings"
echo "" > $TMP.pack
for i in $PACKAGES ; do
    echo $i >> $TMP.pack
done
for i in `grep  "-" $TMP.pack` ; do
    j=`echo $i | sed 's/[-]//'`
    DISABLE="$DISABLE $j"
done
pack=
for p in $PACKAGES ; do
    addit="t"
    for d in $DISABLE ; do
	if test "x$p" = "x$d" ; then
	    addit="f"
	fi
    done
    if test "x$addit" = xt ; then
	pack="$pack $p"
    fi
done
PACKAGES="$pack"
echo "  applying ENABLE settings"
echo "" > $TMP.pack
PACKAGES="$PACKAGES $ENABLE"
#  Test if each explicitly referenced package exists
for i in $PACKAGES ; do
    j=`echo $i | sed 's/[-+]//'`
    if test ! -d "$ROOTDIR/pkg/$j" ; then
	echo "Error: dir '$ROOTDIR/pkg/$i' missing for package '$i'"
	exit 1
    fi
    echo $i >> $TMP.pack
done
PACKAGES=
for i in `grep -v "-" $TMP.pack | sort | uniq` ; do
    PACKAGES="$PACKAGES $i"
done
rm -f $TMP.pack
echo "    packages are: $PACKAGES"

#  Check for packages that relies on NetCDF availability:
#  for package MNC: if NetCDF is available, then build the MNC template files
#    otherwise, delete mnc from the list of packages.
#  for package PROFILES and OBSFIT: if NetCDF is not available,
#    then remove profiles or obsfit from the list of available packages.
echo " $PACKAGES " | grep ' mnc ' > /dev/null 2>&1
mnc_In=$?
if test "x$HAVE_NETCDF" != xt ; then
    echo " $PACKAGES " | grep ' profiles ' > /dev/null 2>&1
    profiles_In=$?
    echo " $PACKAGES " | grep ' obsfit ' > /dev/null 2>&1
    obsfit_In=$?
    if test "x$mnc_In" = x0 -o "x$profiles_In" = x0 -o "x$obsfit_In" = x0 ; then
	turnOff_pkg=1
	cat > $TMP.turnOff_pkg <<EOF
*********************************************************************
WARNING: the "THIS_PKG_NAME" package was enabled but tests failed to compile
  NetCDF applications.  Please check that:

  1) NetCDF is correctly installed for this compiler and
  2) the LIBS variable (within the "optfile") specifies the correct
       NetCDF library to link against.

  Due to this failure, the "THIS_PKG_NAME" package is now DISABLED.
*********************************************************************
EOF
    else turnOff_pkg=0 ; fi
    if test "x$mnc_In" = x0 ; then
	cat $TMP.turnOff_pkg | sed 's/THIS_PKG_NAME/mnc/'
	PACKAGES=`echo $PACKAGES | sed -e 's/mnc//g'`
    fi
    if test "x$profiles_In" = x0 ; then
	cat $TMP.turnOff_pkg | sed 's/THIS_PKG_NAME/profiles/'
	PACKAGES=`echo $PACKAGES | sed -e 's/profiles//g'`
    fi
    if test "x$obsfit_In" = x0 ; then
	cat $TMP.turnOff_pkg | sed 's/THIS_PKG_NAME/obsfit/'
	PACKAGES=`echo $PACKAGES | sed -e 's/obsfit//g'`
    fi
    #  this prevent to add the pkg (due to pdepend rules) if not available
    DISABLE="$DISABLE mnc profiles obsfit"
    if [ $turnOff_pkg -eq 1 ] ; then rm -f $TMP.turnOff_pkg ; fi
else
    # we have NetCDF, we try to build MNC template files
    ( cd $ROOTDIR"/pkg/mnc" && $MAKE testclean && $MAKE templates ) > make_mnc.errors 2>&1
    RETVAL=$?
    if test "x${RETVAL}" = x0 ; then
	rm -f make_mnc.errors
    else
	echo "Error: problem encountered while building source files in pkg/mnc:"
	cat make_mnc.errors 1>&2
	if test "x$mnc_In" = x0 ; then
	    exit 1
	else
	    DISABLE="$DISABLE mnc"
	fi
    fi
fi

#  Make sure the tapenade package is enabled if using TAPENADE
if test "x$TAPENADE" != x ; then
    echo " $PACKAGES " | grep ' tapenade ' > /dev/null 2>&1
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	cat <<EOF

*********************************************************************
ERROR: when generating an adjoint with TAPENADE, the tapenade package
  must be enabled.  Please add it to packages.conf.
*********************************************************************

EOF
        exit 1
    fi
fi

#  Make sure the openad package is enabled if using OpenAD
if test "x$OPENAD" != x ; then
    echo " $PACKAGES " | grep ' openad ' > /dev/null 2>&1
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	cat <<EOF

*********************************************************************
ERROR: when generating an adjoint with OpenAD, the openad package
  must be enabled.  Please add it to packages.conf.
*********************************************************************

EOF
        exit 1
    fi
fi

if  test "x${PKG_DEPEND}" != x ; then
  echo "  applying package dependency rules"
  ck=
  while test "x$ck" != xtt ; do
    i=0
    # rtot=${#PNAME[@]}
    rtot=$nname
    while test $i -le $rtot ; do

	#  Is $pname in the current $PACKAGES list?
	#  pname=${PNAME[$i]}
	tmp="pname=\"\$PNAME_$i\""
	eval $tmp
	pin="f"
	for p in $PACKAGES ; do
	    if test "x$p" = "x$pname" ; then
		pin="t"
	    fi
	done
	#  or in the current $STANDARDDIRS list?
	for p in $STANDARDDIRS ; do
	    if test "x$p" = "x$pname" ; then pin="t" ; fi
	done

	#  Is the DNAME entry a (=), (+) or (-) rule ?
	tmp="dname=\"\$DNAME_$i\""
	eval $tmp
	plus="a"
	echo $dname | grep '^+' > /dev/null 2>&1
	RETVAL=$?
	if test "x$RETVAL" = x0 ; then plus="+" ; fi
	echo $dname | grep '^-' > /dev/null 2>&1
	RETVAL=$?
	if test "x$RETVAL" = x0 ; then plus="-" ; fi

	#  Is $dname in the current $PACKAGES list?
	dname=`echo $dname | sed -e 's/^[=+-]//'`
	din="f"
	for p in $PACKAGES ; do
	    if test "x$p" = "x$dname" ; then
		din="t"
	    fi
	done

	#  Do we need to add $dname according to the dependency rules?
	if test "x$pin" = xt -a "x$plus" != "x-" -a "x$din" = xf ; then
	    #echo "   " $pname ": need to add :" $dname
	    in_dis="f"
	    for dis in $DISABLE ; do
		if test "x$dis" = "x$dname" ; then
		    in_dis="t"
		fi
	    done
	    if test "x$in_dis" = xt ; then
		if test "x$plus" = "x+" ; then
		    echo "Error: can't satisfy package dependencies:"
		    echo "  \"$dname\" is required with pkg \"$pname\" (dependency rules)"
		    echo "  but is disallowed by the DISABLE settings"
		    exit 1
		elif test "x$ck" = xt ; then
		#- (=) is a weaker dependency rule: warning but no stop
		    echo    "Warning: pkg \"$dname\" is set DISABLE (from: \"$PKG_LIST\")"
		    echo -n "     but is recommended with pkg \"$pname\" (dependency rules)"
		    echo " <- ignores recommendation"
		fi
	    else
		PACKAGES="$PACKAGES $dname"
		ck=
	    fi
	fi

	#  Do we need to get rid of $dname according to the dependency rules?
	if test "x$pin" = xt -a "x$plus" = "x-" -a "x$din" = xt; then
	    echo "Error: can't satisfy package dependencies:"
	    echo "  \"$dname\" was requested but is disallowed by"
	    echo "  the dependency rules for \"$pname\""
	    exit 1
	fi
	i=`expr $i + 1`
	#i=`echo "$i + 1" | bc -l`
    done
    ck=$ck"t"
  done
  echo "    packages are: $PACKAGES"
fi
for i in $PACKAGES ; do
    adr="$ROOTDIR/pkg/$i"
    adrmk='$(ROOTDIR)'"/pkg/$i"
    if test -d $adr ; then
	SOURCEDIRS="$SOURCEDIRS $adr"
	INCLUDEDIRS="$INCLUDEDIRS $adr"
	SOURCEDIRSMK="$SOURCEDIRSMK $adrmk"
	INCLUDEDIRSMK="$INCLUDEDIRSMK $adrmk"
	if test "x$i" = xautodiff ; then
	    AUTODIFF_PKG_USED=t
	fi
    else
	echo "Error: the directory \"$adr\" for package $i doesn't exist"
	exit 1
    fi
done

# Create a list of #define and #undef to enable/disable packages
PACKAGES_DOT_H=PACKAGES_CONFIG.h
#  The following UGLY HACK sets multiple "#undef"s and it needs to go
#  away.  On 2003-08-12, CNH, JMC, and EH3 agreed that the CPP_OPTIONS.h
#  file would eventually be split up so that all package-related #define
#  statements could be separated and handled only by genmake.
names=`ls -1 "$ROOTDIR/pkg"`
all_pack=
DISABLED_PACKAGES=
for n in $names ; do
    if test -d "$ROOTDIR/pkg/$n" -a "x$n" != xCVS ; then
	has_pack="f"
	for pack in $PACKAGES ; do
	    if test "x$pack" = "x$n" ; then
		has_pack="t"
		break
	    fi
	done
	if test "x$has_pack" = xf ; then
	    undef=`echo "ALLOW_$n" | sed -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
	    DISABLED_PACKAGES="$DISABLED_PACKAGES -U$undef"
	fi
    fi
done
ENABLED_PACKAGES=
for i in $PACKAGES ; do
    def=`echo "ALLOW_$i" | sed -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
    ENABLED_PACKAGES="$ENABLED_PACKAGES -D$def"
#eh3 DEFINES="$DEFINES -D$def"

#EH3  WARNING :  This is an UGLY HACK that needs to be removed!!!
    case $i in
	aim_v23)
	    ENABLED_PACKAGES="$ENABLED_PACKAGES -DALLOW_AIM"
	    echo "Warning: ALLOW_AIM is set to enable aim_v23."
	    ;;
    esac
#EH3  WARNING :  This is an UGLY HACK that needs to be removed!!!

done

echo "  Adding STANDARDDIRS='$STANDARDDIRS'"
BUILDDIR=${BUILDDIR:-.}
if test "x$STANDARDDIRS" != x ; then
    for d in $STANDARDDIRS ; do
	adr="$ROOTDIR/$d/src"
        adrmk='$(ROOTDIR)/'"$d/src"
	if test ! -d $adr ; then
	    echo "Error:  directory $adr not found -- please check that ROOTDIR=\"$ROOTDIR\""
	    echo "  is correct and that you correctly specified the STANDARDDIRS option"
	    exit 1
	else
	    SOURCEDIRS="$SOURCEDIRS $adr"
	    SOURCEDIRSMK="$SOURCEDIRSMK $adrmk"
	fi
	adr="$ROOTDIR/$d/inc"
        adrmk='$(ROOTDIR)/'"$d/inc"
	if test ! -d $adr ; then
	    echo "Error:  directory $adr not found -- please check that ROOTDIR=\"$ROOTDIR\""
	    echo "  is correct and that you correctly specified the STANDARDDIRS option"
	    exit 1
	else
	    INCLUDEDIRS="$INCLUDEDIRS $adr"
	    INCLUDEDIRSMK="$INCLUDEDIRSMK $adrmk"
	fi
    done
fi

echo "  Searching for *OPTIONS.h files in order to warn about the presence"
echo "    of \"#define \"-type statements that are no longer allowed:"
CPP_OPTIONS=
CPP_EEOPTIONS=
spaths=". $INCLUDEDIRS"
names=`ls -1 "$ROOTDIR/pkg"`
for i in $spaths ; do
    try="$i/CPP_OPTIONS.h"
    if test -f $try -a -r $try -a "x$CPP_OPTIONS" = x ; then
	echo "    found CPP_OPTIONS=\"$try\""
	CPP_OPTIONS="$try"
	# New safety test: make sure packages are not mentioned in CPP_OPTIONS.h
	for n in $names ; do
	    test_for_package_in_cpp_options $CPP_OPTIONS $n
	done
    fi
    try="$i/CPP_EEOPTIONS.h"
    if test -f $try -a -r $try -a "x$CPP_EEOPTIONS" = x ; then
	echo "    found CPP_EEOPTIONS=\"$try\""
	# New safety test: make sure MPI is not determined by CPP_EEOPTIONS.h
#**** not yet enabled ****
#        test_for_mpi_in_cpp_eeoptions $try
#**** not yet enabled ****
	CPP_EEOPTIONS="$try"
    fi
done
if test "x$CPP_OPTIONS" = x ; then
    echo "Error: can't find \"CPP_OPTIONS.h\" in the path list: $spaths"
    exit 1
fi

#  Here, we build the list of files to be "run through" the adjoint compiler.
#  split this list between F77 and F90 src code:
echo "  Creating the list of files for the adjoint compiler."
test -f $TMP.adSrcFiles && rm -f $TMP.adSrcFiles
test -f $TMP.adF90Files && rm -f $TMP.adF90Files
touch $TMP.adSrcFiles $TMP.adF90Files
for i in $SOURCEDIRS ; do
    list_files=`( cd $i && ls -1 *_ad_diff.list 2>/dev/null )`
    for j in $list_files ; do
	grep '\.f\>'   $i/$j | sed 's/\.f/.F/' >> $TMP.adSrcFiles
	# Retain file paths for topo sorting later
	grep '\.f90\>' $i/$j | sed 's/\.f90/.F90/' | while IFS= read -r line; do
	    echo "$i/$line" >> $TMP.adF90Files
	done
    done
done
#  Sort in topological order the list of f90 files to send to adjoint compiler
sort_file_list_from_used_modules $TMP.adF90Files

echo
echo "===  Creating the Makefile  ==="
echo "  setting INCLUDES"
for i in $INCLUDEDIRS ; do
    if test ! -d $i ; then
	echo "Warning: can't find INCLUDEDIRS=\"$i\""
    fi
done

if test ! "x$DIVA" = x -a ! "x$MPI" = x ; then
    if test ! "x$MPIINCLUDEDIR" = x ; then
	#  Do a local copy of MPI headers files (in local dir ./mpi_headers/) after
	#   checking for additional included headers (in case of chain of included
	#   header); also set LOCAL_MPI_HEADERS (if not already set)
	mpi_headers_do_local_copy
    fi
fi

echo "  Determining the list of source and include files"
rm -rf $TMP.links
mkdir $TMP.links
touch $TMP.links/foo
if test ! -r "$TMP.links/foo" ; then
    echo
    echo "ERROR : something is wrong with your directory permissions or"
    echo "   your user file-creation mask (\"umask\") since creating a"
    echo "   sub-dir, touch-ing a file within it, and then reading it is"
    echo "   not working.  Please try setting your umask to something"
    echo "   sane such as:"
    echo
    echo "      umask 0002"
    echo
    echo "   and please verify that you have the proper permissions for"
    echo "   creating sub-directories and then reading files created"
    echo "   within them."
    echo
    exit 1
fi
rm -f $TMP.links/foo

if test "x$TAPENADE" != x ; then
    TAP_DONT_TRANSFORM="/dev/null"
    TAPTOOLS="$TOOLSDIR/TAP_support"
    TAPTOOLSMK='$(TOOLSDIR)/TAP_support'
    echo "  looking for dontTransform file:  "
    for i in "." $MODS $TAPTOOLS ; do
	if test -r $i"/dontTransform" ; then
	    TAP_DONT_TRANSFORM=$i"/dontTransform"
	    echo "     found $TAP_DONT_TRANSFORM"
	    break
	fi
    done
    echo "   TAPENADE exceptions:  "
fi

if test "x$OPENAD" != x ; then
    OAD_DONT_COMPILE="/dev/null"
    OAD_DONT_TRANSFORM="/dev/null"
    OAD_KEEP_ORIGINAL="/dev/null"
    OAD_CB2M_FILES="/dev/null"
    OADTOOLS="$TOOLSDIR/OAD_support"
    OADTOOLSMK='$(TOOLSDIR)/OAD_support'
    echo "  looking for dontCompile file:  "
    for i in "." $MODS $OADTOOLS ; do
	if test -r $i"/dontCompile" ; then
	    OAD_DONT_COMPILE=$i"/dontCompile"
	    echo "     found $OAD_DONT_COMPILE"
	    break
	fi
    done
    echo "  looking for dontTransform file:  "
    for i in "." $MODS $OADTOOLS ; do
	if test -r $i"/dontTransform" ; then
	    OAD_DONT_TRANSFORM=$i"/dontTransform"
	    echo "     found $OAD_DONT_TRANSFORM"
	    break
	fi
    done
    echo "  looking for keepOriginal file:  "
    for i in "." $MODS $OADTOOLS ; do
	if test -r $i"/keepOriginal" ; then
	    OAD_KEEP_ORIGINAL=$i"/keepOriginal"
	    echo "     found $OAD_KEEP_ORIGINAL"
	    break
	fi
    done
    echo "  looking for cb2mFiles:  "
    for i in "." $MODS $OADTOOLS ; do
	if test -r $i"/cb2mFiles" ; then
	    OAD_CB2M_FILES=$i"/cb2mFiles"
	    echo "     found $OAD_CB2M_FILES"
	    break
	fi
    done
    echo "   OpenAD exceptions:  "
fi

echo "# This section creates symbolic links" > $TMP.srclinks
echo "" >> $TMP.srclinks
printf 'F77_SRC_FILES = ' > $TMP.F77srclist
printf 'F90_SRC_FILES = ' > $TMP.F90srclist
printf 'C_SRC_FILES = '   > $TMP.csrclist
printf 'H_SRC_FILES = '   > $TMP.hsrclist
printf 'AD_FLOW_FILES = ' > $TMP.ad_flow_files
printf 'NON_AD_F77_SRC_FILES = ' > $TMP.nonADF77srclist
printf 'NON_AD_F90_SRC_FILES = ' > $TMP.nonADF90srclist
alldirs="$SOURCEDIRS $INCLUDEDIRS ."
alldirsmk=(${SOURCEDIRSMK} ${INCLUDEDIRSMK} ".")
nd=0
for d in $alldirs ; do
    dmk=${alldirsmk[${nd}]}
    nd=$((${nd}+1))
    deplist=
    sfiles=`( cd $d; echo *.[h,c,F] *.flow )`
    sfiles=`( echo $sfiles; cd $d; echo *.F90 )`
    if test "x$TAPENADE" != x ; then
	sfiles=`( echo $sfiles | grep -v _cb2m\. )`
    fi
    if test "x$OPENAD" != x ; then
	sfiles=`( echo $sfiles | grep -v _cb2m\. )`
    fi
    for sf in $sfiles ; do
	if test ! -r "$TMP.links/$sf" ; then
	    if test -f "$d/$sf" ; then
		ignore_f=f
		case $d/$sf in
		  ./$PACKAGES_DOT_H)
			ignore_f=t
			;;
		  ./AD_CONFIG.h)
			ignore_f=t
			;;
		  ./FC_NAMEMANGLE.h)
			ignore_f=t
			;;
		  ./BUILD_INFO.h)
			ignore_f=t
			;;
		  ./EMBEDDED_FILES.h)
			ignore_f=t
			;;
		  *)
			#  For the local directory *ONLY*,
			#  ignore all soft-links
			if test "x$HAVE_TEST_L" = xt -a "x$d" = x. -a -L $sf ; then
			    ignore_f=t
			else
			    touch $TMP.links/$sf
			    deplist="$deplist $sf"
			fi
			;;
		esac
		if test "x$ignore_f" = xf ; then
		    extn=`echo $sf | $AWK -F. '{print $NF}'`
		    # this is built-in bash and does not rely on $AWK :
		    # extn=${sf##*.}
		    case $extn in
		      F)
			echo    " \\"  >> $TMP.F77srclist
			printf " $sf" >> $TMP.F77srclist

			if test "x$TAPENADE" = x -a "x$OPENAD" = x ; then
			    #- default: neither Tapenade nor OpenAD
			    isAD=`grep "^$sf\>" $TMP.adSrcFiles`
			    if test -z "$isAD" ; then
				echo    " \\"  >> $TMP.nonADF77srclist
				printf " $sf" >> $TMP.nonADF77srclist
			    fi
			fi
			if test "x$TAPENADE" != x ; then
			    #- Tapenade case:
			    isAD=`grep "^$sf\>" $TMP.adSrcFiles`
			    if test -z "$isAD" ; then
				echo    " \\"  >> $TMP.nonADF77srclist
				printf " $sf" >> $TMP.nonADF77srclist
			    else # file is initially listed as an AD file we want to exclude
				notToBeTransformed=`grep "^$sf\>" ${TAP_DONT_TRANSFORM}`
				if test -n "$notToBeTransformed" ; then
				    echo "    not to be transformed:  $sf"
				    echo    " \\"  >> $TMP.nonADF77srclist
				    printf " $sf" >> $TMP.nonADF77srclist
				fi
			    fi
			fi
			if test "x$OPENAD" != x ; then
			    #- OpenAD case:
			    basename=${sf%%.F}
			    isAD=`grep "^$sf\>" $TMP.adSrcFiles`
			    if test -z "$isAD" ; then
				toBeIgnored=`grep ^$basename'\>' ${OAD_DONT_COMPILE}`
				if test -z "$toBeIgnored" ; then
				    echo    " \\"  >> $TMP.nonADF77srclist
				    printf " $sf" >> $TMP.nonADF77srclist
				else
				    echo "    not to be compiled   :  $sf"
				fi
			    else # file is initially listed as an AD file we want to exclude it
				 # or we want to retain the untransformed version
				notToBeTransformed=`grep ^$basename'\>' ${OAD_DONT_TRANSFORM}`
				untransformedVersionToBeKept=`grep ^$basename ${OAD_KEEP_ORIGINAL}`
				if test -n "$notToBeTransformed"; then
				    echo "    not to be transformed:  $sf"
				fi
				if test -n "$untransformedVersionToBeKept" ; then
				    echo "    original to be kept  :  $sf"
				fi
				if test -n "$notToBeTransformed" -o -n "$untransformedVersionToBeKept" ; then
				    echo    " \\"  >> $TMP.nonADF77srclist
				    printf " $sf" >> $TMP.nonADF77srclist
				fi
			    fi
			fi
			;;
		    F90)
			echo    " \\" >> $TMP.F90srclist
			printf " $sf" >> $TMP.F90srclist
			if ( test "x$OPENAD" = x && test "x$TAPENADE" = x ) ; then
			    isAD=`grep "^$sf\>" $TMP.adF90Files`
			    if test -z "$isAD" ; then
				echo    " \\" >> $TMP.nonADF90srclist
				printf " $sf" >> $TMP.nonADF90srclist
			    fi
			fi
			;;
		    c)
			echo    " \\"  >> $TMP.csrclist
			printf " $sf" >> $TMP.csrclist
			;;
		    h)
			echo    " \\"  >> $TMP.hsrclist
			printf " $sf" >> $TMP.hsrclist
			;;
		    flow)
			echo    " \\"  >> $TMP.ad_flow_files
			printf " $sf" >> $TMP.ad_flow_files
			;;
		   esac
	        fi
	    fi
	fi
    done
    if test "x$deplist" != x ; then
      if test "$d" != "." ; then
	echo "" >> $TMP.srclinks
	echo "#  These files are linked from $dmk ( aka $d )" >> $TMP.srclinks
	echo "$deplist :" >> $TMP.srclinks
	# We need to make sure that the link isn't already there.
	# This may happen when make thinks that a header file has to be "remade"
	# because a module it depends on has changed.  In this case we do nothing.
	printf "\tif [ ! -L \$@ ]; then \$(LN) %s/\$@ \$@; fi\n" $dmk >> $TMP.srclinks
      fi
    fi
done
rm -rf $TMP.links
echo "" >> $TMP.F77srclist
echo "" >> $TMP.F90srclist
echo "" >> $TMP.csrclist
echo "" >> $TMP.hsrclist
echo "" >> $TMP.ad_flow_files
echo "" >> $TMP.nonADF77srclist
echo "" >> $TMP.nonADF90srclist

CMDLINE=$0
for xx in "$@" ; do nw=`echo $xx | wc -w`
    if test $nw = '1' ; then CMDLINE="$CMDLINE $xx"
			else CMDLINE="$CMDLINE '$xx'" ; fi
done

if test -f $MAKEFILE ; then
    mv -f $MAKEFILE "$MAKEFILE.old"
fi
echo "  Writing makefile: $MAKEFILE"
echo "# Multithreaded + multi-processing makefile for:" > $MAKEFILE
echo "#    $MACHINE" >> $MAKEFILE
echo "# This makefile was generated automatically on" >> $MAKEFILE
echo "#    $THISDATE" >> $MAKEFILE
echo "# by the command:" >> $MAKEFILE
echo "#    $CMDLINE"  >> $MAKEFILE
echo "# executed by:" >> $MAKEFILE
echo "#    ${THISUSER}@${THISHOST}:${THISCWD}" >> $MAKEFILE

if test "x$TAPENADE" = x ; then
    EXE_ADJ=$EXECUTABLE"_ad"
    EXE_TLM=$EXECUTABLE"_ftl"
else
    EXE_ADJ=$EXECUTABLE"_tap_adj"
    EXE_TLM=$EXECUTABLE"_tap_tlm"
fi
EXE_SVD=$EXECUTABLE"_svd"

cat >>$MAKEFILE <<EOF
#
# OPTFILE="$OPTFILE"
#
# BUILDDIR     : Directory where object files are written
# SOURCEDIRS   : Directories containing the source (.F) files
# INCLUDEDIRS  : Directories containing the header-source (.h) files
# EXEDIR       : Directory where executable that is generated is written
# EXECUTABLE   : Full path of executable binary
#
# CPP          : C-preprocessor command
# INCLUDES     : Directories searched for header files
# DEFINES      : Macro definitions for CPP
# MAKEDEPEND   : Dependency generator
# FC           : Fortran compiler command
# FFLAGS       : Configuration/debugging options for FC
# FOPTIM       : Optimization options for FC
# LINK         : Command for link editor program
# LIBS         : Library flags /or/ additional optimization/debugging flags

ROOTDIR     = ${ROOTDIR}
BUILDDIR    = ${BUILDDIR}
SOURCEDIRS  = ${SOURCEDIRSMK}
INCLUDEDIRS = ${INCLUDEDIRSMK}
EXEDIR      = ${EXEDIR}
EXECUTABLE  = \$(EXEDIR)/${EXECUTABLE}
TOOLSDIR    = ${TOOLSDIRMK}
OADTOOLS    = ${OADTOOLSMK}

#eh3  new defines for the adjoint work
AUTODIFF    = \$(ROOTDIR)/pkg/autodiff
EXE_ADJ     = ${EXE_ADJ}
EXE_TLM     = ${EXE_TLM}
EXE_SVD     = ${EXE_SVD}

ENABLED_PACKAGES = ${ENABLED_PACKAGES}
DISABLED_PACKAGES = ${DISABLED_PACKAGES}

# These files are created by Makefile
SPECIAL_FILES = ${PACKAGES_DOT_H} AD_CONFIG.h FC_NAMEMANGLE.h BUILD_INFO.h
EOF

if test "x$EMBED_SRC" = xt ; then
    echo "EMBEDDED_FILES = EMBEDDED_FILES.h" >>$MAKEFILE
else
    echo "EMBEDDED_FILES = " >>$MAKEFILE
fi

# extract default cpp search path so we can pass it to makedepend
CPPINCLUDES=`cat /dev/null | $CPP -v 2>&1 | $AWK '/^End of search/{f=0}!/^#/{if(f){printf " -I%s", $1;}}/^#include "..." search start/{f=1}'`

cat >>$MAKEFILE <<EOF
# Unix ln (link)
LN = ${LN}
# Dependency generator
MAKEDEPEND = ${MAKEDEPEND}
# Special preprocessor (KAP on DECs, FPP on Crays)
KPP = ${KPP}
# Fortran compiler
FC = ${FC}
# Fortran compiler
F90C = ${F90C}
# C compiler
CC = ${CC}
# Link editor
LINK = ${LINK} ${LDADD}

# Defines for CPP
DEFINES = ${DEFINES}
# Includes for CPP
INCLUDES = ${INCLUDES}
# default CPP includes for makedepend
CPPINCLUDES = ${CPPINCLUDES}
# Flags for KPP
KFLAGS1 = ${KFLAGS1}
KFLAGS2 = ${KFLAGS2}
# Optim./debug for FC
FFLAGS = ${FFLAGS}
FOPTIM = ${FOPTIM} ${FEXTRAFLAGS}
# Optim./debug for FC
F90FLAGS = ${F90FLAGS}
F90OPTIM = ${F90OPTIM}
F90FIXEDFORMAT = ${F90FIXEDFORMAT}
# Flags for CC
CFLAGS = ${CFLAGS}
# Files that should not be optimized
NOOPTFILES = ${NOOPTFILES}
NOOPTFLAGS = ${NOOPTFLAGS}
# Flags and libraries needed for linking
LIBS = ${LIBS}
# Name of the makefile
MAKEFILE = ${MAKEFILE}
# Name of the make program
MAKE = ${MAKE}

EOF

cat $TMP.F77srclist      >> $MAKEFILE
cat $TMP.F90srclist      >> $MAKEFILE
cat $TMP.csrclist        >> $MAKEFILE
cat $TMP.hsrclist        >> $MAKEFILE
cat $TMP.ad_flow_files   >> $MAKEFILE

rm -f $TMP.F77srclist $TMP.F90srclist $TMP.csrclist $TMP.hsrclist $TMP.ad_flow_files

echo >> $MAKEFILE

# add definitions for preprocessed sources
# and note that not all systems allow case sensitive extensions
# hence the $FS and $FS90 here.
# for fixed format f90 files we use ff90 or FF90 resp
# but these are not expected to be the original source files

echo 'F77_PP_SRC_FILES = $(F77_SRC_FILES:.F=.'$FS')'     >> $MAKEFILE
echo 'F90_PP_SRC_FILES = $(F90_SRC_FILES:.F90=.'$FS90')' >> $MAKEFILE
echo 'OBJFILES= $(F90_SRC_FILES:.F90=.o) $(F77_SRC_FILES:.F=.o) $(C_SRC_FILES:.c=.o)' >> $MAKEFILE

echo >> $MAKEFILE
echo '.SUFFIXES:' >> $MAKEFILE
echo '.SUFFIXES: .o .'$FS' .p .F .c .f'$FS90' .'$FS90' .FF90 .F90 .flow' >> $MAKEFILE

cat >>$MAKEFILE <<EOF

all: fwd_exe_target
fwd_exe_target:
	@echo Update AD_CONFIG.h and make \$(EXECUTABLE)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Forward version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > ad_config.template
	@cmp ad_config.template AD_CONFIG.h || cat ad_config.template > AD_CONFIG.h
	@-rm -f ad_config.template
	\$(MAKE) -f \$(MAKEFILE) \$(EXECUTABLE)

\$(EXECUTABLE): \$(SPECIAL_FILES) \$(F90_SRC_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(H_SRC_FILES) \$(OBJFILES) \$(EMBEDDED_FILES)
	@echo Creating \$@ ...
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(OBJFILES) \$(LIBS)

depend:
	@\$(MAKE) -f \$(MAKEFILE) links
	\$(MAKEDEPEND) -f \$(MAKEFILE) -o .$FS \$(DEFINES) \$(INCLUDES) \$(CPPINCLUDES) \$(F77_SRC_FILES)
	\$(MAKEDEPEND) -f \$(MAKEFILE) -a -o .$FS90 \$(DEFINES) \$(INCLUDES) \$(CPPINCLUDES) \$(F90_SRC_FILES)
	\$(TOOLSDIR)/f90mkdepend -fs $FS -fs90 $FS90 >> \$(MAKEFILE)
	-rm -f makedepend.out
EOF
if test $CAT_SRC_FOR_TAF = 0 ; then
  echo "	-touch $DEP_TAF_FILE" >> $MAKEFILE
  echo "	-echo 'include $DEP_TAF_FILE' >> \$(MAKEFILE)" >> $MAKEFILE
fi
cat >>$MAKEFILE <<EOF

lib: libmitgcmuv.a

libmitgcmuv.a: \$(SPECIAL_FILES) \$(OBJFILES)
	ar rcv libmitgcmuv.a \$(OBJFILES)
	ar d   libmitgcmuv.a main.o

obj: \$(OBJFILES)

links: \$(F90_SRC_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(H_SRC_FILES) \$(SPECIAL_FILES)

small_f: \$(F90_PP_SRC_FILES) \$(F77_PP_SRC_FILES)

# remove most of the files that "make" generates
clean:
	-rm -rf *.p *.$FS90 *.mod ${RMFILES} work.{pc,pcl} *.template
	-rm -rf *.o
	-rm -rf *.$FS
	-rm -rf *.f$FS90 \$(AD_CLEAN) ad_input*

# remove most of the files that "make" and "make depend" generate
Clean:
	@\$(MAKE) -f \$(MAKEFILE) clean
	@\$(MAKE) -f \$(MAKEFILE) cleanlinks
	-rm -rf *.flowdir
	-rm -f \$(SPECIAL_FILES) f90mkdepend.log $MAKEFILE.old
	-rm -f taf_command taf_output taf_ad.log taf_ad_flow.log taf_ftl.log
EOF
if test $CAT_SRC_FOR_TAF = 0 ; then
cat >>$MAKEFILE <<EOF
	-sed -i.tmp "/^include $DEP_TAF_FILE/d" \$(MAKEFILE) && rm -f $DEP_TAF_FILE \$(MAKEFILE).tmp
	-rm -f taf_ad.f90 taf_tl.f90 f90mkdepend_taf.log
EOF
fi
cat >>$MAKEFILE <<EOF

# remove also the executable, files that "genmake2" generates (except Makefile)
#         and output from a run (plus log files from testreport)
CLEAN:
	@\$(MAKE) -f \$(MAKEFILE) Clean
	-rm -f \$(EXECUTABLE) \$(EXE_ADJ) \$(EXE_TLM) *.bak
	-rm -f $LOGFILE genmake_state genmake_*optfile
	-rm -f SIZE.h.mpi genmake.tr_log make.tr_log
	-rm -rf mpi_headers mnc_test_*
	-find \$(EXEDIR) -name "*.meta" -exec rm {} \;
	-find \$(EXEDIR) -name "*.data" -exec rm {} \;
	-find \$(EXEDIR) -name "fort.*" -exec rm {} \;
	-rm -f *.txt STDOUT.* STDERR.* *diagnostics.log *.[0-9][0-9][0-9][0-9].log
	-rm -f datetime costfinal divided.ctrl snapshot* output_adm.txt.diva_*
	-rm -f *_MIT_CE_000.opt0000 costfunction*0000
	-rm -f oad_cp.[0-9][0-9][0-9].?????

makefile:
	$THIS_SCRIPT $G2ARGS
cleanlinks:
	-find . -type l -exec rm {} \;

# Special targets (SPECIAL_FILES) which are created by make
${PACKAGES_DOT_H}:
	@echo Creating \$@ ...
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines -bPACKAGES_CONFIG_H "Disabled packages:" \$(DISABLED_PACKAGES) " " "Enabled packages:" \$(ENABLED_PACKAGES) > \$@
AD_CONFIG.h:
	@echo Creating \$@ ...
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Default version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > \$@
FC_NAMEMANGLE.h:
	@echo Creating \$@ ...
	echo "$FC_NAMEMANGLE" > \$@

BUILD_INFO.h:
	@echo Creating \$@ ...
EOF

test ! "x$THISVER" = x  && echo "	-echo \"#define THISVER '$THISVER'\" > \$@"   >> $MAKEFILE
test ! "x$THISUSER" = x && echo "	-echo \"#define THISUSER '$THISUSER'\" >> \$@" >> $MAKEFILE
test ! "x$THISDATE" = x && echo "	-echo \"#define THISDATE '$THISDATE'\" >> \$@" >> $MAKEFILE
test ! "x$THISHOST" = x && echo "	-echo \"#define THISHOST '$THISHOST'\" >> \$@" >> $MAKEFILE

if test "x$EMBED_SRC" = xt ; then
    cat >>$MAKEFILE <<EOF

decode_files.o : EMBEDDED_FILES.h

##  \$(F77_PP_SRC_FILES)
all_fF.tar.gz : \$(SPECIAL_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES) \$(F77_PP_SRC_FILES) Makefile
	@echo Creating \$@ ...
	-tar -hcf all_fF.tar \$(SPECIAL_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES) \$(F77_PP_SRC_FILES) Makefile
	-rm -f all_fF.tar.gz
	-gzip all_fF.tar

EMBEDDED_FILES.h : all_fF.tar.gz
	@echo Creating \$@ ...
	-\${ROOTDIR}/tools/embed_encode/encode_files EMBEDDED_FILES.h all_fF.tar.gz

EOF
fi

cat >>$MAKEFILE <<EOF

# The normal chain of rules is (  .F - .$FS - .o  )

## This nullifies any default implicit rules concerning these two file types:
## %.o : %.F

# C preprocessing and replacing the _d in constants:
CPPCMD = cat \$< | ${CPP} \$(DEFINES) \$(INCLUDES) | ${S64}

.F.$FS:
	\$(CPPCMD)  > \$@
.$FS.o:
	\$(FC) \$(FFLAGS) \$(FOPTIM) -c \$<
.F.o:
	\$(FC) \$(FFLAGS) \$(FOPTIM) -c \$<
.F90.$FS90:
	\$(CPPCMD)  > \$@
.FF90.f$FS90:
	\$(CPPCMD)  > \$@
.$FS90.o:
	\$(F90C) \$(F90FLAGS) \$(F90OPTIM) -c \$<
.f$FS90.o:
	cp \$< \$(basename  \$<).$FS90
	\$(F90C) \$(F90FLAGS) \$(F90OPTIM) -c \$(F90FIXEDFORMAT) \$(basename  \$<).$FS90
.c.o:
	\$(CC) \$(CFLAGS) \$(DEFINES) \$(INCLUDES) -c \$<

# Special exceptions that use the ( .F - .p - .$FS - .o ) rule-chain
.F.p:
	\$(CPPCMD) > \$@
.p.$FS:
	\$(KPP) \$(KFLAGS1)\$@ \$(KFLAGS2) \$<

EOF

#=========================================
#===  Automatic Differentiation Rules  ===
#===  for TAF  ===========================

if test "x$TAPENADE" = x -a "x$OPENAD" = x ; then

cat >>$MAKEFILE <<EOF

TAF           = ${TAF}
TAF_EXTRA     = ${TAF_EXTRA}
TAF_F77_FLAGS = ${TAF_F77_FLAGS}
TAF_F90_FLAGS = ${TAF_F90_FLAGS}
LOCAL_MPI_HEADERS = ${LOCAL_MPI_HEADERS}

EOF

ad_vars="AD_TAF_FLAGS FTL_TAF_FLAGS SVD_TAF_FLAGS"
for i in $ad_vars ; do
    name=$i
    t1="t2=\$"`echo "$i"`
    eval $t1
    printf "%-13s = " $name >> $MAKEFILE
    echo "$t2" | sed -e 's| \+| |g' >> $MAKEFILE
done

echo "  Add the source list for AD code generation"
echo >> $MAKEFILE
printf "AD_FILES = " >> $MAKEFILE
AD_FILES=`cat $TMP.adSrcFiles | sed "s/\.F/.$FS/g"`
for i in $AD_FILES ; do
    echo   " \\" >> $MAKEFILE
    printf " $i" >> $MAKEFILE
done
echo >> $MAKEFILE
printf "AD_F90FILES = " >> $MAKEFILE
AD_F90FILES=`cat $TMP.adF90Files | sed "s/\.F90/.$FS90/g"`
for i in $AD_F90FILES ; do
    echo   " \\" >> $MAKEFILE
    printf " $i" >> $MAKEFILE
done
echo >> $MAKEFILE
rm -f $TMP.adSrcFiles $TMP.adF90Files
cat $TMP.nonADF77srclist >> $MAKEFILE
cat $TMP.nonADF90srclist >> $MAKEFILE
rm -f $TMP.nonADF77srclist $TMP.nonADF90srclist
echo >> $MAKEFILE

cat >>$MAKEFILE <<EOF
# ... AD ...
adall: ad_exe_target
adtaf: ad_taf_output.$FS

ad_exe_target:
	@echo Update AD_CONFIG.h and make \$(EXE_ADJ)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Adjoint version" -bAD_CONFIG_H -DALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > ad_config.template0
	@cmp ad_config.template0 AD_CONFIG.h || cat ad_config.template0 > AD_CONFIG.h
	@-rm -f ad_config.template0
	\$(MAKE) -f \$(MAKEFILE) \$(EXE_ADJ)

EOF

if test $CAT_SRC_FOR_TAF = 1 ; then
cat >>$MAKEFILE <<EOF
ad_input_code.$FS: \$(AD_FILES) \$(AD_FLOW_FILES)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Adjoint version" -bAD_CONFIG_H -DALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > ad_config.template1
	cmp ad_config.template1 AD_CONFIG.h || cat ad_config.template1 > AD_CONFIG.h
	@-rm -f ad_config.template1
	@\$(MAKE) -f \$(MAKEFILE) \$(F77_PP_SRC_FILES)
	cat \$(AD_FLOW_FILES) \$(AD_FILES) | sed -f \$(TOOLSDIR)/remove_comments_sed > ad_input_code.$FS

EOF

if test -z "$AD_F90FILES" ; then
cat >>$MAKEFILE <<EOF
# ... send 1 file to TAF ...
ad_taf_output.$FS: ad_input_code.$FS
	@-rm -f ad_input_code_ad.$FS ; echo ''
	\$(TAF) \$(AD_TAF_FLAGS) \$(TAF_EXTRA) -fixed \$(TAF_F77_FLAGS) ad_input_code.$FS
	ls -l ad_input_code_ad.$FS
	cat ad_input_code_ad.$FS | sed -f \$(TOOLSDIR)/adjoint_sed > ad_taf_output.$FS

\$(EXE_ADJ): \$(SPECIAL_FILES) \$(H_SRC_FILES) ad_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES)
	\$(LINK) -o \${EXE_ADJ} \$(FFLAGS) \$(FOPTIM) ad_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(LIBS)

adobj: ad_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o)

EOF
else
cat >>$MAKEFILE <<EOF
ad_inpF90_code.$FS90: \$(AD_F90FILES) \$(AD_FLOW_FILES)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Adjoint version" -bAD_CONFIG_H -DALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > ad_config.template2
	cmp ad_config.template2 AD_CONFIG.h || cat ad_config.template2 > AD_CONFIG.h
	@-rm -f ad_config.template2
	@\$(MAKE) -f \$(MAKEFILE) \$(F90_PP_SRC_FILES)
	cat \$(AD_F90FILES) > ad_inpF90_code.$FS90

# ... send 1 fixed format file and 1 free format file to TAF ...
ad_taf_output.$FS: ad_inpF90_code.$FS90 ad_input_code.$FS
	@-rm -f ad_inpF90_code_ad.$FS90 ad_input_code_ad.$FS ; echo ''
	\$(TAF) \$(AD_TAF_FLAGS) \$(TAF_EXTRA) -free \$(TAF_F90_FLAGS) ad_inpF90_code.$FS90 -fixed \$(TAF_F77_FLAGS) ad_input_code.$FS
	ls -l ad_inpF90_code_ad.$FS90 ad_input_code_ad.$FS
	cat ad_input_code_ad.$FS | sed -f \$(TOOLSDIR)/adjoint_sed > ad_taf_output.$FS

# We need the extra target for ad_taf_outpF90.$FS90, because the file is
# generated together with ad_taf_output.$FS.
ad_taf_outpF90.$FS90: ad_taf_output.$FS
	cat ad_inpF90_code_ad.$FS90 > ad_taf_outpF90.$FS90

\$(EXE_ADJ): \$(SPECIAL_FILES) \$(H_SRC_FILES) ad_taf_outpF90.o ad_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES)
	\$(LINK) -o \${EXE_ADJ} \$(FFLAGS) \$(FOPTIM) ad_taf_outpF90.o ad_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(LIBS)

adobj: ad_taf_outpF90.o ad_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o)

EOF
fi

else
cat >>$MAKEFILE <<EOF
# ... send multiple files to TAF ...
adobjfiles: \$(AD_F90FILES:.$FS90=_ad.o) \$(AD_FILES:.$FS=_ad.o)

ad_taf_output.$FS: \$(AD_FLOW_FILES) \$(AD_F90FILES) \$(AD_FILES)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Adjoint version" -bAD_CONFIG_H -DALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > ad_config.template1
	cmp ad_config.template1 AD_CONFIG.h || cat ad_config.template1 > AD_CONFIG.h
	@-rm -f ad_config.template1
	@\$(MAKE) -f \$(MAKEFILE) \$(F90_PP_SRC_FILES) \$(F77_PP_SRC_FILES)
	sed -i.bak -f \$(TOOLSDIR)/remove_comments_sed \$(AD_FILES)
	@-rm -f \$(AD_F90FILES:.$FS90=_ad.$FS90) \$(AD_FILES:.$FS=_ad.$FS) \$(AD_FILES:.$FS=.$FS.bak); echo ''
	\$(TAF) \$(AD_TAF_FLAGS) \$(TAF_EXTRA) -free \$(TAF_F90_FLAGS) \$(AD_F90FILES) -fixed \$(TAF_F77_FLAGS) \$(AD_FLOW_FILES) \$(AD_FILES)
	ls -l the_main_loop_ad.$FS
	sed -i.bak -f \$(TOOLSDIR)/adjoint_sed \$(AD_FILES:.$FS=_ad.$FS)
	@-rm -f \$(AD_FILES:.$FS=_ad.$FS.bak)
	\$(TOOLSDIR)/f90mkdepend_taf $DEP_TAF_FILE \$(AD_F90FILES:.$FS90=_ad.$FS90) \$(AD_FILES:.$FS=_ad.$FS)
	touch ad_taf_output.$FS

\$(EXE_ADJ): \$(SPECIAL_FILES) \$(H_SRC_FILES) ad_taf_output.$FS \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES)
	\$(MAKE) -f \$(MAKEFILE) adobjfiles
	\$(LINK) -o \${EXE_ADJ} \$(FFLAGS) \$(FOPTIM) \$(AD_F90FILES:.$FS90=_ad.o) \$(AD_FILES:.$FS=_ad.o) \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(LIBS)

adobj: ad_taf_output.$FS \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o)
	\$(MAKE) -f \$(MAKEFILE) adobjfiles

EOF
fi

cat >>$MAKEFILE <<EOF
# ... FTL ...
ftlall: ftl_exe_target
ftltaf: ftl_taf_output.$FS

ftl_exe_target:
	@echo Update AD_CONFIG.h and make \$(EXE_TLM)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "TangLin version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -DALLOW_TANGENTLINEAR_RUN > ad_config.template0
	@cmp ad_config.template0 AD_CONFIG.h || cat ad_config.template0 > AD_CONFIG.h
	@-rm -f ad_config.template0
	\$(MAKE) -f \$(MAKEFILE) \$(EXE_TLM)

EOF

if test $CAT_SRC_FOR_TAF = 1 ; then
cat >>$MAKEFILE <<EOF
ftl_input_code.$FS: \$(AD_FILES) \$(AD_FLOW_FILES)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "TangLin version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -DALLOW_TANGENTLINEAR_RUN > ad_config.template1
	cmp ad_config.template1 AD_CONFIG.h || cat ad_config.template1 > AD_CONFIG.h
	@-rm -f ad_config.template1
	@\$(MAKE) -f \$(MAKEFILE) \$(F77_PP_SRC_FILES)
	cat \$(AD_FLOW_FILES) \$(AD_FILES) | sed -f \$(TOOLSDIR)/remove_comments_sed > ftl_input_code.$FS

EOF

if test -z "$AD_F90FILES" ; then
cat >>$MAKEFILE <<EOF
# ... send 1 file to TAF ...
ftl_taf_output.$FS: ftl_input_code.$FS
	@-rm -f ftl_input_code_tl.$FS ; echo ''
	\$(TAF) \$(FTL_TAF_FLAGS) \$(TAF_EXTRA) -fixed \$(TAF_F77_FLAGS) ftl_input_code.$FS
	ls -l ftl_input_code_tl.$FS
	cat ftl_input_code_tl.$FS | sed -f \$(TOOLSDIR)/adjoint_sed > ftl_taf_output.$FS

\$(EXE_TLM): \$(SPECIAL_FILES) \$(H_SRC_FILES) ftl_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES)
	\$(LINK) -o \${EXE_TLM} \$(FFLAGS) \$(FOPTIM) ftl_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(LIBS)

ftlobj: ftl_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o)

EOF
else
cat >>$MAKEFILE <<EOF
ftl_inpF90_code.$FS90: \$(AD_F90FILES) \$(AD_FLOW_FILES)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "TangLin version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -DALLOW_TANGENTLINEAR_RUN > ad_config.template2
	cmp ad_config.template2 AD_CONFIG.h || cat ad_config.template2 > AD_CONFIG.h
	@-rm -f ad_config.template2
	@\$(MAKE) -f \$(MAKEFILE) \$(F90_PP_SRC_FILES)
	cat \$(AD_F90FILES) > ftl_inpF90_code.$FS90

# ... send 1 fixed format file and 1 free format file to TAF ...
ftl_taf_output.$FS: ftl_inpF90_code.$FS90 ftl_input_code.$FS
	@-rm -f ftl_inpF90_code_tl.$FS90 ftl_input_code_tl.$FS ; echo ''
	\$(TAF) \$(FTL_TAF_FLAGS) \$(TAF_EXTRA) -free \$(TAF_F90_FLAGS) ftl_inpF90_code.$FS90 -fixed \$(TAF_F77_FLAGS) ftl_input_code.$FS
	ls -l ftl_inpF90_code_tl.$FS90 ftl_input_code_tl.$FS
	cat ftl_input_code_tl.$FS | sed -f \$(TOOLSDIR)/adjoint_sed > ftl_taf_output.$FS

# We need the extra target for ftl_taf_outpF90.$FS90, because the file is
# generated together with ftl_taf_output.$FS.
ftl_taf_outpF90.$FS90: ftl_taf_output.$FS
	cat ftl_inpF90_code_tl.$FS90 > ftl_taf_outpF90.$FS90

\$(EXE_TLM): \$(SPECIAL_FILES) \$(H_SRC_FILES) ftl_taf_outpF90.o ftl_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES)
	\$(LINK) -o \${EXE_TLM} \$(FFLAGS) \$(FOPTIM) ftl_taf_outpF90.o ftl_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(LIBS)

ftlobj: ftl_taf_outpF90.o ftl_taf_output.o \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o)

EOF
fi

else
cat >>$MAKEFILE <<EOF
# ... send multiple files to TAF ...
ftlobjfiles: \$(AD_F90FILES:.$FS90=_tl.o) \$(AD_FILES:.$FS=_tl.o)

ftl_taf_output.$FS: \$(AD_FLOW_FILES) \$(AD_F90FILES) \$(AD_FILES)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "TangLin version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -DALLOW_TANGENTLINEAR_RUN > ad_config.template1
	cmp ad_config.template1 AD_CONFIG.h || cat ad_config.template1 > AD_CONFIG.h
	@-rm -f ad_config.template1
	@\$(MAKE) -f \$(MAKEFILE) \$(F90_PP_SRC_FILES) \$(F77_PP_SRC_FILES)
	sed -i.bak -f \$(TOOLSDIR)/remove_comments_sed \$(AD_FILES)
	@-rm -f \$(AD_F90FILES:.$FS90=_tl.$FS90) \$(AD_FILES:.$FS=_tl.$FS) \$(AD_FILES:.$FS=.$FS.bak); echo ''
	\$(TAF) \$(FTL_TAF_FLAGS) \$(TAF_EXTRA) -free \$(TAF_F90_FLAGS) \$(AD_F90FILES) -fixed \$(TAF_F77_FLAGS) \$(AD_FLOW_FILES) \$(AD_FILES)
	ls -l the_main_loop_tl.$FS
	sed -i.bak -f \$(TOOLSDIR)/adjoint_sed \$(AD_FILES:.$FS=_tl.$FS)
	@-rm -f \$(AD_FILES:.$FS=_tl.$FS.bak)
	\$(TOOLSDIR)/f90mkdepend_taf $DEP_TAF_FILE \$(AD_F90FILES:.$FS90=_tl.$FS90) \$(AD_FILES:.$FS=_tl.$FS)
	touch ftl_taf_output.$FS

\$(EXE_TLM): \$(SPECIAL_FILES) \$(H_SRC_FILES) ftl_taf_output.$FS \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES)
	\$(MAKE) -f \$(MAKEFILE) ftlobjfiles
	\$(LINK) -o \${EXE_TLM} \$(FFLAGS) \$(FOPTIM) \$(AD_F90FILES:.$FS90=_tl.o) \$(AD_FILES:.$FS=_tl.o) \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(LIBS)

ftlobj: ftl_taf_output.$FS \$(NON_AD_F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o)
	\$(MAKE) -f \$(MAKEFILE) ftlobjfiles

EOF
fi

if test $CAT_SRC_FOR_TAF = 1 ; then
cat >>$MAKEFILE <<EOF
# ... SVD ...
svdtaf: ad_taf_output.$FS ftl_taf_output.$FS
	@echo "--->>> Only ran TAF to generate SVD code!    <<<---"
	@echo "--->>> Do make svdall afterwards to compile. <<<---"
svdall: svd_touch svd_taf

svd_taf: \$(OBJFILES)
	\$(LINK) -o mitgcmuv_svd \$(FFLAGS) \$(FOPTIM) \$(OBJFILES) ad_taf_output.o ftl_taf_output.o \$(LIBS)

	@echo "--->>> Only COMPILE svd code! <<<---"
	@echo "--->>> Assumes you previously <<<---"
	@echo "--->>> did make svdtaf        <<<---"

svd_touch:
	@echo "--->>> Only COMPILE svd code! <<<---"
	@echo "--->>> Assumes you previously <<<---"
	@echo "--->>> did make svdtaf        <<<---"
	touch ad_taf_output.$FS ftl_taf_output.$FS
	\$(FC) \$(FFLAGS) \$(FOPTIM) -c ad_taf_output.$FS
	\$(FC) \$(FFLAGS) \$(FOPTIM) -c ftl_taf_output.$FS
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "SVD version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -DALLOW_TANGENTLINEAR_RUN > ad_config.template
	cmp ad_config.template AD_CONFIG.h || cat ad_config.template > AD_CONFIG.h
	@-rm -f ad_config.template

EOF
fi

fi

#===  for TAPENADE  ========================

if test "x$TAPENADE" != x ; then

# ============ begin TAPENADE specific section ==============

cat >>$MAKEFILE <<EOF
# ========== begin TAPENADE specific section ==============

EOF

echo "  Add the source list for AD code generation"
printf "AD_FILES = " >> $MAKEFILE
AD_FILES=`cat $TMP.adSrcFiles`
for i in $AD_FILES ; do
  toBeIgnored=`grep "^$i\>" ${TAP_DONT_TRANSFORM}`
  if test -z "$toBeIgnored" ; then
    echo   " \\" >> $MAKEFILE
    printf " $i" | sed "s/\.F/.$FS/" >> $MAKEFILE
  fi
done
echo >> $MAKEFILE
rm -f $TMP.adSrcFiles $TMP.adF90Files
if test $CAT_SRC_FOR_TAF = 0 ; then
 cat $TMP.nonADF77srclist >> $MAKEFILE
#cat $TMP.nonADF90srclist >> $MAKEFILE
fi
rm -f $TMP.nonADF77srclist $TMP.nonADF90srclist

cat >>$MAKEFILE <<EOF

TAPENADECMD = ${TAPENADECMD}

TAPENADE_SUPPORT_F90_SRC_FILES = \
${TAPTOOLS}/diffsizes.F90

f95_test_mods.f90: \$(TAPENADE_SUPPORT_F90_SRC_FILES)
	cat \$^ > \$@

AD_FILES_ADJ=\$(AD_FILES:.$FS=_b.f)
AD_FILES_TLM=\$(AD_FILES:.$FS=_d.f)

AD_CLEAN = \$(AD_FILES_ADJ) \$(AD_FILES_TLM) *.f~ *.msg *.msg~ f95_test_mods.f90

tap_adj: ad_exe_target
ad_exe_target:
	@echo Update AD_CONFIG.h and make \$(EXE_ADJ)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Adjoint version" -bAD_CONFIG_H -DALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > ad_config.template
	@cmp ad_config.template AD_CONFIG.h || cat ad_config.template > AD_CONFIG.h
	@-rm -f ad_config.template
	\$(MAKE) -f \$(MAKEFILE) \$(EXE_ADJ)

tap_tlm: tlm_exe_target
tlm_exe_target:
	@echo Update AD_CONFIG.h and make \$(EXE_TLM)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Tangent linear version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -DALLOW_TANGENTLINEAR_RUN > ad_config.template
	@cmp ad_config.template AD_CONFIG.h || cat ad_config.template > AD_CONFIG.h
	@-rm -f ad_config.template
	\$(MAKE) -f \$(MAKEFILE) \$(EXE_TLM)

EOF

if test $CAT_SRC_FOR_TAF = 1 ; then
#-- cat all AD/TL Subroutine files into a single file (-> compile 1 file):

cat >>$MAKEFILE <<EOF
adj_tap_all.$FS: \$(AD_FILES) f95_test_mods.f90
	\$(TAPENADECMD) -b -ext "${TAPTOOLS}/flow_tap" -head "the_main_loop(fc)/(xx_genarr3d_dummy, xx_genarr2d_dummy, xx_gentim2d_dummy)" \$(AD_FILES) f95_test_mods.f90
	cat \$(AD_FILES_ADJ) > adj_tap_all.$FS 2> /dev/null || true

tlm_tap_all.$FS: \$(AD_FILES) f95_test_mods.f90
	\$(TAPENADECMD) -d -ext "${TAPTOOLS}/flow_tap" -head "the_main_loop(fc)/(xx_genarr3d_dummy, xx_genarr2d_dummy, xx_gentim2d_dummy)" \$(AD_FILES) f95_test_mods.f90
	cat \$(AD_FILES_TLM) > tlm_tap_all.$FS 2> /dev/null || true

\$(EXE_ADJ): \$(SPECIAL_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(OBJFILES) \$(EMBEDDED_FILES) adj_tap_all.$FS
	\$(MAKE) -f \$(MAKEFILE) adj_tap_all.o
	@echo Creating \$@ ...
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(OBJFILES) adj_tap_all.o \$(LIBS)

\$(EXE_TLM): \$(SPECIAL_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(OBJFILES) \$(EMBEDDED_FILES) tlm_tap_all.$FS
	\$(MAKE) -f \$(MAKEFILE) tlm_tap_all.o
	@echo Creating \$@ ...
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(OBJFILES) tlm_tap_all.o \$(LIBS)

EOF
else
#-- append FWD S/R file to AD/TL Subroutine file (-> compile multiple files):

cat >>$MAKEFILE <<EOF
adj_tap_all.$FS: \$(AD_FILES) f95_test_mods.f90
	@-rm -f \$(AD_FILES_ADJ)
	\$(TAPENADECMD) -b -ext "${TAPTOOLS}/flow_tap" -head "the_main_loop(fc)/(xx_genarr3d_dummy, xx_genarr2d_dummy, xx_gentim2d_dummy)" \$(AD_FILES) f95_test_mods.f90
	ls -l the_main_loop_b.f
	@$BASH\$(TOOLSDIR)/TAP_support/append_fwd_src _b $FS \$(AD_FILES)
	touch adj_tap_all.$FS

tlm_tap_all.$FS: \$(AD_FILES) f95_test_mods.f90
	@-rm -f \$(AD_FILES_TLM)
	\$(TAPENADECMD) -d -ext "${TAPTOOLS}/flow_tap" -head "the_main_loop(fc)/(xx_genarr3d_dummy, xx_genarr2d_dummy, xx_gentim2d_dummy)" \$(AD_FILES) f95_test_mods.f90
	ls -l the_main_loop_d.f
	@$BASH\$(TOOLSDIR)/TAP_support/append_fwd_src _d $FS \$(AD_FILES)
	touch tlm_tap_all.$FS

\$(EXE_ADJ): \$(SPECIAL_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES) \$(EMBEDDED_FILES) adj_tap_all.$FS
	\$(MAKE) -f \$(MAKEFILE) \$(AD_FILES_ADJ:.f=.o)
	@echo Creating \$@ ...
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(AD_FILES_ADJ:.f=.o) \$(LIBS)

\$(EXE_TLM): \$(SPECIAL_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(EMBEDDED_FILES) \$(EMBEDDED_FILES) tlm_tap_all.$FS
	\$(MAKE) -f \$(MAKEFILE) \$(AD_FILES_TLM:.f=.o)
	@echo Creating \$@ ...
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(F90_SRC_FILES:.F90=.o) \$(NON_AD_F77_SRC_FILES:.F=.o) \$(C_SRC_FILES:.c=.o) \$(AD_FILES_TLM:.f=.o) \$(LIBS)

EOF
fi

cat >>$MAKEFILE <<EOF
# ============ end TAPENADE specific section ==============

EOF

fi

#===  for OpenAD  ========================

if test "x$OPENAD" != x ; then

# ============ begin OpenAD specific section ==============

cat >>$MAKEFILE <<EOF
# ... OpenAD ...

# all the source files linked from the various locations:
ALL_LINKED_FILES= \
\$(F77_SRC_FILES) \
\$(C_SRC_FILES) \
\$(H_SRC_FILES) \
\$(F90_SRC_FILES) \
\$(SPECIAL_FILES)

EOF

if test "x$SINGULARITYFILE" != x ; then
# run OpenAD commands in singularity container with standard paths
cat >>$MAKEFILE <<EOF
SINGULARITYCMD = singularity exec ${SINGULARITYFILE}
export SINGULARITYENV_LD_LIBRARY_PATH=/OpenAD//Open64/osprey1.0/targ_ia64_ia64_linux/whirl2f/
export OPENADROOT=/OpenAD
export XAIFBOOSTERROOT=/OpenAD/xaifBooster/..
export XAIFSCHEMAROOT=/OpenAD/xaif
export OPENADFORTTK_BASE=/OpenAD/OpenADFortTk
export OPEN64ROOT=/OpenAD/Open64/osprey1.0/targ_ia64_ia64_linux
export OPENADFORTTK=/OpenAD/OpenADFortTk/OpenADFortTk-x86_64-Linux

EOF
else
# run OpenAD directly
cat >>$MAKEFILE <<EOF
SINGULARITYCMD =

EOF
fi

cat >>$MAKEFILE <<EOF
ifndef OPENADROOT
  \$(error "Error:  environment variable OPENADROOT not defined!")
endif

ifndef XAIFSCHEMAROOT
  \$(error "Error:  environment variable XAIFSCHEMAROOT not defined!")
endif

ifndef XAIFBOOSTERROOT
  \$(error "Error:  environment variable XAIFBOOSTERROOT not defined!")
endif

EOF

echo "  Add the source list for common block to module conversion "
echo >> $MAKEFILE
printf "CB2M_F90_SRC_NAMES = " >> $MAKEFILE
for i in `cat ${OAD_CB2M_FILES}` ; do
  echo    " \\" >> $MAKEFILE
  printf " $i" >> $MAKEFILE
done
echo >> $MAKEFILE

echo "  Add the source list for AD code generation"
echo >> $MAKEFILE
printf "AD_FILES = " >> $MAKEFILE
for i in `cat ${OAD_CB2M_FILES}` ; do
  echo    " \\" >> $MAKEFILE
  printf " ${i}_mod.f$FS90" >> $MAKEFILE
done
AD_FILES=`cat $TMP.adSrcFiles | sed "s/\.F/.f/g"`
for i in $AD_FILES ; do
  basename=${i%%.f}
  toBeIgnored=`grep ^$basename'\>' ${OAD_DONT_COMPILE} ${OAD_DONT_TRANSFORM}`
  if test -z "$toBeIgnored" ; then
    echo    " \\" >> $MAKEFILE
    printf " $i" >> $MAKEFILE
  fi
done
echo >> $MAKEFILE
rm -f $TMP.adSrcFiles $TMP.adF90Files
cat $TMP.nonADF77srclist >> $MAKEFILE
rm -f $TMP.nonADF77srclist $TMP.nonADF90srclist

cat >>$MAKEFILE <<EOF

adAll: ad_exe_target
.PHONY: adAll

ad_exe_target:
	@echo Update AD_CONFIG.h and make \$(EXE_ADJ)
	@$BASH\$(TOOLSDIR)/convert_cpp_cmd2defines "Adjoint version" -bAD_CONFIG_H -DALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > ad_config.template
	@cmp ad_config.template AD_CONFIG.h || cat ad_config.template > AD_CONFIG.h
	@-rm -f ad_config.template
	\$(MAKE) -f \$(MAKEFILE) \$(EXE_ADJ)

CB2M_F90_PP_SRC_FILES=\$(addsuffix _mod.f$FS90, \$(CB2M_F90_SRC_NAMES))

.PRECIOUS: \$(CB2M_F90_PP_SRC_FILES) \$(NON_AD_F77_SRC_FILES:.F=_cb2m.f$FS90)

.PHONY: adDepend
adDepend: \$(ALL_LINKED_FILES) \$(addsuffix _mod.h, \$(CB2M_F90_SRC_NAMES)) \$(addsuffix _mod.FF90, \$(CB2M_F90_SRC_NAMES)) \$(F77_SRC_FILES:.F=_cb2m.FF90)
	\$(MAKEDEPEND) -f \$(MAKEFILE) -o .$FS \$(DEFINES) \$(INCLUDES) \$(F77_SRC_FILES)
	\$(TOOLSDIR)/f90mkdepend -fs $FS -fs90 $FS90 >> \$(MAKEFILE)
	-rm -f makedepend.out

OPENAD_SUPPORT_F90_SRC_FILES = \
w2f__types.F90 \
OAD_active.F90 \
OAD_cp.F90 \
OAD_rev.F90 \
OAD_tape.F90 \
OAD_regular_cp.F90 \
revolve.F90

OPENAD_SUPPORT_C_SRC_FILES = \
iaddr.c \
timeRatio.c

f95_test_mods.f90: \$(OPENAD_SUPPORT_F90_SRC_FILES:F90=$FS90)
	cat \$^ > \$@

f95_test.f90: all_mods.xb.x2w.w2f.pp.f$FS90 \$(NON_AD_F77_SRC_FILES:.F=_cb2m.f$FS90) ad_input_code.w2f.pre.xb.x2w.w2f.td.pp.f$FS90
	cat \$^ > \$@

f95_test.out: f95_test_mods.f90 f95_test.f90
	f95 -fixed -w=unused -maxcontin=132 -c f95_test_mods.f90 > \$@ 2>&1
	f95 -fixed -w=unused -maxcontin=132 -c -fixed f95_test.f90 >> \$@ 2>&1

CB2M_AD_FILES=\$(AD_FILES:.f=_cb2m.f$FS90)

AD_OBJ_FILES_S1=\$(OPENAD_SUPPORT_F90_SRC_FILES:.F90=.o) \$(OPENAD_SUPPORT_C_SRC_FILES:.c=.o)  OAD_intrinsics_oad.o \$(CB2M_AD_FILES:.f$FS90=_oad.o)

AD_OBJ_FILES_S2=\$(AD_OBJ_FILES_S1) \$(NON_AD_F77_SRC_FILES:.F=_cb2m.o) \$(C_SRC_FILES:.c=.o) \$(F90_SRC_FILES:.F90=.o)

\$(EXE_ADJ): \$(ALL_LINKED_FILES) \$(addsuffix _mod.h, \$(CB2M_F90_SRC_NAMES)) postProcess.tag \$(AD_OBJ_FILES_S2)
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(AD_OBJ_FILES_S2) \$(LIBS)

# create sources files modules from header files containing common blocks
%_mod.FF90 : %.h \$(OADTOOLS)/cb2mGetModules.csh \$(OADTOOLS)/cb2mGetModules.awk
	\$(OADTOOLS)/cb2mGetModules.csh $< \$(OADTOOLS)/cb2mGetModules.awk

# create new header files with USE statements for the new modules made above
%_mod.h : %.h \$(OADTOOLS)/cb2mGetHeaders.csh \$(OADTOOLS)/cb2mGetHeaders.awk
	\$(OADTOOLS)/cb2mGetHeaders.csh $< \$(OADTOOLS)/cb2mGetHeaders.awk \$(CB2M_F90_SRC_NAMES)

# change the include directives of everybody to refer to  the new header files with the USE statements
%_cb2m.FF90 : %.F \$(OADTOOLS)/cb2mUseModules.bash
	\$(OADTOOLS)/cb2mUseModules.bash $< ${MPI}

# makefile debug rule
small_f: \$(CB2M_F90_PP_SRC_FILES)
.PHONY: small_f

ad_input_code.f$FS90:  \$(CB2M_AD_FILES)
	cat \$^ > \$@

# canonicalizer
ad_input_code_sf.pre.f90 : \$(CB2M_AD_FILES)
	\${SINGULARITYCMD} \${OPENADFORTTK_BASE}/tools/SourceProcessing/preProcess.py --timing --r8 -H -S  -o \$@ \$^

# replace stop statements (to avoid the implied unstructured control flow)  with print statements
ad_input_code_sf.pre.s2p.f90 : ad_input_code_sf.pre.f90
	cat \$< | sed -f \$(OADTOOLS)/stop2print.sed > ad_input_code_sf.pre.s2p.f90

# F -> WHIRL
ad_input_code_sf.pre.s2p.B: ad_input_code_sf.pre.s2p.f90
	\${SINGULARITYCMD} \${OPEN64ROOT}/crayf90/sgi/mfef90 -r8 -z -F ad_input_code_sf.pre.s2p.f90

# WHIRL -> XAIF
ad_input_code_sf.pre.s2p.xaif : ad_input_code_sf.pre.s2p.B
	\${SINGULARITYCMD} \${OPENADFORTTK}/bin/whirl2xaif -s -n --debug 1 -o \$@ \$<

# XAIF -> XAIF'
ad_input_code_sf.pre.s2p.xb.xaif : ad_input_code_sf.pre.s2p.xaif xaif.xsd xaif_base.xsd xaif_inlinable_intrinsics.xsd xaif_derivative_propagator.xsd xaif_output.xsd
	\${SINGULARITYCMD} \${XAIFBOOSTERROOT}/xaifBooster/algorithms/BasicBlockPreaccumulationReverse/driver/oadDriver -f -t forward_step -i \$< -c \${XAIFSCHEMAROOT}/schema/examples/inlinable_intrinsics.xaif -o \$@ -I -r

# XAIF' -> WHIRL'
ad_input_code_sf.pre.s2p.xb.x2w.B : ad_input_code_sf.pre.s2p.xb.xaif
	\${SINGULARITYCMD} \${OPENADFORTTK}/bin/xaif2whirl --debug 1 ad_input_code_sf.pre.s2p.B \$<

# WHIRL' -> F'
ad_input_code_sf.pre.s2p.xb.x2w.w2f.f$FS90: ad_input_code_sf.pre.s2p.xb.x2w.B
	\${SINGULARITYCMD} \${OPEN64ROOT}/whirl2f/whirl2f -FLIST:ftn_file=\$@ -openad \$<

# insert template directives
ad_input_code_sf.pre.s2p.xb.x2w.w2f.td.f$FS90: ad_input_code_sf.pre.s2p.xb.x2w.w2f.f$FS90 \$(OADTOOLS)/insertTemplateDir.bash
	\$(OADTOOLS)/insertTemplateDir.bash \$< \$@

PPEXTRAS=\$(notdir \$(wildcard \$(OADTOOLS)/ad_template.*.F)) ad_inline.F
# postprocess F'
postProcess.tag: ad_input_code_sf.pre.s2p.xb.x2w.w2f.td.f$FS90 \$(PPEXTRAS:.F=.f) | w2f__types.f90
	\${SINGULARITYCMD} \${OPENADFORTTK_BASE}/tools/SourceProcessing/postProcess.py --progress --timing --infoUnitFile w2f__types.f90 --outputFormat=fixed --separateOutput --pathSuffix "" --filenameSuffix "_oad" -m r -i ad_inline.f \$<
	# the target is a placeholder to trigger a single execution of the rule
	touch \$@
# put this so make knows about the postprocessing output
OAD_intrinsics_oad.f \$(CB2M_AD_FILES:.f$FS90=_oad.f): postProcess.tag

# link the XAIF schema files
%.xsd:
	\$(LN) \${XAIFSCHEMAROOT}/schema/\$@ .

# link the support files:
\$(OPENAD_SUPPORT_F90_SRC_FILES) \$(OPENAD_SUPPORT_C_SRC_FILES) \$(PPEXTRAS):
	\$(LN) \$(OADTOOLS)/\$@ .

AD_CLEAN += *_mod.h *_mod.F90 *.FF90 *.mod-whirl temp.sed oad_cp.* postProcess.tag

# ============ end OpenAD specific section ==============

EOF

fi

#=========================================

if test "x$EXEHOOK" != x ; then
    printf "\nexehook:\n\t%s\n" $EXEHOOK >> $MAKEFILE
fi

echo "  Making list of \"exceptions\" that need \".p\" files"
for i in $KPPFILES ; do
    base=`echo $i | sed -e 's/\/.*\///g' | sed -e 's/\..*$//g'`
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	echo "Error: unable to add file \"$i\" to the exceptions list"
    fi
    echo "$base.$FS: $base.p" >> $MAKEFILE
done

echo "  Making list of NOOPTFILES"
for i in $NOOPTFILES ; do
    base=`echo $i | sed -e 's/\/.*\///g' | sed -e 's/\..*$//g'`
    RETVAL=$?
    if test "x$RETVAL" != x0 ; then
	echo "Error: unable to add file \"$i\" to the exceptions list"
    fi
    echo "$base.o: $base.$FS" >> $MAKEFILE
    printf "\t\$(FC) \$(FFLAGS) \$(NOOPTFLAGS) -c \$<\n" >> $MAKEFILE
done

echo "  Add rules for links"
cat $TMP.srclinks >> $MAKEFILE
rm -f $TMP.srclinks

echo "  Adding makedepend marker"
printf "\n\n# DO NOT DELETE\n" >> $MAKEFILE

printf "\n===  Done  ===\n"

# Create special header files
$BASH $TOOLSDIR/convert_cpp_cmd2defines -bPACKAGES_CONFIG_H "Disabled packages:" $DISABLED_PACKAGES " " "Enabled packages:" $ENABLED_PACKAGES > $PACKAGES_DOT_H".tmp"
if test ! -f $PACKAGES_DOT_H ; then
    mv -f $PACKAGES_DOT_H".tmp" $PACKAGES_DOT_H
else
    cmp $PACKAGES_DOT_H".tmp" $PACKAGES_DOT_H > /dev/null 2>&1
    RETVAL=$?
    if test "x$RETVAL" = x0 ; then
	rm -f $PACKAGES_DOT_H".tmp"
    else
	mv -f $PACKAGES_DOT_H $PACKAGES_DOT_H".bak"
	mv -f $PACKAGES_DOT_H".tmp" $PACKAGES_DOT_H
    fi
fi
if test ! -f AD_CONFIG.h ; then
    $BASH $TOOLSDIR/convert_cpp_cmd2defines "Default version" -bAD_CONFIG_H -UALLOW_ADJOINT_RUN -UALLOW_TANGENTLINEAR_RUN > AD_CONFIG.h
fi

#  Write the "state" for future records
if test "x$DUMPSTATE" = xt ; then
    printf "" > genmake_state
    for i in $gm_state ; do
	t1="t2=\$$i"
	eval $t1
	echo "$i='$t2'" | sed -e 's/  */ /g' >> genmake_state
    done
fi

#  Conclude
if test $FC_CHECK = 5 ; then
    echo "  original 'Makefile' generated successfully"
    echo "=> next steps:"
    ad=`echo $PACKAGES | grep -c autodiff`
    if test "x$OPENAD" != x ; then
	echo "  > make adAll    (<-- adjoint executable)"
    elif test $ad != 0 ; then
	echo "  > make depend"
      if test "x$TAPENADE" = x ; then
	echo "    > make adall  (<-- adjoint  executable with TAF)"
	echo " or > make ftlall (<-- tang-lin executable with TAF)"
      else
	echo "    > make tap_adj  (<-- adjoint executable with Tapenade)"
	echo " or > make tap_tlm (<-- tang-lin executable with Tapenade)"
      fi
	echo " or > make        (<-- forward executable)"
    else
#	echo "  > make depend   (add dependencies to Makefile)"
	echo "  > make depend"
	echo "  > make       (<-- to generate executable)"
    fi
elif [ $FC_CHECK -ge 3 ] ; then
    echo "  original 'Makefile' generated but was unable to"
    echo "   run compiled test-program (please see '$LOGFILE')"
elif [ $FC_CHECK -ge 0 ] ; then
    echo "Warning: FORTRAN compiler test failed (please see '$LOGFILE')"
    echo "Warning: 'Makefile' might be unusable (check your optfile)"
fi
