#!/bin/bash
#
# $Id$
#
#
########################################################################
# for debug, uncomment line below
#set -xv
########################################################################
# options par defaut pour la commande make
########################################################################
dim="96x72x19"
physique=lmd
code=gcm
filtre=filtrez
grille=reg
couple=false
veget=false
chimie=false
parallel=none
paramem="par"
compil_mod=prod
io=ioipsl
LIBPREFIX=""
fcm_path=none
cosp=false
cosp2=false
cospv2=false
sisvat=false
inlandsis=false
rrtm=false
rrtm=false
dust=false
strataer=false
full=""

arch_defined="FALSE"
arch_path="arch"
arch_default_path="arch"

# guess a default 'arch'
arch="local" # start with assuming we're on a local machine with local arch file
arch_defined="TRUE" # and thus also set arch_defined to true 
## try to recognise machine and infer arch from it
machine=`hostname`
if [[ "${machine:0:4}" == "jean" ]]
then
  arch="X64_JEANZAY"
fi
if [[ "${machine:0:7}" == "platine" ]]
then
  arch="IA64_PLATINE"
fi
if [[ "${machine:0:6}" == "titane" ]]
then
  arch="X64_TITANE"
fi
if [[ "${machine:0:8}" == "mercure1" ]]
then
  arch="SX8_MERCURE"
fi
if [[ "${machine:0:8}" == "mercure2" ]]
then
  arch="SX9_MERCURE"
fi

LMDGCM=`pwd -P`
LIBFGCM=$LMDGCM/libf
LIBOGCM=$LMDGCM/libo
if [[ ! -d $LIBOGCM ]]
then
  # create the directory
  mkdir $LIBOGCM
  if [[ ! $? ]]
  then
  echo "Failed to create directory $LIBOGCM"
  exit
  fi
fi
#COSP_PATH=$LMDGCM/.void_dir



localdir=`pwd -P`
########################################################################
#  Quelques initialisations de variables du shell.
########################################################################

CPP_KEY="IN_LMDZ" 
INCLUDE='-I$(LIBF)/grid -I$(LIBF)/misc -I$(LIBF)/filtrez -I. '
LIB=""
adjnt=""
##COMPIL_FFLAGS="%PROD_FFLAGS"
PARA_FFLAGS=""
PARA_LD=""
EXT_SRC=""
#src_dirs: directories containing source files 
src_dirs="grid misc" 
########################################################################
# lecture des options
########################################################################

