# Copyright (c) 1999, 2000, 2001, 2002, 2003 by Red Hat, Inc. All rights reserved.
# 
# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
# OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
# 
# Permission is hereby granted to use or copy this program
# for any purpose,  provided the above notices are retained on all copies.
# Permission to modify the code and to distribute modified code is granted,
# provided the above notices are retained, and a notice that the code was
# modified is included with the above copyright notice.
#
# Original author: Tom Tromey

dnl Process this file with autoconf to produce configure.

AC_INIT(gcj_mlc.c)

# This works around the fact that libtool configuration may change LD
# for this particular configuration, but some shells, instead of
# keeping the changes in LD private, export them just because LD is
# exported.
ORIGINAL_LD_FOR_MULTILIBS=$LD

dnl Can't be done in GC_CONFIGURE because that confuses automake. 
AC_CONFIG_AUX_DIR(.)

GC_CONFIGURE(.)

AM_PROG_LIBTOOL

dnl We use these options to decide which functions to include.
AC_ARG_WITH(target-subdir,
[  --with-target-subdir=SUBDIR
                          configuring with a cross compiler])
AC_ARG_WITH(cross-host,
[  --with-cross-host=HOST  configuring with a cross compiler])

AM_MAINTAINER_MODE
# automake wants to see AC_EXEEXT.  But we don't need it.  And having
# it is actually a problem, because the compiler we're passed can't
# necessarily do a full link.  So we fool automake here.
if false; then
  # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
  # to nothing, so nothing would remain between `then' and `fi' if it
  # were not for the `:' below.
  :
  AC_EXEEXT
fi

AC_MSG_CHECKING([for thread model used by GCC])
THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
if test -z "$THREADS"; then
   THREADS=no
fi
AC_MSG_RESULT([$THREADS])

AC_ARG_ENABLE(parallel-mark,
[  --enable-parallel-mark	parallelize marking and free list construction],
   [case "$THREADS" in
      no | none | single)
	AC_MSG_ERROR([Parallel mark requires --enable-threads=x spec])
	;;
    esac]
)

INCLUDES=-I${srcdir}/include
THREADLIBS=
case "$THREADS" in
 no | none | single)
    THREADS=none
    ;;
 posix | pthreads)
    THREADS=posix
    THREADLIBS=-lpthread
    case "$host" in
     x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux*)
	AC_DEFINE(GC_LINUX_THREADS)
	AC_DEFINE(_REENTRANT)
        if test "${enable_parallel_mark}"; then
	  AC_DEFINE(PARALLEL_MARK)
	fi
	AC_DEFINE(THREAD_LOCAL_ALLOC)
	;;
     *-*-linux*)
	AC_DEFINE(GC_LINUX_THREADS)
	AC_DEFINE(_REENTRANT)
	;;
     *-*-hpux*)
	AC_MSG_WARN("Only HP/UX 11 threads are supported.")
	AC_DEFINE(GC_HPUX_THREADS)
	AC_DEFINE(_POSIX_C_SOURCE,199506L)
	if test "${enable_parallel_mark}" = yes; then
	  AC_DEFINE(PARALLEL_MARK)
	fi
	AC_DEFINE(THREAD_LOCAL_ALLOC)
	THREADLIBS="-lpthread -lrt"
	;;
     *-*-freebsd*)
	AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.")
	AC_DEFINE(GC_FREEBSD_THREADS)
	INCLUDES="$INCLUDES -pthread"
	THREADLIBS=-pthread
      	;;
     *-*-solaris*)
	AC_DEFINE(GC_SOLARIS_THREADS)
	AC_DEFINE(GC_SOLARIS_PTHREADS)
	;;
     *-*-irix*)
	AC_DEFINE(GC_IRIX_THREADS)
	;;
     *-*-cygwin*)
	THREADLIBS=
	;;
    esac
    ;;
 win32)
    AC_DEFINE(GC_WIN32_THREADS)
    AC_DEFINE(NO_GETENV)
    ;;
 decosf1 | irix | mach | os2 | solaris | dce | vxworks)
    AC_MSG_ERROR(thread package $THREADS not yet supported)
    ;;
 *)
    AC_MSG_ERROR($THREADS is an unknown thread package)
    ;;
esac
AC_SUBST(THREADLIBS)

AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
AC_SUBST(EXTRA_TEST_LIBS)

target_all=libgcjgc.la
AC_SUBST(target_all)
AC_SUBST(target_alias)

dnl If the target is an eCos system, use the appropriate eCos
dnl I/O routines.
dnl FIXME: this should not be a local option but a global target
dnl system; at present there is no eCos target.
TARGET_ECOS="no"
AC_ARG_WITH(ecos,
[  --with-ecos             enable runtime eCos target support],
TARGET_ECOS="$with_ecos"
)

addobjs=
CXXINCLUDES=
case "$TARGET_ECOS" in
   no)
      ;;
   *)
      AC_DEFINE(ECOS)
      CXXINCLUDES="-I${TARGET_ECOS}/include"
      addobjs="$addobjs ecos.lo"
      ;;
