#!/bin/sh
# Create a loadable object from a C++ function defined in a .cpp file
# $Id$
thecommand="$0"
dircommand=`dirname "$0"`

FFVERSION='3.47'
FFCXXFLAGS='-g  -fdebug-prefix-map=/build/freefem++-gHfp5w/freefem++-3.47+dfsg1=. -fstack-protector-strong -Wformat -Werror=format-security -DNDEBUG -O3 -mmmx -msse -msse2 -DBAMG_LONG_LONG  -DNCHECKPTR -fPIC -Wdate-time -D_FORTIFY_SOURCE=2'
FFFFLAGS='-g  -fdebug-prefix-map=/build/freefem++-gHfp5w/freefem++-3.47+dfsg1=. -fstack-protector-strong -DNDEBUG -O3 -mmmx -msse -msse2 -fPIC'
FFFLIBS='/usr/lib/gcc/x86_64-linux-gnu/7/libgfortran.so /usr/lib/gcc/x86_64-linux-gnu/7/libquadmath.so'
FFCXX11FLAGS='-std=c++11'
INCFF=
if [ "no" != "yes" ] ;then ffcs=0; else ffcs=1;fi 
if [ -z "$CXX" ] ; then CXX='g++ -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed' ; fi
if [ -z "$MPICXX" ] ; then MPICXX="mpic++ -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed" ; fi
if [ -z "$MPI_LIB" ] ; then MPI_LIB="-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed " ; fi
if [ -z "$F77" ] ; then F77="gfortran" ; fi
if [ "$CXX" = '@'CXX'@' ] ; then CXX=""; fi
if [ "$MPICXX" = '@'MPICXX'@' ] ; then MPICXX=""; fi
if [ "$F77" = '@'F77'@' ] ; then F77=""; fi
if [ "$FFCXXFLAGS" = '@'CXXFLAGS'@' ] ; then FFCXXFLAGS=""; fi
if [ "$FFFFLAGS" = '@'FFLAGS'@' ] ; then FFFFLAGS=""; fi
if [ "$FFFLIBS" = '@'FLIBS'@' ] ; then FFFLIBS=""; fi
if [ "$FFVERSION" = '@'VERSION'@' ] ; then FFVERSION=""; fi
if [ -z "$INCFF" ] ; then
    if [ -f "@INCFF@/ff++.hpp" ] ; then
	INCFF="-I@INCFF@"
    elif [ -f "${dircommand}/include/ff++.hpp" ]; then
	INCFF="-I${dircommand}/include"
    elif [ -f ../examples++-load/include/ff++.hpp ]; then
	INCFF="-I../examples++-load/include"
    elif [ -f "FFAPPLI_INC/ff++.hpp" ] ; then 
	INCFF="-IFFAPPLI_INC" 
    elif [ -f '/usr/lib/ff++/3.47/include/ff++.hpp' ] ; then 
	INCFF='-I/usr/lib/ff++/3.47/include' 
    else
	ff=`which freefem++.exe`;
	ffinc=`dirname "$ff"`/examples++-load/include
	if [ -f "$ffinc/ff++.hpp" ]; then
	  INCFF=-I"'$ffinc'";
        else	
	  echo " erreur PB include freefem++ directory " ;
	  exit 1;
	fi
    fi
fi
do="yes"
DEBUG=""
CONLY="false"
uu=`uname -s` 
INC=""
LIBS=""
DLL=""
bin="."
out=""
files=""
fileso=""
OTHER="";
WIN32="";

case "$uu" in
  CYGWIN*|MINGW*)
  if [ -z "" ] ; then 
      onwin32=1; uu="cygwin-version";
  else
      onwin32=1; uu="win32"; # pure windows 
  fi
  WIN32="win32-"
  wff=`which FreeFem++.exe`
  dff=`dirname "$wff"`
  if [ "$bin" = "." -a  -f ../src/bin-win32/libff.dll  ]; then
    bin=../src/bin-win32 
  elif [  -f "$dff/libff.dll"  ]; then
#  modif for install on cygwin
    bin="$dff"
  elif [ "$bin" = "." -a  -f ../libff.dll  ]; then
    bin=..
  elif [ "$bin" = "." -a  -f ../../libff.dll  ]; then
    bin=../..
  fi;; 
esac
autodep=""
withmpi=""
args=""

