Skip to content
Snippets Groups Projects
makenemo 14.1 KiB
Newer Older
Guillaume Samson's avatar
Guillaume Samson committed
#!/bin/bash
set -o posix
#set -x
Guillaume Samson's avatar
Guillaume Samson committed
#set -u
#set -e
#
# ===============
# makenemo
# ===============
#
# --------------------------
# Compile NEMO
# --------------------------
#
# SYNOPSIS
# ========
#
#  $ makenemo
#
#
# DESCRIPTION
# ===========
#
# This script aims :
#
# - to choose MYCONFIG
# - to choose compiler options
# - to create the CONFIG/MYCONFIG/WORK directory
# - to compile this configuration
#
#  Variables used :
#
#  From user input
#
# - NEW_CONF    : configuration to be created
# - REF_CONF    : reference configuration to build the new one from
# - CMP_NAM     : compiler name
# - NBR_PRC     : number of processes used to compile
# - NEM_SUBDIR  : NEMO subdirectory used (specified)
#
#  Locally defined :
#
# - MAIN_DIR    : self explaining
# - CONFIG_DIR  :   "    "    "
# - NEMO_DIR    :   "    "    "
# - REMOTE_CTL  : URL link to a remote resource list for an external configuration
#                 which is not part of the reference suite
# - LOCAL_REF   : Nearest reference configuration to an external configuration
#                 which is not part of the reference suite
#                 (used to populate work directories if remote access is not available)
#
# EXAMPLES
# ========
#
#  $ ./makenemo -m ifort_osx -j 3 -r ORCA2_ICE_PISCES -n MY_ORCA2
Guillaume Samson's avatar
Guillaume Samson committed


# Initialization of the options
x_d=''; x_h=''; x_n=''; x_r=''; x_c='';
x_u=''; x_a=''; x_m=''; x_t=''; x_b='';
x_j='1'; x_e=''; x_s='src'; x_v='1'
Guillaume Samson's avatar
Guillaume Samson committed
list_key='0'; chk_key='1'
list_add_key=''; list_def_key=''; list_del_key=''
x_c_cfg=0; x_nocdf=0


# Local variables
MAIN_DIR=$(cd $(dirname "$0"); pwd)
MAIN_DIR=${MAIN_DIR%/+(sette|tools|cfgs|tests|ext|arch)}
COMPIL_DIR=${MAIN_DIR}/mk
PATH=${MAIN_DIR}/ext/FCM/bin:$PATH
Guillaume Samson's avatar
Guillaume Samson committed


