#! /bin/sh

#*********************************************************************#
#                                                                     #
#                           Objective Caml                            #
#                                                                     #
#            Xavier Leroy, projet Cristal, INRIA Rocquencourt         #
#                                                                     #
#  Copyright 1995 Institut National de Recherche en Informatique et   #
#  Automatique.  Distributed only by permission.                      #
#                                                                     #
#*********************************************************************#

# $Id: configure,v 1.29 1996/10/24 16:14:23 xleroy Exp $

bindir=/usr/local/bin
libdir=/usr/local/lib/ocaml
mandir=/usr/local/man/man1
manext=1
host_type=unknown
cc=''
cclibs=''
x11_include_dir=''
x11_lib_dir=''

# Parse command-line arguments

while : ; do
  case "$1" in
    "") break;;
    -bindir|--bindir) bindir=$2;;
    -libdir|--libdir) libdir=$2;;
    -mandir|--mandir) mandir=$2
                      manext=`echo $mandir | sed -e 's/^.*\(.\)$/\1/'`;;
    -host*|--host*) host_type=$2;;
    -cc*) cc="$2";;
    -lib*) cclibs="$2 ";;
    -x11include*|--x11include*) x11_include_dir=$2;;
    -x11lib*|--x11lib*) x11_lib_dir=$2;;
    *) echo "Unknown option \"$1\"." 1>&2; exit 2;;
  esac
  shift
  shift
done

# Generate the files

cd config/auto-aux
rm -f s.h m.h Makefile
touch s.h m.h Makefile

# Where to install

echo "BINDIR=$bindir" >> Makefile
echo "LIBDIR=$libdir" >> Makefile
echo "MANDIR=$mandir" >> Makefile
echo "MANEXT=$manext" >> Makefile

# Determine the system type

if test "$host_type" = "unknown"; then
  if host_type=`./config.guess`; then :; else
    echo "Cannot guess host type"
    echo "You must specify one with the -host option"
    exit 2
  fi
fi
if host=`./config.sub $host_type`; then :; else
  echo "Please specify the correct host type with the -host option"
  exit 2
fi
echo "Configuring for a $host ..."

# Do we have gcc?

if test -z "$cc"; then
  if sh ./searchpath gcc; then
    echo "gcc found"
    cc=gcc
  else
    cc=cc
  fi
fi

export cc cclibs

# Is cc/gcc the GNU C compiler?

if sh runtest gcctest.c; then
  echo "We're using the GNU C compiler"
  gcc=yes
else
  gcc=no
fi

# Check the sizes of data types

echo "Checking the sizes of integers and pointers..."
set `sh runtest sizes.c`
case "$1,$2,$3" in
  4,4,4) echo "OK, this is a regular 32 bit architecture."
         echo "#undef ARCH_SIXTYFOUR" >> m.h;;
  4,8,8) echo "Wow! A 64 bit architecture!"
         echo "#define ARCH_SIXTYFOUR" >> m.h;;
  8,*,*) echo "Wow! A 64 bit architecture!"
         echo "Unfortunately, Objective Caml does not handle the case"
         echo "sizeof(int) = 8."
         echo "Objective Caml won't run on this architecture."
         exit 2;;
  *,4,8) echo "Wow! A 64 bit architecture!"
         echo "Unfortunately, Objective Caml cannot work in the case"
         echo "sizeof(long) != sizeof(long *)."
         echo "Objective Caml won't run on this architecture."
         exit 2;;
  *,*,*) echo "This architecture seems to be neither 32 bits nor 64 bits."
         echo "Objective Caml won't run on this architecture."
         exit 2;;
      *) echo "Unable to compile the test program."
         echo "Make sure the C compiler $cc is properly installed."
         exit 2;;
esac

# Determine endianness

sh runtest endian.c
case $? in
  0) echo "This is a big-endian architecture."
     echo "#define ARCH_BIG_ENDIAN" >> m.h;;
  1) echo "This is a little-endian architecture."
     echo "#undef ARCH_BIG_ENDIAN" >> m.h;;
  2) echo "This architecture seems to be neither big endian nor little endian."
     echo "Objective Caml won't run on this architecture."
     exit 2;;
  *) echo "Something went wrong during endianness determination."
     echo "You'll have to figure out endianness yourself"
     echo "(option ARCH_BIG_ENDIAN in m.h).";;
esac

# Determine alignment constraints