while [ $# -ne 0 ]  ; do
    argsp=$args
    args="$args '$1'"
    case "$1" in
	-[h?]*) echo usage $0 "[-n] [-g] [-win32] [-l libfile] [-I includedir]  files"
	    echo "    -auto :  build automaticaly the dependance (in test FH) "
	    echo "    -n  :  do nothing just print"
	    echo "    -g  :  compile with -g option"
	    echo "    -c  : compile only"
	    echo "    -mpi:  with  mpi"
	    echo "    -nompi:  without   $MPI_LIB links "
	    echo "    -O*  :  compile with -O* option"
	    echo "    -cygwin: compile for cygwin/win32 OS (Window XP, ...)"
	    echo "    -win32:  compile for win32 OS (Window XP, ...) default under cygwin"
	    echo "    -l files  add files to the ld process (link)"
	    echo "    -I dir  add dir in include seach dir for compilation"
	    echo "    -b dir  to change the default install  dir " 
	    echo "    -dll file  add  dll and this file copie in the install dir"
	    echo "    -o outputfile without suffix"
	    echo "    file.{cpp,cp,cxx,c,f,F}"
	    exit 0;
	    ;;
	F77=*) F77=`echo $1|sed 's/[A-Z0-9]*=//'` ;;
	CXX=*) CXX=`echo $1|sed 's/[A-Z0-9]*=//'` ;;
	MPICXX=*) MPICXX=`echo $1|sed 's/[A-Z0-9]*=//'`;withmpi=yes ;;
	F77=*) F77=`echo $1|sed 's/[A-Z0-9]*=//'` ;;
	CXXFLAGS=*) CXXFLAGS=`echo $1|sed 's/[A-Z0-9]*=//'` ;;
	FFLAGS=*) FFLAGS=`echo $1|sed 's/[A-Z0-9]*=//'` ;;
	MPI_LIB=*) MPI_LIB=`echo $1|sed 's/[A-Z0-9]*=//'` ;;
	-std=*)	 CXXFLAGS="$1 $CXXFLAGS" ;;
	-auto) autodep=yes;args=$argsp;;
	-mpi) withmpi=yes;;
	-nompi) MPI_LIB='';withmpi='';;
	-n)  do="no";;
	-g)  DEBUG="$DEBUG $1";;
	-c)  CONLY=yes;;
	-O*) DEBUG="$DEBUG $1";;
	-cygwin)  onwin32=1; uu="cygwin-version";; 
	-win32)   onwin32=1; uu="win32";; 
	-b)     bin=$2  ; shift;;
	-I*)    INC="$INC '$1'";;
	-D*)    INC="$INC '$1'";;
	-dll)   DLL="$DLL '$2'";shift;;
	-[Ll]*)    LIBS="$LIBS '$1'" ;; # FFCS - 27/10/11 - need quotes for MPICH libraries in 'Program Files' under Windows
	*.a)     LIBS="$LIBS $1" ;;
	*.so)    LIBS="$LIBS $1" ;;
	*.dll)   if [ -f "$1" ] ; then  LIBS="$LIBS '$1'"  
	    elif [ -f "$bin/$1" ] ; then  LIBS="$LIBS '$bin/$1'"
	    else
	      echo " erreur file not found $1" ;
	      exit 1;
	    fi;;
	-Wl*)    LIBS="$LIBS $1" ;;
	*.cpp) files="$files '$1'";  o=`basename "$1" .cpp` ; fileso="$fileso '$o.o'"; args=$argsp;; 
	*.cp)  files="$files '$1'";  o=`basename "$1" .cp`   ; fileso="$fileso '$o.o'"; args=$argsp;; 
	*.cxx) files="$files '$1'";  o=`basename "$1" .cxx` ; fileso="$fileso '$o.o'"; args=$argsp;;
	*.c)   files="$files '$1'";  o=`basename "$1" .c` ; fileso="$fileso '$o.o'"; args=$argsp;;  
	*.f)   ffiles="$ffiles '$1'";  o=`basename "$1" .f` ; fileso="$fileso '$o.o'";; 
	*.F)   ffiles="$ffiles '$1'";  o=`basename "$1" .F` ; fileso="$fileso '$o.o'";; 
	*.o)   fileso="$fileso '$1'"; o=`basename "$1" .o` ;; 
	-o)    out="$2"; shift;;
	*) OTHER="$OTHER $1";;
    esac
    shift
done

#  remove old file... FH sep 2013..
SUF=so

if [ -n "$autodep"  ] ; then
#    echo "$thecommand" $args  `eval "'$dircommand/ff-get-dep'" -ff $files`
    argsdep=`eval "'$dircommand/ff-get-dep'" -ff $files`
    
     error=`echo "$argsdep"| grep ERROR`
     if [ -n "$error" ] ; then
	 echo " WARNING in  auto dependance seach ( missing plugin $2) .  sorry : $error "

	 # FFCS - 28/11/11 - we need to stop compiling as soon as there is an error because we want a fixed set of features in
	 # FFCS
	 # return a error when FFCS enable .. FH. 
	 echo " -- $error " >>Missing-plugins-so.log
	 exit $ffcs;
     fi
    echo eval "$thecommand" $args  $argsdep
    eval "$thecommand" $args  $argsdep

    # FFCS needs an error exit code to make sure that all libraries are correctly compiled
    exit $?;
fi

if [  -n "$onwin32" -a ! -f "$bin/libff.dll"  ] ; then 
    echo " Error the file libff.dll  must be exist in '$bin' the install directory," 
    echo " to link on windows OS "
    echo " Use the parameter -b to set the correct install directory " 
    exit 1;
fi