esac
AC_SUBST(CXX)

AC_SUBST(INCLUDES)
AC_SUBST(CXXINCLUDES)

machdep=
case "$host" in
 alpha*-*-openbsd*)
    machdep="alpha_mach_dep.lo"
    if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
       AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is disabled)
       AM_DISABLE_SHARED
    fi
    ;;
 alpha*-*-*)
    machdep="alpha_mach_dep.lo"
    ;;
 i?86-*-solaris2.[[89]]*)
    AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED)
    ;;
 mipstx39-*-elf*)
    machdep="mips_ultrix_mach_dep.lo"
    AC_DEFINE(STACKBASE, __stackbase)
    AC_DEFINE(DATASTART_IS_ETEXT)
    ;;
 mips-dec-ultrix*)
    machdep="mips_ultrix_mach-dep.lo"
    ;;
 mips-*-*)
    machdep="mips_sgi_mach_dep.lo"
    AC_DEFINE(NO_EXECUTE_PERMISSION)
    ;;
 sparc-sun-solaris2.3*)
    machdep="sparc_mach_dep.lo"
    AC_DEFINE(SUNOS53_SHARED_LIB)
    ;;
 sparc-sun-solaris2.*)
    machdep="sparc_mach_dep.lo"
    ;;
 ia64-*-*)
    machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
    ;;
esac
if test x"$machdep" = x; then
   machdep="mach_dep.lo"
fi
addobjs="$addobjs $machdep"
AC_SUBST(addobjs)

dnl As of 4.13a2, the collector will not properly work on Solaris when
dnl built with gcc and -O.  So we remove -O in the appropriate case.
case "$host" in
 sparc-sun-solaris2*)
    if test "$GCC" = yes; then
       new_CFLAGS=
       for i in $CFLAGS; do
	  case "$i" in
	   -O*)
	      ;;
	   *)
	      new_CFLAGS="$new_CFLAGS $i"
	      ;;
	  esac
       done
       CFLAGS="$new_CFLAGS"
    fi
    ;;
esac

dnl We need to override the top-level CFLAGS.  This is how we do it.
MY_CFLAGS="$CFLAGS"
AC_SUBST(MY_CFLAGS)

dnl Include defines that have become de facto standard.
dnl ALL_INTERIOR_POINTERS can be overridden in startup code.
AC_DEFINE(SILENT)
AC_DEFINE(NO_SIGNALS)
AC_DEFINE(NO_EXECUTE_PERMISSION)
AC_DEFINE(ALL_INTERIOR_POINTERS)

dnl By default, make the library as general as possible.
AC_DEFINE(JAVA_FINALIZATION)
AC_DEFINE(GC_GCJ_SUPPORT)
AC_DEFINE(ATOMIC_UNCOLLECTABLE)

dnl This is something of a hack.  When cross-compiling we turn off
dnl some functionality. These is only correct when targetting an
dnl embedded system.  FIXME.
if test -n "${with_cross_host}"; then
   AC_DEFINE(NO_SIGSET)
   AC_DEFINE(NO_DEBUGGING)
fi

AC_ARG_ENABLE(full-debug,
[  --enable-full-debug	include full support for pointer backtracing etc.],
[ if test "$enable_full_debug" = "yes"; then
    AC_MSG_WARN("Must define GC_DEBUG and use debug alloc. in clients.")
    AC_DEFINE(KEEP_BACK_PTRS)
    AC_DEFINE(DBG_HDRS_ALL)
    case $host in
      ia64-*-linux* )
	AC_DEFINE(MAKE_BACK_GRAPH)
      ;;
      x86-*-linux* | i586-*-linux* | i686-*-linux* )
	AC_DEFINE(MAKE_BACK_GRAPH)
	AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
	AC_DEFINE(SAVE_CALL_COUNT, 8)
      ;;
    esac ]
  fi)

if test -n "$with_cross_host" &&
   test x"$with_cross_host" != x"no"; then
  toolexecdir='$(exec_prefix)/$(target_alias)'
  toolexeclibdir='$(toolexecdir)/lib'
else
  toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
  toolexeclibdir='$(libdir)'
fi
toolexeclibdir=$toolexeclibdir/`$CC -print-multi-os-directory`
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)

if test "${multilib}" = "yes"; then
  multilib_arg="--enable-multilib"
else
  multilib_arg=
fi

AC_OUTPUT(Makefile include/Makefile, [
dnl Put all the -D options in a file.
echo "$DEFS" > boehm-cflags

if test -n "$CONFIG_FILES"; then
  LD="${ORIGINAL_LD_FOR_MULTILIBS}"
  ac_file=Makefile . ${gc_basedir}/../config-ml.in
fi],
srcdir=${srcdir}
host=${host}
target=${target}
with_multisubdir=${with_multisubdir}
ac_configure_args="${multilib_arg} ${ac_configure_args}"
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
gc_basedir=${gc_basedir}
CC="${CC}"
DEFS="$DEFS"
)
