#!/bin/sh

#----------------------------------------------------------------------------
#    This file is part of KNLMeansCL,
#    Copyright(C) 2014-2018 Edoardo Brunetti,
#    Copyright(C) 2015-2016 sl1pkn07,
#    Copyright(C) 2015      ldepandis.
#    
#    KNLMeansCL is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    KNLMeansCL is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with KNLMeansCL. If not, see <http://www.gnu.org/licenses/>.
#----------------------------------------------------------------------------

# -- 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)

  --install=PATH           set dir for install library
                           [/usr/local/lib/vapoursynth]

  --cxx=CXX                use a defined compiler for compilation and linking
                           [g++]
  --target-os=OS           build programs to run on OS [auto]
  --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

  --target=TARGET          set target instruction set []

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 'extern "C" {' > conftest.cpp
        echo "#include <$3>" >> conftest.cpp
        echo } >> conftest.cpp
    fi
    echo "int main(void){$4 return 0;}" >> config.log
    echo "int main(void){$4 return 0;}" >> conftest.cpp
    echo $CXX conftest.cpp -o conftest $1 $2 >> config.log
    $CXX conftest.cpp -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"

# -- init -------------------------------------------------------------------
libdir="/usr/local/lib/vapoursynth"

TARGET_OS=""
CROSS=""

SYSROOT=""
CXX="g++"
LD="g++"
STRIP="strip"

DEBUG=""

LIBNAME=""

CXXFLAGS="-std=gnu++11 -Wall -Wno-unused-local-typedefs -I. -I./shared -I$SRCDIR/include"
LDFLAGS=""
SOFLAGS="-shared"
DEPLIBS="OpenCL"
CL_HEADER="CL/cl.h"
LD_OPT="-l"
TARGET=""

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

for opt; do
    optarg="${opt#*=}"
    case "$opt" in
        --install=*)
            libdir="$optarg"
            ;;
        --enable-debug)
            DEBUG="enabled"
            CXXFLAGS="$CXXFLAGS -g"
            ;;
        --cxx=*)
            CXX="$optarg"
            LD="$optarg"
            ;;
        --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"
            ;;
        --target=*)
            TARGET="-m$optarg"
            ;;
        *)
            error_exit "unknown option $opt"
            ;;
    esac
done

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

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

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*)
        LIBNAME="KNLmeansCL.dll"
        SOFLAGS="$SOFLAGS -Wl,--dll,--add-stdcall-alias"
        ;;
    *darwin*)
        LIBNAME="libknlmeanscl.dylib"
        SOFLAGS="$SOFLAGS -dynamiclib -Wl,-undefined,suppress -Wl,-read_only_relocs,suppress -Wl,-flat_namespace"
        CL_HEADER="OpenCL/cl.h"
        LD_OPT="-framework "
        ;;
    *linux*)
        LIBNAME="libknlmeanscl.so"
        CXXFLAGS="$CXXFLAGS -fPIC"
        SOFLAGS="$SOFLAGS -fPIC"
        ;;
    *)
        error_exit "target is unsupported system"
esac


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

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

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

log_echo "checking for vapoursynth headers..."
if $PKGCONFIGBIN --exists vapoursynth 2> /dev/null; then
    VSCFLAGS="$($PKGCONFIGBIN --cflags vapoursynth)"
else
    log_echo "warning: pkg-config or pc files not found, header detection may be inaccurate."
fi
if ! cc_check "$CXXFLAGS $VSCFLAGS" "$LDFLAGS $LIBS $XLIBS" "VapourSynth.h" "getVapourSynthAPI;" ; then
    log_echo "error: vapoursynth checking failed."
    error_exit "VapourSynth.h might not be installed."
fi

log_echo "checking for OpenCL..."
if ! cc_check "$CXXFLAGS" "$LDFLAGS $LIBS $XLIBS" "$CL_HEADER" "clCreateContextFromType(0,0,0,0,0);" ; then
    log_echo "error: OpenCL checking failed."
    error_exit "$CL_HEADER might not be installed or some libs missing."
fi

LDFLAGS="$SOFLAGS $LDFLAGS"
LIBS="$LIBS $XLIBS"
CXXFLAGS="$CXXFLAGS $VSCFLAGS"


cat >> config.mak << EOF
CXX = $CXX
LD = $LD
STRIP = $STRIP
CXXFLAGS = $CXXFLAGS
LDFLAGS = $LDFLAGS
LIBS = $LIBS
SRCDIR = $SRCDIR
LIBNAME = $LIBNAME
libdir = $libdir
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
LIBNAME      = $LIBNAME
install path = $libdir
EOF

test "$SRCDIR" = "." || ln -sf $SRCDIR/GNUmakefile .

echo configure finished.

exit 0
