dnl ####################################################################
dnl #   Copyright (c)
dnl #
dnl #   You may copy, distribute, and modify it freely as long as you  #
dnl #   preserve this copyright and permission notice.                 #
dnl #                                                                  #
dnl #
dnl ####################################################################
dnl 
dnl Process this file and acconfig.h by autoconf to produce a configure script.
dnl 

AC_INIT(./configure)

AC_PREFIX_DEFAULT(`pwd`)
AC_CONFIG_AUX_DIR(./config)

AC_CONFIG_HEADER(./src/include/config.h)

AC_CANONICAL_SYSTEM
AC_ARG_PROGRAM
AC_HEADER_STDC

dnl AC_CHECK_TYPE(u_short,unsigned short)
AC_HEADER_SYS_WAIT

AC_PROG_RANLIB

VERSION=1.09
AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
AC_SUBST(VERSION)

dnl current working directory

CWD=`pwd`
AC_SUBST(CWD)

dnl an inline which function

which () {
  oldIFS=$IFS

  IFS=:
  for dir in $PATH
  do
    if test -x $dir/$1; then
       found="$dir/$1"; 
       echo $found; 
       break ;
    fi
  done;

  if test -z "$found" ; then
    echo $1; # echo input if not found.
  fi 

  IFS=$oldIFS 
}

dnl function to find mpi.h

mpiinc () {
  MPI_PREFIX=`which mpirun | sed 's%/bin/mpirun%%'`
  if test -f $MPI_PREFIX/include/mpi.h; then
#    echo $MPI_PREFIX/include
    MPI_INC=$MPI_PREFIX/include
  else
    MPI_PREFIX=`which mpirun | sed 's%/lib/[^/]*/[^/]*/mpirun%%'`
    if test -f $MPI_PREFIX/include/mpi.h; then
#      echo $MPI_PREFIX/include
      MPI_INC=$MPI_PREFIX/include
    else
      echo "Please input the absolute path for mpich include dir:"
      read MPI_INC
    fi
  fi      
}

dnl function to find libmpich.a(MPICH1.1.2)
mpilib_1_1_2 () {
  MPI_PREFIX=`which mpirun | sed 's%/bin/mpirun%%'`
  num=0
  CCLIBKEY="-lmpich"

  for dir in $MPI_PREFIX/build/*/*/lib; do 
      if test -f $dir/libmpich.a ; then
        num=`expr $num + 1`
      fi       
  done
# echo $num
  if test `expr $num` -eq 1 ; then
    for dir in $MPI_PREFIX/build/*/*/lib; do 
        if test -f $dir/libmpich.a ; then  
          MPI_LIB=$dir
          return         
        fi
    done
  fi
##
  if test `expr $num` -lt 1 ; then
    MPI_LIB=`which mpirun | sed 's%/mpirun%%'`
      if test -f $MPI_LIB/libmpich.a ; then
        return
      else
        echo "Please input the absolute path for mpich library dir:"
        read MPI_LIB
        return
      fi
  fi
##
  if test `expr $num` -gt 1 ; then
    echo "Configure script found multi communication devices,"
    echo "Please input the absolute path for mpich library dir,"
    echo "the one work with "$MPI_PREFIX/bin/mpirun:
    read MPI_LIB
    return
  fi
}

