# Process this file with autoconf to produce a configure script.
AC_INIT(vg_clientmalloc.c)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(valgrind, 1.0pre4)

AM_MAINTAINER_MODE

# Checks for programs.
CFLAGS=""

AC_PROG_LN_S
AC_PROG_CC
AC_PROG_CPP
AC_PROG_RANLIB

# Check for the compiler support
if test "${GCC}" != "yes" ; then
   AC_MSG_ERROR([Valgrind relies on GCC to be compiled])
fi

# some older automake's don't have it so try something on our own
ifdef([AM_PROG_AS],[AM_PROG_AS],
[
AS="${CC}"
AC_SUBST(AS)

ASFLAGS=""
AC_SUBST(ASFLAGS)
])

# This variable will collect the individual suppression files
# depending on the results of autoconf

DEFAULT_SUPP=""


# We don't want gcc 2.7
AC_MSG_CHECKING([for a supported version of gcc])

gcc_version=`${CC} --version | head -n 1`

case "${gcc_version}" in
     gcc-2.7.*)
	AC_MSG_RESULT([no (${gcc_version})])
	AC_MSG_ERROR([please use a recent (>= gcc-2.95) version of gcc])
	;;

     *)
	AC_MSG_RESULT([ok (${gcc_version})])
	;;
esac


# Checks for the platform
AC_CANONICAL_HOST

AC_MSG_CHECKING([for a supported CPU])

case "${host_cpu}" in
     i?86) 
	AC_MSG_RESULT([ok (${host_cpu})])
        ;;

     *) 
	AC_MSG_RESULT([no (${host_cpu})])
	AC_MSG_ERROR([Valgrind is ix86 specific. Sorry])
	;;
esac

AC_MSG_CHECKING([for a supported OS])

case "${host_os}" in
     *linux*) 
	AC_MSG_RESULT([ok (${host_os})])
        ;;

     *) 
	AC_MSG_RESULT([no (${host_os})])
	AC_MSG_ERROR([Valgrind is Linux specific. Sorry])
	;;
esac


# Ok, this is linux. Check the kernel version
AC_MSG_CHECKING([for the kernel version])

kernel=`uname -r`

case "${kernel}" in
     2.4.*) 
	    AC_MSG_RESULT([2.4 family (${kernel})])
	    AC_DEFINE(KERNEL_2_4)
	    ;;

     2.2.*) 
	    AC_MSG_RESULT([2.2 family (${kernel})])
	    AC_DEFINE(KERNEL_2_2)
	    ;;

     *) 
	    AC_MSG_RESULT([unsupported (${kernel})])
	    AC_MSG_ERROR([Valgrind works on kernels 2.2 and 2.4])
	    ;;
esac

AC_SUBST(DEFAULT_SUPP)


# Ok, this is linux. Check the kernel version
AC_MSG_CHECKING([the glibc version])

glibc=""

AC_EGREP_CPP([GLIBC_21], [
#include <features.h>
#ifdef __GNU_LIBRARY__
 #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 1)
  GLIBC_21
 #endif
#endif
],
glibc="2.1")

AC_EGREP_CPP([GLIBC_22], [
#include <features.h>
#ifdef __GNU_LIBRARY__
 #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2)
  GLIBC_22
 #endif
#endif
],
glibc="2.2")

case "${glibc}" in
     2.1)
	AC_MSG_RESULT(2.1 family)
	AC_DEFINE(GLIBC_2_1)
	DEFAULT_SUPP="${DEFAULT_SUPP} glibc-2.1.supp"
	;;

     2.2)
	AC_MSG_RESULT(2.2 family)
	AC_DEFINE(GLIBC_2_2)
	DEFAULT_SUPP="${DEFAULT_SUPP} glibc-2.2.supp"
	;;

     *)
	AC_MSG_RESULT(unsupported version)
	AC_MSG_ERROR([Valgrind requires the glibc version 2.1 or 2.2])
	;;
esac

# APIs introduced in recent glibc versions

AC_MSG_CHECKING([whether sched_param has a sched_priority member])
AC_CACHE_VAL(vg_have_sched_priority,
[
AC_TRY_COMPILE([#include <pthread.h>],[
struct sched_param p; p.sched_priority=1;],
vg_have_sched_priority=yes,
vg_have_sched_priority=no)
])
AC_MSG_RESULT($vg_have_sched_priority)
if test "$vg_have_sched_priority" = yes; then
AC_DEFINE(HAVE_SCHED_PRIORITY)
fi