# Choice of the options
while [ ${#1} -gt 0 ]; do
    
    case "$1" in
	-h|--help) cat <<EOF
Guillaume Samson's avatar
Guillaume Samson committed
Usage:
------
./makenemo -[arn] CONFIG -m ARCH [-[...] ...] 
Guillaume Samson's avatar
Guillaume Samson committed

Mandatory
   -m, --mach, --machine, --arch <machine_name>
            Computing architecture, will use the file arch_<machine_name>.fcm located
            in ./arch (sub)directory(ies)
Guillaume Samson's avatar
Guillaume Samson committed

   -n, --name <config_name>
            Name of the configuration to compile
Guillaume Samson's avatar
Guillaume Samson committed

 and, if -n defines a new configuration, one of the following option (use 'all' arg to
 list available items):

   -r, --ref <ref_config_name>  
            To specify which reference configuration (./cfgs) must be used to buit the
            new configuration
   -a, --test <test_config_name>  
            To specify which academic test case (./tests) must be used to buit the new
            configuration
Guillaume Samson's avatar
Guillaume Samson committed

Optional
   --add_key, key_add, add_key "<list of keys>"
            list of cpp keys to be added in cpp_<config_name>.fcm file
   -b, --dbg, --debug    
            add it to compile in debug mode
   --clean, --clean_compil, clean
            Clean all files and directories used for  compilation + the REPRO_* and
            the SHORT directories
   --clean_config, clean_config
            Completly delete a configuration 
   -d, --dirs, --comp <sub-components>  
            New set of sub-components (subfolders from ./src directory) to be used
   --def_key, key_def, def_key "<list of keys>"
            list of all cpp keys to be defined in cpp_<config_name>.fcm file
   --del_key, key_del, del_key "<list of keys>"
            list of cpp keys to be deleted in cpp_<config_name>.fcm file
   -e, --my_srcpath, --my_src_path, --MY_SRCpath, --MY_SRC_path <path>  
            Path for alter patch location (default: 'MY_SRC' in configuration folder)
   -h, --help
            Print this help
   -j, --jobs <nb_job>
            Number of processes to compile (0: dry run with no build)
   -k, --chkkey <O/1>
            Set to 0 to bypass the check of the cpp keys (takes time at the beginning
            of makenemo). Default is 1
   --list_key, --key_list, list_key
            List all existing cpp keys in the configuration and exit without compiling 
   --nonc, --nocdf, --nonetcdf, --no_nc, --no_cdf, --no_netcdf 
            Compile without the NetCDF Library
   -s, --srcpath, --src_path  <path>   
            Path for alter source location (default: 'src' root directory)
   -t, --bldpath, --bld_path, --BLDpath, --BLD_path <path>   
            Path for alter build  location (default: 'BLD' in configuration folder)
   -v, --verbose <0/1/2/3>
            Level of verbosity ([0-3])
Guillaume Samson's avatar
Guillaume Samson committed

Examples
   ¤ Configuration creation
        Build          : ./makenemo         -[ar] ... [...]
        Copy           : ./makenemo -n ...  -[ar] ... [...]
Guillaume Samson's avatar
Guillaume Samson committed
   ¤ Configuration management
        List CPP keys  : ./makenemo -n ... list_key
        Add-Remove keys: ./makenemo -n ... --add_key '...' --del_key '...'
        Fresh start    : ./makenemo -n ... --clean
        Removal        : ./makenemo -n ... --clean_config
Guillaume Samson's avatar
Guillaume Samson committed

EOF
	    exit 0       ;;
	-b|--dbg|--debug)
	    x_b="True" ;;
	-d|--dirs|--comp)
	    x_d=${2} ; shift ;;
	-n|--name)
	-r|--ref)
	    x_r=${2} ; shift ;;
	-a|--academic|--test)
	    x_a=${2} ; shift ;;
	-m|--mach|--machine|--arch)
	    x_m=${2} ; shift ;;
	-j) x_j=${2} ; shift ;;
	-t|--bldpath|--bld_path|--BLDpath|--BLD_path)
	    x_t=${2} ; shift ;;
	-e|--my_srcpath|--my_src_path|--MY_SRCpath|--MY_SRC_path)
	    x_e=${2} ; shift ;;
	-s|--srcpath|--src_path)
	    x_s=${2} ; shift ;;
	-v|--verbose)
	    x_v=${2} ; shift ;;
	-k|--chkkey)
	    chk_key=${2} ; shift ;;
	--nonc|--nocdf|--nonetcdf|--no_nc|--no_cdf|--no_netcdf)
	    x_nocdf=1  ;;
	--clean|--clean_compil|clean)
	    x_c="--clean"  ;;
	--clean_config|clean_config)
	--add_key|--key_add|add_key     ) [[ ! "$2" =~ ^\ +$ ]] && list_add_key=$2; shift;;
	--def_key|--key_def|def_key     ) [[ ! "$2" =~ ^\ +$ ]] && list_def_key=$2; shift;;
	--del_key|--key_del|del_key     ) [[ ! "$2" =~ ^\ +$ ]] && list_del_key=$2; shift;;
	--list_key|--key_list|list_key) list_key='1'                                   ;;
	*) echo -e "\033[0;31m\n \"$1\" BAD OPTION\033[0m\n"; exit 2              ;;
Guillaume Samson's avatar
Guillaume Samson committed
done


# Variables definition based on options
Guillaume Samson's avatar
Guillaume Samson committed
NBR_PRC=${x_j}
CMP_NAM=${x_m}
NEMO_DIR=${MAIN_DIR}/${x_s}


# Print available arch files
[ "${CMP_NAM}" == 'all' ] && ${COMPIL_DIR}/Flist_archfile.sh && exit 0


