#!/bin/bash
function usage()
{
   cat <<EOF

 Build NWChem
 ============

 This script compiles an executable of NWChem aiming to make this as automatic
 as possible. While the script tries to guess as many configuration options 
 possible one can always override this by setting appropriate environment 
 variables (see section ENVIRONMENT VARIABLES). On most platforms it should
 be enough to load modules for the compilers, and MPI libraries.

 The script should be run in the top level NWChem directory (e.g. nwchem-6.1,
 put differently the top level directory contains the directories src and
 contrib) and takes at most one argument. This way you can use it to build
 NWChem by simply invoking 

    ./contrib/distro-tools/build_nwchem

 and similarly clean everything up by invoking

    ./contrib/distro-tools/build_nwchem realclean

 running

    ./contrib/distro-tools/build_nwchem help

 produces this text.


 ENVIRONMENT VARIABLES
 ---------------------

 The script will not override any user set environment variables. This allows
 you to specify setting by hand that the script guesses wrong. Below is a list
 of the environment variables the script tries to guess and what they 
 control:

 NWCHEM_TOP        -- The top level NWChem directory.
                      Example: /home/mydir/nwchem-6.1.

 NWCHEM_TARGET     -- The platform for which NWChem should be compiled. It
                      should end in "64" if the machine provides a 64-bit
                      platform. 
                      Examples: BGP, LINUX, LINUX64, MACX, MACX64, IBM, IBM64.

 NWCHEM_MODULES    -- A list of code modules your NWChem build should include. 
                      Examples: "all", "qm", "qmandpw md", "all python".

 NWCHEM_EXECUTABLE -- The full name of the NWChem executable.
                      Example: /home/mydir/nwchem-6.1/bin/LINUX64/nwchem.

 NWCHEM_NOVERSION  -- By default a routine listing the version numbers of all
                      source code files will be included in the file
                      util_version.F. Occasionally compilers run into trouble
                      if they try and optimize this routine. For those cases
                      this environment variable may be set (any value will do)
                      and the version routine will be replaced by a stub.
                      Examples: y, yes.

 ARMCI_NETWORK     -- The communication infra-structure the ARMCI library in
                      the GA should use. 
                      Examples: DCMFMPI, GEMINI, PORTALS, OPENIB, MPI-MT.

 MPI_F90           -- The Fortran compiler matching your MPI library.
                      Examples: gfortran, ftn, ifort, xlf, pgf90.

 MPI_CC            -- The C compiler matching your MPI library.
                      Examples: gcc, cc, icc, xlc, pgcc.

 MPI_CXX           -- The C++ compiler matching your MPI library.
                      Examples: g++, CC, iCC, pgCC.

 MPI_INCLUDE       -- The path at which the MPI include files live.
                      Example: -I/usr/mpi/include.

 MPI_LIB           -- The path at which the MPI libraries live.
                      Example: -L/usr/mpi/lib.

 LIBMPI            -- The MPI libraries to link against.
                      Example: "-lmpichf90 -lmpichf90 -lmpich -lopa".

 BLASOPT           -- Specifies the BLAS, LAPACK and maybe even ScaLAPACK
                      libraries in a generic way. This setting overrides
                      BLAS_LIB, LAPACK_LIB, and SCALAPACK_LIB as various 
                      makefiles will use this regardless of anything.

 BLAS_LIB          -- The BLAS linear algebra library to use.
                      Examples: -lblas, -latlas, -lacml, -lmkl.

 BLAS_SIZE         -- The size of the integers in bytes that the BLAS interface
                      uses.
                      Examples: 4, 8.

 LAPACK_LIB        -- The LAPACK linear algebra library to use.
                      Examples: -llapack, -lacml, -lmkl.

 LAPACK_SIZE       -- The size of the integers in bytes that the LAPACK
                      interface uses.
                      Examples: 4, 8.

 SCALAPACK_LIB     -- The ScaLAPACK linear algebra library to use.
                      Examples: -lscalapack, -lacml, -lmkl.

 SCALAPACK_SIZE    -- The size of the integers in bytes that the ScaLAPACK
                      interface uses.
                      Examples: 4, 8.

 Notes:

 The environment variables BLAS_SIZE, LAPACK_SIZE and SCALAPACK_SIZE all have 
 to have the same value, either 4 or 8, to successfully build NWChem.

 Huub van Dam
 \$Id: build_nwchem 21881 2012-01-27 00:03:59Z d3y133 $
EOF
}
declare -a LIST_COMPFLAGS
declare -a LIST_LINLIBS
LIST_COMPFLAGS=( ' ' '-q64' )
LIST_LINLIBS=( '-lmkl' '-lacml' '-lcxml' '-lscs' '-lcomplib.sgimath' '-lsunmath' '-latlas' '-lgoto' '-lessl' '-lscalapack' '-llapack' '-lcblas' '-lblas' '-lf77blas' '-framework Accelerate' )
export LIST_COMPFLAGS
export LIST_LINLIBS
function get_mpi_include ()
{
   # This shell function extracts the MPI include file directories
   # and returns them as a list for a compile line.
   # E.g.: /usr/include -I/usr/local/include
   #
   # Most support -show
   #
   inlist="`mpif90 -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`mpif90 -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -compile-info
     #
     inlist="`mpif90 -show`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get compile info from mpif90" > /dev/stderr
     exit 1
   fi
   outlist=""
   for word in ${inlist} ; do
      len=`expr "${word}" : '-I*'`
      if [ ${len} -ge 2 ] ; then
        outlist="${outlist} ${word}"
      fi
   done
#  len=`expr "${outlist}" : ' -I*'`
#  if [ ${len} -ge 3 ] ; then
#    outlist="${outlist:3}"
#  fi
   echo ${outlist}
}
function get_mpi_link ()
{
   # This shell function extracts the MPI library file directories
   # and returns them as a list for a link line.
   # E.g.: /usr/lib -L/usr/local/lib
   #
   # MPICH2 and MVAPICH2 support -link-info
   #
   inlist="`mpif90 -link-info`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`mpif90 -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # HPMPI supports -show
     #
     inlist="`mpif90 -show`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get link info from mpif90" > /dev/stderr
     exit 1
   fi
   outlist=""
   for word in ${inlist} ; do
      len=`expr "${word}" : '-L*'`
      if [ ${len} -ge 2 ] ; then
        outlist="${outlist} ${word}"
      fi
   done
#  len=`expr "${outlist}" : ' -L*'`
#  if [ ${len} -ge 3 ] ; then
#    outlist="${outlist:3}"
#  fi
   echo ${outlist}
}
function get_mpi_lib ()
{
   # This shell function extracts the MPI libraries
   # and returns them as a list for a link line.
   # E.g.: -lmpich
   #
   # Most support -show
   #
   inlist="`mpif90 -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`mpif90 -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -link-info
     #
     inlist="`mpif90 -link-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get library info from mpif90" > /dev/stderr
     exit 1
   fi
   outlist=""
   for word in ${inlist} ; do
      len=`expr "${word}" : '-l*'`
      if [ ${len} -ge 2 ] ; then
        outlist="${outlist} ${word}"
      fi
   done
   echo ${outlist}
}
function get_mpi_fortran ()
{
   # This shell function extracts the fortran compiler
   # and returns its name as a list for a compile line.
   # E.g.: gfortran
   #
   # Most support -show
   #
   inlist="`mpif90 -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`mpif90 -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -compile-info
     #
     inlist="`mpif90 -compile-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get compile info from mpif90" > /dev/stderr
     exit 1
   fi
   outlist=""
   length=${#LIST_COMPFLAGS[*]}
   for word in ${inlist} ; do
      echo "c23456 test program">/tmp/$$.f
      echo "       program test">>/tmp/$$.f
      echo "       write(6,'(\"hello world\")')">>/tmp/$$.f
      echo "       end">>/tmp/$$.f
      word=`basename ${word}`
      indx=0
      while [ "${indx}" -lt "${length}" ] ; do
         flags=${LIST_COMPFLAGS[$indx]}
         ((indx++))
         ${word} ${flags} -o /tmp/$$.x /tmp/$$.f
         result=$?
         if [ ${result} -eq 0 ] ; then
           /tmp/$$.x > /dev/null
           result=$?
           if [ ${result} -eq 0 ] ; then
             echo ${word}
             rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.f
             return 0
           fi
         fi
      done
   done
   rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.f
   echo "ERROR: could not find a valid Fortran compiler" > /dev/stderr
   exit 1
}
function get_mpi_cc ()
{
   # This shell function extracts the C compiler
   # and returns its name as a list for a compile line.
   # E.g.: gcc
   #
   # Most support -show
   #
   inlist="`mpicc -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`mpicc -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -compile-info
     #
     inlist="`mpicc -compile-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get compile info from mpicc" > /dev/stderr
     exit 1
   fi
   outlist=""
   length=${#LIST_COMPFLAGS[*]}
   for word in ${inlist} ; do
      echo "#include <stdio.h>">/tmp/$$.c
      echo "int main(void){">>/tmp/$$.c
      echo "    printf(\"hello world\n\");">>/tmp/$$.c
      echo "    return 0;">>/tmp/$$.c
      echo "}">>/tmp/$$.c
      word=`basename ${word}`
      indx=0
      while [ "${indx}" -lt "${length}" ] ; do
         flags=${LIST_COMPFLAGS[$indx]}
         ((indx++))
         ${word} ${flags} -o /tmp/$$.x /tmp/$$.c
         result=$?
         if [ ${result} -eq 0 ] ; then
           /tmp/$$.x > /dev/null
           result=$?
           if [ ${result} -eq 0 ] ; then
             echo ${word}
             rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.c
             return 0
           fi
         fi
      done
   done
   rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.c
   echo "ERROR: could not find a valid C compiler" > /dev/stderr
   exit 1
}
function get_mpi_cxx ()
{
   # This shell function extracts the C++ compiler
   # and returns its name as a list for a compile line.
   # Because there are some case insensitive file systems we
   # have to try mpic++ and mpicxx first because if they are
   # not found mpiCC will find the C-compiler wrapper script
   # on those systems.
   # E.g.: g++
   #
   # Most support -show
   #
   inlist="`mpicxx -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     inlist="`mpic++ -show`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`mpicxx -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     inlist="`mpic++ -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -compile-info
     #
     inlist="`mpicxx -compile-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     inlist="`mpic++ -compile-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # Most support -show
     #
     inlist="`mpiCC -show`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`mpiCC -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -compile-info
     #
     inlist="`mpiCC -compile-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get compile info from mpiCC" > /dev/stderr
     exit 1
   fi
   outlist=""
   length=${#LIST_COMPFLAGS[*]}
   for word in ${inlist} ; do
      echo "#include <iostream>">/tmp/$$.cpp
      echo "int main(void) {">>/tmp/$$.cpp
      echo "    std::cout << \"hello world\n\";">>/tmp/$$.cpp
      echo "    return 0;">>/tmp/$$.cpp
      echo "}">>/tmp/$$.cpp
      word=`basename ${word}`
      indx=0
      while [ "${indx}" -lt "${length}" ] ; do
         flags=${LIST_COMPFLAGS[$indx]}
         ((indx++))
         ${word} ${flags} -o /tmp/$$.x /tmp/$$.cpp
         result=$?
         if [ ${result} -eq 0 ] ; then
           /tmp/$$.x > /dev/null
           result=$?
           if [ ${result} -eq 0 ] ; then
             echo ${word}
             rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.cpp
             return 0
           fi
         fi
      done
   done
   rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.cpp
   echo "ERROR: could not find a valid C++ compiler" > /dev/stderr
   exit 1
}
function get_config_value()
{
   # This function extracts the value of a setting in config.status.
   # The approach is to simply grep the key on the config.status file.
   # We expect to get 1 line in response, and we return whatever appears
   # after the equals sign.
   key=$1
   line=`grep $key ${NWCHEM_TOP}/src/tools/build/config.status`
   line=${line/*=/}
   line=${line/#\"/}
   line=${line/%\"/}
   echo ${line}
}
function config_is_set()
{
   # This function retrieves the value of a seting in config.status according
   # to the key specified. It then checks the length of the result. If
   # the result was "" (length <= 0) then it was not set, otherwise it is.
   key=$1
   result=`get_config_value $key`
   if [ ${#result} -gt 0 ] ; then
     value=0
   else
     value=1
   fi
   echo ${value}
}
function get_blas_lib()
{
   # This function tries to find a BLAS library. Any library found must allow
   # a Fortran program that calls BLAS routines to compile, link and run.
   # The first library that matches these criteria is returned.
   fcomp=$1
   blasopt="$2"
   if [ ${#fcomp} -eq 0 ] ; then
       echo
       return
   fi
   lib=""
   length=${#LIST_LINLIBS[*]}
   indx=0
   while [ "${indx}" -lt "${length}" ] ; do
     candidate="${LIST_LINLIBS[${indx}]}"
     ((indx++))
     # echo "blas: trying ${candidate}" > /dev/stderr
     if [ "${blasopt}" != "0" ] ; then
       candidate="${blasopt}"
     fi
     if [ ${#lib} -eq 0 ] ; then
       echo "      program testblas" > testblas$$.f
       echo "      implicit none" >> testblas$$.f
       echo "      double precision a, b, c" >> testblas$$.f
       echo "      integer*8 n, m, k" >> testblas$$.f
       echo "      integer*8 lda" >> testblas$$.f
       echo "      a = 1.0d0" >> testblas$$.f
       echo "      b = 2.0d0" >> testblas$$.f
       echo "      c = 0.0d0" >> testblas$$.f
       echo "      lda = 1" >> testblas$$.f
       echo "      n = 1" >> testblas$$.f
       echo "      m = 1" >> testblas$$.f
       echo "      k = 1" >> testblas$$.f
       echo "      call dgemm('n','n',m,n,k,1.0d0,a,lda,b,lda,0.0d0,c,lda)" >> testblas$$.f
       echo "      end" >> testblas$$.f
       $fcomp -o testblas$$.x testblas$$.f ${candidate} > /dev/null
       result=$?
       if [ ${result} -eq 0 ] ; then
         ./testblas$$.x > /dev/null
         result=$?
         if [ ${result} -eq 0 ] ; then
           # This library worked so we will go with this
           lib="${candidate}"
           # echo "blas: found ${lib}" > /dev/stderr
         fi
         rm -f ./testblas$$.x
       fi
       rm -f ./testblas$$.f
     fi
   done
   echo ${lib}
}
function get_blas_integer()
{
   #
   # Establish whether the BLAS library found uses integer*4 or integer*8.
   #
   fcomp=$1
   blaslib=$2
   echo "      program testblasint" > ./testblas$$.f
   echo "      implicit none" >> ./testblas$$.f
   echo "      integer*8 typecast" >> ./testblas$$.f
   echo "      integer*4 data(2)" >> ./testblas$$.f
   echo "      double precision a, b, c" >> ./testblas$$.f
   echo "      integer*8 n, m, k, ld" >> ./testblas$$.f
   echo "      integer*8 two" >> ./testblas$$.f
   echo "      external  typecast" >> ./testblas$$.f
   echo "      logical   obigendian" >> ./testblas$$.f
   echo "      a = 0.5d0" >> ./testblas$$.f
   echo "      b = 2.0d0" >> ./testblas$$.f
   echo "      c = 0.0d0" >> ./testblas$$.f
   echo "      data(1) = 0" >> ./testblas$$.f
   echo "      data(2) = 1" >> ./testblas$$.f
   echo "      obigendian = (1.eq.typecast(data))" >> ./testblas$$.f
   echo "      two = 2" >> ./testblas$$.f
   echo "      if (obigendian) then" >> ./testblas$$.f
   echo "        n  = two**32+two**0" >> ./testblas$$.f
   echo "        m  = two**32+two**1" >> ./testblas$$.f
   echo "        k  = two**32+two**2" >> ./testblas$$.f
   echo "        ld = two**32" >> ./testblas$$.f
   echo "      else" >> ./testblas$$.f
   echo "        n  = two**32+two**0" >> ./testblas$$.f
   echo "        m  = two**33+two**0" >> ./testblas$$.f
   echo "        k  = two**34+two**0" >> ./testblas$$.f
   echo "        ld = two**0" >> ./testblas$$.f
   echo "      endif" >> ./testblas$$.f
   echo "      call dgemm('n','n',m,n,k,1.0d0,a,ld,b,ld,0.0d0,c,ld)" >> ./testblas$$.f
   echo "      if (abs(c-1.0d0).lt.1.0d-10) then" >> ./testblas$$.f
   echo "        write(*,'(a)')'4'" >> ./testblas$$.f
   echo "      else" >> ./testblas$$.f
   echo "        write(*,'(a)')'8'" >> ./testblas$$.f
   echo "      endif" >> ./testblas$$.f
   echo "      end" >> ./testblas$$.f
   echo "      integer*8 function typecast(input)" >> ./testblas$$.f
   echo "      implicit none" >> ./testblas$$.f
   echo "      integer*8 input" >> ./testblas$$.f
   echo "      typecast = input" >> ./testblas$$.f
   echo "      return" >> ./testblas$$.f
   echo "      end" >> ./testblas$$.f
   ${fcomp} -o ./testblas$$.x ./testblas$$.f ${blaslib}
   result=`./testblas$$.x`
   status=$?
   if [ ${status} -ne 0 ] ; then
     result=8
   elif [ "${result}" != "4" ] ; then
     result=8
   fi
   rm -f ./testblas$$.f
   rm -f ./testblas$$.x
   echo ${result}
}
function get_lapack_lib()
{
   # This function tries to find a LAPACK library. Any library found must allow
   # a Fortran program that calls LAPACK routines to compile, link and run.
   # The first library that matches these criteria is returned.
   fcomp=$1
   if [ ${#fcomp} -eq 0 ] ; then
       echo
       return
   fi
   blas=$2
   blasopt=$3
   lib=""
   length=${#LIST_LINLIBS[*]}
   indx=0
   while [ "${indx}" -lt "${length}" ] ; do
     candidate="${LIST_LINLIBS[${indx}]}"
     ((indx++))
     # echo "lapack: trying ${candidate}" > /dev/stderr
     if [ "${blasopt}" != "0" ] ; then
       candidate="${blasopt}"
     fi
     if [ ${#lib} -eq 0 ] ; then
       echo "      program testlapack" > testlapack$$.f
       echo "      implicit none" >> testlapack$$.f
       echo "      double precision a, w, work" >> testlapack$$.f
       echo "      integer*8 n" >> testlapack$$.f
       echo "      integer*8 lda" >> testlapack$$.f
       echo "      integer*8 lwork, info" >> testlapack$$.f
       echo "      a = 1.0d0" >> testlapack$$.f
       echo "      lda = 1" >> testlapack$$.f
       echo "      n = 1" >> testlapack$$.f
       echo "      lwork = 1" >> testlapack$$.f
       echo "      call dsyev('n','u',n,a,lda,w,work,lwork,info)" >> testlapack$$.f
       echo "      end" >> testlapack$$.f
       $fcomp -o testlapack$$.x testlapack$$.f ${candidate} ${blas} > /dev/null
       result=$?
       if [ ${result} -eq 0 ] ; then
         ./testlapack$$.x > /dev/null
         result=$?
         if [ ${result} -eq 0 ] ; then
           # This library worked so we will go with this
           lib="${candidate}"
           # echo "lapack: found ${lib}" > /dev/stderr
         fi
         rm -f ./testlapack$$.x
       fi
       rm -f ./testlapack$$.f
     fi
   done
   echo ${lib}
}
function get_lapack_integer()
{
   # This function works out whether the LAPACK library uses 
   # an integer*4 or integer*8 interface.
   fcomp=$1
   blaslapack=$2
   echo "      program testlapackint" > ./testlapack$$.f
   echo "      implicit none" >> ./testlapack$$.f
   echo "      integer*8 typecast" >> ./testlapack$$.f
   echo "      integer*4 data(2)" >> ./testlapack$$.f
   echo "      double precision a, w, ww(10)" >> ./testlapack$$.f
   echo "      integer*8 n, ld, lw" >> ./testlapack$$.f
   echo "      integer*8 two" >> ./testlapack$$.f
   echo "      integer*8 info" >> ./testlapack$$.f
   echo "      external  typecast" >> ./testlapack$$.f
   echo "      logical   obigendian" >> ./testlapack$$.f
   echo "      a = 0.5d0" >> ./testlapack$$.f
   echo "      w = 1.0d0" >> ./testlapack$$.f
   echo "      data(1) = 0" >> ./testlapack$$.f
   echo "      data(2) = 1" >> ./testlapack$$.f
   echo "      obigendian = (1.eq.typecast(data))" >> ./testlapack$$.f
   echo "      two = 2" >> ./testlapack$$.f
   echo "      info = 0" >> ./testlapack$$.f
   echo "      if (obigendian) then" >> ./testlapack$$.f
   echo "        n  = two**32+two**0" >> ./testlapack$$.f
   echo "        lw = 10*two**32+two**0" >> ./testlapack$$.f
   echo "        ld = two**32" >> ./testlapack$$.f
   echo "      else" >> ./testlapack$$.f
   echo "        n  = two**32+two**0" >> ./testlapack$$.f
   echo "        lw = two**32+10*two**0" >> ./testlapack$$.f
   echo "        ld = two**0" >> ./testlapack$$.f
   echo "      endif" >> ./testlapack$$.f
   echo "      call dsyev('n','u',n,a,ld,w,ww,lw,info)" >> testlapack$$.f
   echo "      if (info.eq.0) then" >> ./testlapack$$.f
   echo "        write(*,'(a)')'4'" >> ./testlapack$$.f
   echo "      else" >> ./testlapack$$.f
   echo "        write(*,'(a)')'8'" >> ./testlapack$$.f
   echo "      endif" >> ./testlapack$$.f
   echo "      end" >> ./testlapack$$.f
   echo "      integer*8 function typecast(input)" >> ./testlapack$$.f
   echo "      implicit none" >> ./testlapack$$.f
   echo "      integer*8 input" >> ./testlapack$$.f
   echo "      typecast = input" >> ./testlapack$$.f
   echo "      return" >> ./testlapack$$.f
   echo "      end" >> ./testlapack$$.f
   $fcomp -o testlapack$$.x testlapack$$.f ${blaslapack} > /dev/null
   result=`./testlapack$$.x`
   status=$?
   if [ ${status} -ne 0 ] ; then
     result=8
   elif [ "${result}" != "4" ] ; then
     result=8
   fi
   rm -f ./testlapack$$.x
   rm -f ./testlapack$$.f
   echo ${result}
}
function get_scalapack_lib()
{
   # This function tries to find a ScaLAPACK library. Any library found must allow
   # a Fortran program that calls ScaLAPACK routines to compile, link and run.
   # The first library that matches these criteria is returned.
   fcomp=$1
   lapackblas=$2
   blasopt=$3
   if [ ${#fcomp} -eq 0 ] ; then
       echo
       return
   fi
   lib=""
   length=${#LIST_LINLIBS[*]}
   indx=0
   while [ "${indx}" -lt "${length}" ] ; do
     candidate="${LIST_LINLIBS[${indx}]}"
     ((indx++))
     # echo "lapack: trying ${candidate}" > /dev/stderr
     if [ "${blasopt}" != "0" ] ; then
       candidate="${blasopt}"
     fi
     if [ ${#lib} -eq 0 ] ; then
       echo "      program testscalapack" > testscalapack$$.f
       echo "      implicit none" >> testscalapack$$.f
       echo "      double precision a, b" >> testscalapack$$.f
       echo "      integer*8 n" >> testscalapack$$.f
       echo "      integer*8 ia,ja,ib,jb, info" >> testscalapack$$.f
       echo "      integer*8 desca(1),descb(1),ipiv(2)" >> testscalapack$$.f
       echo "      a = 2.0d0" >> testscalapack$$.f
       echo "      b = 1.0d0" >> testscalapack$$.f
       echo "      ia = 1" >> testscalapack$$.f
       echo "      ja = 1" >> testscalapack$$.f
       echo "      ib = 1" >> testscalapack$$.f
       echo "      jb = 1" >> testscalapack$$.f
       echo "      n = 1" >> testscalapack$$.f
       echo "      call pdgetrs('n',n,n,a,ia,ja,desca,ipiv,b,ib,jb,descb,info)" >> testscalapack$$.f
       echo "      end" >> testscalapack$$.f
       $fcomp -o testscalapack$$.x testscalapack$$.f ${candidate} ${lapackblas} > /dev/null
       result=$?
       if [ ${result} -eq 0 ] ; then
         ./testscalapack$$.x > /dev/null
         result=$?
         if [ ${result} -eq 0 ] ; then
           # This library worked so we will go with this
           lib="${candidate}"
           # echo "lapack: found ${lib}" > /dev/stderr
         fi
         rm -f ./testscalapack$$.x
       fi
       rm -f ./testscalapack$$.o
       rm -f ./testscalapack$$.f
     fi
   done
   echo ${lib}
}
function get_scalapack_integer()
{
   # This function works out whether the LAPACK library uses 
   # an integer*4 or integer*8 interface.
   fcomp=$1
   blaslapacksca=$2
   echo "      program testscalapack" > testscalapack$$.f
   echo "      implicit none" >> testscalapack$$.f
   echo "      double precision a, b" >> testscalapack$$.f
   echo "      integer*8 n" >> testscalapack$$.f
   echo "      integer*8 ia,ja,ib,jb" >> testscalapack$$.f
   echo "      integer*8 id(9),ip(10)" >> testscalapack$$.f
   echo "      integer*8 info" >> testscalapack$$.f
   echo "      integer*8 typecast" >> testscalapack$$.f
   echo "      logical   integer8" >> testscalapack$$.f
   echo "      external  typecast,integer8" >> testscalapack$$.f
   echo "      integer*4 data(2)" >> testscalapack$$.f
   echo "      a = 1.0d0" >> testscalapack$$.f
   echo "      b = 1.0d0" >> testscalapack$$.f
   echo "      do ia = 1, 9" >> testscalapack$$.f
   echo "        id(ia) = -1" >> testscalapack$$.f
   echo "      enddo" >> testscalapack$$.f
   echo "      ia = 0" >> testscalapack$$.f
   echo "      ib = 0" >> testscalapack$$.f
   echo "      data(1) = -1" >> testscalapack$$.f
   echo "      data(2) = -1" >> testscalapack$$.f
   echo "      ja = typecast(data)" >> testscalapack$$.f
   echo "      jb = typecast(data)" >> testscalapack$$.f
   echo "      data(2) = 0" >> testscalapack$$.f
   echo "      data(1) = 8" >> testscalapack$$.f
   echo "      n = typecast(data)" >> testscalapack$$.f
   echo "      data(1) = 999999" >> testscalapack$$.f
   echo "      data(2) = 999999" >> testscalapack$$.f
   echo "      info = typecast(data)" >> testscalapack$$.f
   echo "      call pdgetrs('n',n,n,a,ia,ja,id,ip,b,ib,jb,id,info)" >> testscalapack$$.f
   echo "      if (integer8(data,info)) then" >> testscalapack$$.f
   echo "        write(*,'(a)')'8'" >> ./testscalapack$$.f
   echo "      else" >> ./testscalapack$$.f
   echo "        write(*,'(a)')'4'" >> ./testscalapack$$.f
   echo "      endif" >> ./testscalapack$$.f
   echo "      end" >> testscalapack$$.f
   echo "      integer*8 function typecast(input)" >> ./testscalapack$$.f
   echo "      implicit none" >> testscalapack$$.f
   echo "      integer*8 input" >> ./testscalapack$$.f
   echo "      typecast = input" >> ./testscalapack$$.f
   echo "      return" >> ./testscalapack$$.f
   echo "      end" >> ./testscalapack$$.f
   echo "      logical function integer8(data,input)" >> ./testscalapack$$.f
   echo "      implicit none" >> testscalapack$$.f
   echo "      integer*4 input(2),data(2)" >> ./testscalapack$$.f
   echo "      integer8 = (input(1).ne.data(1)).and.(input(2).ne.data(2))" >> ./testscalapack$$.f
   echo "      return" >> ./testscalapack$$.f
   echo "      end" >> ./testscalapack$$.f
   $fcomp -o testscalapack$$.x testscalapack$$.f ${blaslapacksca} > /dev/null
   result=`./testscalapack$$.x`
   out=`expr "${result}" : '*4'`
   if [ ${#out} -eq 0 ] ; then
     out=8
   else
     out=4
   fi
   rm -f ./testscalapack$$.x
   rm -f ./testscalapack$$.o
   rm -f ./testscalapack$$.f
   echo ${out}
}
function get_pointer_size ()
{
   # This shell function works out whether pointers
   # are 8- or 4-bytes on this platform. This function
   # expects to be given the compiler to use as an input.
   declare -a list
   ccomp=$1
   output=""
   length=${#LIST_COMPFLAGS[*]}
   echo "#include <stdio.h>">/tmp/$$.c
   echo "int main(void){">>/tmp/$$.c
   echo "    int* ptr = NULL;">>/tmp/$$.c
   echo "    int size = sizeof(ptr);">>/tmp/$$.c
   echo "    printf(\"%d\n\",size);">>/tmp/$$.c
   echo "    return 0;">>/tmp/$$.c
   echo "}">>/tmp/$$.c
   indx=0
   while [ "${indx}" -lt "${length}" ] ; do
     flags=${LIST_COMPFLAGS[$indx]}
     ((indx++))
     ${ccomp} ${flags} -o /tmp/$$.x /tmp/$$.c
     result=$?
     if [ ${result} -eq 0 ] ; then
       output=`/tmp/$$.x`
       result=$?
       if [ ${result} -eq 0 ] ; then
         echo ${output}
         rm -f  /tmp/$$.c /tmp/$$.o /tmp/$$.x
         return 0
       fi
     fi
   done
   rm -f  /tmp/$$.c /tmp/$$.o /tmp/$$.x
   echo "ERROR: could not establish the pointer size" > /dev/stderr
   exit 1
}
#
# Decide what we need to do here
#
option=$1
if [ "$option" == "help" ] ; then
  usage
  exit 1
elif [ "$option" == "" ] ; then
  echo > /dev/null
elif [ "$option" == "realclean" ] ; then
  echo > /dev/null
elif [ "$option" == "python" ] ; then
  echo > /dev/null
elif [ "$option" == "python64" ] ; then
  echo > /dev/null
else
  usage
  exit 1
fi
#
# See if we can detect which platform we are on.
# This is most relevant to the various BlueGene platforms as they are a complete
# package, i.e. if you know you are on a BlueGene/P then all required settings
# are prescribed. This is not the case on other platforms.
#
echo "=== figure out Network, MPI, and LinAlg libraries ==="
if [ -d /bgsys/drivers/ppcfloor ] ; then
  #
  # This is a BlueGene/P machine
  #
  if [ ${#NWCHEM_TARGET} -eq 0 ] ; then
    export NWCHEM_TARGET=BGP
  fi
  if [ ${#ARMCI_NETWORK} -eq 0 ] ; then
    export ARMCI_NETWORK=DCMFMPI
  fi
  if [ ${#MSG_COMMS} -eq 0 ] ; then
    export MSG_COMMS=DCMFMPI
  fi
  if [ ${#USE_MPI} -eq 0 ] ; then
    export USE_MPI=y
  fi
  if [ ${#BGCOMPILERS} -eq 0 ] ; then
    export BGCOMPILERS=/bgsys/drivers/ppcfloor/gnu-linux/bin
  fi
  if [ ${#BGP_INSTALLDIR} -eq 0 ] ; then
    export BGP_INSTALLDIR=/bgsys/drivers/ppcfloor
  fi
  if [ ${#BGP_RUNTIMEPATH} -eq 0 ] ; then
    export BGP_RUNTIMEPATH=/bgsys/drivers/ppcfloor/runtime
  fi
  if [ ${#ARMCIDRV} -eq 0 ] ; then
    export ARMCIDRV=${BGP_INSTALLDIR}
  fi
  if [ ${#BGDRIVER} -eq 0 ] ; then
    export BGDRIVER=${ARMCIDRV}
  fi
  if [ ${#MPI_LIB} -eq 0 ] ; then
    export MPI_LIB=${BGDRIVER}/comm/lib
  fi
  if [ ${#MPI_INCLUDE} -eq 0 ] ; then
    export MPI_INCLUDE=${BGDRIVER}/comm/include
  fi
  if [ ${#BGMLMPI_INCLUDE} -eq 0 ] ; then
    export BGMLMPI_INCLUDE=${MPI_INCLUDE}
  fi
  if [ ${#LIBMPI} -eq 0 ] ; then
    export LIBMPI="-L${MPI_LIB} -lfmpich_.cnk -lmpich.cnk -ldcmf.cnk -ldcmfcoll.cnk -lpthread -lrt -L${BGP_RUNTIMEPATH}/SPI -lSPI.cna"
  fi
  if [ ${#MPI_F90} -eq 0 ] ; then
    export MPI_F90=mpixlf77
  fi
  if [ ${#MPI_CC} -eq 0 ] ; then
    export MPI_CC=mpixlc
  fi
  if [ ${#MPI_CXX} -eq 0 ] ; then
    export MPI_CXX=mpixlcxx
  fi
fi
#
# End of BlueGene stuff
#
if [ ${#NWCHEM_TOP} -eq 0 ] ; then
  export NWCHEM_TOP=`pwd`
fi
if [ ${#NWCHEM_MODULES} -eq 0 ] ; then
  export NWCHEM_MODULES="all"
fi
if [ ${#USE_MPI} -eq 0 ] ; then
  export USE_MPI=y
fi
if [ ${#USE_MPI} -ne 0 ] ; then
  if [ ${#USE_MPIF} -eq 0 ] ; then
    export USE_MPIF=y
  fi
  if [ ${#USE_MPIF4} -eq 0 ] ; then
    export USE_MPIF4=y
  fi
fi
if [ ${#MSG_COMMS} -eq 0 ] ; then
  export MSG_COMMS=MPI
fi
export LDOPTIONS=" "
export USE_SUBGROUPS=y
#export DEV_GA=y    # do not set this for the release
#export USE_GPROF=y
#
# Now we try and guess the network on the machine.
# The default is MPI-MT.
#
if [ ${#ARMCI_NETWORK} -eq 0 ] ; then
  #
  # Do we have a CRAY Gemini interconnect?
  # /opt/cray present then we are probably on a Cray machine
  # /opt/cray/*/gemini present then we have a Gemini interconnect
  # This is at least the situation on Hopper @ NERSC.
  #
  if [ -d /opt/cray ] ; then
    GEMINIDIRS=`find /opt/cray -name gemini`
    if [ ${#GEMINIDIRS} -ne 0 ] ; then
      echo "This machine is a Cray with a GEMINI interconnect"
      echo "Please ensure you have the following modules loaded:"
      echo "  module load ntk"
      echo "  module load onesided"
      echo "Module ntk provides numatoolkit.h and libnumatoolkit,"
      echo "whereas module onesided provides onesided.h and libonesided."
      echo "Use the following command to check which modules are loaded:"
      echo "  module list"
      # There seems to be a Gemini interconnect on this Cray machine
      export ARMCI_NETWORK="GEMINI"
      if [ ${#MPI_F90} -eq 0 ] ; then
        export MPI_F90=ftn
      fi
      if [ ${#MPI_CC} -eq 0 ] ; then
        export MPI_CC=cc
      fi
      if [ ${#MPI_CXX} -eq 0 ] ; then
        export MPI_CXX=CC
      fi
    fi
  fi
fi
if [ ${#ARMCI_NETWORK} -eq 0 ] ; then
  #
  # This test is stolen from GASNET
  # /dev/ukbride present then we are probably on a Cray XT machine
  # /proc/portals/meminfo present then this machine has Cray Portals
  #
  if [ -f /proc/portals/meminfo ] ; then
    # There seems to be a portals infrastructure on this machine
    export ARMCI_NETWORK="PORTALS"
    if [ ${#MPI_F90} -eq 0 ] ; then
      export MPI_F90=ftn
    fi
    if [ ${#MPI_CC} -eq 0 ] ; then
      export MPI_CC=cc
    fi
    if [ ${#MPI_CXX} -eq 0 ] ; then
      export MPI_CXX=CC
    fi
    if [ ${#MA_USE_ARMCI_MEM} -eq 0 ] ; then
      export MA_USE_ARMCI_MEM=1
    fi
  fi
fi
if [ "${ARMCI_NETWORK}" == "OPENIB" ] ; then
  if [ ${#IB_LIB} -eq 0 ]; then
    export IB_LIB="-libverbs"
  fi
  if [ ${#IB_INCLUDE} -eq 0 ]; then
    if [ -d /usr/include/infiniband ] ; then
      export IB_INCLUDE="/usr/include/infiniband"
    else
      echo "ERROR: Infiniband include files not in expected location"
      exit 1
    fi
  fi
fi
if [ ${#ARMCI_NETWORK} -eq 0 ] ; then
  if [ -d /dev/infiniband ] ; then
    # There seems to be an infiniband network on this machine
    export ARMCI_NETWORK="OPENIB"
    export IB_LIB="-libverbs"
    if [ -d /usr/include/infiniband ] ; then
      export IB_INCLUDE="/usr/include/infiniband"
    else
      echo "ERROR: Infiniband include files not in expected location"
      exit 1
    fi
  fi
fi
if [ ${#ARMCI_NETWORK} -eq 0 ] ; then
  echo "#include \"stdio.h\""                                         >  ./mpi_threads$$.c
  echo "#include \"mpi.h\""                                           >> ./mpi_threads$$.c
  echo "int main(int argc, char **argv)"                              >> ./mpi_threads$$.c
  echo "{"                                                            >> ./mpi_threads$$.c
  echo "   int required = MPI_THREAD_MULTIPLE;"                       >> ./mpi_threads$$.c
  echo "   int provided;"                                             >> ./mpi_threads$$.c
  echo "   int result;"                                               >> ./mpi_threads$$.c
  echo "   result = MPI_Init_thread(&argc,&argv,required,&provided);" >> ./mpi_threads$$.c
  echo "   if (provided == MPI_THREAD_MULTIPLE) {"                    >> ./mpi_threads$$.c
  echo "     printf(\"multithreaded\n\");"                            >> ./mpi_threads$$.c
  echo "   } else if (provided == MPI_THREAD_SERIALIZED) {"           >> ./mpi_threads$$.c
  echo "     printf(\"serialthreaded\n\");"                           >> ./mpi_threads$$.c
  echo "   } else if (provided == MPI_THREAD_FUNNELED) {"             >> ./mpi_threads$$.c
  echo "     printf(\"funnelthreaded\n\");"                           >> ./mpi_threads$$.c
  echo "   } else if (provided == MPI_THREAD_SINGLE) {"               >> ./mpi_threads$$.c
  echo "     printf(\"singlethreaded\n\");"                           >> ./mpi_threads$$.c
  echo "   } else {"                                                  >> ./mpi_threads$$.c
  echo "     result = 1;"                                             >> ./mpi_threads$$.c
  echo "   }"                                                         >> ./mpi_threads$$.c
  echo "   result = result || MPI_Finalize();"                        >> ./mpi_threads$$.c
  echo "   return result;"                                            >> ./mpi_threads$$.c
  echo "}"                                                            >> ./mpi_threads$$.c
  mpicc -o ./mpi_threads$$.x ./mpi_threads$$.c
  result=$?
  if [ ${result} -ne 0 ] ; then
    # Testing multi-threaded support did not work, so hope for the best
    export ARMCI_NETWORK="MPI-MT"
  else
    output=`./mpi_threads$$.x`
    result=$?
    if [ ${result} -ne 0 ] ; then
      # Testing multi-threaded support did not work, so hope for the best
      export ARMCI_NETWORK="MPI-MT"
    else
      if [ "${output}" == "multithreaded" ] ; then
        export ARMCI_NETWORK="MPI-MT"
      fi
    fi
  fi
  rm -f ./mpi_threads$$.x ./mpi_threads$$.c
fi
#
# Below we have to realize that EXPORT is a command. Hence if we use
#   EXPORT DUMMY=`ls`
#   status=$?
# then status will be set to the exit code of the EXPORT command. If we
# want the exit code from the ls command we need to write
#   DUMMY=`ls`
#   status=$?
#   EXPORT DUMMY
#
if [ ${#MPI_INCLUDE} -eq 0 ] ; then
  MPI_INCLUDE=`get_mpi_include`
  if [ $? -ne 0 ] ; then
    unset MPI_INCLUDE
  fi
fi
if [ ${#MPI_LIB} -eq 0 ] ; then
  MPI_LIB=`get_mpi_link`
  if [ $? -ne 0 ] ; then
    unset MPI_LIB
  fi
fi
if [ ${#LIBMPI} -eq 0 ] ; then
  LIBMPI=`get_mpi_lib`
  if [ $? -ne 0 ] ; then
    unset LIBMPI
  fi
  LIBMPI="${LIBMPI} ${IB_LIB}"
fi
if [ ${#MPI_F90} -eq 0 ] ; then
  MPI_F90=`get_mpi_fortran`
  if [ $? -ne 0 ] ; then
    unset MPI_F90
  fi
fi
if [ ${#MPI_CC} -eq 0 ] ; then
  MPI_CC=`get_mpi_cc`
  if [ $? -ne 0 ] ; then
    unset MPI_CC
  fi
fi
if [ ${#MPI_CXX} -eq 0 ] ; then
  MPI_CXX=`get_mpi_cxx`
  if [ $? -ne 0 ] ; then
    unset MPI_CXX
  fi
fi
export MPI_INCLUDE
export MPI_LIB
export LIBMPI
#
# Work out whether this is a 32- or 64-bit platform
# We need a C-compiler to do this, hence the compiler detection comes before
# this step. To detect the linear algebra routines we need to have worked out
# how to build code for this platform which requires detecting the 32- vs. 64-
# bit characteristics before attempting to detect the linear algebra routines.
#
if [ ${#NWCHEM_PTR_SIZE} -eq 0 ] ; then
  NWCHEM_PTR_SIZE=`get_pointer_size ${MPI_CC}`
  if [ $? -ne 0 ] ; then
    unset NWCHEM_PTR_SIZE
  fi
fi
if [ ${#NWCHEM_OS} -eq 0 ] ; then
  NWCHEM_OS=`uname | tr '[a-z]' '[A-Z]'`
  if [ $? -ne 0 ] ; then
    unset NWCHEM_OS
  fi
  if [ ${#NWCHEM_OS} -ne 0 ] ; then
    if [ ${NWCHEM_OS} == "DARWIN" ] ; then
      export NWCHEM_OS=MACX
    fi
    if [ ${NWCHEM_OS} == "AIX" ] ; then
      export NWCHEM_OS=IBM
    fi
  fi
fi
if [ ${#NWCHEM_TARGET} -eq 0 ] ; then
  if [ ${#NWCHEM_PTR_SIZE} -eq 0 ] ; then
    echo "ERROR: could not establish pointer size needed to set NWCHEM_TARGET: aborting..."
    exit 1
  fi
  if [ ${#NWCHEM_OS} -eq 0 ] ; then
    echo "ERROR: could not establish the OS needed to set NWCHEM_TARGET: aborting..."
    exit 1
  fi
  if [ ${NWCHEM_PTR_SIZE} -eq 4 ] ; then
    export NWCHEM_TARGET=${NWCHEM_OS}
    if [ ${NWCHEM_OS} == "IBM" ] ; then
      export OBJECT_MODE=32
    fi
  else
    export NWCHEM_TARGET=${NWCHEM_OS}64
    if [ ${NWCHEM_OS} == "IBM" ] ; then
      export OBJECT_MODE=64
    fi
  fi
fi
#
# Find out whether there are any BLAS, LAPACK and/or ScaLAPACK libraries 
# available.
#
# If BLASOPT is set that runs shot over everything. 
#
if [ ${#BLASOPT} -ne 0 ] ; then
  DUMMY=`get_blas_lib ${MPI_F90} "${BLASOPT}"`
  result=$?
  if [ ${result} -eq 0 ] ; then
    export BLAS_LIB="${BLASOPT}"
  fi
  DUMMY=`get_lapack_lib ${MPI_F90} "${BLASOPT}" "${BLASOPT}"`
  result=$?
  if [ ${result} -eq 0 ] ; then
    export LAPACK_LIB="${BLASOPT}"
  fi
  MPI_LIB_TMP=`echo "-L${MPI_LIB}" | sed 's/^-L-L/-L/'`
  DUMMY=`get_scalapack_lib ${MPI_F90} "${BLASOPT} ${MPI_LIB_TMP} ${LIBMPI}" "${BLASOPT}"`
  result=$?
  if [ ${result} -eq 0 ] ; then
    export SCALAPACK_LIB="${BLASOPT}"
  fi
fi
#
# If needed find libraries and work out which integer types they support
#
if [ ${#BLAS_LIB} -eq 0 ] ; then
  BLAS_LIB=`get_blas_lib ${MPI_F90} 0`
  export BLAS_LIB
fi
if [ ${#BLAS_SIZE} -eq 0 ] ; then
  if [ ${#BLAS_LIB} -eq 0 ] ; then
    # In this case we will build the BLAS from source
    BLAS_SIZE=8
  else
    BLAS_SIZE=`get_blas_integer ${MPI_F90} ${BLAS_LIB}`
    if [ $? -ne 0 ] ; then
      BLAS_SIZE=8
    fi
  fi
  export BLAS_SIZE
fi
if [ ${#LAPACK_LIB} -eq 0 ] ; then
  LAPACK_LIB=`get_lapack_lib ${MPI_F90} "${BLAS_LIB}" 0`
  export LAPACK_LIB
fi
if [ ${#LAPACK_SIZE} -eq 0 ] ; then
  if [ ${#LAPACK_LIB} -eq 0 ] ; then
    # In this case we will build the LAPACK from source
    LAPACK_SIZE=8
  else
    LAPACK_SIZE=`get_lapack_integer ${MPI_F90} "${LAPACK_LIB} ${BLAS_LIB}"`
    if [ $? -ne 0 ] ; then
      LAPACK_SIZE=8
    fi
  fi
  export LAPACK_SIZE
fi
if [ ${#SCALAPACK_LIB} -eq 0 ] ; then
  MPI_LIB_TMP=`echo "-L${MPI_LIB}" | sed 's/^-L-L/-L/'`
  SCALAPACK_LIB=`get_scalapack_lib ${MPI_F90} "${LAPACK_LIB} ${BLAS_LIB} ${MPI_LIB_TMP} ${LIBMPI}" 0`
  export SCALAPACK_LIB
fi
if [ ${#SCALAPACK_SIZE} -eq 0 ] ; then
  if [ ${#SCALAPACK_LIB} -eq 0 ] ; then
    # In this case there is no ScaLAPACK
    SCALAPACK_SIZE=0
  else
    MPI_LIB_TMP=`echo "-L${MPI_LIB}" | sed 's/^-L-L/-L/'`
    SCALAPACK_SIZE=`get_scalapack_integer ${MPI_F90} "${SCALAPACK_LIB} ${LAPACK_LIB} ${BLAS_LIB} ${MPI_LIB_TMP} ${LIBMPI}"`
  fi
  export SCALAPACK_SIZE
fi
#
# Work out whether BLAS, LAPACK and SCALAPACK are compatible and based on that
# what we are actually going to use.
#
if [ ${#SCALAPACK_LIB} -eq 0 ] ; then
  # No ScaLAPACK found so worry only about BLAS and LAPACK
  if [ ${LAPACK_SIZE} -ne ${BLAS_SIZE} ] ; then
    # So at least one of LAPACK and BLAS has to fall back to source code
    # and integer*8.
    if [ ${BLAS_SIZE} -eq 4 ] ; then
      export BLAS_LIB=""
      export BLAS_SIZE=8
    fi
    if [ ${LAPACK_SIZE} -eq 4 ] ; then
      export LAPACK_LIB=""
      export LAPACK_SIZE=8
    fi
  fi
else
  if [[ ( ${LAPACK_SIZE} -ne ${BLAS_SIZE} ) || ( ${SCALAPACK_SIZE} -ne ${BLAS_SIZE} ) ]] ; then
    if [ ${BLAS_SIZE} -eq 4 ] ; then
      export BLAS_LIB=""
      export BLAS_SIZE=8
    fi
    if [ ${LAPACK_SIZE} -eq 4 ] ; then
      export LAPACK_LIB=""
      export LAPACK_SIZE=8
    fi
    if [ ${SCALAPACK_SIZE} -eq 4 ] ; then
      export SCALAPACK_LIB=""
      export SCALAPACK_SIZE=8
    fi
  fi
fi
if [ ${#NWCHEM_EXECUTABLE} -eq 0 ] ; then
  export NWCHEM_EXECUTABLE=$NWCHEM_TOP/bin/$NWCHEM_TARGET/nwchem
fi
if [ "x$1" == "xpython" ]; then
  export PYTHONVERSION=2.4
  export PYTHONHOME=/usr
  export PYTHONPATH=./:$NWCHEM_TOP/contrib/python/
  export NWCHEM_MODULES="$NWCHEM_MODULES python"
  echo "===================================="
  echo "Building NWChem including Python $PYTHONVERSION"
  echo "===================================="
  echo
  option=""
elif [ "x$1" == "xpython64" ]; then
  export USE_PYTHON64=yes
  export PYTHONVERSION=2.4
  export PYTHONHOME=/usr
  export PYTHONPATH=./:$NWCHEM_TOP/contrib/python/
  export NWCHEM_MODULES="$NWCHEM_MODULES python"
  echo "===================================="
  echo "Building NWChem including Python $PYTHONVERSION"
  echo "===================================="
  echo
  option=""
else
  echo "==============="
  echo "Building NWChem"
  echo "==============="
  echo
fi
echo "NWCHEM_TOP    =" ${NWCHEM_TOP}
echo "NWCHEM_TARGET =" ${NWCHEM_TARGET}
echo "MPI_INCLUDE   =" ${MPI_INCLUDE}
echo "MPI_LIB       =" ${MPI_LIB}
echo "LIBMPI        =" ${LIBMPI}
echo "MPI_F90       =" ${MPI_F90}
echo "MPI_CC        =" ${MPI_CC}
echo "MPI_CXX       =" ${MPI_CXX}
echo "ARMCI_NETWORK =" ${ARMCI_NETWORK}
if [ ${#IB_INCLUDE} -ne 0 ] ; then
  echo "IB_INCLUDE    =" ${IB_INCLUDE}
fi
if [ ${#BLAS_LIB} -ne 0 ] ; then
  echo "BLAS_LIB      =" ${BLAS_LIB} " integer-size = " ${BLAS_SIZE}
fi
if [ ${#LAPACK_LIB} -ne 0 ] ; then
  echo "LAPACK_LIB    =" ${LAPACK_LIB} " integer-size = " ${LAPACK_SIZE}
fi
if [ ${#SCALAPACK_LIB} -ne 0 ] ; then
  echo "SCALAPACK_LIB =" ${SCALAPACK_LIB} " integer-size = " ${SCALAPACK_SIZE}
fi
#
# Stop if we find essential information missing.
# I.e. no Fortran, C, or C++ compilers or settings to use obsolete versions
# of GA.
#
if [ ${#MPI_F90} -eq 0 ] ; then
  echo "ERROR: No Fortran compiler found: aborting..." > /dev/stderr
  exit 1
fi
if [ ${#MPI_CC} -eq 0 ] ; then
  echo "ERROR: No C compiler found: aborting..." > /dev/stderr
  exit 1
fi
if [ ${#MPI_CXX} -eq 0 ] ; then
  echo "ERROR: No C++ compiler found: aborting..." > /dev/stderr
  exit 1
fi
if [ "`basename ${MPI_F90}`" != "${MPI_F90}" ] ; then
  echo "ERROR: Fortran compiler has to be the basename: ${MPI_F90}" > /dev/stderr
  echo "ERROR: Invalid Fortran compiler: aborting..." > /dev/stderr
  exit 1
fi
if [ "`basename ${MPI_CC}`" != "${MPI_CC}" ] ; then
  echo "ERROR: C compiler has to be the basename: ${MPI_CC}" > /dev/stderr
  echo "ERROR: Invalid C compiler: aborting..." > /dev/stderr
  exit 1
fi
if [ "`basename ${MPI_CXX}`" != "${MPI_CXX}" ] ; then
  echo "ERROR: C++ compiler has to be the basename: ${MPI_CXX}" > /dev/stderr
  echo "ERROR: Invalid C++ compiler: aborting..." > /dev/stderr
  exit 1
fi

if [ ${#OLD_GA} -ne 0 ] ; then
  echo "ERROR: OLD_GA is set but this script only works with GA-5-1 or later: aborting..." > /dev/stderr
  exit 1
fi
cd $NWCHEM_TOP/src
echo "=== configure GA ==="
if [ "x${option}" != "xrealclean" ]; then
  make DIAG=PAR FC=$MPI_F90 CC=$MPI_CC CXX=$MPI_CXX LDOPTIONS="$LDOPTIONS" configure_ga
  #
  # Extract information about BLAS libraries from the GA config.status file
  #
  have_blas_false=`get_config_value "HAVE_BLAS_FALSE"`
  have_blas_true=`get_config_value "HAVE_BLAS_TRUE"`
  if [ "x${have_blas_true}" == "x" ] ; then
    if [ "x${have_blas_false}" == "x#" ] ; then
      # The GA found some BLAS library, set GA_BLAS accordingly
      GA_BLAS=`get_config_value "BLAS_LDFLAGS"`
      GA_BLAS="${GA_BLAS} `get_config_value \"BLAS_LIBS\"`"
      GA_BLAS_SIZE=`get_config_value "BLAS_SIZE"`
      export GA_BLAS
      if [ ${#BLAS_SIZE} -ne 0 ] ; then
        if [ "${BLAS_SIZE}" != "${GA_BLAS_SIZE}" ] ; then
          echo "Warning: BLAS_SIZE and GA_BLAS_SIZE do not match " ${BLAS_SIZE} ${GA_BLAS_SIZE}
          export GA_BLAS_SIZE=${BLAS_SIZE}
        fi
      fi
      if [ "${GA_BLAS_SIZE}" == "4" ] ; then
        export USE_64TO32=y
      else
        unset USE_64TO32
      fi
      echo "Found BLAS " ${GA_BLAS}
      echo "Found BLAS type: integer*"${GA_BLAS_SIZE}
    else
      # Confused
      echo "ERROR: A: inconsistent data on presence of BLAS library"
      echo "have_blas_true  = " ${have_blas_true}
      echo "have_blas_false = " ${have_blas_false}
      exit 1
    fi
  elif [ "x${have_blas_true}" == "x#" ] ; then
    if [ "x${have_blas_false}" == "x" ] ; then
      # The GA found no BLAS library, unset GA_BLAS to maintain consistency
      unset GA_BLAS
      echo "Found no BLAS "
    else
      # Confused
      echo "ERROR: B: inconsistent data on presence of BLAS library"
      echo "have_blas_true  = " ${have_blas_true}
      echo "have_blas_false = " ${have_blas_false}
      exit 1
    fi
  else
    echo "ERROR: C: invalid settings" 
    echo "have_blas_true  = " ${have_blas_true}
    echo "have_blas_false = " ${have_blas_false}
    exit 1
  fi
fi
if [ ${#BLASOPT} -eq 0 ] ; then
  if [ ${#GA_BLAS} -ne 0 ] ; then
    export BLASOPT=${GA_BLAS}
  fi
fi
echo "=== configure NWChem ==="
if [ "x${option}" != "xrealclean" ]; then
  make DIAG=PAR FC=$MPI_F90 CC=$MPI_CC CXX=$MPI_CXX LDOPTIONS="$LDOPTIONS" nwchem_config
fi
cd $NWCHEM_TOP/src/util
echo "=== build NWChem version table ==="
if [ "x${option}" != "xrealclean" ]; then
  if [ ${#NWCHEM_NOVERSION} -eq 0 ] ; then
    make DIAG=PAR FC=$MPI_F90 CC=$MPI_CC CXX=$MPI_CXX LDOPTIONS="$LDOPTIONS" version
  else
    rm -f util_version.F
  fi
fi
cd $NWCHEM_TOP/src
echo "=== do NWChem code conversion ==="
if [ "x${option}" != "xrealclean" ]; then
  if [ ${#USE_64TO32} -eq 0 ] ; then
     make 32_to_64
  else
     make 64_to_32
  fi
  # The make 32_to_64 or 64_to_32 forced the dependencies to be created
  # However, at this time the Global Arrays have not been built yet and
  # therefore the nwchem/src/tools/install/include directory does not exist,
  # and hence the GA include files cannot be successfully located. As a result
  # all the dependencies involving GA include files are bogus and wrong.
  # So delete the time stamps that protect these dependencies so that new
  # dependencies can be recorded at the right moment in the following make.
  if [[ ! ( -d $NWCHEM_TOP/src/tools/install/include || \
            -d $NWCHEM_TOP/src/tools/include ) ]] ; then
    find . -name include_stamp -exec rm -f {} \; -print
    find . -name dependencies -exec rm -f {} \; -print
  fi
fi
echo "=== compile nwchem ==="
make DIAG=PAR FC=$MPI_F90 CC=$MPI_CC CXX=$MPI_CXX LDOPTIONS="$LDOPTIONS" $option
cd $NWCHEM_TOP/contrib/mov2asc
make DIAG=PAR FC=$MPI_F90 CC=$MPI_CC CXX=$MPI_CXX LDOPTIONS="$LDOPTIONS" $option
echo "=== all done ==="
