#!/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='-g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -flto=auto -ffat-lto-objects -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -mbranch-protection=standard -fdebug-prefix-map=/build/freefem++-PTskgT/freefem++-4.15+dfsg=/usr/src/freefem++-4.15+dfsg-2build1 -DNDEBUG -O3 -mtune=generic -std=gnu++14 -DBAMG_LONG_LONG  -DNCHECKPTR -fPIC -Wdate-time -D_FORTIFY_SOURCE=3  -I/usr/include/suitesparse -I/usr/include -I/usr/include/hdf5/serial'
FFFFLAGS='-g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -flto=auto -ffat-lto-objects -fstack-protector-strong -fstack-clash-protection -mbranch-protection=standard -fdebug-prefix-map=/build/freefem++-PTskgT/freefem++-4.15+dfsg=/usr/src/freefem++-4.15+dfsg-2build1 -DNDEBUG -O3 -mtune=generic -fPIC -fallow-argument-mismatch -fallow-invalid-boz'
# change FH 22/12/2022  
FFFLIBS='-ldl -lm -lrt   -L/usr/lib/gcc/aarch64-linux-gnu/15 -L/usr/lib/gcc/aarch64-linux-gnu/15/../../../aarch64-linux-gnu -L/usr/lib/gcc/aarch64-linux-gnu/15/../../../../lib -L/lib/aarch64-linux-gnu -L/lib/../lib -L/usr/lib/aarch64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/aarch64-linux-gnu/15/../../.. -L/lib -L/usr/lib -lgfortran -lm  -L/usr/lib/aarch64-linux-gnu/hdf5/serial  -lhdf5_hl -lhdf5  -lcrypto -lcurl -lpthread -lsz -lz -ldl -lm'
FFCXX11FLAGS='-std=gnu++14'
FFLDFLAGS='-Wl,-Bsymbolic-functions -Wl,--package-metadata={%22type%22:%22deb%22%2C%22os%22:%22ubuntu%22%2C%22name%22:%22freefem++%22%2C%22version%22:%224.15+dfsg-2build1%22%2C%22architecture%22:%22arm64%22} -flto=auto -ffat-lto-objects -Wl,-z,relro -Wl,-z,now -rdynamic'
INCFF=
if [ "no" != "yes" ] ;then ffcs=0; else ffcs=1;fi
if [ -z "$CXX" ] ; then CXX='g++' ; fi
if [ -z "$MPICXX" ] ; then MPICXX="mpicxx" ; fi
if [ -z "$MPI_LIB" ] ; then MPI_LIB="-L/usr/lib/aarch64-linux-gnu/openmpi/lib -lmpi " ; 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 [ -f "@INCFF@/ff++.hpp" ] ; then
	INCFF="'-I@INCFF@'"
    elif [ -f "${dircommand}/include/ff++.hpp" ]; then
	INCFF="'-I${dircommand}/include'"
    elif [ -f ../seq/include/ff++.hpp ]; then
	INCFF="-I../seq/include"
    elif [ -f "@FFAPPLI_INC@/ff++.hpp" ] ; then
	INCFF="'-I@FFAPPLI_INC@'"
    elif [ -f '/usr/lib/ff++/4.15/include/ff++.hpp' ] ; then
	INCFF="'-I/usr/lib/ff++/4.15/include'"
    elif [ -f '/usr/include/freefem++/ff++.hpp' ] ; then
	INCFF="'-I/usr/include/freefem++'"
    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 $LDFLAGS
	if [  $do = yes ] ; then
	    eval $CXX -c $INC $FLAGS $CXXFLAGS $PIC $FFCXXFLAGS $files $LDFLAGS
	    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 $FFLDFLAGS $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $out.$SUF $LIBS  $DLL $OTHER $WMPI_LIB $LDFLAGS
	if [  $do = yes ] ; then
	   eval $CXX $FFLDFLAGS $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $out.$SUF $LIBS $DLL $OTHER $WMPI_LIB $LDFLAGS
	    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 $FFLDFLAGS $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $OWMPI $LIBS $DLL $OTHER $MPI_LIB $LDFLAGS
	    if [  $do = yes ] ; then
		eval $CXX $FFLDFLAGS $SHARED $FLAGS $CXXFLAGS $FFCXXFLAGS $fileso -o $OWMPI $LIBS $DLL $OTHER $MPI_LIB $LDFLAGS
		ret=$?; if [ $ret -ne 0 ] ; then exit $ret ;fi
	    fi
	    echo
	fi
    fi
fi
