#! /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 package MNC: if NetCDF is available, then build the MNC
#  template files ; otherwise, delete mnc from the list of packages.
echo " $PACKAGES " | grep ' mnc ' > /dev/null 2>&1
mnc_in=$?
if test "x$HAVE_NETCDF" != xt ; then
    if test "x$mnc_in" = x0 ; then
	cat <<EOF
*********************************************************************
WARNING: the "mnc" 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 "mnc" package is now DISABLED.
*********************************************************************
EOF
	PACKAGES=`echo $PACKAGES | sed -e 's/mnc//g'`
	DISABLE="$DISABLE mnc"
    else
    #  this prevent to add mnc (due to pdepend rules) if not available
	DISABLE="$DISABLE mnc"
    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

#  Check for package PROFILES: if NetCDF is not available,
#  then delete profiles from the list of available packages.
if test "x$HAVE_NETCDF" != xt ; then
    echo " $PACKAGES " | grep ' profiles ' > /dev/null 2>&1
    RETVAL=$?
    if test "x$RETVAL" = x0 ; then
	cat <<EOF
*********************************************************************
WARNING: the "profiles" 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 "profiles" package is now DISABLED.
*********************************************************************
EOF
	PACKAGES=`echo $PACKAGES | sed -e 's/profiles//g'`
	DISABLE="$DISABLE profiles"
    else
    #  this prevent to add profiles (due to pdepend rules) if not available
	DISABLE="$DISABLE profiles"
    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

if test "x$TAPENADE" != x ; then
cat >>$MAKEFILE <<EOF
TAPENADE_SUPPORT_C_SRC_FILES = \
${TAPTOOLS}/ADFirstAidKit/adStack.c \
${TAPTOOLS}/ADFirstAidKit/adBinomial.c
EOF
echo 'TAP_SUPPORT_OBJFILES = $(TAPENADE_SUPPORT_C_SRC_FILES:.c=.o)' >> $MAKEFILE
fi

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"
echo >> $MAKEFILE
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
    printf " $i" | sed "s/\.F/.f/" >> $MAKEFILE
  fi
done
echo >> $MAKEFILE
rm -f $TMP.adSrcFiles $TMP.adF90Files
#cat $TMP.nonADF77srclist >> $MAKEFILE
#cat $TMP.nonADF90srclist >> $MAKEFILE
rm -f $TMP.nonADF77srclist $TMP.nonADF90srclist

cat >>$MAKEFILE <<EOF

TAPENADECMD = ${TAPENADECMD}

TAPENADE_SUPPORT_F90_SRC_FILES = \
${TAPTOOLS}/diffsizes.F90
AD_CLEAN = *_b.f *_d.f *.f~ *.msg *.msg~ f95_test_mods.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)
#
.PHONY: TAP_TLM_FILES
TAP_TLM_FILES: \$(AD_FILES) f95_test_mods.f90
	touch \$(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
#
.PHONY: TAP_ADJ_FILES
TAP_ADJ_FILES: \$(AD_FILES) f95_test_mods.f90
	touch \$(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

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)

\$(EXE_ADJ): \$(SPECIAL_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES) \$(OBJFILES) \$(TAP_SUPPORT_OBJFILES) \$(EMBEDDED_FILES) TAP_ADJ_FILES
	@echo Creating \$@ ...
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(OBJFILES) \$(AD_FILES_ADJ) \$(TAP_SUPPORT_OBJFILES:${TAPTOOLS}/ADFirstAidKit/%=%) \$(LIBS)

\$(EXE_TLM): \$(SPECIAL_FILES) \$(F77_SRC_FILES) \$(C_SRC_FILES) \$(H_SRC_FILES) \$(F90_SRC_FILES) \$(OBJFILES) \$(TAP_SUPPORT_OBJFILES) \$(EMBEDDED_FILES) TAP_TLM_FILES
	@echo Creating \$@ ...
	\$(LINK) -o \$@ \$(FFLAGS) \$(FOPTIM) \$(OBJFILES) \$(AD_FILES_TLM) \$(TAP_SUPPORT_OBJFILES:${TAPTOOLS}/ADFirstAidKit/%=%) \$(LIBS)

# ============ 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