while (($# > 0))
  do
  case $1 in
      "-h") cat <<fin
Usage :
makelmdz [options] -arch nom_arch exec
[-h]                       : brief help
[-d [[IMx]JMx]LM]          : IM, JM, LM are the dimensions in x, y, z (default: $dim)
[-p PHYS]                  : set of physical parametrizations (in libf/phyPHYS), (default: lmd)
[-prod / -dev / -debug]    : compilation mode production (default) / developement / debug
[-c false/MPI1/MPI2]       : coupling with ocean model : MPI1/MPI2/false (default: false)
[-v false/orchidee2.0/orchidee1.9/true] : version of the vegetation model to include (default: false)
          false       : no vegetation model
          orchidee2.1 : compile using ORCHIDEE 2.1 (or more recent version)
          orchidee2.0 : compile using ORCHIDEE 2.0 (or more recent version)
          orchidee1.9 : compile using ORCHIDEE up to the version including OpenMP in ORCHIDEE : tag 1.9-1.9.5(version AR5)-1.9.6
          true        : (obsolete; for backward compatibility) use ORCHIDEE tag 1.9-1.9.6
[-chimie INCA/false]       : with INCA chemistry model or without (default: false)
[-cosp true/false]    : compile with/without cosp package (default: false)
[-cosp2 true/false]    : compile with/without cosp2 package (default: false)
[-cospv2 true/false]    : compile with/without cospv2 package (default: false)
[-sisvat true/false]  : compile with/without sisvat package (default: false)
[-inlandsis true/false]  : compile with/without inlandsis package (default: false)
[-rrtm true/false]    : compile with/without rrtm package (default: false)
[-dust true/false]    : compile with/without the dust package from Boucher et al. (default: false)
[-strataer true/false]    : compile with/without the strat aer package from Boucher et al. (default: false)
[-parallel none/mpi/omp/mpi_omp] : parallelism (default: none) : mpi, openmp or mixted mpi_openmp
[-g GRI]                   : grid configuration in dyn3d/GRI_xy.h  (default: reg, inclues a zoom)
[-io ioipsl/mix/xios]                   : Input/Output library (default: ioipsl)
[-include INCLUDES]        : extra include path to add
[-cpp CPP_KEY]             : additional preprocessing definitions
[-adjnt]                   : adjoint model, not operational ...
[-mem]                     : reduced memory dynamics (if in parallel mode)
[-filtre NOMFILTRE]        : use filtre from libf/NOMFILTRE (default: filtrez)
[-full]                    : Full (re)compilation (from scratch)
[-link LINKS]              : additional links with other libraries
[-fcm_path path]           : path to the fcm tool (default: tools/fcm/bin)
[-ext_src path]            : path to an additional set of routines to compile with the model
[-arch_path path]          : path to architecture files (default: $arch_default_path)
 -arch nom_arch            : target architecture 
 exec                      : executable to build
fin
	  exit;;
      "-d")
	  dim=$2 ; shift ; shift ;;
      
      "-p")
	  physique="$2" ;  shift ; shift ;;

      "-g")
	  grille="$2" ; shift ; shift ;;

      "-c")
	  couple="$2" ; shift ; shift ;;

      "-prod")
	  compil_mod="prod" ; shift ;;

      "-dev")
	  compil_mod="dev" ; shift ;;

      "-debug")
	  compil_mod="debug" ; shift ;;

      "-io")
	  io="$2" ; shift ; shift ;;

      "-v")
	  veget="$2" ; shift ; shift ;;

      "-chimie")
	  chimie="$2" ; shift ; shift ;;

      "-parallel")
	  parallel="$2" ; shift ; shift ;;
      
      "-include")
	  INCLUDE="$INCLUDE -I$2" ; shift ; shift ;;

      "-cpp")
	  CPP_KEY="$CPP_KEY $2" ; shift ; shift ;;

      "-cosp")
          cosp="$2" ; shift ; shift ;;

      "-cosp2")
          cosp2="$2" ; shift ; shift ;;

      "-cosp2")
          cospv2="$2" ; shift ; shift ;;
      
      "-sisvat")
          sisvat="$2" ; shift ; shift ;;

      "-inlandsis")
          inlandsis="$2" ; shift ; shift ;;  

      "-rrtm")
          rrtm="$2" ; shift ; shift ;;

      "-dust")
          dust="$2" ; shift ; shift ;;
      
      "-strataer")
          strataer="$2" ; shift ; shift ;;
      
      "-mem")
          paramem="mem" ; shift ;;

      "-filtre")
	  filtre=$2 ; shift ; shift ;;

      "-full")
      full="full" ; shift ;;

      "-link")
	  LIB="$LIB $2" ; shift ; shift ;;

      "-fcm_path")
	  fcm_path=$2 ; shift ; shift ;;

      "-ext_src")
	  EXT_SRC=$2 ; src_dirs="$src_dirs $EXT_SRC" ; shift ; shift ;;

      "-arch")
	  arch=$2 ; arch_defined="TRUE" ; shift ; shift ;;

      "-arch_path")
	  arch_path=$2 ; arch_path_defined="TRUE"; shift ; shift ;;

      *)
	  code="$1" ; shift ;;
  esac
done

###############################################################
# lecture des chemins propres \`a l'architecture de la machine #
###############################################################
rm -f .void_file
echo > .void_file
rm -rf .void_dir
mkdir .void_dir

if [[ "$arch_defined" == "TRUE" ]]
then
  rm -f arch.path
  rm -f arch.fcm
  rm -f arch.env

  if test -f $arch_path/arch-${arch}.path
  then
    ln -s $arch_path/arch-${arch}.path arch.path
  elif test -f $arch_default_path/arch-${arch}.path
  then
    ln -s $arch_default_path/arch-${arch}.path arch.path
  fi
        
  if test -f $arch_path/arch-${arch}.fcm
  then
    ln -s $arch_path/arch-${arch}.fcm arch.fcm
  elif test -f $arch_default_path/arch-${arch}.fcm
  then
    ln -s $arch_default_path/arch-${arch}.fcm arch.fcm
  fi

  if test -f $arch_path/arch-${arch}.env
  then
    ln -s $arch_path/arch-${arch}.env arch.env
  elif test -f $arch_default_path/arch-${arch}.env
  then
    ln -s $arch_default_path/arch-${arch}.env arch.env
  else
    ln -s .void_file arch.env
  fi
  # source architecture PATH and ENV files
  source arch.env
  source arch.path