AC_MSG_CHECKING([whether nfds_t is defined])
AC_CACHE_VAL(vg_have_nfds_t,
[
AC_TRY_COMPILE([#include <sys/poll.h>],[
nfds_t i=0;],
vg_have_nfds_t=yes,
vg_have_nfds_t=no)
])
AC_MSG_RESULT($vg_have_nfds_t)
if test "$vg_have_nfds_t" = yes; then
AC_DEFINE(HAVE_NFDS_T)
fi

# try to detect the XFree version
# JRS 2002-06-17: this is completely bogus because it
# detects the server version, whereas we need to know the 
# client library version.  So what follows is hacked to
# use all the X supp files regardless of what is detected.
# This is really stoooopid and should be fixed properly.

AC_PATH_X

if test "${no_x}" != 'yes' ; then

   AC_MSG_CHECKING([XFree version])

   cat<<EOF > conftest.c
#include <X11/Xlib.h>

int main (int argc, char * argv [])
{
  Display * display = XOpenDisplay (NULL);

  if (display) {
    printf ("%s version=%d\n", ServerVendor (display), VendorRelease (display));
  }

  return 0;
}
EOF

   ${CC} -o conftest conftest.c -I${x_includes} -L${x_libraries} -lX11 >&5 2>&1

   if test "$?" != 0 ; then
     AC_MSG_RESULT([cannot compile test program])
   else
     xfree=`./conftest`

     case "${xfree}" in
	*XFree86*) 
	   ;;

	*) AC_MSG_RESULT([not a XFree86 server])
	   ;;
     esac

     case "${xfree}" in

	*version=4*) 
	   AC_MSG_RESULT([XFree 4.x family])
	   AC_DEFINE(XFREE_4)
	   DEFAULT_SUPP="${DEFAULT_SUPP} xfree-4.supp"
	   # haaaaaaack!
	   DEFAULT_SUPP="${DEFAULT_SUPP} xfree-3.supp"
	   ;;

	*version=3*) 
	   AC_MSG_RESULT([XFree 3.x family])
	   AC_DEFINE(XFREE_3)
	   DEFAULT_SUPP="${DEFAULT_SUPP} xfree-3.supp"
	   # haaaaaaack!
	   DEFAULT_SUPP="${DEFAULT_SUPP} xfree-4.supp"
	   ;;

	*) AC_MSG_RESULT([unknown XFree86 server (${xfree})])
	   # haaaaaaack!
	   DEFAULT_SUPP="${DEFAULT_SUPP} xfree-3.supp"
	   DEFAULT_SUPP="${DEFAULT_SUPP} xfree-4.supp"
	   ;;
     esac
   fi

   rm -f conftest conftest.c
fi

# does this compiler support -mpreferred-stack-boundary=2 ?
AC_MSG_CHECKING([if gcc accepts -mpreferred-stack-boundary])

CFLAGS="-mpreferred-stack-boundary=2"

AC_TRY_COMPILE(, [

int main () { return 0 ; }

],
[
PREFERRED_STACK_BOUNDARY="-mpreferred-stack-boundary=2"
AC_MSG_RESULT([$PREFERRED_STACK_BOUNDARY])
], [
PREFERRED_STACK_BOUNDARY=""
AC_MSG_RESULT([no])
])

AC_SUBST(PREFERRED_STACK_BOUNDARY)



# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h malloc.h stdlib.h string.h sys/socket.h sys/statfs.h sys/time.h termios.h unistd.h utime.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_HEADER_TIME

# Checks for library functions.
AC_FUNC_MEMCMP
AC_FUNC_MMAP
AC_TYPE_SIGNAL

AC_CHECK_FUNCS([floor memchr memset mkdir strchr strdup strpbrk strrchr strstr])

AC_OUTPUT(
   vg_annotate
   valgrind
   valgrind.spec
   cachegrind
   Makefile 
   docs/Makefile 
   tests/Makefile 
   demangle/Makefile)

cat<<EOF

Using the following suppressions by default: 

      ${DEFAULT_SUPP}
EOF

cat<<EOF > default.supp
# This is a generated file, composed of the following suppression rules:
#
#      ${DEFAULT_SUPP}
#

EOF

for file in ${DEFAULT_SUPP} ; do
    cat ${srcdir}/$file >> default.supp
done
