#!/bin/sh

usage () {
cat <<EOF
Usage: $0 [OPTION]... [VAR=VALUE]... [TARGET]

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  --srcdir=DIR            source directory [detected]

Installation directories:
  --prefix=PREFIX         main installation prefix [/usr/local/musl]
  --exec-prefix=EPREFIX   installation prefix for executable files [PREFIX]

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR		  system executables [EPREFIX/sbin]
  --libdir=DIR            library files for the linker [EPREFIX/lib]
  --includedir=DIR        include files for the C compiler [PREFIX/include]
  --syslibdir=DIR         location for the dynamic linker [/lib]

System types:
  --target=TARGET         configure to run on target TARGET [detected]
  --host=HOST             same as --target

Optional features:
  --enable-optimize       optimize for speed over size [auto]
  --enable-debug          build with debugging information [disabled]
  --enable-warnings       build with recommended warnings flags [disabled]

Some influential environment variables:
  CC                      C compiler command [detected]
  CFLAGS                  C compiler flags [-Os -pipe ...]
  CROSS_COMPILE           prefix for cross compiler and tools [none]

Use these variables to override the choices made by configure.

EOF
exit 0
}

# Helper functions

quote () {
tr '\n' ' ' <<EOF | grep '^[-[:alnum:]_=,./:]* $' >/dev/null 2>&1 && { echo "$1" ; return 0 ; }
$1
EOF
printf %s\\n "$1" | sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/" -e "s#^'\([-[:alnum:]_,./:]*\)=\(.*\)\$#\1='\2#"
}
echo () { printf "%s\n" "$*" ; }
fail () { echo "$*" ; exit 1 ; }
fnmatch () { eval "case \"\$2\" in $1) return 0 ;; *) return 1 ;; esac" ; }
cmdexists () { type "$1" >/dev/null 2>&1 ; }
trycc () { test -z "$CC" && cmdexists "$1" && CC=$1 ; }
tryyacc () { test -z "$YACC" && cmdexists "$1" && YACC=$1 ; }
trylex () { test -z "$LEX" && cmdexists "$1" && LEX=$1 ; }

stripdir () {
while eval "fnmatch '*/' \"\${$1}\"" ; do eval "$1=\${$1%/}" ; done
}

trycppif () {
printf "checking preprocessor condition %s... " "$1"
echo "typedef int x;" > "$tmpc"
echo "#if $1" >> "$tmpc"
echo "#error yes" >> "$tmpc"
echo "#endif" >> "$tmpc"
if $CC $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
printf "false\n"
return 1
else
printf "true\n"
return 0
fi
}

tryflag () {
printf "checking whether compiler accepts %s... " "$2"
echo "typedef int x;" > "$tmpc"
if $CC $CFLAGS_TRY $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
printf "yes\n"
eval "$1=\"\${$1} \$2\""
eval "$1=\${$1# }"
return 0
else
printf "no\n"
return 1
fi
}

tryldlib () {
printf "checking whether library %s exists..." "$2"
echo "$3" >"$tmpc"
echo "int main(){" "$4" ";}" > "$tmpc"
if $CC $CFLAGS_TRY $LDFLAGS_TRY -o /dev/null "$tmpc" "$2" >/dev/null 2>&1 ; then
printf "yes\n"
eval "$1=\"\${$1} \$2\""
eval "$1=\${$1# }"
return 0
else
printf "no\n"
return 1
fi
}

tryldflag () {
printf "checking whether linker accepts %s... " "$2"
echo "int main(){return 0;}" > "$tmpc"
if $CC $LDFLAGS_TRY "$2" -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
printf "yes\n"
eval "$1=\"\${$1} \$2\""
eval "$1=\${$1# }"
return 0
else
printf "no\n"
return 1
fi
}



# Beginning of actual script

CFLAGS_C99=
CFLAGS_AUTO=
CFLAGS_TRY=
LDFLAGS_AUTO=
LDFLAGS_TRY=
LDLIBS_AUTO=
srcdir=
prefix=/usr/local/
exec_prefix='$(prefix)'
sbindir='$(exec_prefix)/sbin'
bindir='$(exec_prefix)/bin'
libdir='$(exec_prefix)/lib'
includedir='$(prefix)/include'
syslibdir='/lib'
target=
optimize=auto
debug=no
warnings=no

