#!/bin/bash

#----------------------------------------------------------------------------------------------
#  configure script for VapourSynth plugins
#----------------------------------------------------------------------------------------------

# -- help -------------------------------------------------------------------------------------
if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
cat << EOF
Usage: [PKG_CONFIG_PATH=/foo/bar/lib/pkgconfig] ./configure [options]
options:
  -h, --help                 print help (this)

  --prefix=PREFIX            install architecture-independent files into PREFIX
                             [/usr/local]
  --exec-prefix=EPREFIX      install architecture-dependent files into EPREFIX
                             [PREFIX]
  --libdir=DIR               install libs in DIR [EPREFIX/lib]
  --vs-plugindir=DIR         location of VapourSynth plugin directory,
                                default is [libdir]/vapoursynth

  --target-os=TARGET_OS      select target operating system
  --cross-prefix=PREFIX      use PREFIX for compilation tools
  --sysroot=SYSROOT          root of cross-build tree
  --enable-debug             compile with debug symbols and never strip

  --extra-cxxflags=XCXXFLAGS add XCXXFLAGS to CXXFLAGS
  --extra-ldflags=XLDFLAGS   add XLDFLAGS to LDFLAGS
  --extra-libs=XLIBS         add XLIBS to LIBS

EOF
exit 1
fi

#-- func --------------------------------------------------------------------------------------
error_exit()
{
    echo error: $1
    exit 1
}

log_echo()
{
    echo $1
    echo >> config.log
    echo --------------------------------- >> config.log
    echo $1 >> config.log
}

cc_check()
{
    rm -f conftest.c
    if [ -n "$3" ]; then
        echo "#include <$3>" >> config.log
        echo "#include <$3>" > conftest.c
    fi
    echo "int main(void){$4 return 0;}" >> config.log
    echo "int main(void){$4 return 0;}" >> conftest.c
    echo $CXX conftest.c -o conftest $1 $2 >> config.log
    $CXX conftest.c -o conftest $1 $2 2>> config.log
    ret=$?
    echo $ret >> config.log
    rm -f conftest*
    return $ret
}
#----------------------------------------------------------------------------------------------
rm -f config.* .depend

SRCDIR="$(cd $(dirname $0); pwd)"
test "$SRCDIR" = "$(pwd)" && SRCDIR=.
test -n "$(echo $SRCDIR | grep ' ')" && \
    error_exit "out-of-tree builds are impossible with whitespace in source path"

# -- output config.h --------------------------------------------------------------------------
pushd $SRCDIR
REV="$(git rev-list --count HEAD 2> /dev/null)"
HASH="$(git rev-parse --short HEAD 2> /dev/null)"
popd
cat >> config.h << EOF
#define VSTNLMEANS_REV "$REV"
#define VSTNLMEANS_GIT_HASH "$HASH"
EOF

# -- init -------------------------------------------------------------------------------------
CXX="g++"
LD="g++"
STRIP="strip"
DEBUG=""

prefix=""
exec_prefix=""
libdir=""
vsplugindir=""
DESTDIR=""

CXXFLAGS="-Wall -std=c++11 -I. -I$SRCDIR"
LDFLAGS="-L."
DEPLIBS=""

SRC_SOURCE="AlignedMemory.cpp TNLMeans.cpp Plugin.cpp"

# -- options ----------------------------------------------------------------------------------
echo all command lines: > config.log
echo "$*" >> config.log

for opt; do
    optarg="${opt#*=}"
    case "$opt" in
        --prefix=*)
            prefix="$optarg"
            ;;
        --exec-prefix=*)
            exec_prefix="$optarg"
            ;;
        --libdir=*)
            libdir="$optarg"
            ;;
        --vs-plugindir=*)
            vsplugindir="$optarg"
            ;;
        --destdir=*)
            DESTDIR="$optarg"
            ;;
        --enable-debug)
            DEBUG="enabled"
            ;;
        --extra-cxxflags=*)
            XCXXFLAGS="$optarg"
            ;;
        --extra-ldflags=*)
            XLDFLAGS="$optarg"
            ;;
        --extra-libs=*)
            XLIBS="$optarg"
            ;;
        --target-os=*)
            TARGET_OS="$optarg"
            ;;
        --cross-prefix=*)
            CROSS="$optarg"
            ;;
        --sysroot=*)
            CXXFLAGS="$CXXFLAGS --sysroot=$optarg"
            LDFLAGS="$LDFLAGS --sysroot=$optarg"
            ;;
        *)
            error_exit "unknown option $opt"
            ;;
    esac
done

test -n "$prefix" || prefix="/usr/local"
test -n "$exec_prefix" || exec_prefix='${prefix}'
test -n "$libdir" || libdir='${exec_prefix}/lib'
test -n "$vsplugindir" || vsplugindir='${libdir}/vapoursynth'

BASENAME="vstnlmeans"

if test -n "$TARGET_OS"; then
    TARGET_OS=$(echo $TARGET_OS | tr '[A-Z]' '[a-z]')
else
    TARGET_OS=$($CXX -dumpmachine | tr '[A-Z]' '[a-z]')