dnl function to find libmpi.a or libmpich.a(MPICH1.1.1)
mpilib_old () {
  MPI_PREFIX=`which mpirun | sed 's%/bin/mpirun%%'`
  num=0

  for dir in $MPI_PREFIX/lib/*/*; do 
    if test -f $dir/libmpi.a ; then
      num=`expr $num + 1`
      CCLIBKEY="-lmpi"
    else
      if test -f $dir/libmpich.a ; then
        num=`expr $num + 1`
        CCLIBKEY="-lmpich"
      fi       
    fi
  done
# echo $num
##
  if test `expr $num` -eq 1 ; then
    for dir in $MPI_PREFIX/lib/*/*; do 
      if test -f $dir/libmpi.a ; then
        MPI_LIB=$dir
        return
      else 
        if test -f $dir/libmpich.a ; then  
          MPI_LIB=$dir
          return         
        fi
      fi
    done
  fi
##
  if test `expr $num` -lt 1 ; then
    MPI_LIB=`which mpirun | sed 's%/mpirun%%'`
    if test -f $MPI_LIB/libmpi.a ; then
      return
    else 
      if test -f $MPI_LIB/libmpich.a ; then
        return
      else
        echo "Please input the absolute path for mpich library dir:"
        read MPI_LIB
        return
      fi
    fi
  fi
##
  if test `expr $num` -gt 1 ; then
    echo "Configure script found multi communication devices,"
    echo "Please input the absolute path for mpich library dir,"
    echo "the one work with "$MPI_PREFIX/bin/mpirun:
    read MPI_LIB
    return
  fi
}

dnl function to find libmpi.a
mpilib () {
    MPI_PREFIX=`which mpirun | sed 's%/bin/mpirun%%'`
    if test -f $MPI_PREFIX/lib/libmpich.a; then
        MPI_LIB=$MPI_PREFIX/lib
    else
       if test -d $MPI_PREFIX/build; then
           mpilib_1_1_2;
       else
           mpilib_old;
       fi
    fi
}

dnl deciding mpi package

AC_MSG_CHECKING(MPI package)

AC_ARG_WITH(MPI, [
--with-MPI=mpich          Use mpich MPI (the defualt setting)
--with-MPI=sunhpc         Use HPC MPI from SUN
--with-MPI=sp2            Use SP2 MPI from IBM ], MPI=${withval}, MPI=mpich )

AC_CACHE_VAL(adlib_cv_mpipackage, adlib_cv_mpipackage=$MPI) 

AC_MSG_RESULT($adlib_cv_mpipackage)

MPI=$adlib_cv_mpipackage
AC_SUBST(MPI)

