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

FFVERSION='4.15'
FFCXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fPIC -DNDEBUG -std=gnu++14 -DBAMG_LONG_LONG  -DNCHECKPTR -fPIC -I/builddir/build/BUILD/freefem++-4.15-build/freefem++-4.15/serial -I/usr/include/scotch -I/usr/include/suitesparse -I/usr/include'
FFFFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules   -DNDEBUG -fPIC -fallow-argument-mismatch -fallow-invalid-boz'
# change FH 22/12/20202  
FFFLIBS='-ldl -lm -lrt   -L/usr/lib/gcc/aarch64-redhat-linux/16 -L/usr/lib/gcc/aarch64-redhat-linux/16/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/aarch64-redhat-linux/16/../../.. -L/lib -L/usr/lib -lgfortran -lm -latomic_asneeded   -lhdf5_hl -lhdf5  -lhdf5_hl'
FFCXX11FLAGS='-std=gnu++14'
INCFF=
if [ "no" != "yes" ] ;then ffcs=0; else ffcs=1;fi
if [ -z "$CXX" ] ; then CXX='g++' ; fi
if [ -z "$MPICXX" ] ; then MPICXX="" ; fi
if [ -z "$MPI_LIB" ] ; then MPI_LIB="" ; 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" = '@'FF_FLAGS'@' ] ; then FFFFLAGS=""; fi
if [ "$FFFLIBS" = '@'FLIBS'@' ] ; then FFFLIBS=""; fi
if [ "$FFVERSION" = '@'VERSION'@' ] ; then FFVERSION=""; fi
if [ -z "$INCFF" ] ; then
    if [ -e "@INCFF@/ff++.hpp" ] ; then
	INCFF="-I@INCFF@"
    elif [ -e "${dircommand}/include/ff++.hpp" ]; then
	INCFF="-I${dircommand}/include"
    elif [ -e ../seq/include/ff++.hpp ]; then
	INCFF="-I../seq/include"
    elif [ -e "FFAPPLI_INC/ff++.hpp" ] ; then
	INCFF="-IFFAPPLI_INC"
    elif [ -e '/usr/lib64/ff++/4.15/include/ff++.hpp' ] ; then
	INCFF='-I/usr/lib64/ff++/4.15/include'
    else
	ff=`which freefem++.exe`;
	ffinc=`dirname "$ff"`/seq/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*|MSYS*)
  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 [ "$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=../..
  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 add remove optimisation"
	    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;
	    ;;
	LIBFF=*) LIBFF=`echo $1|sed 's/[A-Z0-9]*=//'` ;; 
	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";
            FFCXXFLAGS=`echo $FFCXXFLAGS| sed -e 's/-O[0-9]*//g' -e 's/-DNDEBUG//g' ` ;;
	-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" -a -z "$MPICXX" ] ; then echo $0: Sorry NO MPI; exit 0; 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 ../mpi -a -n "$MPI_LIB" -a "$withmpi" != "yes" -a ! -f  "../mpi/$out.cpp"  &&  OWMPI="../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"  

	if [  -f "$LIBFF" ] ; then
		echo " xcode interface  with $LIBFF"
		SHARED="-bundle"
		out=`dirname "$LIBFF"`/$out
		LIBS="$LIBFF $LIBS"
		OWMPI=
	fi 
	;;
    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)
	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 $INC $PIC $FFCXXFLAGS $files
	if [  $do = yes ] ; then
	    eval $CXX -c $INC $FLAGS $CXXFLAGS $PIC $FFCXXFLAGS $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