fi
case "$TARGET_OS" in
    *mingw*|*cygwin*)
        SYS="WIN32"
        SOSUFFIX="dll"
        SONAME="$BASENAME.$SOSUFFIX"
        SOFLAGS="-Wl,--enable-auto-image-base -Wl,--export-all-symbols"
        ;;
    *darwin*)
        SYS="MACOSX"
        SOSUFFIX="dylib"
        SONAME="lib$BASENAME.$REV.$SOSUFFIX"
        SONAME_LN="lib$BASENAME.$SOSUFFIX"
        SOFLAGS="-dynamiclib -Wl,-single_module -Wl,-read_only_relocs,suppress -install_name ${DESTDIR}${libdir}/${SONAME}"
        ;;
    *)
        SOSUFFIX="so"
        SONAME="lib$BASENAME.$SOSUFFIX.$REV"
        SONAME_LN="lib$BASENAME.$SOSUFFIX"
        SOFLAGS="-Wl,-soname,$SONAME"
        CXXFLAGS="$CXXFLAGS -fPIC"
        LDFLAGS="-fPIC $LDFLAGS"
        ;;
esac

# -- add extra --------------------------------------------------------------------------------
if test -n "$prefix"; then
    CXXFLAGS="$CXXFLAGS -I$prefix/include"
    LDFLAGS="$LDFLAGS -L$prefix/lib"
fi
test -n "$libdir" && LDFLAGS="$LDFLAGS -L$libdir"

CXXFLAGS="$CXXFLAGS $XCXXFLAGS"
LDFLAGS="$LDFLAGS $XLDFLAGS"

# -- check_exe --------------------------------------------------------------------------------
CXX="${CROSS}${CXX}"
LD="${CROSS}${LD}"
STRIP="${CROSS}${STRIP}"
for f in "$CXX" "$LD" "$STRIP"; do
    test -n "$(which $f 2> /dev/null)" || error_exit "$f is not executable"
done

# -- check & set cxxflags and ldflags  ----------------------------------------------------------
if test -n "$DEBUG"; then
    CXXFLAGS="$CXXFLAGS -g3 -O0"
    STRIP=""
else
    CXXFLAGS="-O3 -ffast-math -fomit-frame-pointer -fno-tree-vectorize $CXXFLAGS"
fi

log_echo "CXXFLAGS/LDFLAGS checking..."
if ! cc_check "$CXXFLAGS" "$LDFLAGS"; then
    error_exit "invalid CXXFLAGS/LDFLAGS"
fi

if cc_check "$CXXFLAGS -fexcess-precision=fast" "$LDFLAGS"; then
    CXXFLAGS="$CXXFLAGS -fexcess-precision=fast"
fi

if cc_check "-msse2 -mfpmath=sse $CXXFLAGS" "$LDFLAGS"; then
    CXXFLAGS="-msse2 -mfpmath=sse $CXXFLAGS"
fi

# -- check pkg-config ----------------------------------------------------------------
PKGCONFIGEXE="pkg-config"
test -n "$(which ${CROSS}${PKGCONFIGEXE} 2> /dev/null)" && \
    PKGCONFIGEXE=${CROSS}${PKGCONFIGEXE}

if $PKGCONFIGEXE --exists $DEPLIBS 2> /dev/null; then
    LIBS="$($PKGCONFIGEXE --libs $DEPLIBS)"
    CXXFLAGS="$CXXFLAGS $($PKGCONFIGEXE --cflags $DEPLIBS)"
else
    for lib in $DEPLIBS; do
        LIBS="$LIBS -l${lib#lib}"
    done
    log_echo "warning: pkg-config or pc files not found, lib detection may be inaccurate."
fi

# -- LDFLAGS settings --------------------------------------------------------------------------
if [ "$SYS" = WIN32 ]; then
    LDFLAGS="$LDFLAGS -shared -Wl,--dll,--add-stdcall-alias"
    LIBS="-lwinmm $LIBS $XLIBS"
else
    LDFLAGS="$LDFLAGS -shared"
    LIBS="$LIBS $XLIBS"
fi

# -- output config.mak ------------------------------------------------------------------------
rm -f config.mak
cat >> config.mak << EOF
CXX = $CXX
LD = $LD
STRIP = $STRIP
CXXFLAGS = $CXXFLAGS
LDFLAGS = $LDFLAGS
LIBS = $LIBS
SRCDIR = $SRCDIR
DESTDIR = $DESTDIR
prefix = $prefix
exec_prefix = $exec_prefix
libdir = $libdir
vsplugindir = $vsplugindir
SRC_SOURCE = $SRC_SOURCE
BASENAME=$BASENAME
SONAME=$SONAME
SONAME_LN=$SONAME_LN
SOSUFFIX=$SOSUFFIX
SOFLAGS=$SOFLAGS
EOF

cat >> config.log << EOF
---------------------------------
    setting
---------------------------------
EOF
cat config.mak >> config.log

cat << EOF

settings...
CXX         = $CXX
LD          = $LD
STRIP       = $STRIP
CXXFLAGS    = $CXXFLAGS
LDFLAGS     = $LDFLAGS
LIBS        = $LIBS
SONAME      = $SONAME
SOFLAGS     = $SOFLAGS
PREFIX      = $prefix
VSPLUGINDIR = $vsplugindir
EOF

test "$SRCDIR" = "." || cp -f $SRCDIR/GNUmakefile .

# ---------------------------------------------------------------------------------------------

cat << EOF

configure finished.
type 'make' : compile $SONAME
EOF
