#!/bin/sh
#
# configure script for ghdl (c) 2014 Tristan Gingold
#

backend=mcode
CC=${CC:-gcc}
CXX=${CXX:-clang++}
CFLAGS=${CFLAGS:--g}
GNATMAKE=${GNATMAKE:-gnatmake}
LDFLAGS=
prefix=/usr/local
libdirsuffix=lib/ghdl
libdirreverse=../..
gcc_src_dir=
llvm_config=
backtrace_lib=
llvm_be=llvm
build=
build_mode=
enable_werror=true
enable_checks=true
enable_openieee=unknown
EXEEXT=
SOEXT=.so
PIC_FLAGS=-fPIC

show_help=no
progname=$0

subst_vars="CC CXX GNATMAKE CFLAGS LDFLAGS build srcdir abs_srcdir prefix backend libdirsuffix libdirreverse gcc_src_dir llvm_config llvm_be backtrace_lib build_mode EXEEXT SOEXT PIC_FLAGS default_pie enable_werror enable_checks enable_openieee"

# Find srcdir
srcdir=`dirname $progname`
if test x$srcdir = x; then
    srcdir=.
fi

# Check echo -n / echo \c
if test x`echo -n` = x"-n" ; then
  echon=
  echoc="\c"
else
  echon="-n"
  echoc=
fi

# Check $1 is a prefix of $2
check_version()
{
  exp_ver=`echo $1 | sed 's/\./v/g'`
  tool_ver=`echo $2 | sed 's/\./v/g'`
  if echo $tool_ver | grep -q "^$exp_ver"; then
      return 0
  else
      return 1
  fi
}

# Decode options
for opt do
  optarg=`expr x"$opt" : 'x[^=]*=\(.*\)'`
  case "$opt" in
      CC=*|CFLAGS=*|GNATMAKE=*|LDFLAGS=*|CXX=*)
        optvar=`expr x"$opt" : 'x\([^=]*\)=.*'`
	eval $optvar=\"$optarg\"
	;;
      --prefix=*) prefix="$optarg";;
      --srcdir=*) srcdir="$optarg";;
      --with-gcc=*) gcc_src_dir="$optarg"; backend=gcc;;
      --with-llvm=*) echo "--with-llvm is deprecated, use --with-llvm-config";
		     llvm_config="$optarg/bin/llvm-config"; backend=llvm;;
      --with-llvm-config) llvm_config="llvm-config"; backend=llvm;;
      --with-llvm-config=*) llvm_config="$optarg"; backend=llvm;;
      --with-backtrace-lib=*) backtrace_lib="$optarg";;
      --enable-werror) enable_werror=true;;
      --disable-werror) enable_werror=false;;
      --enable-checks) enable_checks=true;;
      --disable-checks) enable_checks=false;;
      --enable-openieee) enable_openieee=true;;
      --disable-openieee) enable_openieee=false;;
      --enable-coverage) build_mode="coverage";;
      -h|-help|--help) show_help=yes;;
      *) echo "$0: unknown option $opt; try $0 --help"
	  exit 1
	  ;;
  esac
done

# Help
if test $show_help != no; then
cat <<EOF
Usage: configure [options]

Options [defaults in brackets]:
  --prefix=PREFIX             install in PREFIX [$prefix]
  --srcdir=SRCDIR             source code path [$srcdir]
  --with-gcc=DIR              use gcc backend from DIR
  --with-llvm-config=PATH     use llvm from PATH (needs llvm 3.5 - 3.9)
  --with-backtrace-lib=LIB.a  link with libbacktrace LIB.a to display a
                              backtrace on errors (only for llvm).
  --disable-werror            warnings don't stop build
  --disable-checks            disable internal checks
  --enable-openieee           use gpl-compatible sources for ieee library
EOF
exit 0
fi