if [ -z "$out" ] ; then  out=$o  ; fi;
if [ -f  "$out.$SUF" ] ; then rm $out.$SUF ; fi 


# Default compiler
if [ -z "$CXX"  ];then  CXX=g++ ; fi
if [ -n "$withmpi" ]; then  CXX=$MPICXX;fi

test "$withmpi" = "yes" && WMPI_LIB="$MPI_LIB"

# build a mpi version of the plugin if the plugin do exist un mpi dir
# and if the mpi version exist and if 
OWMPI=""
test  -d ../examples++-mpi -a -n "$MPI_LIB" -a "$withmpi" != "yes" -a ! -f  "../examples++-mpi/$out.cpp"  &&  OWMPI="../examples++-mpi/$out.$SUF"
test -f "$OWMPI" -a -n "$OWMPI" && rm "$OWMPI"



INC="$INCFF $INC"  
SHARED="-shared"
case "$WIN32$uu" in
    Darwin*) 
#        echo "export MACOSX_DEPLOYMENT_TARGET=10.3"
#	export MACOSX_DEPLOYMENT_TARGET=10.4
#	SUF=dylib
	SHARED="-bundle -undefined dynamic_lookup"  ;;
    win32-CYGWIN*|win32-win32)
        echo " Window without cygwin "
	WMPI_LIB=''
        b="$bin"
        LIBS=" '$b/libff.dll'  $LIBS $DLL"

	# FFCS - 17/10/12 - --unresolved-symbols=ignore-all is not understood by the current mingw64 compilers
        SHARED="-shared -Wl,--enable-auto-import"

	# FFCS - 17/10/12 - -mno-cygwin is not understood by the current mingw64 compilers
        ###FLAGS='  -mno-cygwin '
#        SUF=dll
	;;
    win32-cygwin-version)
        echo " cygwin-version "
	WMPI_LIB=''
        b=$bin
        FLAGS=' '
        LIBS="'$b/libff.dll' $LIBS $DLL"
#        SUF=dll
	;;
    FreeBSD|NetBSD|GNU|GNU/kFreeBSD)
	SHARED="-shared" 
	FLAGS='-fPIC';;
	# 64 bit Linux needs -fPIC (ALH)
    SunOS)
        SHARED="-shared"
        FLAGS='-fPIC';;
        # 64 bit Linux needs -fPIC (ALH)
    Linux)
	FLAGS='-fPIC'
	SHARED="-shared " ;;
    *)
	echo "sorry unknown achitecture "`uname`
	exit 1;;
esac


#FLAGS="$FLAGS $DEBUG $FFCXXFLAGS"
#  change F. H Version 3.17 
FLAGS="$FLAGS $DEBUG"

if [ -n "$ffiles$files$fileso" ] ; then
    if [  -n "$WIN32"  -a  ! -f "$bin/libff.dll"  ]; then
	echo " Sorry, no freefem .dll file (libff.dll)  in $bin dir "
	echo " try with -b dir-path where the file libff.dll exist"
	exit 1;
    fi
    if [ "$files" ] ;then 
	echo $CXX -c $FLAGS $CXXFLAGS $FFCXXFLAGS $INC $PIC $files
	if [  $do = yes ] ; then 
	    eval $CXX -c $INC $FLAGS $CXXFLAGS $FFCXXFLAGS  $PIC  $files
	    ret=$?; if [ $ret -ne 0 ] ; then exit $ret ;fi
	fi
	echo 
    fi
    if [ "$ffiles" ] ;then 
	echo $F77 -c $FLAGS $FFLAGS $FFFFLAGS $INC $PIC $ffiles
	LIBS="$FFFLIBS $LIBS"
	if [  $do = yes ] ; then 
	    eval $F77 -c $INC $FFLAGS $FLAGS $FFFFLAGS $PIC  $ffiles
	    ret=$?; if [ $ret -ne 0 ] ; then exit $ret ;fi
	fi
	echo 
    fi
    if [ "$CONLY" != yes ]; then
	echo $CXX $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $out.$SUF $LIBS $DLL $OTHER $WMPI_LIB
	if [  $do = yes ] ; then 
	   eval $CXX $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $out.$SUF $LIBS $DLL $OTHER $WMPI_LIB
	    ret=$?; if [ $ret -ne 0 ] ; then exit $ret ;fi
	fi
	echo 
	if [  "$bin" != "." ]; then
	    echo cp $out.$SUF  $bin
	    test $do = yes &&   cp $out.$SUF  "$bin"
	fi
	if [ -n "$DLL" ] ; then
	    echo cp $DLL $bin
	    test $do = yes &&   cp $DLL "$bin"
	fi 
	if [ -n "$OWMPI" ] ; then
	    echo $CXX $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $OWMPI $LIBS $DLL $OTHER $MPI_LIB
	    if [  $do = yes ] ; then 
		eval $CXX $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $OWMPI $LIBS $DLL $OTHER $MPI_LIB
		ret=$?; if [ $ret -ne 0 ] ; then exit $ret ;fi
	    fi
	    echo
	fi
    fi
fi
