dnl
dnl Copyright (C) 2001, Sun Microsystems, Inc
dnl Copyright (C) 2001, The University of Queensland
dnl
dnl See the file "LICENSE.TERMS" for information on usage and
dnl redistribution of this file, and for a DISCLAIMER OF ALL
dnl WARRANTIES.
dnl
dnl File: configure.in
dnl Process this file with autoconf to produce a configure script.
dnl $Revision: 1.27 $
dnl
dnl 18 May 01 - Nathan: first attempt at looking for java & jni files 
dnl 21 May 01 - Nathan: started change over to formal --target form, old
dnl               --with-target left temporarily for backwards compatibility
dnl 18 Jul 01 - Mike: Changed "test -e" to "test -r" for Solaris portability
dnl 24 Jul 01 - Brian: Added support for ARM target using ARM VPO backend.
dnl 22 Aug 01 - Brian: Changes required for move of emu, tools, emuDebug files
dnl              to the inside-Sun dynamic repository.
dnl 23 Aug 01 - Brian: Don't link with VPO libraries unless target=SPARC or ARM.
dnl 24 Oct 01 - Mike: machine/pent -> machine/pentium; pent.rules -> pentium

AC_INIT(NJMCdecoder.cc)
AC_CONFIG_HEADER(include/config.h)

AC_CANONICAL_SYSTEM

dnl Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_CPP
AC_PROG_RANLIB
AC_PROG_MAKE_SET
AC_PROG_INSTALL
AC_PROG_YACC
AC_PROG_LEX
AC_PATH_PROG( AR, ar )
AC_PATH_PROG( BISONPP, bison++ )
AC_PATH_PROG( FLEXPP, flex++ )
AC_PATH_PROG( JAVAC, javac )
AC_SUBST( BISONPP )
AC_SUBST( FLEXPP )
AC_SUBST( JAVAC )

dnl Look for jni.h in `dirname $JAVAC`/../include
JNI_PATH="`dirname $JAVAC`/../include"
AC_MSG_CHECKING( [for JNI headers in $JNI_PATH] )
if test -r $JNI_PATH/jni.h; then
   CPPFLAGS="$CPPFLAGS -I$JNI_PATH"
   AC_MSG_RESULT( "yes" )
else
   AC_MSG_RESULT( "no" )
   AC_CHECK_HEADERS( jni.h )
fi

dnl Look for jni_md.h in JNI_PATH/solaris or JNI_PATH/linux
AC_MSG_CHECKING( [for jni_md.h] )
if test -r $JNI_PATH/solaris; then
   CPPFLAGS="$CPPFLAGS -I$JNI_PATH/solaris"
   AC_MSG_RESULT( "yes" )
elif test -r $JNI_PATH/linux; then
   CPPFLAGS="$CPPFLAGS -I$JNI_PATH/linux"
   AC_MSG_RESULT( "yes" )
else
   AC_MSG_RESULT( "no" )
   AC_CHECK_HEADERS( jni_md.h )
fi

# Backend tools

if test -z "${TARGET_PREFIX}"; then
   if test "${target}" = "${host}"; then
      TARGET_PREFIX=""
   elif test "${target}" = "m68k-palmos-coff" -a -x /usr/local/m68k-palmos/bin; then
      # magic for eng.sun
      TARGET_PREFIX="/usr/local/m68k-palmos/bin/"
   else
      TARGET_PREFIX="${target}-"
   fi
fi

AC_DEFUN(AC_PATH_BINUTIL, [
   for i in $2; do
      if test -f ${TARGET_PREFIX}$i; then
          AC_MSG_CHECKING([for ${TARGET_PREFIX}$i])
          $1=${TARGET_PREFIX}$i
	  AC_MSG_RESULT( [yes] )
      else
         AC_PATH_PROG( $1, ${TARGET_PREFIX}$i )
      fi
      if test -n "$$1"; then
         break
      fi
   done
   if test -z "$$1"; then
      # not found, try to fall back on basic versions
      AC_PATH_PROGS( $1, $2 )
   fi
] )