for arg ; do
case "$arg" in
--help|-h) usage ;;
--srcdir=*) srcdir=${arg#*=} ;;
--prefix=*) prefix=${arg#*=} ;;
--exec-prefix=*) exec_prefix=${arg#*=} ;;
--bindir=*) bindir=${arg#*=} ;;
--sbindir=*) sbindir=${arg#*=} ;;
--libdir=*) libdir=${arg#*=} ;;
--includedir=*) includedir=${arg#*=} ;;
--syslibdir=*) syslibdir=${arg#*=} ;;
--enable-optimize|--enable-optimize=yes) optimize=yes ;;
--disable-optimize|--enable-optimize=no) optimize=no ;;
--enable-debug|--enable-debug=yes) debug=yes ;;
--disable-debug|--enable-debug=no) debug=no ;;
--enable-warnings|--enable-warnings=yes) warnings=yes ;;
--disable-warnings|--enable-warnings=no) warnings=no ;;
--enable-visibility|--enable-visibility=yes) visibility=yes ;;
--disable-visibility|--enable-visibility=no) visibility=no ;;
--enable-*|--disable-*|--with-*|--without-*|--*dir=*|--build=*) ;;
--host=*|--target=*) target=${arg#*=} ;;
-* ) echo "$0: unknown option $arg" ;;
CC=*) CC=${arg#*=} ;;
CFLAGS=*) CFLAGS=${arg#*=} ;;
CPPFLAGS=*) CPPFLAGS=${arg#*=} ;;
LDFLAGS=*) LDFLAGS=${arg#*=} ;;
CROSS_COMPILE=*) CROSS_COMPILE=${arg#*=} ;;
*=*) ;;
*) target=$arg ;;
esac
done

for i in srcdir prefix exec_prefix bindir libdir includedir syslibdir ; do
stripdir $i
done

#
# Get the source dir for out-of-tree builds
#
if test -z "$srcdir" ; then
srcdir="${0%/configure}"
stripdir srcdir
fi
abs_builddir="$(pwd)" || fail "$0: cannot determine working directory"
abs_srcdir="$(cd $srcdir && pwd)" || fail "$0: invalid source directory $srcdir"
test "$abs_srcdir" = "$abs_builddir" && srcdir=.
test "$srcdir" != "." && test -f Makefile && test ! -h Makefile && fail "$0: Makefile already exists in the working directory"

#
# Get a temp filename we can use
#
i=0
set -C
while : ; do i=$(($i+1))
tmpc="./conf$$-$PPID-$i.c"
2>|/dev/null > "$tmpc" && break
test "$i" -gt 50 && fail "$0: cannot create temporary file $tmpc"
done
set +C
trap 'rm "$tmpc"' EXIT INT QUIT TERM HUP

#
# Set CROSS_COMPILE from target if needed
#
if test -z "$CROSS_COMPILE" && test -n "$target";then
	CROSS_COMPILE=$target-
fi

#
# Find a C compiler to use
#
printf "checking for C compiler... "
trycc ${CROSS_COMPILE}gcc
trycc ${CROSS_COMPILE}c99
trycc ${CROSS_COMPILE}cc
printf "%s\n" "$CC"
test -n "$CC" || { echo "$0: cannot find a C compiler" ; exit 1 ; }

printf "checking whether C compiler works... "
echo "typedef int x;" > "$tmpc"
if output=$($CC $CPPFLAGS $CFLAGS -c -o /dev/null "$tmpc" 2>&1) ; then
printf "yes\n"
else
printf "no; compiler output follows:\n%s\n" "$output"
exit 1
fi

#
# Find a yacc to use
#
printf "checking for yacc... "
tryyacc ${CROSS_COMPILE}yacc
tryyacc yacc
tryyacc ${CROSS_COMPILE}bison
tryyacc bison
printf "%s\n" "$YACC"
test -n "$YACC" || echo "$0: cannot find yacc. Will try to use pre-provided source."

#
# Find a lex to use
#
printf "checking for lex... "
trylex ${CROSS_COMPILE}lex
trylex lex
trylex ${CROSS_COMPILE}flex
trylex flex
printf "%s\n" "$LEX"
test -n "$LEX" || echo "$0: cannot find lex. Will try to use pre-provided source."


#
# Figure out options to force errors on unknown flags.
#
tryflag   CFLAGS_TRY  -Werror=unknown-warning-option
tryflag   CFLAGS_TRY  -Werror=unused-command-line-argument
tryldflag LDFLAGS_TRY -Werror=unknown-warning-option
tryldflag LDFLAGS_TRY -Werror=unused-command-line-argument

#
# Try libs necessary for features we use
#
tryldlib LDLIBS_AUTO -lpthread "#include <pthread.h>" "pthread_create(0, 0, (void*(*)(void*))0, 0);"
tryldlib LDLIBS_AUTO -ll "" ""
tryldlib LDLIBS_AUTO -ly "" ""
tryldlib LDLIBS_AUTO -lxnet "#include <sys/socket.h>" "listen(0, 0);"
tryldlib LDLIBS_AUTO -ldl "#include <dlfcn.h>" "dlclose(0);"

#
# Try to get a conforming C99 environment
#
tryflag CFLAGS_C99 -std=c99

#
# Enable debugging if requessted.
#
test "$debug" = yes && CFLAGS_AUTO=-g
test "$debug" = no && LDFLAGS_AUTO=-s

