#!/bin/bash #set -x set -o posix #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 : # # - TAB : NEMO subdirectory used (read) # - MAIN_DIR : self explaining # - CONFIG_DIR : " " " # - MODELES_DIR : " " " # - TOOLS_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 - j3 -n ORCA2_SI3_PISCES # # # TODO # ==== # # option debug # # # EVOLUTIONS # ========== # # $Id: makenemo 15186 2021-08-12 16:39:09Z gsamson $ # # # # * creation # #- #- ##- 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='none'; x_s='src'; x_v='1' x_nocdf=0 x_name='' ##- Local variables --- b_n=$(basename ${0}) OPTIND='1' MAIN_DIR=$(cd $(dirname "$0"); pwd) MAIN_DIR=${MAIN_DIR%/sette*} MAIN_DIR=${MAIN_DIR%/tools*} MAIN_DIR=${MAIN_DIR%/cfgs*} MAIN_DIR=${MAIN_DIR%/tests*} MAIN_DIR=${MAIN_DIR%/ext*} MAIN_DIR=${MAIN_DIR%/arch*} export MAIN_DIR # export CFGS_DIR=${MAIN_DIR}/cfgs export TESTS_DIR=${MAIN_DIR}/tests export TOOLS_DIR=${MAIN_DIR}/tools export COMPIL_DIR=${MAIN_DIR}/mk export NEMO_DIR=${MAIN_DIR}/${x_s} export AGRIFUSE='10' list_key='0'; chk_key='1' list_add_key=''; list_def_key=''; list_del_key='' #- #- FCM and functions location --- export PATH=${MAIN_DIR}/ext/FCM/bin:$PATH #- #- Choice of the options --- ## Get clean, clean_config options while [ ${#1} -gt 0 ]; do case "$1" in -h|--help) cat <<EOF Usage: ------ ./makenemo -[arn] CONFIG -m ARCH [-[...] ...] [{list_key,clean,clean_config}] Mandatory -m, --mach, --machine, --arch <machine_name> Computing architecture, will use the file arch_<machine_name>.fcm located in ./arch (sub)directory(ies) -n, --name <config_name> Name of the configuration to compile 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 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 -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 --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]) Examples ¤ Configuration creation Build : ./makenemo -[ar] ... [...] Copy : ./makenemo -n ... -[ar] ... [...] ¤ 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 EOF exit 0 ;; -b|--dbg|--debug) x_b="True" ;; -d|--dirs|--comp) x_d=${2} ; shift ;; -n|--name) x_name=${2} ; shift ;; -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) x_c="--$1" ;; --clean_config|clean_config) . ${COMPIL_DIR}/Fclean_config.sh; exit ;; ## Checking if argument has anything other than whitespace --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|list_key ) list_key='1' ;; '*' ) echo " \"$1\" BAD OPTION"; exit 2 ;; ':') echo ${b_n}" : -"${1}" option : missing value" 1>&2; exit 2 ;; '?') echo ${b_n}" : -"${1}" option : not supported" 1>&2; exit 2 ;; esac shift done if [ -n "$x_name" ] # is the configuration existing in cfgs or tests? or is it a new conf? then incfg=$( find $CFGS_DIR -type d -name $x_name | wc -l ) # this configuration exists in CFGS_DIR intst=$( find $TESTS_DIR -type d -name $x_name | wc -l ) # this configuration exists in TESTS_DIR [[ $incfg -eq 0 && $intst -eq 0 ]] && x_n=$x_name # this is a new configuration -> dedine/overwrite x_n [[ $incfg -eq 1 && -z "$x_r" ]] && x_r=$x_name # this is a reference configuration -> dedine/overwrite x_r [[ $intst -eq 1 && -z "$x_a" ]] && x_a=$x_name # this is a test configuration -> dedine/overwrite x_a fi export NEW_CONF=${x_n} NBR_PRC=${x_j} CMP_NAM=${x_m} NEM_SUBDIR=${x_d} REF_CONF=${x_r} DEMO_CONF=${x_a} export NEMO_DIR=${MAIN_DIR}/${x_s} NEMO_DBG=${x_b} [ "${CMP_NAM}" == 'all' ] && . ${COMPIL_DIR}/Flist_archfile.sh all && exit ## No ref. cfg or demo selected if [[ -z "${REF_CONF}" && -z "${DEMO_CONF}" ]]; then ## Reuse last configuration compiled if any (existing 'work_cfgs.txt') # if [[ $( find ./cfgs ./tests -name work_cfgs.txt ) ]]; then # CFGS_DIR=${MAIN_DIR}/$( ls -rt */work_cfgs.txt | awk -F/ 'END{ print $1}' ) # TML_CONF=$( tail -1 ${CFGS_DIR}/work_cfgs.txt | awk '{ print $1 }' ) # else ## No ${REF_CONF}, ${DEMO_CONF} nor ${NEM_SUBDIR} and 1st compilation => exit # echo -e "\033[0;33m\nNo previous build found!" echo -e "\033[0;31m\nAt least a reference configuration ('-r'), a test case ('-a'), " echo -e "a remote configuration ('-u') has to be choosen!!!\033[0m" ${COMPIL_DIR}/Flist_cfgs.sh exit 2 # fi fi ## At least one config has been requested ## 'all' arg: list all available configurations if [[ "${REF_CONF}" == 'all' || "${DEMO_CONF}" == 'all' ]]; then ${COMPIL_DIR}/Flist_cfgs.sh exit 2 ## Probably useless but who knows? elif [[ -n "${REF_CONF}" && -n "${DEMO_CONF}" ]]; then echo -e "\033[0;31m\nYou have to choose whether you work with:" echo -e " - LTS configurations in ./cfgs ('-r') or" echo -e " - Unsupported cases in ./tests ('-a')\033[0m\n" exit 2 elif [ -n "${REF_CONF}" ]; then conf_file=ref_cfgs.txt ; export CONFIG_DIR=${CFGS_DIR} ; TML_CONF=${REF_CONF} elif [ -n "${DEMO_CONF}" ]; then conf_file=demo_cfgs.txt; export CONFIG_DIR=${TESTS_DIR}; TML_CONF=${DEMO_CONF} fi ## Reuse a working cfg grep -q "${TML_CONF} " ${CONFIG_DIR}/work_cfgs.txt 2>/dev/null && conf_file=work_cfgs.txt ## Test if ref. cfg or demo case does exist if (! grep -q "${TML_CONF} " ${CONFIG_DIR}/$conf_file ); then echo -e "\033[0;31m\nThe reference configuration ('-r') or " echo -e "demonstration case ('-a') selected is not available!!!" echo -e "Check the option used and the available items in .txt files\033[0m" ${COMPIL_DIR}/Flist_cfgs.sh exit 2 fi ## If new cfg exists, work in it if [ -n "${NEW_CONF}" ] then echo printf "\nYou are installing a new configuration %s from %s " ${NEW_CONF} ${TML_CONF} printf "with sub-components: %s\n" "${NEM_SUBDIR}" echo else NEW_CONF=${TML_CONF} fi ## Update sub-comps if needed if [ -z "${NEM_SUBDIR}" ]; then NEM_SUBDIR=$( grep "${TML_CONF} " ${CONFIG_DIR}/${conf_file} | awk '{$1 = ""; print $0}' ) fi export NEMO_TDIR=${x_t:-$CONFIG_DIR} export NEM_SUBDIR="${NEM_SUBDIR}" NEW_CONF="${NEW_CONF}" ## Save new configuration with sub-components set in work_cfgs.txt [ -f ${CONFIG_DIR}/work_cfgs.txt ] && sed -i "/${NEW_CONF} /d" ${CONFIG_DIR}/work_cfgs.txt echo ${NEW_CONF} "${NEM_SUBDIR}" >> ${CONFIG_DIR}/work_cfgs.txt cd ${CONFIG_DIR} ## Create new config even in existing one (mkdir with -p option, cp with -n) ${COMPIL_DIR}/Fmake_config.sh ${NEW_CONF} ${TML_CONF} ## create EXP00 if needed [ ! -d ${CONFIG_DIR}/${NEW_CONF}/EXP00 ] && \cp -R -n ${CONFIG_DIR}/${NEW_CONF}/EXPREF ${CONFIG_DIR}/${NEW_CONF}/EXP00 #- Create the WORK --- #- Clean links and librairies --- #- Creating the good links, at first on OCE --- . ${COMPIL_DIR}/Fmake_WORK.sh ${x_e[@]} || exit 3 . ${COMPIL_DIR}/Fmake_bld.sh ${CONFIG_DIR} ${NEW_CONF} ${NEMO_TDIR} || exit 3 # build the complete list of the cpp keys of this configuration if [ ${chk_key} -eq 1 ] ; then for i in $( grep "^ *#.* key_" ${NEW_CONF}/WORK/* ); do echo $i | grep key_ | sed -e "s/=.*//" done \ | sort -d | uniq > ${COMPIL_DIR}/full_key_list.txt [ ${list_key} -eq 1 ] && cat ${COMPIL_DIR}/full_key_list.txt && exit 0 fi #- At this stage new configuration has been added, we add or remove keys [ ! -z "${list_add_key}" ] && { . ${COMPIL_DIR}/Fadd_keys.sh ${NEW_CONF} add_key ${list_add_key}; } [ ! -z "${list_def_key}" ] && { . ${COMPIL_DIR}/Fdef_keys.sh ${NEW_CONF} def_key ${list_def_key}; } [ ! -z "${list_del_key}" ] && { . ${COMPIL_DIR}/Fdel_keys.sh ${NEW_CONF} del_key ${list_del_key}; } #- check that all keys are really existing... if [ $chk_key -eq 1 ] ; then for kk in $( cat ${NEW_CONF}/cpp_${NEW_CONF}.fcm ); do if [ "$( echo $kk | cut -c 1-4 )" == "key_" ]; then kk=${kk/=*/} if [ ! $( grep -w $kk ${COMPIL_DIR}/full_key_list.txt ) ]; then echo echo "E R R O R : key "$kk" is not found in ${NEW_CONF}/WORK routines..." echo "we stop..." echo exit 1 fi fi done fi #- At this stage cpp keys have been updated. we can check the arch file #- When used for the first time, choose a compiler --- . ${COMPIL_DIR}/Fcheck_archfile.sh arch_nemo.fcm cpp.fcm ${CMP_NAM} || exit 3 #- At this stage the configuration has beeen chosen #- We coose the default light file [ $x_nocdf -eq 1 ] && export USEBLD=bldxagxcdf.cfg || export USEBLD=bldxag.cfg #- We look after agrif grep key_agrif ${COMPIL_DIR}/cpp.fcm && export AGRIFUSE=1 && export USEBLD=${USEBLD/xag/} . ${COMPIL_DIR}/Fprep_agrif.sh ${NEW_CONF} ${NEMO_TDIR} arch_nemo.fcm || exit 3 #- #_ END OF CONFIGURATION PHASE #_ #- #- Compile --- if [ "${NBR_PRC}" -gt 0 ]; then cd ${NEMO_TDIR}/${NEW_CONF} || cd - ## if AGRIF we do a first preprocessing if [[ ${#x_c} -eq 0 && "$AGRIFUSE" -eq 1 ]]; then fcm build --ignore-lock -j 1 ${COMPIL_DIR}/bld_preproagr.cfg ||{ cd - ; exit 1 ;} echo '' echo "---------------------------------" echo "CONV preprocessing successfull !!" echo "---------------------------------" echo '' fi fcm build ${x_c} --ignore-lock -v ${x_v} -j ${NBR_PRC} ${COMPIL_DIR}/$USEBLD ||{ cd - ; exit 1 ;} if [ -f ${NEMO_TDIR}/${NEW_CONF}/BLD/bin/nemo.exe ]; then ln -sf ${NEMO_TDIR}/${NEW_CONF}/BLD/bin/nemo.exe ${CONFIG_DIR}/${NEW_CONF}/EXP00/nemo fi ## add remove for clean option if [ ${#x_c} -ne 0 ]; then echo 'Cleaning in '${NEW_CONF}' the building folders' for dir in AGRIFLIB BLD LONG NEMOFILES REPRO_* SHORT WORK; do rm -rf ${NEMO_TDIR}/${NEW_CONF}/$dir done for file in cpp.history cpp.fcm full_key_list.txt; do rm -f ${COMPIL_DIR}/$file done fi fi #- Come back to original directory --- cd - #- #- Unset variables ${COMPIL_DIR}/Fclean_var.sh