case "$MPI" in
  mpich )

  dnl check if mpi installed.
  if test ! -x `which mpirun`
  then 
    echo "Please install mpich first ..."
    exit
  fi

  dnl decide whether there is MPICC

  AC_CHECK_PROG(MPICC, mpiCC, mpiCC)

  dnl check whether mpiCC work.

  if test "$MPICC" = "mpiCC" 
  then
    AC_MSG_CHECKING(whether mpiCC configured)

    echo "void any(){}" > conftest.C

    rm -f conftest.o
    mpiCC -c conftest.C > /dev/null 2> /dev/null
    
    if test -f conftest.o
    then
      MPICCCONFIG=yes
    else
      MPICCCONFIG=no
    fi

    AC_MSG_RESULT($MPICCCONFIG)
     	
    rm -f conftest.C conftest.o
  fi  

  dnl get mpi prefix
  AC_MSG_CHECKING(MPI include dir)

  AC_CACHE_VAL(adlib_cv_mpi_inc, mpiinc;adlib_cv_mpi_inc=$MPI_INC) 
  AC_MSG_RESULT($adlib_cv_mpi_inc)

  MPI_INC=$adlib_cv_mpi_inc
  AC_SUBST(MPI_INC)

  dnl get mpich exec_prefix

  AC_MSG_CHECKING(MPI lib dir)

  AC_CACHE_VAL(adlib_cv_mpi_lib, mpilib; adlib_cv_mpi_lib=$MPI_LIB) 

  AC_MSG_RESULT($adlib_cv_mpi_lib)

  MPI_LIB=$adlib_cv_mpi_lib
  AC_SUBST(MPI_LIB) 

  dnl find the actual lib name.

  AC_MSG_CHECKING(MPI lib key)
  if test -f $MPI_LIB/libmpich.a 
  then 
    MPI_LIBKEY=mpich
  else 
    MPI_LIBKEY=mpi
  fi
  AC_MSG_RESULT($MPI_LIBKEY)
  AC_SUBST(MPI_LIBKEY)  
        
  dnl tarch and tdevice from mpich only return defaults setting.
  ARCH=`echo $MPI_LIB | sed 's/^.*lib\///' | sed 's/\/.*$//'`

  dnl deciding compiler and linker

  if test "$MPICCCONFIG" = "yes" 
  then
    CXX=mpiCC
    AC_SUBST(CXX)

    LIBKEY="$LIBKEY -lm"
  else
    dnl    AC_PROG_CC
    dnl    AC_PROG_CPP
    dnl    AC_PROG_CXX

    dnl decide compiler and lib according to machine.
    LIBKEY="-l"$MPI_LIBKEY

    case $target in
      *ibm* )
        AC_CHECK_PROGS(CXX, xlC c++)        	
	if test "$CXX" = "xlC"
	then
	  LIBINLINE=
	  CPLINLINE=
	fi
        ;;

      *solaris* )
        AC_CHECK_PROGS(CXX, CC c++)
        LIBKEY="$LIBKEY -lsocket -lnsl" 
        case $CXX in
          CC*)
	    LIBINLINE=
	    CPLINLINE=+d
            ;;
        esac
        ;;

      *dec* )
        AC_CHECK_PROGS(CXX, cxx c++)
        if test $CXX = cxx 
        then
          LIBKEY="$LIBKEY -lcomplex -lm"
	  LIBINLINE=-noinline
	  CPLINLINE=-noinline
        fi
        ;;

      *mips* )
        AC_CHECK_PROGS(CXX, CC c++)
	if test "$CXX" = "CC"
	then
          LIBKEY="$LIBKEY -lm"
          case $ARCH in
            IRIX64)
              CXX="CC -64"
              ;;
            IRIXN32)
              CXX="CC -n32"
              ;;
            IRIX32)
              CXX="CC -32"
              ;;
            *)
              ;;
          esac
	fi
        ;;

      * ) 
        AC_CHECK_PROGS(CXX, c++)
        ;; 
    esac
  fi

  if test "$CXX" = "" ; then
    echo "Found no C++ compiler on $target"
    exit
  fi

  AC_SUBST(LIBKEY)
  AC_SUBST(LIBINLINE)
  AC_SUBST(CPLINLINE)  
  ;;

  chimp )
  echo Not supported 
  ;;

  sp2 )

  AC_CHECK_PROG(MPICC, mpCC, mpCC)

  if test "$MPICC" = "mpCC" 
  then 
    CXX=mpCC
  else
    echo "Please install SP2 mpCC first ..."
    exit
  fi

  MPI_INC=
  AC_SUBST(MPI_INC)

  MPI_LIB=
  AC_SUBST(MPI_LIB) 

  LIBKEY=
  AC_SUBST(LIBKEY)
  ;;

  sunhpc )

  AC_CHECK_PROG(MPIRUN, tmrun, tmrun)

  if test "$MPIRUN" = "tmrun" 
  then 
    AC_CHECK_PROGS(CXX, CC c++)
    case $CXX in
      CC*)
	LIBINLINE=
	CPLINLINE=+d
        ;;
    esac
  else
    echo "Please install Sun HPC first ..."
    exit
  fi

  MPI_INC="/opt/SUNWhpc/include"
  AC_SUBST(MPI_INC)

  MPI_LIB="/opt/SUNWhpc/lib -R/opt/SUNWhpc/lib:/opt/SUNWspro/lib"
  AC_SUBST(MPI_LIB) 

  LIBKEY="-lmpi -lrte -lnsl -lgen -lsocket -lrpcsvc -lposix4"
  AC_SUBST(LIBKEY)

  MPI_LIBKEY=mpi
  AC_MSG_RESULT($MPI_LIBKEY)
  AC_SUBST(MPI_LIBKEY)  
  ;;

  * )
  echo The package does not support $MPI MPI.
  exit
  ;;

esac

dnl decide about overloading

PERL=`which perl`
if test "$PERL" = "" 
then
  echo "perl is needed to configure the package"
  exit 1
fi
dnl AC_SUBST(PERL)