# New config case
if [ -n "${x_n}" ]; then

  # Look for already-existing new config
  NEW_CONF=${x_n}
  if [ -n "${x_t}" ]; then
    NEW_DIR=$( find -L ${x_t} -maxdepth 1 -type d -name ${x_n} 2>/dev/null )
    NEW_DIR=$( find -L ${MAIN_DIR}/cfgs ${MAIN_DIR}/tests -maxdepth 1 -type d -name ${NEW_CONF} 2>/dev/null )
  fi
  NEW_NB=$( echo ${NEW_DIR} | wc -w )
  NEW_CMP=$( grep -l "^${NEW_CONF} " ${MAIN_DIR}/cfgs/*_cfgs.txt ${MAIN_DIR}/tests/*_cfgs.txt | tail -1 )

  # Define if new config needs to be created or not
  if [[ ${NEW_NB:-0} -eq 0 || -z "${NEW_CMP}" ]]; then
    DO_NEW=1
  else
    DO_NEW=0
    NEW_SUB="$( grep "^${NEW_CONF} " ${NEW_CMP} | awk '{$1 = ""; print $0}' )"
    if [[ -n "${x_r}" || -n "${x_a}" ]]; then
      echo -e "\nWARNING: ${NEW_CONF} configuration is already existing, we ignore \"-r\" & \"-a\" options\n"
    fi
  fi
Guillaume Samson's avatar
Guillaume Samson committed

fi


# Define ref config if new config not defined or not existing yet
if [[ ${DO_NEW:-0} -eq 1 || -z "${NEW_CONF}" ]]; then

  if [[ -n "${x_r}" || -n "${x_a}" ]]; then
    REF_DIR=$( find ${MAIN_DIR}/cfgs ${MAIN_DIR}/tests -maxdepth 1 -type d -name ${x_r:-""} -o -name ${x_a:-""} 2>/dev/null )
    REF_NB=$( echo ${REF_DIR} | wc -w )
    REF_CMP=$( grep -l "^${x_r} \|^${x_a} " ${MAIN_DIR}/cfgs/ref_cfgs.txt ${MAIN_DIR}/tests/demo_cfgs.txt )
    if [[ ${REF_NB} -eq 1 && -n "${REF_CMP}" ]]; then
      REF_CONF=$(basename ${REF_DIR})
      REF_TYPE=$(basename ${REF_DIR%\/*})
      REF_FILE=$(basename ${REF_CMP})
      REF_SUB="$( grep "^${REF_CONF} " ${REF_CMP} | awk '{$1 = ""; print $0}' )"
    elif [ ${REF_NB} -gt 1 ]; then
      echo -e "Please choose only one reference configuration (-r) or testcase (-a)"; exit 2
    elif [ ${REF_NB} -eq 0 ]; then
      echo -e "Please choose at least one reference configuration (-r) or testcase (-a) from:"
      ${COMPIL_DIR}/Flist_cfgs.sh ${MAIN_DIR}; exit 2
  else
    echo -e "Please choose at least one reference configuration (-r) or testcase (-a) from:"
    ${COMPIL_DIR}/Flist_cfgs.sh ${MAIN_DIR}; exit 2
  fi

  # force config creation if ref config installed outside nemo directory
  if [[ -n "${x_t}" && ${x_t} != ${REF_DIR%\/*} ]]; then DO_NEW=1; fi

Guillaume Samson's avatar
Guillaume Samson committed


# Current config (new or ref) definition
CFG_DIR=$( dirname ${NEW_CMP:-${REF_CMP}} )
CUR_DIR=${NEW_DIR:-${REF_DIR}}
CUR_CONF=${NEW_CONF:-${REF_CONF}}
CUR_SUB=${NEW_SUB:-${REF_SUB}}
NEMO_TDIR=${x_t:-${CUR_DIR%\/*}}
# Config cleaning
if [ -d ${NEMO_TDIR}/${CUR_CONF} ]; then

    if [ $x_c_cfg -eq 1 ] ; then
        ${COMPIL_DIR}/Fclean_config.sh ${NEMO_TDIR}/${CUR_CONF}
        exit 0
    elif [ ${#x_c} -ne 0 ]; then

        #read -p "Are you sure that you want to clean $CUR_CONF configuration ? " -n 1 -r; echo
        #if [[ $REPLY =~ ^[Yy]$ ]]; then
            # choose & generate fcm cfg file
            [ $x_nocdf -eq 1 ] && USEBLD=bldxagxcdf.cfg || USEBLD=bldxag.cfg
            grep key_agrif ${NEMO_TDIR}/${CUR_CONF}/BLD/cpp.fcm 2>/dev/null && USEBLD=${USEBLD/xag/}
            sed -e "s~MAIN_DIR~${MAIN_DIR}~; s~NEMO_TDIR~${NEMO_TDIR}~; s~CUR_CONF~${CUR_CONF}~; s~COMPIL_DIR~${COMPIL_DIR}~" ${COMPIL_DIR}/${USEBLD} > ${NEMO_TDIR}/${CUR_CONF}/BLD/${USEBLD}

            fcm build ${x_c} --ignore-lock -v ${x_v} -j ${NBR_PRC} ${NEMO_TDIR}/${CUR_CONF}/BLD/${USEBLD} || exit 1

            # remove all build directories
            echo -e '\nCleaning '${CUR_CONF}' building directories and variables\n'
            for dir in AGRIFLIB BLD LONG NEMOFILES REPRO_* SHORT WORK; do
               rm -rf ${NEMO_TDIR}/${CUR_CONF}/$dir
            done
            for file in cpp.history cpp.fcm full_key_list.txt; do
               rm -f ${NEMO_TDIR}/${CUR_CONF}/BLD/$file
        #else
        #    echo "cleaning cancelled"
        #    exit 2
        #fi
    [ $x_c_cfg -eq 1 ] && echo -e "\nWARNING: Configuration cleaning of a non-existing configuration, we ignore\n" && exit 0
    [  ${#x_c} -ne 0 ] && echo -e "\nWARNING: Compilation cleaning of a non-existing configuration, we ignore\n" && exit 0
fi


# Create/update config components list
NEM_SUBDIR=( ${x_d:-${CUR_SUB}} )
if [ ${DO_NEW:-0} -eq 1 ]; then
    echo
    printf "\nYou are installing a new configuration %s from %s " ${CUR_CONF} ${REF_CONF}
    printf  "with sub-components: %s\n"  "${NEM_SUBDIR[*]}"
    echo
else
    echo
    printf "\nYou are compiling an existing configuration %s " ${CUR_CONF}
    printf  "with sub-components: %s\n"  "${NEM_SUBDIR[*]}"
    echo
if [[ -n "${x_d}" || ${DO_NEW:-0} -eq 1 ]]; then
    [ -f ${CFG_DIR}/work_cfgs.txt ] && sed -i'' -e "/^${CUR_CONF} /d" ${CFG_DIR}/work_cfgs.txt
    echo ${CUR_CONF} "${NEM_SUBDIR[*]}" >> ${CFG_DIR}/work_cfgs.txt
# Create config directories
${COMPIL_DIR}/Fmake_config.sh ${NEMO_TDIR}/${CUR_CONF} ${REF_DIR:-${NEMO_TDIR}/${CUR_CONF}}
Guillaume Samson's avatar
Guillaume Samson committed

# Create/update WORK directory
${COMPIL_DIR}/Fmake_WORK.sh "${NEM_SUBDIR[*]/#/${NEMO_DIR}/}" "${x_e:-"MY_SRC"}" ${NEMO_TDIR}/${CUR_CONF} || exit 3
# Build the complete list of the CPP keys of this configuration
if [[ ${chk_key} -eq 1 || ${list_key} -eq 1 ]] ; then
    grep -h "^#.*defined.*\|^#if.*def.*" ${NEMO_TDIR}/${CUR_CONF}/WORK/* | \
    grep -o "key_[[:alnum:]]\+\|key_[[:alnum:]]\+_[[:alnum:]]\+\|iso_[[:alnum:]]\+_[[:alnum:]]\+" | \
    sort | uniq > ${NEMO_TDIR}/${CUR_CONF}/BLD/full_key_list.txt
    [ ${list_key} -eq 1 ] && echo && cat ${NEMO_TDIR}/${CUR_CONF}/BLD/full_key_list.txt && exit 0
# CPP keys addition/removal
[ -n "${list_add_key}" ] && ${COMPIL_DIR}/Fadd_keys.sh ${NEMO_TDIR}/${CUR_CONF} "${list_add_key}"
[ -n "${list_def_key}" ] && ${COMPIL_DIR}/Fdef_keys.sh ${NEMO_TDIR}/${CUR_CONF} "${list_def_key}"
[ -n "${list_del_key}" ] && ${COMPIL_DIR}/Fdel_keys.sh ${NEMO_TDIR}/${CUR_CONF} "${list_del_key}"


# CPP keys check
Guillaume Samson's avatar
Guillaume Samson committed
if [ $chk_key -eq 1 ] ; then
    for kk in $( sed -n -e "s/bld::tool::fppkeys \+//p" ${NEMO_TDIR}/${CUR_CONF}/cpp_${CUR_CONF}.fcm ); do
        if ! grep -q $kk ${NEMO_TDIR}/${CUR_CONF}/BLD/full_key_list.txt; then
	    echo
	    echo "E R R O R : key "$kk" is not found in ${NEMO_TDIR}/${CUR_CONF}/WORK routines..."
	    echo "we stop..."
	    echo
	    exit 1
        fi
# CPP & arch files check
ln -sf ${NEMO_TDIR}/${CUR_CONF}/cpp_${CUR_CONF}.fcm ${NEMO_TDIR}/${CUR_CONF}/BLD/cpp.fcm
${COMPIL_DIR}/Fcheck_archfile.sh ${NEMO_TDIR}/${CUR_CONF}/BLD/arch_nemo.fcm ${NEMO_TDIR}/${CUR_CONF}/BLD/cpp.fcm ${MAIN_DIR}/arch/arch-${CMP_NAM}.fcm ${NEMO_DBG} || exit 3
Guillaume Samson's avatar
Guillaume Samson committed


# Compilation
Guillaume Samson's avatar
Guillaume Samson committed
if [ "${NBR_PRC}" -gt 0 ]; then
    # choose & generate fcm cfg file
    [ $x_nocdf -eq 1 ] && USEBLD=bldxagxcdf.cfg || USEBLD=bldxag.cfg
    # AGRIF preprocessing
    grep key_agrif ${NEMO_TDIR}/${CUR_CONF}/BLD/cpp.fcm 2>/dev/null && USEBLD=${USEBLD/xag/}
    if [[ ! ${USEBLD} =~ "xag" ]]; then
        ${COMPIL_DIR}/Fprep_agrif.sh ${MAIN_DIR} ${NEMO_TDIR}/${CUR_CONF} || exit 3

        # compile & copy conv
        sed -e "s~MAIN_DIR~${MAIN_DIR}~; s~NEMO_TDIR~${NEMO_TDIR}~; s~CUR_CONF~${CUR_CONF}~; s~COMPIL_DIR~${COMPIL_DIR}~" ${COMPIL_DIR}/conv.cfg > ${NEMO_TDIR}/${CUR_CONF}/BLD/conv.cfg
        fcm build ${NEMO_TDIR}/${CUR_CONF}/BLD/conv.cfg || exit 1
        ln -sfv ${MAIN_DIR}/ext/AGRIF/agrif_oce.in ${NEMO_TDIR}/${CUR_CONF}/AGRIFLIB/bin/conv ${NEMO_TDIR}/${CUR_CONF}/NEMOFILES/.

        sed -e "s~MAIN_DIR~${MAIN_DIR}~; s~NEMO_TDIR~${NEMO_TDIR}~; s~CUR_CONF~${CUR_CONF}~; s~COMPIL_DIR~${COMPIL_DIR}~" ${COMPIL_DIR}/bld_preproagr.cfg > ${NEMO_TDIR}/${CUR_CONF}/BLD/bld_preproagr.cfg
	fcm build --ignore-lock -j 1 ${NEMO_TDIR}/${CUR_CONF}/BLD/bld_preproagr.cfg || exit 1
	echo
	echo "---------------------------------"
	echo "CONV preprocessing successfull !!"
	echo "---------------------------------"
    sed -e "s~MAIN_DIR~${MAIN_DIR}~; s~NEMO_TDIR~${NEMO_TDIR}~; s~CUR_CONF~${CUR_CONF}~; s~COMPIL_DIR~${COMPIL_DIR}~" ${COMPIL_DIR}/${USEBLD} > ${NEMO_TDIR}/${CUR_CONF}/BLD/${USEBLD}
    fcm build --ignore-lock -v ${x_v} -j ${NBR_PRC} ${NEMO_TDIR}/${CUR_CONF}/BLD/${USEBLD} || exit 1
Guillaume Samson's avatar
Guillaume Samson committed

    if [ -f ${NEMO_TDIR}/${CUR_CONF}/BLD/bin/nemo.exe ]; then
	(cd ${NEMO_TDIR}/${CUR_CONF}/EXP00; ln -sfv ../BLD/bin/nemo.exe ./nemo)