dnl -------------------
AC_PATH_PROG( JASMIN, jasmin )
AC_PATH_PROG( HEAD, head )
AC_PATH_BINUTIL( AS, as gas )
AC_PATH_BINUTIL( OBJCOPY, objcopy )
AC_PATH_BINUTIL( TARGET_CC, gcc cc )
AC_DEFINE_UNQUOTED( TARGET_CC_PATH, "$TARGET_CC", [Target C compiler command line] )
AC_DEFINE_UNQUOTED( TARGET_AS_PATH, "$AS", [Target assembler prog] )
AC_DEFINE_UNQUOTED( TARGET_OBJCOPY_PATH, "$OBJCOPY", [Target objcopy prog] )
AC_DEFINE_UNQUOTED( TARGET_JASMIN_PATH, "$JASMIN", [Path to jasmin] )
AC_DEFINE_UNQUOTED( TARGET_HEAD_PATH, "$HEAD", [Path to head] )

dnl -------------------
AC_MSG_CHECKING( [if using GNU ld] )
TARGET_GNU_LD=no
if ${TARGET_CC} -v 2>&1 </dev/null | egrep "gcc" 1>&5; then
   TARGET_GCC=yes
   TARGET_LD=`${TARGET_CC} -print-prog-name=ld`
else
   TARGET_LD=ld
fi
if ${TARGET_LD} -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
   TARGET_GNU_LD=yes
   AC_DEFINE( TARGET_GNU_LD, 1, [Target uses GNU ld] )
fi
AC_MSG_RESULT( $TARGET_GNU_LD )


if test "$target" = "m68k-palmos-coff"; then
  AC_PATH_BINUTIL( OBJRES, obj-res )
  AC_PATH_PROGS( BUILDPRC, build-prc )
  AC_DEFINE_UNQUOTED( TARGET_OBJRES_PATH, "$OBJRES", [PalmOS object translator] )
  AC_DEFINE_UNQUOTED( TARGET_BUILDPRC_PATH, "$BUILDPRC", [PalmOS PRC generator] )
fi

dnl Checks for libraries.       
AC_CHECK_LIB(elf, elf_begin)
AC_CHECK_LIB(stdc++, main)
AC_CHECK_LIB(socket, socket)

dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
AC_CHECK_HEADERS(fcntl.h malloc.h sys/time.h unistd.h byteswap.h)
AC_CHECK_HEADERS(libelf.h libelf/libelf.h, break)
AC_CHECK_HEADERS(link.h sys/link.h, break)
AC_CHECK_HEADERS(elf.h sys/elf_SPARC.h sys/auxv.h)

AC_MSG_CHECKING( [for auxilliary vector struct] )
AUXV_T='not found'
AC_EGREP_HEADER( Elf32_auxv_t, elf.h, [ AUXV_T='Elf32_auxv_t' ])
AC_EGREP_HEADER( auxv_t, sys/auxv.h, [ AUXV_T='auxv_t' ])
AC_MSG_RESULT( $AUXV_T )
if test "$AUXV_T" != 'not found'; then
  AC_DEFINE_UNQUOTED( AUXV_T, $AUXV_T, [Auxiliary vector structure] )
fi
AC_MSG_CHECKING( [for Elf32_Versym] )
HAVE_ELF32_VERSYM=no
AC_EGREP_HEADER( Elf32_Versym, elf.h, [ HAVE_ELF32_VERSYM=yes ])
AC_EGREP_HEADER( Elf32_Versym, sys/link.h, [ HAVE_ELF32_VERSYM=yes ])
AC_MSG_RESULT( $HAVE_ELF32_VERSYM )
if test "$HAVE_ELF32_VERSYM" = yes; then
  AC_DEFINE( HAVE_ELF32_VERSYM, 1, [Elf32_Versym] )
fi

dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_BIGENDIAN
AC_C_INLINE
AC_C_LONG_DOUBLE
AC_TYPE_SIZE_T

AC_CHECK_SIZEOF(char,1)
AC_CHECK_SIZEOF(short,2)
AC_CHECK_SIZEOF(int,4)
AC_CHECK_SIZEOF(long,4)
AC_CHECK_SIZEOF(long long,8)
AC_CHECK_SIZEOF(float,4)
AC_CHECK_SIZEOF(double,8)
AC_CHECK_SIZEOF(long double,16)


dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_FUNC_MMAP
AC_FUNC_UTIME_NULL

dnl Now the options...
AC_CHECK_FUNCS(mkdir rmdir socket strdup strspn strstr strtol uname getexecname)