# Set abs_srcdir (absolute srcdir)
case $srcdir in
    /*) abs_srcdir=$srcdir;;
    *)
        # Use a Windows path on windows.
        case "$OS" in
            Windows_NT) abs_srcdir="`pwd -W`/$srcdir" ;;
            *) abs_srcdir=`pwd`/$srcdir ;;
        esac
        ;;
esac

# Sanity checks
# Check srcdir
pat="2019802090ed76fc5c54cec58f22a2c1"
if ! grep $pat $srcdir/configure > /dev/null 2>&1; then
    echo "Incorrect srcdir; try with --srcdir=xx"
    echo "srcdir=$srcdir"
    exit 1
fi

if ! cmp $srcdir/configure $abs_srcdir/configure > /dev/null 2>&1; then
    echo "Cannot compute absolute source dir (or incorrect srcdir)"
    echo "srcdir=$srcdir"
    echo "abs_srcdir=$abs_srcdir"
    exit 1
fi
# Check that gnatmake exists
if ! $GNATMAKE --version >/dev/null 2>&1; then
    echo "Sorry, you need GNAT to build GHDL.  See the README"
    echo "(gnatmake executable is: $GNATMAKE)"
    exit 1
fi

# Check that compiler exists
if ! $CC -v 2> /dev/null; then
    echo "Sorry, you need a C compiler to build GHDL.  See the README"
    exit 1
fi

# Default for enable_openieee
if [ "$enable_openieee" = "unknown" ]; then
    if test -d $srcdir/libraries/ieee ; then
	enable_openieee=false
	echo "Use full IEEE library"
    else
	enable_openieee=true
	echo "Use openieee source files for IEEE library (but partial)"
    fi
elif [ "$enable_openieee" = false ]; then
    if ! test -d $srcdir/libraries/ieee ; then
	echo "Sorry, full ieee library source files not present"
	echo "consider --enable-openieee"
	exit 1
    fi
fi

# Compute build machine
if test x$build = x; then
    build=`$CC $CFLAGS -dumpmachine`
fi
echo "Build machine is: $build"

# For mcode, check that gcc emits i386
if test $backend = mcode; then
    gcc_machine=`$CC $CFLAGS -dumpmachine`
    case "$gcc_machine" in
	i[3-6]86*) mcode64="" ;;
	x86_64*) mcode64="64" ;;
	*)
	  mcode64=""
	  echo "WARNING: GHDL for mcode is supported only on x86"
	  echo "continuing, but build failure expected (See the README)"
	  ;;
    esac
    if test "x$backtrace_lib" != x ; then
	echo "WARNING: --with-backtrace-lib= ignored with mcode"
	backtrace_lib=
    fi
fi

# For gcc backend, check existing version
if test $backend = gcc; then
    if ! test -f $gcc_src_dir/gcc/BASE-VER; then
	echo "cannot find gcc/BASE-VER in $gcc_src_dir"
	exit 1
    fi
    if test "x$backtrace_lib" = x ; then
	# Automatically use libbacktrace from gcc.
	backtrace_lib="$prefix/$libdirsuffix/libbacktrace.a"
    fi
fi

# For llvm backend, check llvm-config
if test $backend = llvm; then
    llvm_version=`"$llvm_config" --version 2>/dev/null`
    if [ $? != 0 ]; then
	echo "cannot run $llvm_config"
	exit 1
    fi
    if check_version 3.5 $llvm_version; then
	llvm_be=llvm
    elif check_version 3.6 $llvm_version ||
	 check_version 3.7 $llvm_version ||
         check_version 3.8 $llvm_version;
    then
	echo "Debugging is not enabled with llvm $llvm_version"
	llvm_be=llvm-nodebug
	# Tested with llvm 3.5, so assume 3.6, 3.7 and 3.8
    elif check_version 3.9 $llvm_version ||
         check_version 4.0 $llvm_version ||
         check_version 5.0 $llvm_version; then
	echo "Debugging is not enabled with llvm $llvm_version"
	llvm_be=llvm4-nodebug
    else
	echo "Unhandled version llvm $llvm_version"
	exit 1
    fi
    # For llvm, the c++ compiler is used for linking so that the standard c++
    # library is included.  However, the linker needs the no_compact_unwind
    # flag because code generated by gcc is not compatible with compact unwind.
    case "$build" in
	*darwin*) LDFLAGS="$LDFLAGS -Wl,-no_compact_unwind" ;;
    esac
fi

# Define default file extensions for Windows or Linux-like systems and
# use -fPIC or not.
case "$build" in
    *mingw*)  SOEXT=".dll";   EXEEXT=".exe"; PIC_FLAGS="";;
    *darwin*) SOEXT=".dylib"; EXEEXT="";     PIC_FLAGS="";;
    *)        SOEXT=".so";    EXEEXT="";     PIC_FLAGS="-fPIC";;
esac

# Check if gcc was configured with --enable-default-pie.  In that case -fPIC
# should be added.
if gcc -v 2>&1 | grep -q enable-default-pie; then
    default_pie="yes"
else
    default_pie="no"
fi

# Create subdirectories
if [ ! -d pic ]; then
    echo "create pic/ subdirectory"
    if ! mkdir pic; then
        echo "failed to create pic/"
        exit 1;
    fi
fi

# Generate config.status
rm -f config.status
{
echo "#! /bin/sh"
echo "# Generated by configure."
echo "# Run this file to recreate the current configuration."
echo
echo 'if [ x"$1" = x"--reconfigure" ]; then'
#  Do not use exec as bash 3.2 pass the absolute path in argv[0]
echo $echon "   $progname"$echoc
for opt do
  echo $echon \ \"$opt\"$echoc
done
echo
echo "  exit"
echo 'fi'
echo
echo subst_vars=\"$subst_vars\"
for v in $subst_vars; do
    eval vval=\$$v
    echo $v=\"$vval\"
done
sed_opts=`echo $subst_vars | sed -e "s/\\([a-zA-Z_]*\\)/ -e \"s%@\1@%\$\1%g\"/g"`
echo 'echo "Creating ghdl.gpr"'
echo sed $sed_opts '< $srcdir/ghdl.gpr.in > ghdl.gpr'
echo 'echo "Creating Makefile"'
echo sed $sed_opts '< $srcdir/Makefile.in > Makefile'
} > config.status || \
{
  echo "$progname: cannot create config.status"
  exit 1
}

chmod +x ./config.status

# Run config.status to generate files
if ! sh ./config.status; then
    echo "$progname: cannot execute config.status"
    exit 1
fi

# Create dirs
make create-dirs

# Generate ortho_code-x86-flags
if test $backend = mcode; then
    case "$build" in
	*darwin*) ortho_flags="Flags_Macosx${mcode64}" ;;
	*mingw32*) ortho_flags="Flags_Windows${mcode64}" ;;
	*linux*) ortho_flags="Flags_Linux${mcode64}" ;;
	*) echo "Unsupported $build build for mcode"; exit 1;;
    esac
    echo "Generate ortho_code-x86-flags.ads"
    {
     echo "with Ortho_Code.X86.$ortho_flags;"
     echo "package Ortho_Code.X86.Flags renames Ortho_Code.X86.$ortho_flags;"
    } > ortho_code-x86-flags.ads
    echo "Generate elf_arch.ads"
    {
	echo "with Elf_Arch${mcode64:-32};"
	echo "package Elf_Arch renames Elf_Arch${mcode64:-32};"
    } > elf_arch.ads
fi

# Generate default_paths.ads
# Also update dist/windows/mcode/default_paths.ads if you change this
# template.
echo "Generate default_paths.ads"
curdir=`pwd`
sed -e "s%@COMPILER_GCC@%ghdl1-gcc$EXEEXT%" \
    -e "s%@COMPILER_DEBUG@%ghdl1-debug$EXEEXT%" \
    -e "s%@COMPILER_MCODE@%ghdl1-mcode$EXEEXT%" \
    -e "s%@COMPILER_LLVM@%bin/ghdl1-llvm$EXEEXT%" \
    -e "s%@POST_PROCESSOR@%oread-$backend%" \
    -e "s%@INSTALL_PREFIX@%$prefix%" \
    -e "s%@LIB_PREFIX@%$libdirsuffix%" \
    -e "s%@SOEXT@%$SOEXT%" \
    -e "s%@default_pie@%$default_pie%" \
    < $srcdir/src/ghdldrv/default_paths.ads.in > default_paths.ads

exit 0