AC_MSG_CHECKING(matching template subclass arguments)

dnl Check for restrictions on matching template subclass arguments

AC_CACHE_VAL(adlib_cv_tmpl_subcls_arg,
  cat > conftest.C <<EOF   
// From section 14.8.3 of the draft ANSI standard

template<class T> struct B {};
template<class T> struct D: public B<T> {};
template<class T> void f(B<T>&);
void g(B<int>& bi, D<int>& di) 
{
  f(bi); f(di);
}
EOF

  $CXX -c conftest.C > /dev/null 2> /dev/null

  if test $? = 0 
  then
    adlib_cv_tmpl_subcls_arg=UNRESTRICTED
  else
    adlib_cv_tmpl_subcls_arg=RESTRICTED
  fi
  rm -f conftest.C conftest.o

)
AC_MSG_RESULT($adlib_cv_tmpl_subcls_arg)

if test "$adlib_cv_tmpl_subcls_arg" = "RESTRICTED"
then
  TEMPLATE_SUBCLASS_ARG_MATCHING_OK=no
else
  TEMPLATE_SUBCLASS_ARG_MATCHING_OK=yes
fi
AC_SUBST(TEMPLATE_SUBCLASS_ARG_MATCHING_OK)

AC_MSG_CHECKING(matching template const arguments)

dnl Check for restrictions on matching const template arguments

AC_CACHE_VAL(adlib_cv_tmpl_const_arg,
  cat > conftest.C <<EOF   
// DEC cxx under OSF1 V3.0 fails this

template<class T> class A {} ;
template<class T> void f(const A<T> x) {}
void g() {
  A<float> a ;
  f(a) ;
}
EOF

  $CXX -c conftest.C > /dev/null 2> /dev/null

  if test $? = 0 
  then
    adlib_cv_tmpl_const_arg=UNRESTRICTED
  else
    adlib_cv_tmpl_const_arg=RESTRICTED
  fi
  rm -f conftest.C conftest.o

)
AC_MSG_RESULT($adlib_cv_tmpl_const_arg)

if test "$adlib_cv_tmpl_const_arg" = "RESTRICTED"
then
  TEMPLATE_CONST_ARG_MATCHING_OK=no
else
  TEMPLATE_CONST_ARG_MATCHING_OK=yes
fi
AC_SUBST(TEMPLATE_CONST_ARG_MATCHING_OK)

dnl compiler option

AC_MSG_CHECKING(compiler option)

AC_ARG_ENABLE(STRONG, 
--enable-STRONG           Package building flag (default as disabled),
COMPILER_OPT=-Dstrong,
COMPILER_OPT= )

AC_MSG_RESULT($COMPILER_OPT)
AC_SUBST(COMPILER_OPT)

dnl when we want better performance

AC_MSG_CHECKING(optimize option)

AC_ARG_ENABLE(OPTIMIZE, 
--disable-OPTIMIZE        Package building flag (default as enabled),
OPTIMIZE=,
OPTIMIZE=-O )

AC_MSG_RESULT($OPTIMIZE)
AC_SUBST(OPTIMIZE)

dnl for adJava interface

JAVA=`which java | sed 's%/bin/java%%'`

dnl if JDK is available

if test "$JAVA" != "" 
then
  AC_SUBST(JAVA)

  case $target in

    *aix* )
    JOS="aix"
    ;;

    *solaris* )
    JOS="solaris"
    ;;

    *irix* )
    JOS="irix"
    ;;

    *)
    echo Java interface not tested on $target yet.
    ;;

  esac

  AC_SUBST(JOS)

#  adJava=adJava
  adJava=
else
  adJava=
fi

AC_SUBST(adJava)


dnl for pcrcFortran interface

