#!/bin/sh

# Script for easily compiling the correct executable for a machine.
#
# Just do this:
#  make clean
#  build <command> <project> <target>
#
# Be sure to do a "make clean" between making versions for different execution
# models, because the shared .o files are not compatible.
#
# <command> can be one of:
#   get_info
#   build_makefile

# -- set up portable echo command
case "`echo 'x\c'`" in
'x\c')  echo="echo -n"  nnl= ;;     #BSD
x)      echo="echo"     nnl="\c";;  #SysV
*)      echo 'Cannot setup echo. What weird machine do you have?' 1>2&
        exit 1;;
esac

# Check for correct number of arguments
if [ $# -lt 2 ]
then
  echo "ERROR: You must specify the project and target machine."
  exit 1
fi


# get basename of current application
projname=$1
if [ -f ${1}.pmf ]
then
  projfile=${1}.pmf
else
  echo "ERROR: project file (${1}.pmf) not found in this directory."
  exit 1
fi


# get path to sageroot for finding binaries and Makefile
if [ "x$TAUROOT" = "x" ]
then
  TauRoot=`awk 'BEGIN {ln=1;} {if(ln==2) {print $0; exit;} else {ln++;}}' $projfile`
else 
  TauRoot=$TAUROOT
fi

echo "Building project-independent portion of Makefile...${nnl}"


# Setup the generic mode variables
case $2 in
prf-*)
  mode="prf-"
  lmode="prf-"
  bldtgt=`echo $2 | sed -e 's/^prf-//'`
  ;;
trc-*)
  mode="trc-"
  lmode="trc-"
  bldtgt=`echo $2 | sed -e 's/^trc-//'`
  ;;
brk-*)
  mode="brk-"
  lmode=""
  bldtgt=`echo $2 | sed -e 's/^brk-//'`
  ;;
rpl-*)
  # For replay debugging with Ariadne.
  mode="rpl-"
  lmode="rpl-"
  bldtgt=`echo $2 | sed -e 's/^rpl-//'`
  ;;
snz-rpl-*)
  # For both Sneezy _and_ Ariadne.
  # Order matters in the shell script!
  mode="snzrpl-"
  lmode="snzrpl-"
  bldtgt=`echo $2 | sed -e 's/^snz-rpl-//'`
  ;;
snz-*)
  # For debugging or interaction with Sneezy.
  mode="snz-"
  lmode="snz-"
  bldtgt=`echo $2 | sed -e 's/^snz-//'`
  ;;
*)
  mode=""
  bldtgt=$2
  ;;
esac


# Use archfind command script in ./utils
arch=""
arch=`${TauRoot}/utils/archfind`


# check if $TauRoot/bin/$arch exists, if not, ERROR
if [ -d ${TauRoot}/bin/${arch} ]
then 
  true
else 
  echo ERROR: Could not find necessary binaries in ${TauRoot}/bin/${arch}/
  exit 1
fi


# Get list of languages from project
projlangs=`awk '/Proj_Langs:/ {printf("%s\\n", substr($0,12,length($0)));}' $projfile`

# Get list of source files from project
tmp_projsources=`sed -e '/^File:/!d' -e '/^File:/s/^File://' $projfile`
tmp_projobjects=`sed -e '/^File:/!d' -e '/^File:/s/^File://;s/\.[a-zA-Z]*$/\.o/' $projfile`
tmp_projdepfiles=`sed -e '/^File:/!d' -e '/^File:/s/^File://;s/\.[a-zA-Z]*$/\.dep/' $projfile`
projsources=`echo $tmp_projsources`
projobjects=`echo $tmp_projobjects`
projdepfiles=`echo $tmp_projdepfiles`


# These accumulate linker options - flags and libraries.
loader=""
extra_libraries=""
extra_linker_flags=""


# get rid of first two arguments
shift
shift


# This sets default compilers and options from configure script
info=`sed -e '/^#/d' -e '/^$/d' \
  -e '/^'$arch:'/s/^[^:]*: *\([A-Za-z0-9_][^ ]*\) *= \(.*\)$/\1="\2";/' \
  -e '/:/d' $TauRoot/build/Config.info`
eval $info

# Setup the loader and loader flags with target specific ones
info=`sed -e '/^#/d' -e '/^$/d' \
  -e '/^'$bldtgt:'/s/^[^:]*: *\([A-Za-z0-9_][^ ]*\) *= \(.*\)$/\1="\2";/' \
  -e '/:/d' $TauRoot/build/Target.info`
eval $info

# override these variables with architecture and target specific ones
info=`sed -e '/^#/d' -e '/^$/d' \
  -e '/^'$bldtgt,$arch:'/s/^[^:]*: *\([A-Za-z0-9_][^ ]*\) *= \(.*\)$/\1="\2";/'\
  -e '/:/d' $TauRoot/build/Target.info`
eval $info


# loader may now be set
generic_tgtlibs=$extraobjs


echo "done."