sh runtest dblalign.c
case $? in
  0) echo "Doubles can be word-aligned."
     echo "#undef ARCH_ALIGN_DOUBLE" >> m.h;;
  1) echo "Doubles must be doubleword-aligned."
     echo "#define ARCH_ALIGN_DOUBLE" >> m.h;;
  *) echo "Something went wrong during alignment determination for doubles."
     echo "I'm going to assume this architecture has alignment constraints over doubles."
     echo "That's a safe bet: Objective Caml will work even if"
     echo "this architecture has actually no alignment constraints."
     echo "#define ARCH_ALIGN_DOUBLE" >> m.h;;
esac

# Configure the bytecode compiler

bytecc="$cc"
bytecccompopts=""
bytecclinkopts=""
if test $gcc = yes; then
  bytecccompopts="-fno-defer-pop -Wall"
  case "$host" in
    *-*-nextstep*)
      bytecccompopts="$bytecccompopts -U__GNUC__ -D_POSIX_SOURCE";;
    alpha-*-osf*)
      bytecclinkopts="-Xlinker -taso";;
  esac
else
  $bytecc=cc
fi

echo "BYTECC=$bytecc" >> Makefile
echo "BYTECCCOMPOPTS=$bytecccompopts" >> Makefile
echo "BYTECCLINKOPTS=$bytecclinkopts" >> Makefile

# Configure the native-code compiler

arch=none
model=default
system=unknown

case "$host" in
  alpha-*-osf*)                 arch=alpha;;
  sparc-*-sunos4.*)             arch=sparc; system=sunos;;
  sparc-*-solaris2.*)           arch=sparc; system=solaris;;
  sparc-*-*bsd*)                arch=sparc; system=bsd;;
  i[3456]86-*-linuxaout)        arch=i386; system=linux_aout;;
  i[3456]86-*-linuxoldld)       arch=i386; system=linux_aout;;
  i[3456]86-*-linux)            arch=i386; system=linux_elf;;
  i[3456]86-*-*bsd*)            arch=i386; system=bsd;;
  i[3456]86-*-nextstep*)        arch=i386; system=nextstep;;
  i[3456]86-*-solaris*)         arch=i386; system=solaris;;
  mips-*-ultrix*)               arch=mips;;
  hppa1.1-*-hpux*)              arch=hppa; system=hpux;;
  hppa1.1-*-nextstep*)          arch=hppa; system=nextstep;;
  rs6000-*-aix*)                arch=power; model=rs6000; system=aix;;
  powerpc-*-aix*)               arch=power; model=ppc; system=aix;;
  powerpc-*-linux*)             arch=power; model=ppc; system=elf;;
  m68k-*-sunos*)                arch=m68k; system=sunos;;
esac

case "$arch" in
  alpha|mips) nativecc=cc;;
  *) nativecc="$bytecc";;
esac

case "$arch,$nativecc,$system" in
  alpha,cc,*)   nativecccompopts=-std1;;
  mips,cc,*)    nativecccompopts=-std;;
  *,*,nextstep) nativecccompopts="-Wall -D_POSIX_SOURCE";;
  *,gcc,*)      nativecccompopts=-Wall;;
  *)            nativecccompopts='';;
esac

nativecclinkopts=''

asflags=''
aspp='$(AS)'
asppflags=''

case "$arch,$model,$system" in
  alpha,*,*)        asflags='-O2'; asppflags="$asflags";;
  mips,*,*)         asflags='-O2'; asppflags="$asflags";;
  sparc,*,bsd)      aspp='gcc'; asppflags='-c -DSYS_$(SYSTEM)';;
  sparc,*,*)        asppflags='-P -DSYS_$(SYSTEM)';;
  i386,*,solaris)   asppflags='-P -DSYS_$(SYSTEM)';;
  i386,*,*)         aspp='gcc'; asppflags='-c -DSYS_$(SYSTEM)';;
  hppa,*,*)         aspp="$cc"; asppflags='-c -DSYS_$(SYSTEM)';;
  power,rs6000,aix) asflags='-u -m pwr -w'; asppflags="$asflags";;
  power,ppc,aix)    asflags='-u -m ppc -w'; asppflags="$asflags";;
  power,*,elf)      aspp='gcc'; asppflags='-c';;
esac