case $target in
	
  *ibm* )

  if test $MPICC = yes 
  then
    AC_CHECK_PROG(FCL, mpxlf, mpxlf)
  fi
  if test "$FCL" = "" 
  then 
    AC_CHECK_PROG(FCL, xlf, xlf)
  fi
  if test "$FCL" = "" 
  then 
    AC_CHECK_PROG(FCL, f77, f77)
  fi
  if test "$FCL" != "" 
  then 
    FC_OPT=
  fi
  PLATFORM="-DAIX"
  ;;

  *dec* )

  AC_CHECK_PROG(FCL, f90, f90)

  if test "$FCL" = "" 
  then 
    AC_CHECK_PROG(FCL, f77, f77)
  fi
  PLATFORM="-DDEC"
  ;;

  *solaris* )

  AC_CHECK_PROG(FCL, f90, f90)
  if test "$FCL" = "f90" 
  then
    cat > conftest.f <<EOF
      SUBROUTINE FOO
      END
EOF
    $FCL -c conftest.f > /dev/null 2> /dev/null
    if test $? = 0 
    then
      FCL=f90
    else
      FCL=
    fi
  fi

  rm -f conftest.f conftest.o	

  if test "$FCL" = "" 
  then
    AC_CHECK_PROG(F77, f77, f77)
    FCL=$F77
  fi

  PLATFORM="-DSOLARIS"
  ;;

  *mips* )

  AC_CHECK_PROG(FCL, f90, f90)
  if test "$FCL" = "f90"
  then
    PLATFORM="-DMIPS"
    case $ARCH in
      IRIX64)
	FCL="f90 -64"
	;;
      IRIXN32)
	FCL="f90 -n32"
	;;
      IRIX32)
	FCL="f90 -32"
	;;
      *)
	;;
    esac
  else
    echo "No Fortran compiler found on this mips."
  fi
  ;;

  *linux* ) 

  AC_CHECK_PROG(FCL, f77, f77)
  if test "$FCL" = "f77"
  then
    PLATFORM="-DF2C"
  else
    echo "No Fortran compiler found on this linux."
  fi
  ;;
  * ) 
  echo "pcrc Fortran interface is not test on $target." 
  ;; 

esac

dnl if Fortran compiler available
if test "$FCL" != ""
then
  dnl decide tailing underscore

  AC_MSG_CHECKING(subroutine name used by Fortran compiler)
  AC_CACHE_VAL(adlib_cv_tail,   
  cat > conftest.f <<EOF
      SUBROUTINE FOO_FOO
      END
EOF

  $FCL -c conftest.f > /dev/null 2> /dev/null

  NAME=`nm conftest.o | grep "foo_foo__"`
  if test "$NAME" != "" 
  then
    adlib_cv_tail=TWOSCORE
  else
    NAME=`nm conftest.o | grep "foo_foo_"`
    if test "$NAME" != ""   
    then
      adlib_cv_tail=ONESCORE
    else
      NAME=`nm conftest.o | grep "foo_foo"`
      if test "$NAME" != ""   
      then
        adlib_cv_tail=NONSCORE
      else
        echo "FORTRAM compiler generated name not supported yet"
        exit 1 
      fi
    fi
  fi

  rm -f conftest.f conftest.o
  )

  AC_MSG_RESULT($adlib_cv_tail)
  
  if test "$adlib_cv_tail" = TWOSCORE 
  then
    SUFFIX=__
  fi

  if test "$adlib_cv_tail" = ONESCORE 
  then
    SUFFIX=_
  fi

  if test "$adlib_cv_tail" = NONSCORE 
  then
    SUFFIX=
  fi

  AC_SUBST(SUFFIX)

  dnl decide how to link C++ library from Fortran

  if test "$CXX" = "gcc"
  then
    dnl CXXLIBKEY is not a good name here!
    CXXLIBKEY=`gcc -print-libgcc-file-name | sed 's%/libgcc.a%%'`
    
  else
    if test "$CXX" = "g++"
    then
      dnl CXXLIBKEY is not a good name here!
      CXXLIBKEY=`g++ -print-libgcc-file-name | sed 's%/libgcc.a%%'`
    else
      if test "$CXX" = "c++"
      then
        dnl CXXLIBKEY is not a good name here!
        CXXLIBKEY=`c++ -print-libgcc-file-name | sed 's%/libgcc.a%%'`
      else
        case $target in

        *ibm* )
        CXXLIBKEY="-lC"
        ;;

        *solaris* )
        CXXLIBKEY="-lcxx"
        ;;

        *dec* )
        CXXLIBKEY=""
        ;;

        *mips* )
        case $ARCH in
          IRIX64)
          CXXLIBKEY="-lC -lCsup"
	    ;;
          IRIXN32)
          CXXLIBKEY="-lC -lCsup"
	    ;;
          *)
          CXXLIBKEY="-lC"
	    ;;
        esac
        ;;

        *)
        echo linking Fortran with C++ not tested on $target yet.
        ;;

        esac
      fi
    fi
  fi
  echo "CXXLIBKEY is" $CXXLIBKEY