AC_ARG_ENABLE(uqbt-only, [  --enable-uqbt-only      only build the uqbt translator], 
              [ TOOLS=0 ], [ TOOLS=1 ] )
AC_ARG_ENABLE(dynamic, [  --enable-dynamic        build the dynamic tools], 
              [ DYNAMIC=1 ], [ DYNAMIC=0 ] )
AC_ARG_ENABLE(remote, [  --enable-remote         don't try to regenerate source files],
              [ REMOTE=1 ], [ REMOTE=0 ] )
#AC_ARG_ENABLE(direct, [  --enable-direct         direct mapping of sections to their original
#			  locations, ie. no relocation. ],
#              [ DIRECT=1 ], [ DIRECT=0 ] )
AC_ARG_ENABLE(debug,  [  --enable-debug[=what]   enable debugging suport, 'what' is one of
                          ANALYSIS, DECODER, CSR, SWITCH, SS_SIMP, SSLPARSER ], [
   if test "$enableval" = "yes"; then
      DEBUGS="-DDEBUG"
   else 
      DEBUGS="-DDEBUG_"`echo $enableval | sed -e 's/,/ -DDEBUG_/g'`
   fi
] )
AC_ARG_WITH(  source, [  --with-source=<arch>    translate from <arch> architecture,
                          one of sparc, pentium, mc68k, hppa, 286],
              [ SRC=$withval ] )
AC_ARG_WITH(  target, [  --with-target=<arch>    translate to <arch> architecture,
                          either arm or one of above architectures],
              [ TGT=$withval ] )

AC_SUBST(TOOLS)
AC_SUBST(DYNAMIC)
AC_SUBST(REMOTE)
AC_SUBST(DEBUGS)

if test "$SRC" = ""; then
  AC_MSG_ERROR( [Source architecture must be given with --with-source] )
fi

case "$SRC" in
  sparc|SPARC) 
	SRC=SPARC; 
	src_rules=$srcdir/machine/sparc/sparc.rules;;
  pent|pentium|PENT|386|win32) 
	SRC=PENT; 
	src_rules=$srcdir/machine/pentium/pentium.rules;;
  mc68k|palm) 
	SRC=MC68K; 
	src_rules=$srcdir/machine/mc68k/mc68k.rules;;
  hppa|HPPA) 
	SRC=HPPA; 
	src_rules=$srcdir/machine/hppa/hppa.rules;;
  286) 
	SRC=286; 
	src_rules=$srcdir/machine/286/286.rules;;
  *) AC_MSG_ERROR( [Unrecognized source architecture \"$SRC\"] ) ;;
esac

if test -z "$TGT"; then
  case $target_cpu in
    sparc) TGT=SPARC;;
    i686|i586|i486|i386) TGT=PENT;;
    hppa*) TGT=HPPA;;
    m68*|mc68*) TGT=MC68K;;
    i286)  TGT=i286;;
    arm)   TGT=ARM;;
    *) TGT=SPARC;;
  esac
else
  case "$TGT" in
    sparc|SPARC) TGT=SPARC;;
    pent|pentium|PENT|386|win32) TGT=PENT;;
    mc68k|palm) TGT=MC68K;;
    hppa|HPPA) TGT=HPPA;;
    286) TGT=286;;
    arm) TGT=ARM;;
    *) AC_MSG_ERROR( [Unrecognized target architecture \"$TGT\"] ) ;;
  esac
fi

SRC_LTR=""
case "$SRC" in 
  SPARC) SRC_LTR=s;;
  PENT)  SRC_LTR=p;;
  HPPA)  SRC_LTR=h;;
  MC68K) SRC_LTR=m;;
  286)   SRC_LTR=2;;
esac

TGT_LTR=""
case "$TGT" in
  SPARC) TGT_LTR=s;;
  PENT)  TGT_LTR=p;;
  HPPA)  TGT_LTR=h;;
  MC68K) TGT_LTR=m;;
  286)   TGT_LTR=2;;
  ARM)   TGT_LTR=a;;
esac

if test "$TGT" = "ARM"; then
  AC_PATH_PROG( VPO, vpo-arm )
  VPOBACKEND="backend/vpo/ARMVPOBackend.o"
  VPOLIBS="-L${srcdir}/optimizer/vpo/arm -lvpoi-arm -lasm-arm"