echo "ARCH=$arch" >> Makefile
echo "MODEL=$model" >> Makefile
echo "SYSTEM=$system" >> Makefile
echo "NATIVECC=$nativecc" >> Makefile
echo "NATIVECCCOMPOPTS=$nativecccompopts" >> Makefile
echo "NATIVECCLINKOPTS=$nativecclinkopts" >> Makefile
echo "ASFLAGS=$asflags" >> Makefile
echo "ASPP=$aspp" >> Makefile
echo "ASPPFLAGS=$asppflags" >> Makefile

# Checking how to invoke cpp
# We don't need cpp anymore
#if sh ./searchpath cpp; then
#  cpp="cpp -P"
#elif test -f /lib/cpp; then
#  cpp="/lib/cpp -P"
#elif test -f /usr/ccs/lib/cpp; then
#  cpp="/usr/ccs/lib/cpp -P"
#else
#  cpp="not found"
#fi
#
#echo "CPP=$cpp" >> Makefile
#
#echo "How to invoke the C preprocessor: $cpp"
#
#if test "$cpp" = "not found"; then
#  echo "(Please edit the generated config/Makefile to set CPP correctly)"
#fi

# Where is ranlib?

if sh ./searchpath ranlib; then
  echo "ranlib found"
  echo "RANLIB=ranlib" >> Makefile
else
  echo "ranlib not used"
  echo "RANLIB=ar -rs" >> Makefile
fi

# Do #! scripts work?

if (SHELL=/bin/sh; export SHELL; ./sharpbang > /dev/null); then
  echo "#! appears to work in shell scripts"
  if test `echo $bindir/ocamlrun | wc -c` -gt 32; then
    echo "We won't use it, though, because the path"
    echo "      $bindir/ocamlrun"
    echo "is too long (more than 32 characters -- some kernels don't support this)"
    echo "SHARPBANGSCRIPTS=false" >> Makefile
  else
    echo "SHARPBANGSCRIPTS=true" >> Makefile
  fi
else
  echo "No support for #! in shell scripts"
  echo "SHARPBANGSCRIPTS=false" >> Makefile
fi

# This is obviously a Unix system

echo '#define OCAML_OS_TYPE "Unix"' >> s.h

# Find a good byte move function

if sh runtest -Dcopy=memmove -Dreverse bytecopy.c; then
  echo "Function \"memmove\" is provided and handles overlapping moves correctly."
  echo "#define HAS_MEMMOVE" >> s.h
fi
if sh runtest -Dcopy=bcopy bytecopy.c; then
  echo "Function \"bcopy\" is provided and handles overlapping moves correctly."
  echo "#define HAS_BCOPY" >> s.h
fi

# Check the semantics of signal handlers

if sh hasgot sigaction sigprocmask; then
  echo "POSIX signal handling found."
  echo "#define POSIX_SIGNALS" >> s.h
else
  if sh runtest signals.c; then
    echo "Signals have the BSD semantics."
    echo "#define BSD_SIGNALS" >> s.h
  else
    echo "Signals have the System V semantics."
  fi
  if sh hasgot sigsetmask; then
    echo "sigsetmask() found"
    echo "#define HAS_SIGSETMASK" >> s.h
  fi
fi

# For the sys module

if sh hasgot strerror; then
  echo "strerror() found."
  echo "#define HAS_STRERROR" >> s.h
fi

# For the terminfo module

if sh hasgot -lcurses -ltermcap tgetent tgetstr tgetnum tputs; then
  echo "termcap functions found."
  echo "#define HAS_TERMCAP" >> s.h
  cclibs="${cclibs}-lcurses -ltermcap"
fi

# Configuration for the libraries

otherlibraries="unix str num dynlink"

# For the Unix library

if sh hasgot socket socketpair bind listen accept connect; then
  echo "You have BSD sockets."
  echo "#define HAS_SOCKETS" >> s.h
elif sh hasgot -lnsl -lsocket socket socketpair bind listen accept connect; then
  echo "You have BSD sockets (with the additional libraries -lnsl -lsocket)"
  cclibs="$cclibs -lnsl -lsocket"
  echo "#define HAS_SOCKETS" >> s.h
fi

if sh hasgot -i unistd.h; then
  echo "unistd.h found."
  echo "#define HAS_UNISTD" >> s.h
fi

if sh hasgot -i dirent.h; then
  echo "dirent.h found."
  echo "#define HAS_DIRENT" >> s.h
fi

if sh hasgot rewinddir; then
  echo "rewinddir() found."
  echo "#define HAS_REWINDDIR" >> s.h
fi

