#!/bin/sh
AMPICC="$0"
CHARMBIN=`dirname $0`
CHARMLIB="$CHARMBIN/../lib"
CHARMINC="$CHARMBIN/../include"
. "$CHARMINC/conv-mach-opt.sh"

[ -z "$AMPICC_MODE" ] && AMPICC_MODE='ampi'
VERBOSE=''
STANDALONE=''
ROMIO_CONFIGURE=''
MPITEST=''
FSGLOBALS=''
PIPGLOBALS=''
EXPLICIT_COMPILATION=''
BUILD_SHARE=''

ARGS=''
OBJECT=''

processArgs() {
while [ ! $# -eq 0 ]
do
  arg="$1"
  case "$arg" in
  -show)
     echo "charmc"
     exit 0
     ;;
  -verbose)
     VERBOSE='true'
     ARGS="$ARGS \"$arg\""
     ;;
  -standalone)
     STANDALONE='true'
     ;;

  # These arguments manage compilation of ROMIO's configure tests.
  # Simple environment tests will be compiled as standalone binaries,
  # while MPI tests will be compiled with AMPI.
  -ampi-romio-configure) # Strictly for internal use.
     ROMIO_CONFIGURE='true'
     ;;
  mpitest*) # mpitest.c, mpitest1.c, mpitest.f, etc
     ARGS="$ARGS \"$arg\""
     MPITEST='true'
     ;;

  -fsglobals)
     FSGLOBALS='true'
     ;;
  -pipglobals)
     PIPGLOBALS='true'
     ;;

  -c)
     EXPLICIT_COMPILATION='true'
     ARGS="$ARGS \"$arg\""
     ;;
  -shared|-G)
     BUILD_SHARE='true'
     ARGS="$ARGS \"$arg\""
     ;;
  -o)
     shift
     OBJECT="$1"
     ;;
  *)
     ARGS="$ARGS \"$arg\""
     ;;
  esac
  shift
done
}

eval processArgs "$@"

Do() {
  [ -n "$VERBOSE" ] && echo "$AMPICC: Executing $@" 1>&2
  eval "$@"
}

if [ -n "$FSGLOBALS" ]
then
  if [ "$CMK_SUPPORTS_FSGLOBALS" != '1' ]
  then
    echo "Error: Prerequisites for -fsglobals support were not detected."
    exit 1
  fi
fi

if [ -n "$PIPGLOBALS" ]
then
  if [ "$CMK_SUPPORTS_PIPGLOBALS" != '1' ]
  then
    echo "Error: Prerequisites for -pipglobals support were not detected."
    exit 1
  fi
fi

AMPICC_POST_OPTS=''

[ -n "$ROMIO_CONFIGURE" -a -z "$MPITEST" ] && STANDALONE='true'

[ -n "$STANDALONE" ] && ARGS="$ARGS -standalone"

[ -f $CHARMBIN/../lib/libampiromio.a -a -z "$STANDALONE" -a -z "$ROMIO_CONFIGURE" ] && ROMIO='-lampiromio -pthread'

FUNCPTR_SHIM_SUFFIX='.user'

if [ -n "$FSGLOBALS" -o -n "$PIPGLOBALS" ]
then
  if [ -z "$EXPLICIT_COMPILATION" -a -z "$BUILD_SHARE" -a -z "$STANDALONE" ] # if linking an AMPI executable
  then
    # link the user program against the shim
    [ -z "$OBJECT" ] && USEROBJECT="a.out$FUNCPTR_SHIM_SUFFIX" || USEROBJECT="$OBJECT$FUNCPTR_SHIM_SUFFIX"
    SHIM_OBJS="\"$CHARMLIB/ampi_funcptr_shim.o\""
    [ "$AMPICC_MODE" = 'ampif' ] && SHIM_OBJS="$SHIM_OBJS \"$CHARMLIB/ampi_funcptr_fortran.o\" \"$CHARMLIB/ampifimpl.o\" \"$CHARMLIB/ampimod.o\""
    Do $CHARMBIN/charmc $ARGS $AMPICC_POST_OPTS $SHIM_OBJS -standalone -ampi-funcptr-shim -o "$USEROBJECT"

    # set up linking the loader against the runtime
    AMPICC_POST_OPTS="$AMPICC_POST_OPTS -clear-input \"$CHARMLIB/ampi_funcptr_loader.o\""
    if [ -n "$FSGLOBALS" ]
    then
      AMPICC_POST_OPTS="$AMPICC_POST_OPTS \"$CHARMLIB/ampi_funcptr_fsglobals.o\""
    elif [ -n "$PIPGLOBALS" ]
    then
      AMPICC_POST_OPTS="$AMPICC_POST_OPTS \"$CHARMLIB/ampi_funcptr_pipglobals.o\""

      # look for PiP-glibc
      [ -z "$PIP_GLIBC_INSTALL_DIR" ] && PIP_GLIBC_INSTALL_DIR='/opt/pip'
      pipldquery="$PIP_GLIBC_INSTALL_DIR/lib/ld-*.so"
      set -- $pipldquery
      pipld="$1"
      if [ "$pipld" = "$pipldquery" ]
      then
        echo 'Note: PiP-glibc not found. Maximum virtualization count will be limited.'
        echo '      Please set and export $PIP_GLIBC_INSTALL_DIR appropriately.'
      else
        AMPICC_POST_OPTS="$AMPICC_POST_OPTS -Wl,--dynamic-linker=$pipld"
      fi
    fi
  else
    AMPICC_POST_OPTS="$AMPICC_POST_OPTS -ampi-funcptr-shim"
  fi
fi

if [ -n "$OBJECT" ]
then
  AMPICC_POST_OPTS="$AMPICC_POST_OPTS -o \"$OBJECT\""
fi

Do $CHARMBIN/charmc -language $AMPICC_MODE -default-to-aout $ARGS $AMPICC_POST_OPTS $ROMIO
status=$?

# Copy ampirun, but do not overwrite it if it already exists.
[ $status -eq 0 ] && cp -n $CHARMBIN/ampirun .

exit $status
