#!/bin/sh
# configure script for zlib. This script is needed only if
# you wish to build a shared library and your system supports them,
# of if you need special compiler, flags or install directory.
# Otherwise, you can just use directly "make test; make install"
#
# To create a shared library, use "configure --shared"; by default a static
# library is created. If the primitive shared library support provided here
# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
#
# To impose specific compiler or flags or install directory, use for example:
#    prefix=$HOME CC=cc CFLAGS="-O4" ./configure
# or for csh/tcsh users:
#    (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
# LDSHARED is the command to be used to create a shared library

# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
# If you have problems, try without defining CC and CFLAGS before reporting
# an error.

LIBS=libz.a
SHAREDLIB=libz.so
VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
AR=${AR-"ar rc"}
RANLIB=${RANLIB-"ranlib"}
prefix=${prefix-/usr/local}
exec_prefix=${exec_prefix-$prefix}
shared_ext='.so'
shared=0
gcc=0
old_cc="$CC"
old_cflags="$CFLAGS"

case "$1" in
  -s* | --s*) shared=1; shift;;
  -h* | --h*) echo 'syntax: configure [ --shared ]'; exit 0;;
esac

test=ztest$$
cat > $test.c <<EOF
extern int getchar();
int hello() {return getchar();}
EOF

test -z "$CC" && echo Checking for gcc...
cc=${CC-gcc}
cflags=${CFLAGS-"-O3"}
case "$cc" in
  *gcc*) gcc=1;;
esac

if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
  CC="$cc"
  SFLAGS=${CFLAGS-"-fPIC -O3"}
  CFLAGS="$cflags"
  case `(uname -s || echo unknown) 2>/dev/null` in
  Linux | linux) LDSHARED=${LDSHARED-"gcc -shared -Wl,-soname,libz.so.1"};;
  *)             LDSHARED=${LDSHARED-"gcc -shared"};;
  esac
else
  # find system name and corresponding cc options
  CC=${CC-cc}
  case `(uname -sr || echo unknown) 2>/dev/null` in
  SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
             CFLAGS=${CFLAGS-"-fast -xcg89"}
	     LDSHARED=${LDSHARED-"cc -G"};;
  SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
	     CFLAGS=${CFLAGS-"-O2"}
	     LDSHARED=${LDSHARED-"ld"};;
  IRIX*)     SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
	     CFLAGS=${CFLAGS-"-ansi -O2"}
	     LDSHARED=${LDSHARED-"cc -shared"};;
  QNX*)      SFLAGS=${CFLAGS-"-4 -O"}
             CFLAGS=${CFLAGS-"-4 -O"}
	     LDSHARED=${LDSHARED-"cc"}
             RANLIB=${RANLIB-"true"}
             AR="cc -A";;
  SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
	     CFLAGS=${CFLAGS-"-O3"}
	     LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
  HP-UX*)    SFLAGS=${CFLAGS-"-O +z"}
	     CFLAGS=${CFLAGS-"-O"}
#	     LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
	     LDSHARED=${LDSHARED-"ld -b"}
	     shared_ext='.sl'
	     SHAREDLIB='libz.sl';;
  UNIX_System_V\ 4.2.0) 
	     SFLAGS=${CFLAGS-"-KPIC -O"}
	     CFLAGS=${CFLAGS-"-O"}
	     LDSHARED=${LDSHARED-"cc -G"};;
  # send working options for other systems to support@gzip.org
  *)         SFLAGS=${CFLAGS-"-O"}
	     CFLAGS=${CFLAGS-"-O"}
	     LDSHARED=${LDSHARED-"cc -shared"};;
  esac
fi

if test $shared -eq 1; then
  echo Checking for shared library support...
  # we must test in two steps (cc then ld), required at least on SunOS 4.x
  if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
     test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
    CFLAGS="$SFLAGS"
    LIBS="$SHAREDLIB.$VER"
    echo Building shared library $SHAREDLIB.$VER with $CC.
  elif test -z "$old_cc" -a -z "$old_cflags"; then
    echo No shared library suppport.
    shared=0;
  else
    echo 'No shared library suppport; try without defining CC and CFLAGS'
    shared=0;
  fi
fi
if test $shared -eq 0; then
  LDSHARED="$CC"
  echo Building static library $LIBS version $VER with $CC.
fi

if test -f /usr/include/unistd.h; then
  CFLAGS="$CFLAGS -DHAVE_UNISTD_H"
fi

if test ! -f /usr/include/errno.h; then
  CFLAGS="$CFLAGS -DNO_ERRNO_H"
fi

cat > $test.c <<EOF
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
caddr_t hello() {
  return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); 
}
EOF
if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
  CFLAGS="$CFLAGS -DUSE_MMAP"
  echo Checking for mmap support... Yes.
else
  echo Checking for mmap support... No.
fi

rm -f $test.[co] $test$shared_ext

# udpate Makefile
sed < Makefile.in "
/^CC *=/s%=.*%=$CC%
/^CFLAGS *=/s%=.*%=$CFLAGS%
/^LDSHARED *=/s%=.*%=$LDSHARED%
/^LIBS *=/s%=.*%=$LIBS%
/^SHAREDLIB *=/s%=.*%=$SHAREDLIB%
/^AR *=/s%=.*%=$AR%
/^RANLIB *=/s%=.*%=$RANLIB%
/^VER *=/s%=.*%=$VER%
/^prefix *=/s%=.*%=$prefix%
/^exec_prefix *=/s%=.*%=$exec_prefix%
" > Makefile
