#! /bin/sh
# configure script for LoopTools
# note: has nothing to do with GNU autoconf
# last modified 7 Mar 12 by Thomas Hahn


LC_ALL=C
export LC_ALL

test=test$$
trap "rm -fr $test*" 0 1 2 3 15

if (echo "test\c"; echo 1,2,3) | grep c > /dev/null ; then
  if (echo -n test; echo 1,2,3) | grep n > /dev/null ; then
    echo_n=
    echo_c='
'
  else
    echo_n=-n
    echo_c=
  fi
else
  echo_n=
  echo_c='\c'
fi


findprog()
{
  echo $echo_n "looking for $1... $echo_c" 1>&2
  shift
  test -n "$CONF_TARGET" && for prog in "$@" ; do
    full="`which \"$CONF_TARGET-$prog\" 2> /dev/null`"
    test -x "$full" && {
      echo $full 1>&2
      echo $CONF_TARGET-$prog
      return 0
    }
  done
  for prog in "$@" ; do
    full="`which \"$prog\" 2> /dev/null`"
    test -x "$full" && {
      echo $full 1>&2
      echo $prog
      return 0
    }
  done
  echo "no $@ in your path" 1>&2
  return 1
}


getldflags()
{
  # Mma 5.1's mcc needs -lpthread for static linking
  ldflags="$LDFLAGS -lpthread"

  while read line ; do
    set -- `echo $line | tr ':,()' '    '`
    case $1 in
    */collect2$CONF_EXE | */ld$CONF_EXE | ld$CONF_EXE) ;;
    *) continue ;;
    esac
    while test $# -gt 1 ; do
      shift
      case $1 in
      *.o | -lc | -lgcc*)
        ;;
      -l* | -L* | *.a)
        ldflags="$ldflags $1" ;;
      -Bstatic | -Bdynamic | *.ld)
        ldflags="$ldflags -Wl,$1" ;;
      /*)
        ldflags="$ldflags -L$1" ;;
      -rpath*)
        ldflags="$ldflags -Wl,$1,$2"
        shift ;;
      -dynamic-linker)
        shift ;;
      esac
    done
  done

  echo $ldflags
}


CONF_SRC=`dirname $0`/src
CONF_OS=`uname -s`
CONF_MACH=`uname -m`
CONF_DEFPREFIX="$CONF_MACH-$CONF_OS"
CONF_PREFIX="$CONF_DEFPREFIX"
test "$CONF_PREFIX" = x86_64-Linux && CONF_LIBDIRSUFFIX=64
CONF_TARGET=
CONF_STATIC=
CONF_STATIC_EXT=
CONF_DEBUG=
CONF_BITS=
CONF_EXE=
case "$CONF_OS" in
CYG*) CONF_EXE=.exe ;;
esac

for arg in "$@" ; do
  case "$arg" in
  --prefix=*)
	CONF_PREFIX=`expr "$arg" : ".*--prefix=\(.*\)"` ;;
  --host=*)
	CONF_TARGET=`expr "$arg" : ".*--host=\(.*\)"` ;;
  --static)
	CONF_STATIC="-static"
	case "$CONF_OS" in
# Apple discourages static linking, see
# http://developer.apple.com/qa/qa2001/qa1118.html,
# so we make only libgcc static.  For a static libg2c do:
# sudo chmod 000 /usr/local/lib/libg2c.dylib
	Darwin | CYG*)
		CONF_STATIC_EXT=$CONF_STATIC
		CONF_STATIC= ;;
	esac ;;
  --debug)
	CONF_DEBUG="-O0 -g" ;;
  --32)
	CONF_BITS=32 ;;
  --64)
	CONF_BITS=64 ;;
  --help)
	cat << _EOF_ 1>&2
$0 configures LoopTools, i.e. determines or guesses the
compiler and flags and writes out a makefile.

$0 understands the following options:

--prefix=DIR        use DIR as installation directory,

--host=HOST         target host triplet, e.g. i386-pc-linux,

--static            link the executables statically,

--debug             compile without optimization,

--32                force 32-bit compilation,

--64                force 64-bit compilation.

_EOF_
	exit 1 ;;
  -*)
	echo "Warning: $arg is not a valid option." 1>&2 ;;
  *=*)
	eval `echo $arg\" | sed 's/=/="/'` ;;
  *)
	echo "Warning: $arg is not a valid argument." 1>&2 ;;
  esac
done

CONF_M=${CONF_BITS:+-m$CONF_BITS}


## look for some programs

CONF_MAKE=`findprog make $MAKE gmake Make make` || exit 1

CONF_CC=`findprog gcc $CC gcc` || exit 1

CONF_CXX=`findprog g++ $CXX g++` || exit 1

CONF_FC=`findprog f77 $FC pgf77 ifort xlf gfortran g77 g95 f77 f90 fort77` || exit 1

CONF_AR=`findprog ar $AR ar`

CONF_RANLIB=`findprog ranlib $RANLIB ranlib`

CONF_NM=`findprog nm $NM nm`

CONF_DLLTOOL=`findprog dlltool $DLLTOOL dlltool`

CONF_DEF="-D"

case "`$CONF_FC --version -c 2>&1`" in
*G95*)
  CONF_FFLAGS="$FFLAGS -O0 -g -ffixed-line-length-132 -freal-loops $CONF_M $CONF_STATIC ${CONF_DEBUG:+-Wall}" ;;
*GNU*)
  CONF_FFLAGS="$FFLAGS -O0 -g -ffixed-line-length-none $CONF_M $CONF_STATIC ${CONF_DEBUG:+-Wall}"
  case "$CONF_FC" in
  *gfortran*)
	CONF_FFLAGS="$CONF_FFLAGS ${CONF_DEBUG:+-Wtabs -ffpe-trap=invalid,overflow,zero} -fno-range-check -ff2c ${CONF_STATIC_EXT:+-static-libgfortran -static-libgcc}" ;;
  esac ;;
*)
  CONF_FFLAGS="${FFLAGS-default}"
  test "$CONF_FFLAGS" = default && case "$CONF_FC$CONF_MACH" in
  *pgf*)
	CONF_FFLAGS="${CONF_DEBUG:--O3 -g} ${CONF_DEBUG:+-Ktrap=fp} -Mextend -Minform=inform -g77libs ${CONF_STATIC:+-Bstatic} $CONF_M" ;;
  *ifort*)
	CONF_FFLAGS="${CONF_DEBUG:--O3 -g} -extend_source -warn truncated_source $CONF_STATIC ${CONF_STATIC_EXT:+-static-intel} $CONF_M" ;;
  *alpha)
	CONF_FFLAGS="-old_f77 ${CONF_DEBUG:--O3 -g3} ${CONF_DEBUG:+-fpe0} -extend_source -warn truncated_source ${CONF_STATIC:+-non_shared}" ;;
  *sun* | *sparc*)
	CONF_FFLAGS="${CONF_DEBUG:--O3 -g} ${CONF_DEBUG:+-ftrap=common} -e ${CONF_STATIC:+-Bstatic}" ;;
  *hp*)
	CONF_FFLAGS="${CONF_DEBUG:--O2 -g} ${CONF_DEBUG:++FPVZO} +es +U77 ${CONF_STATIC:+-Wl,-noshared}" ;;
  *xlf*)
	CONF_FFLAGS="${CONF_DEBUG:--O2 -g} ${CONF_DEBUG:+-qflttrap=enable:invalid:overflow:zerodivide} -qfixed=132 -qmaxmem=-1 -qextname"
	CONF_DEF="-WF,-D" ;;
  *)
	CONF_FFLAGS="${CONF_DEBUG:--O -g}" ;;
  esac ;;
esac


## find the Fortran libraries

echo $echo_n "extracting the Fortran libraries... $echo_c" 1>&2

rm -fr $test*

cat > $test.f << _EOF_
	program dontpanic
	print *, "Hi"
	end
_EOF_

CONF_LDFLAGS=`$CONF_FC $CONF_FFLAGS -v -o $test $test.f 2>&1 | getldflags`

echo $CONF_LDFLAGS 1>&2


test -z "$CONF_BITS" && case "$CONF_MACH" in
*86*)	CONF_BITS=32
	case "`file $test`" in
	*x86?64*) CONF_BITS=64 ;;
	esac
	CONF_M="-m$CONF_BITS" ;;
esac

CONF_CFLAGS="${CFLAGS-${CONF_DEBUG:--O3 -g} -fomit-frame-pointer -ffast-math -Wall} $CONF_M $CONF_STATIC ${CONF_STATIC_EXT:+-static-libgcc}"

CONF_CXXFLAGS="${CXXFLAGS-${CONF_DEBUG:--O3 -g} -fomit-frame-pointer -ffast-math -Wall} $CONF_M $CONF_STATIC ${CONF_STATIC_EXT:+-static-libstdc++ -static-libgcc}"


## does f77 support REAL*16?

echo $echo_n "does $CONF_FC support REAL*16... $echo_c" 1>&2

rm -fr $test*

cat > $test.f << _EOF_
	program test
	real*16 r
	r = qext(1d0)
	end
_EOF_

$CONF_FC $CONF_FFLAGS $test.f -o $test$CONF_EXE > /dev/null 2>&1

if test -x $test$CONF_EXE ; then
  echo "yes" 1>&2
  CONF_QUAD=1
else
  echo "no" 1>&2
  CONF_QUAD=0
fi


## does Fortran need externals for U77 routines?

echo $echo_n "does $CONF_FC need externals for U77 routines... $echo_c" 1>&2

rm -fr $test*

cat > $test.f << _EOF_
	program test
	implicit none
	print *, iargc(), len_trim("Hi")
	end
_EOF_

if $CONF_FC $CONF_FFLAGS -c $test.f > /dev/null 2>&1 ; then
  echo "no" 1>&2
  CONF_U77EXT=0
else
  echo "yes" 1>&2
  CONF_U77EXT=1
fi


## does Fortran append underscores to symbols?

echo $echo_n "does $CONF_FC append underscores... $echo_c" 1>&2

rm -fr $test*

cat > $test.f << _EOF_
	subroutine uscore
	end
_EOF_

cat > $test-c.c << _EOF_
int main() {
  void uscore_();
  uscore_();
  return 0;
}
_EOF_

$CONF_FC $CONF_FFLAGS -c $test.f > /dev/null 2>&1

if $CONF_CC $CONF_CFLAGS -o $test-c $test-c.c $test.o $CONF_LDFLAGS > /dev/null 2>&1 ; then
  echo "yes" 1>&2
  CONF_NOUNDERSCORE=0
else
  echo "no" 1>&2
  CONF_NOUNDERSCORE=1
fi


## are we on a big-endian machine?

echo $echo_n "are we big-endian... $echo_c" 1>&2

rm -fr $test*

cat > $test.c << _EOF_
#include <stdio.h>
int main() {
  union { int i; char c; } u;
  u.i = 1;
  u.c = 0;
  printf("%d\n", u.i != 0);
}
_EOF_

$CONF_CC $CONF_CFLAGS -o $test$CONF_EXE $test.c > /dev/null 2>&1

if test "`./$test$CONF_EXE`" = 1 ; then
  echo "yes" 1>&2
  CONF_BIGENDIAN=1
else
  echo "no" 1>&2
  CONF_BIGENDIAN=0
fi


## can we do MathLink compilations

echo $echo_n "do we have MathLink... $echo_c" 1>&2

rm -fr $test*

cat > $test.tm << _EOF_
:Begin:
:Function: test
:Pattern: Test[i_Integer]
:Arguments: {i}
:ArgumentTypes: {Integer}
:ReturnType: Integer
:End:

#include "mathlink.h"

static int test(const int i) {
  return i + 1;
}

int main(int argc, char **argv) {
  return MLMain(argc, argv);
}
_EOF_

: ${MCCDEBUG=0}
test "$MCCDEBUG" -ge 1 && set -x

CONF_MCC=${MCC:-mcc}
CONF_MCFLAGS="${CONF_STATIC:+-st} ${CONF_STATIC_EXT:+-st} ${CONF_BITS:+-b$CONF_BITS}"

NM="$CONF_NM" DLLTOOL="$CONF_DLLTOOL" \
CC="$CONF_SRC/tools/fcc.in" REALCC="$CONF_CC $CONF_CFLAGS" \
CXX="$CONF_SRC/tools/f++.in" REALCXX="$CONF_CXX $CONF_CXXFLAGS" \
PATH="$PATH:$CONF_SRC/tools" \
  "$CONF_MCC" $CONF_MCFLAGS -o $test$CONF_EXE $test.tm > /dev/null 2>&1

test "$MCCDEBUG" -ge 1 && {
  cat $test.tm
  cp $test.tm test.tm
  file $test$CONF_EXE
  set +x
}

if test -x $test$CONF_EXE ; then
  echo "yes" 1>&2
  CONF_ML=1
else
  echo "no" 1>&2
  CONF_ML=0
fi


case "$CONF_OS" in
Linux*)	cpus=`grep -c processor /proc/cpuinfo` ;;
Darwin)	cpus=`system_profiler SPHardwareDataType | \
	  awk '/Total Number .f Cores:/ { print $5 }'` ;;
esac
test "${cpus:-1}" -gt 1 && CONF_PARALLEL="-j $cpus"


echo "creating makefile" 1>&2

cat - `dirname $0`/makefile.in > makefile << _EOF_
# --- variables defined by configure ---

SRC = $CONF_SRC
PREFIX = $CONF_PREFIX
LIBDIRSUFFIX = $CONF_LIBDIRSUFFIX

EXE = $CONF_EXE
DEF = $CONF_DEF
NOUNDERSCORE = $CONF_NOUNDERSCORE

FC = $CONF_FC
FFLAGS = $CONF_FFLAGS \$(DEF)QUAD=$CONF_QUAD \$(DEF)U77EXT=$CONF_U77EXT

CC = $CONF_CC
CFLAGS = $CONF_CFLAGS -DNOUNDERSCORE=\$(NOUNDERSCORE) -DBIGENDIAN=$CONF_BIGENDIAN

CXX = $CONF_CXX
CXXFLAGS = $CONF_CXXFLAGS

ML = $CONF_ML
MCC = $CONF_MCC
MCFLAGS = $CONF_MCFLAGS

LDFLAGS = $CONF_LDFLAGS $CONF_M

AR = $CONF_AR
RANLIB = $CONF_RANLIB
NM = $CONF_NM
DLLTOOL = $CONF_DLLTOOL

PARALLEL = $CONF_PARALLEL

# --- end defs by configure ---


_EOF_


echo "" 1>&2
echo "now you must run $CONF_MAKE" 1>&2
echo "" 1>&2

exit 0