#
# Add a -O option to CFLAGS based on --enable-optimize and provided CFLAGS.
#
printf "checking for optimization settings... "
case "x$optimize" in
xauto)
if fnmatch '-O*|*\ -O*' "$CFLAGS_AUTO $CFLAGS" ; then
printf "using provided CFLAGS\n" ;optimize=no
else
printf "using defaults\n" ; optimize=yes
fi
;;
xsize|xnone) printf "minimize size\n" ; optimize=size ;;
xno|x) printf "disabled\n" ; optimize=no ;;
*) printf "custom\n" ;;
esac

case "x$optimize" in
xyes) tryflag CFLAGS_AUTO -O2 || tryflag CFLAGS_AUTO -O ;;
xsize) tryflag CFLAGS_AUTO -Os || tryflag CFLAGS_AUTO -O ;;
esac

# Always try -pipe
tryflag CFLAGS_AUTO -pipe

#
# If debugging is disabled, omit frame pointer. Modern GCC does this
# anyway on most archs even when debugging is enabled since the frame
# pointer is no longer needed for debugging.
#
if fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ; then :
else 
tryflag CFLAGS_AUTO -fomit-frame-pointer
fi

#
# Attempt to put each function and each data object in its own
# section. This both allows additional size optimizations at link
# time and works around a dangerous class of compiler/assembler bugs
# whereby relative address expressions are constant-folded by the
# assembler even when one or more of the symbols involved is
# replaceable. See gas pr 18561 and gcc pr 66609, 68178, etc.
#
tryflag CFLAGS_AUTO -ffunction-sections
tryflag CFLAGS_AUTO -fdata-sections

#
# On x86, make sure we don't have incompatible instruction set
# extensions enabled by default. This is bad for making static binaries.
# We cheat and use i486 rather than i386 because i386 really does not
# work anyway (issues with atomic ops).
# Some build environments pass -march and -mtune options via CC, so
# check both CC and CFLAGS.
#
if test "$ARCH" = "i386" ; then
fnmatch '-march=*|*\ -march=*' "$CC $CFLAGS" || tryldflag CFLAGS_AUTO -march=i486
fnmatch '-mtune=*|*\ -mtune=*' "$CC $CFLAGS" || tryldflag CFLAGS_AUTO -mtune=generic
fi

#
# Even with -std=c99, gcc accepts some constructs which are constraint
# violations. We want to treat these as errors regardless of whether
# other purely stylistic warnings are enabled -- especially implicit
# function declarations, which are a dangerous programming error.
#
tryflag CFLAGS_AUTO -Werror=implicit-function-declaration
tryflag CFLAGS_AUTO -Werror=implicit-int
tryflag CFLAGS_AUTO -Werror=pointer-sign
tryflag CFLAGS_AUTO -Werror=pointer-arith

if test "x$warnings" = xyes ; then
tryflag CFLAGS_AUTO -Wall
tryflag CFLAGS_AUTO -Wextra
tryflag CFLAGS_AUTO -Wno-unused-parameter
fi

# Omit empty sections from unreferenced functions or data
tryldflag LDFLAGS_AUTO -Wl,--gc-sections

#
# Some build systems globally pass in broken CFLAGS like -ffast-math
# for all packages. On recent GCC we can detect this and error out
# early rather than producing a seriously-broken math library.
#
if trycppif "__FAST_MATH__" \
  "$CFLAGS_C99FSE $CPPFLAGS $CFLAGS" ; then
fail "$0: error: compiler has broken floating point; check CFLAGS"
fi

printf "creating config.mak... "

cmdline=$(quote "$0")
for i ; do cmdline="$cmdline $(quote "$i")" ; done

exec 3>&1 1>config.mak


cat << EOF
# This version of config.mak was generated by:
# $cmdline
# Any changes made here will be lost if configure is re-run
srcdir = $srcdir
prefix = $prefix
exec_prefix = $exec_prefix
sbindir = $sbindir
bindir = $bindir
libdir = $libdir
includedir = $includedir
syslibdir = $syslibdir
CC = $CC
YACC = $YACC
LEX = $LEX
CFLAGS = $CFLAGS
CFLAGS_AUTO = $CFLAGS_AUTO
CFLAGS_C99 = $CFLAGS_C99
CPPFLAGS = $CPPFLAGS
LDFLAGS = $LDFLAGS
LDFLAGS_AUTO = $LDFLAGS_AUTO
LDLIBS_AUTO = $LDLIBS_AUTO
CROSS_COMPILE = $CROSS_COMPILE
LIBCC = $LIBCC
OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
ALL_TOOLS = $tools
TOOL_LIBS = $tool_libs
ADD_CFI = $ADD_CFI
EOF
exec 1>&3 3>&-

test "$srcdir" = "." || ln -sf $srcdir/Makefile .

printf "done\n"