else
  echo "You must define a target architecture"
  exit 1
fi

########################################################################
# Definition des clefs CPP, des chemins des includes et modules
#  et des libraries
########################################################################

# basic compile flags from arch.fcm file
archfileline=$( grep -i '^%BASE_FFLAGS' arch.fcm )
COMPIL_FFLAGS=$( echo ${archfileline##%BASE_FFLAGS} )

# other compile flags, depending on compilation mode
if [[ "$compil_mod" == "prod" ]]
then
## read COMPIL_FFLAGS from arch.fcm file
  archfileline=$( grep -i '^%PROD_FFLAGS' arch.fcm )
  archfileopt=$( echo ${archfileline##%PROD_FFLAGS} )
  COMPIL_FFLAGS="${COMPIL_FFLAGS} ${archfileopt}"
elif [[ "$compil_mod" == "dev" ]]
then
## read %DEV_FFLAGS from arch.fcm file
  archfileline=$( grep -i '^%DEV_FFLAGS' arch.fcm )
  archfileopt=$( echo ${archfileline##%DEV_FFLAGS} )
  COMPIL_FFLAGS="${COMPIL_FFLAGS} ${archfileopt}"
elif [[ "$compil_mod" == "debug" ]]
then
## read %DEBUG_FFLAGS from arch.fcm file
  archfileline=$( grep -i '^%DEBUG_FFLAGS' arch.fcm )
  archfileopt=$( echo ${archfileline##%DEBUG_FFLAGS} )
  COMPIL_FFLAGS="${COMPIL_FFLAGS} ${archfileopt}"
fi

# add CPP_KEY defined in arch.fcm file
archfileline=$( grep -i '^%FPP_DEF' arch.fcm )
archfileopt=$( echo ${archfileline##%FPP_DEF} )
CPP_KEY="$CPP_KEY ${archfileopt}"

# get compiler name from arch.fcm file
archfileline=$( grep -i '^%COMPILER' arch.fcm )
fcompiler=$( echo ${archfileline##%COMPILER} )

# get linker name from arch.fcm file
archfileline=$( grep -i '^%LINK' arch.fcm )
linker=$( echo ${archfileline##%LINK} )

# get ar command from arch.fcm file
archfileline=$( grep -i '^%AR ' arch.fcm )
arcommand=$( echo ${archfileline##%AR} )

# get ar command options from arch.fcm file
archfileline=$( grep -i '^%ARFLAGS' arch.fcm )
arflags=$( echo ${archfileline##%ARFLAGS} )

# get make utility from arch.fcm file
archfileline=$( grep -i '^%MAKE' arch.fcm )
makecommand=$( echo ${archfileline##%MAKE} )

# get basic libraries to link with arch.fcm file
archfileline=$( grep -i '^%BASE_LD' arch.fcm )
archfileopt=$( echo ${archfileline##%BASE_LD} )
LIB="$LIB  ${archfileopt}"

# add Include files defined in arch.fcm file for pre-processing
archfileline=$( grep -i '^%FPP_FLAGS' arch.fcm )
for inc in $archfileline ; do INCLUDE="$INCLUDE `echo $inc | grep '\-I'`" ; done

phys_root=$physique
if [[ "${physique:0:3}" == "lmd" ]] ; then phys_root=lmd ; fi
if [[ "${physique:0:4}" == "mars" ]] ; then phys_root=mars ; fi
if [[ "${physique:0:3}" == "std" ]] ; then phys_root=std ; fi
if [[ "${physique:0:5}" == "venus" ]] ; then phys_root=venus ; fi
if [[ "${physique:0:5}" == "titan" ]] ; then phys_root=titan ; fi
if [[ "${physique:0:3}" == "mar" ]] ; then phys_root=mar ; fi
if [[ "${physique:0:3}" == "dev" ]] ; then phys_root=dev ; fi

if [[ "$physique" != "nophys" ]]
then
   #We'll use some physics
   src_dirs="$src_dirs phy_common phy$physique"
   LIBPHY='$(LIBO)/libphy'"$physique"'.a'
   LIBPHY_COMMON='$(LIBO)/libphy_common.a'
   lib_phy='-lphy'"$physique"' -lphy_common'
   CPP_KEY="$CPP_KEY CPP_PHYS"
   if [[ $phys_root == "lmd" ]]
      then
      #For lmd physics, default planet type is Earth
      CPP_KEY="$CPP_KEY CPP_EARTH"
   fi
fi

if [[ "$chimie" == "INCA" ]]
then
   CPP_KEY="$CPP_KEY INCA"
   INCLUDE="$INCLUDE -I${INCA_INCDIR}"
   LIB="$LIB -L${INCA_LIBDIR} -lchimie"
   libchimie=" -L${INCA_LIBDIR} -lchimie"
fi

if [[ "$couple" != "false" ]]
then
   CPP_KEY="$CPP_KEY CPP_COUPLE"
   INCLUDE="$INCLUDE -I${OASIS_INCDIR}"
   LIB="$LIB -L${OASIS_LIBDIR} -lpsmile.${couple} -lmpp_io"
fi

if [[ "$parallel" == "none" ]]
then
  FLAG_PARA=''
else
  FLAG_PARA="$paramem"
  if [[ $paramem == par ]]
  then
      echo "The version of the dynamics in dyn3dpar is no longer updated."
      echo "You should use option \"-mem\"."
      exit 1
  fi
fi

if [[ "$parallel" == "mpi" ]]
then
   CPP_KEY="$CPP_KEY CPP_PARA CPP_MPI"
  # MPI additional compilation options 
  archfileline=$( grep -i '^%MPI_FFLAGS' arch.fcm )
  PARA_FFLAGS=$( echo ${archfileline##%MPI_FFLAGS} )
  # MPI additional links
  archfileline=$( grep -i '^%MPI_LD' arch.fcm )
  PARA_LD=$( echo ${archfileline##%MPI_LD} )
elif [[ "$parallel" == "omp" ]]
then
   CPP_KEY="$CPP_KEY CPP_PARA CPP_OMP"
  # OMP additional compilation options 
  archfileline=$( grep -i '^%OMP_FFLAGS' arch.fcm )
  PARA_FFLAGS=$( echo ${archfileline##%OMP_FFLAGS} )
  # OMP additional links
  archfileline=$( grep -i '^%OMP_LD' arch.fcm )
  PARA_LD=$( echo ${archfileline##%OMP_LD} )
elif [[ "$parallel" == "mpi_omp" ]]
then
   CPP_KEY="$CPP_KEY CPP_PARA CPP_MPI CPP_OMP"
  # MPI additional compilation options 
  archfileline=$( grep -i '^%MPI_FFLAGS' arch.fcm )
  PARA_FFLAGS=$( echo ${archfileline##%MPI_FFLAGS} )
  # OMP additional compilation options 
  archfileline=$( grep -i '^%OMP_FFLAGS' arch.fcm )
  PARA_FFLAGS="${PARA_FFLAGS} "$( echo $archfileopt ${archfileline##%OMP_FFLAGS} )
  # MPI additional links
  archfileline=$( grep -i '^%MPI_LD' arch.fcm )
  PARA_LD=$( echo ${archfileline##%MPI_LD} )
  # OMP additional links
  archfileline=$( grep -i '^%OMP_LD' arch.fcm )
  PARA_LD="${PARA_LD} "$( echo $archfileopt ${archfileline##%OMP_LD} )
fi

if [[ ( "$parallel" == "omp" || "$parallel" == "mpi_omp" ) \
   && "$compil_mod" == "debug" ]]
then
    echo "Usually, parallelization with OpenMP requires some optimization."
    echo "We suggest switching to \"-dev\"."
fi


#==============================================================================
if [ "$veget" = "true" -o "$veget" = "orchidee1.9" -o "$veget" = "orchidee2.0" -o "$veget" = "orchidee2.1" ]
then

   INCLUDE="${INCLUDE} -I${ORCH_INCDIR}"
   CPP_KEY="$CPP_KEY CPP_VEGET"
# temporary, for Orchidee versions 1.9.* (before openmp activation)
   if [[ "$veget" == "orchidee1.9" ]] ; then
      CPP_KEY="$CPP_KEY ORCHIDEE_NOOPENMP"
   fi
   if [[ "$veget" == "orchidee2.0" ]] ; then
      orch_libs="sechiba parameters stomate parallel orglob orchidee"
      CPP_KEY="$CPP_KEY ORCHIDEE_NOUNSTRUCT"
   elif [[ "$veget" == "orchidee2.1" ]] ; then
      orch_libs="sechiba parameters stomate parallel orglob orchidee"
   else
      orch_libs="sechiba parameters stomate parallel orglob"
   fi
   LIB="${LIB} -L${ORCH_LIBDIR}"
   for lib in ${orch_libs} ; do
      if [ -f ${ORCH_LIBDIR}/lib${LIBPREFIX}$lib.a ] ; then
         LIB="${LIB} -l${LIBPREFIX}$lib "
      fi
   done
elif [[ "$veget" != "false" ]] ; then
   echo "Option -v $veget does not exist"
   echo "Use ./makelmdz -h for more information"
   exit 
fi

#===============================================================================
if [[ $io == ioipsl ]]
then
   CPP_KEY="$CPP_KEY CPP_IOIPSL"
   INCLUDE="$INCLUDE -I${IOIPSL_INCDIR}"
   LIB="$LIB -L${IOIPSL_LIBDIR} -l${LIBPREFIX}ioipsl"
elif [[ $io == mix ]]
then
   # For now, xios implies also using ioipsl
   CPP_KEY="$CPP_KEY CPP_IOIPSL CPP_XIOS"
   INCLUDE="$INCLUDE -I${IOIPSL_INCDIR} -I${XIOS_INCDIR}"
   LIB="$LIB -L${IOIPSL_LIBDIR} -l${LIBPREFIX}ioipsl -L${XIOS_LIBDIR} -l${LIBPREFIX}stdc++ -l${LIBPREFIX}xios -l${LIBPREFIX}stdc++"
elif [[ $io == xios ]]
then
   # For now, xios implies also using ioipsl
   CPP_KEY="$CPP_KEY CPP_IOIPSL CPP_XIOS CPP_IOIPSL_NO_OUTPUT"
   INCLUDE="$INCLUDE -I${IOIPSL_INCDIR} -I${XIOS_INCDIR}"
   LIB="$LIB -L${IOIPSL_LIBDIR} -l${LIBPREFIX}ioipsl -L${XIOS_LIBDIR} -l${LIBPREFIX}stdc++ -l${LIBPREFIX}xios -l${LIBPREFIX}stdc++"
fi

if [[ "$cosp" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_COSP"
#   COSP_PATH="$LIBFGCM/phylmd/cosp"
   src_dirs="$src_dirs phy${physique}/cosp"
#   LIB="${LIB} -l${LIBPREFIX}cosp"
#  opt_dep="$opt_dep cosp"
#  lcosp="-l${LIBPREFIX}cosp"
   INCLUDE="$INCLUDE"' -I$(LIBF)/'phy${physique}'/cosp'
fi

if [[ "$cosp2" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_COSP2"
   src_dirs="$src_dirs phy${physique}/cosp2"
   INCLUDE="$INCLUDE"' -I$(LIBF)/'phy${physique}'/cosp2'
fi

if [[ "$cospv2" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_COSPV2"
   src_dirs="$src_dirs phy${physique}/cospv2"
   INCLUDE="$INCLUDE"' -I$(LIBF)/'phy${physique}'/cospv2'
fi


if [[ "$sisvat" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_SISVAT"
   src_dirs="$src_dirs phy${physique}/sisvat"
fi


if [[ "$inlandsis" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_INLANDSIS"
   src_dirs="$src_dirs phy${physique}/inlandsis"
fi


if [[ "$rrtm" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_RRTM"
   src_dirs="$src_dirs phy${physique}/rrtm"
fi

if [[ "$dust" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_Dust"
   src_dirs="$src_dirs phy${physique}/Dust"
fi

if [[ "$strataer" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_StratAer"
   src_dirs="$src_dirs phy${physique}/StratAer"
fi

#add new ocean skin modelisation to source dir by default

src_dirs="$src_dirs phy${physique}/Ocean_skin"


INCLUDE="$INCLUDE ${NETCDF_INCDIR}"
LIB="$LIB ${NETCDF_LIBDIR}"

########################################################################
# calcul du nombre de dimensions
########################################################################


dim_full=$dim
dim=`echo $dim | sed -e 's/[^0-9]/ /g'` 
set $dim
dimc=$#
echo calcul de la dimension
echo dim $dim
echo dimc $dimc

########################################################################
# Gestion des dimensions du modele.
# on cree ou remplace le fichier des dimensions
########################################################################

cd $LIBFGCM/grid
if [[ -f dimensions.h ]]
then
  echo 'ATTENTION: vous etes sans doute en train de compiler le modele par ailleurs'
  echo "Attendez que la premiere compilation soit terminee pour relancer la suivante."
  echo "Si vous etes sur que vous ne compilez pas le modele par ailleurs,"
  echo  vous pouvez continuer en repondant oui.
  echo "Voulez-vous vraiment continuer?"
  echo ""
  echo "WARNING: you are probably already compiling the model somewhere else."
  echo "Wait until the first compilation is finished before launching this one."
  echo "If you are sure that you are not compiling elsewhere, just answer "
  echo "yes (or 'oui') to the question below to proceed."
  echo "Do you wish to continue?"
  read reponse
  if [[ $reponse == "oui" || $reponse == "yes" ]]
  then
    \rm -f $LIBFGCM/grid/dimensions.h
  else
    exit
  fi
fi

cd $LIBFGCM/grid/dimension
./makdim $dim
if (($? != 0))
then
    exit 1
fi

cat $LIBFGCM/grid/dimensions.h
cd $LMDGCM

########################################################################
# Differentes dynamiques (3d, 2d, 1d)
########################################################################

if (( $dimc == 3 )) ; then
   src_dirs="$src_dirs $filtre dyn3d_common dyn3d${FLAG_PARA}"
   if [[ $physique != "nophys" ]] ; then
     src_dirs="$src_dirs dynphy_lonlat dynphy_lonlat/phy${phys_root}"
     libdyn_phy="-ldynphy_lonlat"
     LIBDYN_PHYS='$(LIBO)/libdynphy_lonlat.a'
     INCLUDE="$INCLUDE "'-I$(LIBF)/dynphy_lonlat'
     INCLUDE="$INCLUDE "'-I$(LIBF)/dynphy_lonlat/'"phy${phys_root}"
   fi
   cd $LIBFGCM/grid
   \rm fxyprim.h
   cp -p fxy_${grille}.h fxyprim.h
   filtre="FILTRE=$filtre"
   INCLUDE="$INCLUDE "'-I$(LIBF)/dyn3d${FLAG_PARA} -I$(LIBF)/dyn3d_common '
elif (( $dimc == 2 )) ; then
   src_dirs="$src_dirs dyn2d"
   filtre="FILTRE= L_FILTRE= "
   INCLUDE="$INCLUDE "'-I$(LIBF)/dyn2d'
elif (( $dimc == 1 )) ; then
   #src_dirs="$src_dirs dyn3d dyn3d_common filtrez"
   src_dirs="$src_dirs phy${physique}/dyn1d"
   CPP_KEY="$CPP_KEY CPP_1D"
   filtre="L_DYN= DYN= FILTRE= L_FILTRE= "
   #INCLUDE="$INCLUDE "'-I$(LIBF)/dyn3d -I$(LIBF)/dyn3d_common ' # Pas tres propre
   INCLUDE="$INCLUDE "' -I$(LIBF)/phy'"$physique"'/dyn1d'
else
   echo Dimension dimc=$dimc pas prevu ; exit
fi

cd $LMDGCM

########################################################################
# library directory name:
########################################################################

nomlib=`echo ${arch}_${physique}_${dim_full}_${grille}_${compil_mod}_parall${parallel}_${CPP_KEY}_${FLAG_PARA} | sed -e 's/ //g' -e 's/-//g ' | sed -e 's/CPP_//g'`
echo "Path to library: "$nomlib

########################################################################
#  Cleanup for a full recompilation, if requested
########################################################################

if [[ $full == "full" ]]
then
# remove makefile and librairies
  echo "-full option: recompiling from scratch"
  \rm -f makefile
  \rm -rf "${LIBOGCM}/${nomlib}"
fi

########################################################################
#  Avant de lancer le make, on recree le makefile si necessaire
########################################################################
########################################################################
# c'est a dire dans 3 cas:
# 1. si la liste des fichiers .F et .h a ete modifiee depuis la
#    derniere creation du makefile
# 2. si le fichier contenant cette liste "liste_des_sources"
#    n'existe pas.
# 3. Si le makefile n'existe pas.
########################################################################
cd $LMDGCM


if [[ -r .makelmdz ]]
then
old_lmdz_configuration=$(cat .makelmdz )
else
old_lmdz_configuration=""
fi
lmdz_configuration="$src_dirs"
if [[ "$lmdz_configuration" != "$old_lmdz_configuration" ]]
then
  configuration_change="true"
else
  configuration_change="false"
fi

mkdir -p make_dir
suf_make=`echo $src_dirs | sed -e 's/\//_/g' -e 's/ /_/g'`
echo suf_make $suf_make

\rm tmp77 tmp90
for dir in $src_dirs ; do
find libf/$dir -name '*.[Fh]' -print | sort >> tmp77
find libf/$dir -name '*.F90' -print | sort >> tmp90
done

liste77=make_dir/liste_des_sources_f77_$suf_make
liste90=make_dir/liste_des_sources_f90_$suf_make
makefile=make_dir/makefile_$suf_make

if [[ $configuration_change == "true" || ! ( -r $makefile ) || ! ( -r $liste90 ) || ! ( -r $liste77 ) || ` diff tmp77 $liste77 | wc -w ` -ne 0 || ` diff tmp90 $liste90 | wc -w ` -ne 0 ]]
then
  echo "les fichiers suivants ont ete crees ou detruits"
  echo "ou les fichiers suivants sont passes ou ne sont plus en Fortran 90"
  diff $liste77 tmp77
  diff $liste90 tmp90
  \cp -f tmp77 $liste77
  \cp -f tmp90 $liste90
  echo "Recreating the makefile"
  echo "src_dirs: $src_dirs"
  ./create_make_gcm $src_dirs > tmp 
  \mv -f tmp $makefile
  echo "New makefile created"
fi

ln -sf $makefile makefile

#Create a .makelmdz file containing main compilation option for later comparisons
echo "$lmdz_configuration" > .makelmdz

#################################################################
# Preparation de l'execution de la comande make
#################################################################

source_code=${code}.F
dirmain=dyn${dimc}d${FLAG_PARA}
if [[ -r $LMDGCM/libf/dyn${dimc}d${FLAG_PARA}/${code}.F90 ]]
then
  source_code=${code}.F90
elif [[ -r $LMDGCM/libf/phy$physique/${code}.F90 ]] ; then
  dirmain=phy$physique
  source_code=${code}.F90
elif [[ -r $LMDGCM/libf/dynphy_lonlat/phy$phys_root/${code}.F90 ]] ; then
  dirmain="dynphy_lonlat/phy${phys_root}"
  source_code=${code}.F90
elif [[ -r $LMDGCM/libf/phy$physique/dyn1d/${code}.F90 ]] ; then
  dirmain=phy$physique/dyn1d
  source_code=${code}.F90
fi

if [[ ! -d "${LIBOGCM}/${nomlib}" ]]
then
  mkdir ${LIBOGCM}/${nomlib}
  # check we indeed managed to create the directory
  if [[ ! $? ]]
  then
    echo "Error: could not create directory ${LIBOGCM}/${nomlib}"
    exit
  fi
fi

# where module files are created 
mod_loc_dir=$localdir

if [[ "$physique" != "nophys" ]]
then
  INCLUDE="$INCLUDE"' -I$(LIBF)/phy'"$physique"
fi
INCLUDE="$INCLUDE"' -I'${LIBOGCM}/${nomlib}

# ranlib utility (check it exists or else default to ls)
if [[ `which ranlib > /dev/null 2>&1 ; echo $?` -eq 0 ]]
then
  ranlib="ranlib"
else
  ranlib="ls"
fi

# add CPP keys to COMPIL_FLAGS
# (but first add -D before all CPP_KEY items)
cpp_definitions=`echo $CPP_KEY | sed -e 's/[A-Za-z_=0-9]*/-D&/g'`
# (but add a -WF,-D before all CPP_KEY items) => for xlf on Vargas
if [[ "${fcompiler:0:3}" == "xlf" ]]
then
cpp_definitions=`echo $CPP_KEY | sed -e 's/[A-Za-z_=0-9]*/-WF,-D&/g'`
fi
COMPIL_FFLAGS="${COMPIL_FFLAGS} ${cpp_definitions}"

#################################################################
# Execution du make
#################################################################
echo $makecommand RANLIB=$ranlib -f $LMDGCM/makefile \
OPTION_DEP="$opt_dep" OPTION_LINK="$LIB ${PARA_LD}" \
OPTIM90="${COMPIL_FFLAGS} ${PARA_FFLAGS}" \
OPTIMTRU90="${COMPIL_FFLAGS} ${PARA_FFLAGS}" \
OPTIM="${COMPIL_FFLAGS} ${PARA_FFLAGS}" \
INCLUDE="$INCLUDE" \
$filtre \
LIBO=${LIBOGCM}/${nomlib} \
"PHYS=$physique" \
LIBPHY=${LIBPHY} \
LIBPHY_COMMON=${LIBPHY_COMMON} \
LIBDYN_PHYS=${LIBDYN_PHYS} \
DIM=$dimc \
FLAG_PARA=$FLAG_PARA \
L_PHY="$lib_phy" \
L_DYN_PHY="$libdyn_phy" \
L_ADJNT=$adjnt \
L_COSP="$lcosp" \
L_COSP2="$lcosp2" \
L_COSPV2="$lcospv2" \
L_CHIMIE="$libchimie" \
LOCAL_DIR="$localdir"  \
F77="$fcompiler" \
F90="$fcompiler" \
OPLINK="$LIB" \
LINK="$linker" \
GCM="$LMDGCM" \
MOD_LOC_DIR=$mod_loc_dir \
MOD_SUFFIX="mod" \
AR=$arcommand \
ARFLAGS="$arflags" \
DIRMAIN=$dirmain \
SOURCE=$source_code \
PROG=$code

$makecommand RANLIB=$ranlib -f $LMDGCM/makefile \
OPTION_DEP="$opt_dep" OPTION_LINK="$LIB ${PARA_LD}" \
OPTIM90="${COMPIL_FFLAGS} ${PARA_FFLAGS}" \
OPTIMTRU90="${COMPIL_FFLAGS} ${PARA_FFLAGS}" \
OPTIM="${COMPIL_FFLAGS} ${PARA_FFLAGS}" \
INCLUDE="$INCLUDE" \
$filtre \
LIBO=${LIBOGCM}/${nomlib} \
"PHYS=$physique" \
LIBPHY=${LIBPHY} \
LIBPHY_COMMON=${LIBPHY_COMMON} \
LIBDYN_PHYS=${LIBDYN_PHYS} \
DIM=$dimc \
FLAG_PARA=$FLAG_PARA \
L_PHY="$lib_phy" \
L_DYN_PHY="$libdyn_phy" \
L_ADJNT=$adjnt \
L_COSP="$lcosp" \
L_COSP2="$lcosp2" \
L_COSPV2="$lcospv2" \
L_CHIMIE="$libchimie" \
LOCAL_DIR="$localdir"  \
F77="$fcompiler" \
F90="$fcompiler" \
OPLINK="$LIB" \
LINK="$linker" \
GCM="$LMDGCM" \
MOD_LOC_DIR=$mod_loc_dir \
MOD_SUFFIX="mod" \
AR=$arcommand \
ARFLAGS="$arflags" \
DIRMAIN=$dirmain \
SOURCE=$source_code \
PROG=$code


if [[ -r $LIBFGCM/grid/dimensions.h ]]
then
  # Cleanup: remove dimension.h file
  \rm -f $LIBFGCM/grid/dimensions.h
fi