elif test "$TGT" = "SPARC"; then
  AC_PATH_PROG( VPO, vpo )
  VPOBACKEND="backend/vpo/SparcIRTLToVPOBackend.o"
  VPOLIBS="-L${srcdir}/optimizer/vpo/sparc -lvpoi-sparc -lasm-sparc"
else
  VPO=""
  VPOBACKEND=""
  VPOLIBS=""
fi
AC_DEFINE_UNQUOTED( TARGET_VPO_PATH, "$VPO", [Path to VPO optimizer] )
AC_SUBST(VPOBACKEND)
AC_SUBST(VPOLIBS)

TRANSLATOR=uqbt$SRC_LTR$TGT_LTR
AC_MSG_RESULT( [Generating $TRANSLATOR for $SRC => $TGT] )
AC_SUBST(TRANSLATOR)

extra_rules=/dev/null;
INSTRM=0
# *** Instrumentation (and so dynamic) support ***
AC_ARG_WITH( instrm, [  --with-instrm=<dir>     add instrumentation to emulator using files in <dir> ],
             [ 
	if test -d $withval; then
  		INSTRM=1
  		INSTR_DIR=$withval
  		if test -r $INSTR_DIR/make.rules; then
  			extra_rules=$INSTR_DIR/make.rules;
  		fi
	else
  		AC_MSG_ERROR( [Instrumentation file directory "$withval" not readable] )
	fi
] )
AC_SUBST(INSTR_DIR)
AC_SUBST(INSTRM)
AC_SUBST_FILE(extra_rules)
			  
# *** Backends ***
BACKEND_C=yes; BACKEND_JVM=yes; BACKEND_PO=yes; BACKEND_VPO=no;
if test "$TGT" = "ARM"; then
  # we want the ARM VPO backend
  BACKEND_PO=no
elif test "$TGT" != "SPARC"; then
  BACKEND_PO=no
  BACKEND_VPO=no
fi
dnl AC_ARG_ENABLE(c,      [  --disable-c             disable C backend ],
dnl               [ BACKEND_C=$enableval ] )
AC_ARG_ENABLE(jvm,    [  --disable-jvm           disable JVM backend ],
              [ BACKEND_JVM=$enableval ] )
AC_ARG_ENABLE(po,     [  --disable-po            disable post-optimizer backend (sparc only) ],
              [ BACKEND_PO=$enableval ] )
AC_ARG_ENABLE(vpo,    [  --disable-vpo           disable vpo backend ],
              [ if test x$enableval != xyes ; then 
                   BACKEND_VPO=no
                else 
                   BACKEND_VPO=yes
                fi
              ])

if test "$TGT" = "ARM"; then
  if test "$BACKEND_VPO" != "yes"; then
    AC_MSG_ERROR( [ARM target requires VPO backend] )
  fi
fi

BACKENDS=""
if test "$BACKEND_C" = "yes" ; then BACKENDS="c"; fi
if test "$BACKEND_JVM" = "yes" ; then BACKENDS="$BACKENDS jvm"; fi
if test "$BACKEND_PO" = "yes" ; then BACKENDS="$BACKENDS po"; fi
if test "$BACKEND_VPO" = "yes" ; then BACKENDS="$BACKENDS vpo"; fi

AC_MSG_RESULT( [Building backends: $BACKENDS] )
AC_SUBST(BACKENDS)
AC_SUBST(BACKEND_C)
AC_SUBST(BACKEND_JVM)
AC_SUBST(BACKEND_VPO)
AC_SUBST(BACKEND_PO)

AC_DEFINE_UNQUOTED( SRC, $SRC, [Source architecture] )
AC_DEFINE_UNQUOTED( TGT, $TGT, [Target architecture] )
AC_SUBST(SRC)
AC_SUBST(TGT)
AC_SUBST_FILE(src_rules)

# Create output directories
AC_MSG_RESULT( [Creating directories] )
mkdir -p backend/common/ backend/c/ backend/jvm/ backend/po/ backend/runtime/ backend/vpo/
mkdir -p loader cfg pal proc prog rtl util disasm
mkdir -p machine/sparc machine/pentium machine/mc68k machine/hppa machine/286

AC_OUTPUT(Makefile backend/common/instance.cc)