if sh hasgot lockf; then
  echo "lockf() found."
  echo "#define HAS_LOCKF" >> s.h
fi

if sh hasgot mkfifo; then
  echo "mkfifo() found."
  echo "#define HAS_MKFIFO" >> s.h
fi

if sh hasgot getcwd; then
  echo "getcwd() found."
  echo "#define HAS_GETCWD" >> s.h
fi

if sh hasgot getwd; then
  echo "getwd() found."
  echo "#define HAS_GETWD" >> s.h
fi

if sh hasgot getpriority setpriority; then
  echo "getpriority() found."
  echo "#define HAS_GETPRIORITY" >> s.h
fi

if sh hasgot -i utime.h && sh hasgot utime; then
  echo "utime() found."
  echo "#define HAS_UTIME" >> s.h
fi

if sh hasgot utimes; then
  echo "utimes() found."
  echo "#define HAS_UTIMES" >> s.h
fi

if sh hasgot dup2; then
  echo "dup2() found."
  echo "#define HAS_DUP2" >> s.h
fi

if sh hasgot fchmod fchown; then
  echo "fchmod() found."
  echo "#define HAS_FCHMOD" >> s.h
fi

if sh hasgot truncate ftruncate; then
  echo "truncate() found."
  echo "#define HAS_TRUNCATE" >> s.h
fi

if sh hasgot select; then
  echo "select() found."
  echo "#define HAS_SELECT" >> s.h
  has_select=yes
fi

if sh hasgot -i sys/select.h; then
  echo "sys/select.h found."
  echo "#define HAS_SYS_SELECT_H" >> s.h
fi

if sh hasgot symlink readlink lstat;  then
  echo "symlink() found."
  echo "#define HAS_SYMLINK" >> s.h
fi

if sh hasgot waitpid;  then
  echo "waitpid() found."
  echo "#define HAS_WAITPID" >> s.h
  has_wait=yes
fi

if sh hasgot wait4;  then
  echo "wait4() found."
  echo "#define HAS_WAIT4" >> s.h
  has_wait=yes
fi

if sh hasgot -i sys/param.h && sh runtest getgroups.c; then
  echo "getgroups() found."
  echo "#define HAS_GETGROUPS" >> s.h
fi

if sh hasgot -i termios.h && 
   sh hasgot tcgetattr tcsetattr tcsendbreak tcflush tcflow; then
  echo "POSIX termios found."
  echo "#define HAS_TERMIOS" >> s.h
fi

# Async I/O under OSF1 3.x are so buggy that the test program hangs...
testasyncio=true
if test -f /usr/bin/uname; then
  case "`uname -s -r`" in
    "OSF1 V3."*) testasyncio=false;;
  esac
fi
if $testasyncio && sh runtest async_io.c; then
  echo "Asynchronous I/O are supported."
  echo "#define HAS_ASYNC_IO" >> s.h
fi

if sh hasgot setitimer; then
  echo "setitimer() found."
  echo "#define HAS_SETITIMER" >> s.h
  has_setitimer="yes"
fi

if sh hasgot gethostname; then
  echo "gethostname() found."
  echo "#define HAS_GETHOSTNAME" >> s.h
fi

if sh hasgot -i sys/utsname.h && sh hasgot uname; then
  echo "uname() found."
  echo "#define HAS_UNAME" >> s.h
fi

if sh hasgot gettimeofday; then
  echo "gettimeofday() found."
  echo "#define HAS_GETTIMEOFDAY" >> s.h
  has_gettimeofday="yes"
fi

if sh hasgot mktime; then
  echo "mktime() found."
  echo "#define HAS_MKTIME" >> s.h
fi

# Determine the target architecture for the "num" library

case "$host" in
  mips*) bignum_arch=mips;;
  alpha*) bignum_arch=alpha;;
  i960*) bignum_arch=i960;;
  sparc-*-sunos*) bignum_arch=supersparc;;
  sparc-*-solaris*) bignum_arch=supersparc-solaris;;
  sparc-*-*bsd*) bignum_arch=sparc;;
  m68k-*-sunos*) bignum_arch=68K;;
  *) bignum_arch=C
esac

echo "BIGNUM_ARCH=$bignum_arch" >> Makefile

# Determine if the threads library is supported

if test "$has_select" = "yes" \
&& test "$has_setitimer" = "yes" \
&& test "$has_gettimeofday" = "yes" \
&& test "$has_wait" = "yes"; then
  echo "Threads library supported."
  otherlibraries="$otherlibraries threads"