# Setup for each language
extra_mode_lib=""
extraobjs=""
extra_bldtgt_libraries=""
for lang in $projlangs
do

  echo "Setting up language-specific target information for $lang...${nnl}"

  . ${TauRoot}/build/${lang}/SetupMode

  # Set paths to BUILD files
  TI=${TauRoot}/build/${lang}/Target.info
  CI=${TauRoot}/build/${lang}/Config.info

  temp_bldtgt_objs1=""
  temp_bldtgt_objs2=""

  # check if specified target exists for each language
  if grep \^$bldtgt $TI > /dev/null
  then
    true
  else
    echo "build: unknown target $bldtgt for $lang language."
    exit 1
  fi

  # set configure specified default paths / variables
  # This sets default compilers and options from configure script
  info=`sed -e '/^#/d' -e '/^$/d' \
    -e '/^'$arch:'/s/^[^:]*: *\([A-Za-z0-9_][^ ]*\) *= \(.*\)$/\1="\2";/' \
    -e '/:/d' $CI`
  eval $info

  # override with target specific variables
  # This sets language specific compiler flags
  info=`sed -e '/^#/d' -e '/^$/d' \
    -e '/^'$bldtgt:'/s/^[^:]*: *\([A-Za-z0-9_][^ ]*\) *= \(.*\)$/\1="\2";/' \
    -e '/:/d' $TI`
  eval $info

  # override these variables with architecture and target specific ones
  info=`sed -e '/^#/d' -e '/^$/d' \
    -e '/^'$bldtgt,$arch:'/s/^[^:]*: *\([A-Za-z0-9_][^ ]*\) *= \(.*\)$/\1="\2";/'\
    -e '/:/d' $TI`
  eval $info

  temp_bldtgt_objs1="$temp_bldtgt_objs1 $extra_bldtgtobjs1"
  temp_bldtgt_objs2="$temp_bldtgt_objs2 $extra_bldtgtobjs2"

  echo "done."
done

extra_bldtgt_libraries="$temp_bldtgt_objs1 $extra_mode_lib $temp_bldtgt_objs2"

# add socket libraries if necessary
SI=${TauRoot}/build/Socket.info
if [ "	x$mode" = "xbrk-" ]
then
  info=`sed -e '/^#/d' -e '/^$/d' \
    -e '/^'$arch:'/s/^[^:]*: *\([A-Za-z0-9_][^ ]*\) *= \(.*\)$/\1="\2";/' \
    -e '/:/d' $SI`
  eval $info
fi

if [ "x$loader" = "x" ] 
then
  # From generic Config.info
  loader="$cxx $useropt"
fi


loader=$loader
loader_flags=$lextra
loader_objects="$extra_bldtgt_libraries $generic_tgtlibs $extraobjs $socketobjs"


if [ -f Makefile ] 
then
  cp Makefile Makefile.bak
fi

if result=`cp $TauRoot/build/Makefile.header Makefile`
then
  true
else 
  echo "Couldn't create $projdir/Makefile"
  exit 1
fi


if [ "x$cc" = "x" ] 
then
cat << EOF >> Makefile
CC = \$(CONFIG_CC)
EOF
else
cat << EOF >> Makefile
CC = $cc
EOF
fi

if [ "x$cxx" = "x" ] 
then
cat << EOF >> Makefile
CXX = \$(CONFIG_CXX)
EOF
else
cat << EOF >> Makefile
CXX = $cxx
EOF
fi

if [ "x$loader" = "x" ] 
then
cat << EOF >> Makefile
LOADER = \$(CXX)
EOF
else
cat << EOF >> Makefile
LOADER = $loader

EOF
fi


cat << EOF >> Makefile
TAUROOT   = $TauRoot
ANSIC     = $TauRoot/bin/$arch/ansiC
HPCXX2DEP = $TauRoot/bin/$arch/hpcxx2dep
PCXXROOT  = ${pcxx_root}
HPNXROOT  = ${hpcxx_hpnx}
PSTLROOT  = ${hpcxx_pstl}

# This is currently hard-coded in tau/build/build, but should be configurable!
STLROOT   = /home/grads/aida/hpc++/stl

EOF


projopts=`sed -e '/^Project_Options: /!d' -e '/^Project_Options: /s/^Project_Options: //' $projfile`
echo $projopts | tr @ \\n >> Makefile


cat << EOF >> Makefile
ARCH        = $arch
STDINCLUDES = $stdincludes
CXX_SWITCHES= $cextra
LDFLAGS     = \$(LDSWITCHES) $loader_flags 
LOBJS       = \$(USEROBJS) $loader_objects

DEPS        = $projdepfiles
OBJS        = $projobjects

EXECUTABLES =   *-awe-ms *-cm5 *-cnxspp-ms *-cs2.nx *-ksr *-ksr-ms *-lwp-ms \\
		*-mpi *-mpiNEW *-paragon *-pthread-ms *-pvmexe *-pvmexeNEW \\
		*-sgimp *-sgimp-ms *-sp2 *-sunmos *-symmetry *-t3d \\
		*-task-ms *-uniproc a.out

$projname-$mode$bldtgt: \$(DEPS) \$(OBJS)
	\$(LOADER) \$(LDFLAGS) -o $projname-$mode$bldtgt \$(OBJS) \$(LOBJS)

EOF


for srcfile in $projsources
do

  echo "Building language specific Makefile target for $srcfile...${nnl}"

  # Need to know lang, compile options
  srcbasename=`echo $srcfile | sed -e '/^/s/\.[a-zA-Z]*$//'`
  projsection=`awk -f ${TauRoot}/build/GetSection.awk filen=$srcfile $projfile`
  srclang=`echo $projsection | sed -e '/^Lang:/!d' -e '/^Lang:/s/^Lang://'`
  srcopts=`echo $projsection | sed -e '/^Comp_Opts:/!d' -e '/^Comp_Opts:/s/^Comp_Opts://'`

  # Create a Target in Makefile
  . ${TauRoot}/build/${srclang}/MakeMakeTarget

  echo "done."
done


cat << EOF >> Makefile
###########################################################################
## Cleanup Targets

clean:
	-/bin/rm -f *.o *.dep trc-* prf-* brk-* snz-* rpl-* snzrpl-* \\
		*~ *temp.C *temp.c align.h TEMP* TypeInfoFile.TIF

realclean: clean
	-/bin/rm -f \$(EXECUTABLES) core* *.tdl *.key *.trc *.edf \\
		profile.* dummy.c *.trace *.proj

dataclean:
	-/bin/rm -f profile.[0-9]* *.trc

EOF

exit 0