#  pcrcFortran=pcrcFortran
  pcrcFortran=
else
  pcrcFortran=
fi

AC_SUBST(FC_OPT)
AC_SUBST(PLATFORM)
AC_SUBST(CXXLIBKEY)
AC_SUBST(pcrcFortran)

AC_OUTPUT(
Makefile 
src/Makefile 
src/include/Makefile src/kernel/Makefile src/script/Makefile 
src/pcrcFortran/Makefile
src/shpfFortran/Makefile
src/include/generate_Array
src/include/generate_transformations
src/include/generate_block
man/Makefile
man/man1/Makefile
test/Makefile 
test/kernel/Makefile
test/adJava/Makefile 
test/hpjava/Makefile 
test/pcrcFortran/Makefile
src/script/ad++:src/script/ad++.in
src/script/prun:src/script/prun.in
src/hpjava/Makefile
src/adJava/jc:src/adJava/jc.in
src/adJava/jh:src/adJava/jh.in
src/adJava/adjavac:src/adJava/adjavac.in
src/adJava/prunjava:src/adJava/prunjava.in
src/hpjava/Makefile
src/hpjava/native/Makefile
src/hpjava/native/tools/Makefile
src/hpjava/native/lib/Makefile
src/hpjava/native/tools/prunjava:src/hpjava/native/tools/prunjava.in
src/hpjava/lang/Makefile
src/hpjava/spmd/Makefile
src/hpjava/spmd/adlib/Makefile
src/pcrcFortran/pcrcf:src/pcrcFortran/pcrcf.in 
src/pcrcFortran/extname.h:src/pcrcFortran/extname.h.in
src/shpfFortran/adaptf:src/shpfFortran/adaptf.in
src/shpfFortran/extname.h:src/shpfFortran/extname.h.in
src/shpfFortran/farg.f:src/shpfFortran/farg.f.in
test/kernel/runtests:test/kernel/runtests.in
test/adJava/runtests:test/adJava/runtests.in
test/hpjava/runtests:test/hpjava/runtests.in
test/pcrcFortran/runtests:test/pcrcFortran/runtests.in
test/shpfFortran/runtests:test/shpfFortran/runtests.in
)

chmod a+x src/include/generate_Array
chmod a+x src/include/generate_transformations
chmod a+x src/include/generate_block
chmod a+x src/script/ad++
chmod a+x src/script/prun

#if test "$adJava" != ""
#then
  chmod a+x src/adJava/jc
  chmod a+x src/adJava/jh
  chmod a+x src/adJava/adjavac
  chmod a+x src/adJava/prunjava
  chmod a+x src/hpjava/native/tools/prunjava
#fi

#if [[ "$pcrcFortran" != "" ]]
#then
  chmod a+x src/pcrcFortran/pcrcf
#fi

#fi
#if [[ "$shpfFortran" != "" ]]
#then
  chmod a+x src/shpfFortran/adaptf
#fi

chmod a+x test/kernel/runtests
chmod a+x test/adJava/runtests
chmod a+x test/hpjava/runtests
chmod a+x test/pcrcFortran/runtests
chmod a+x test/shpfFortran/runtests

echo Done!