else
  echo "No threads library (missing system calls)"
fi

# Determine the location of X include files and libraries

x11_include="not found"
x11_link="not found"

for dir in $x11_include_dir \
  /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include \
  /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 \
  /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include \
  /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 \
  /usr/X11/include /usr/include/X11 /usr/local/X11/include \
  /usr/local/include/X11 /usr/X386/include /usr/x386/include \
  /usr/XFree86/include/X11 /usr/include /usr/local/include \
  /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include \
  /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include \
  /opt/X11R6/include /opt/X11R5/include
do
  if test -f $dir/X11/X.h; then
    x11_include=$dir
    break
  fi
done

for dir in $x11_lib_dir \
  /usr/X11R6/lib /usr/X11R5/lib /usr/X11R4/lib \
  /usr/lib/X11R6 /usr/lib/X11R5 /usr/lib/X11R4 \
  /usr/local/X11R6/lib /usr/local/X11R5/lib /usr/local/X11R4/lib \
  /usr/local/lib/X11R6 /usr/local/lib/X11R5 /usr/local/lib/X11R4 \
  /usr/X11/lib /usr/lib/X11 /usr/local/X11/lib \
  /usr/local/lib/X11 /usr/X386/lib /usr/x386/lib \
  /usr/XFree86/lib/X11 /usr/lib /usr/local/lib \
  /usr/unsupported/lib /usr/athena/lib /usr/local/x11r5/lib \
  /usr/lpp/Xamples/lib /usr/openwin/lib /usr/openwin/share/lib \
  /opt/X11R6/lib /opt/X11R5/lib
do
  if test -f $dir/libX11.a || \
     test -f $dir/libX11.so || \
     test -f $dir/libX11.sa; then
    x11_link="-cclib -L$dir -cclib -lX11"
    break
  fi
done


if test "$x11_include" = "not found" || test "$x11_link" = "not found"
then
  echo "X11 not found, the \"graph\" library will not be supported."
else
  echo "X11_INCLUDES=$x11_include" >> Makefile
  echo "X11_LINK=$x11_link" >> Makefile
  echo "Location of X11 include files: $x11_include"
  echo "Options for linking with X11: $x11_link"
  otherlibraries="$otherlibraries graph"
fi

# See if we can compile the dbm library

if sh hasgot -i ndbm.h
then
  echo "NDBM library found."
  otherlibraries="$otherlibraries dbm"
else
  echo "NDBM not found, the \"dbm\" library will not be supported."
fi

# Finish generated files

cclibs="$cclibs -lm"
echo "CCLIBS=$cclibs" >> Makefile
echo "OTHERLIBRARIES=$otherlibraries" >> Makefile

rm -f tst hasgot.c
rm -f ../m.h ../s.h ../Makefile
mv m.h s.h Makefile ..

# Print a summary

echo
echo "** Configuration summary **"
echo
echo "Directories where Objective Caml will be installed:"
echo "	binaries.................. $bindir"
echo "	standard library.......... $libdir"
echo "	manual pages.............. $mandir (with extension .$manext)"

echo "Configuration for the bytecode compiler:"
echo "	C compiler used........... $bytecc"
echo "	options for compiling..... $bytecccompopts"
echo "	options for linking....... $bytecclinkopts $cclibs"

echo "Configuration for the native-code compiler:"
if test "$arch" = "none"; then
  echo "	(not supported on this platform)"
else
  if test "$model" = "default"; then
    echo "	hardware architecture..... $arch"
  else
    echo "	hardware architecture..... $arch ($model)"
  fi
  if test "$system" = "unknown"; then : ; else
  echo "	OS variant................ $system"
  fi
  echo "	C compiler used........... $nativecc"
  echo "	options for compiling..... $nativecccompopts"
  echo "	options for linking....... $nativecclinkopts $cclibs"
  echo "        assembler ................ \$(AS) $asflags"
  echo "        preprocessed assembler ... $aspp $asppflags"
fi

echo "Configuration for the external libraries:"
echo "	libraries supported....... $otherlibraries"

echo "The \"num\" library:"
echo "	target architecture ...... $bignum_arch"

if test "$x11_include" != "not found" && test "$x11_lib" != "not found"; then
echo "The \"graph\" library:"
echo "	options for compiling .... -I$x11_include"
echo "	options for linking ...... $x11_link"
fi

