From 0319ce3fdd03a88d100a4051f96cd2ed04f576bf Mon Sep 17 00:00:00 2001 From: Daniel Rosen Date: Mon, 19 Jul 2021 17:49:02 +0000 Subject: [PATCH] Add arguments to devbuild.sh script * Documented with --help * Automatically determines machine name * Automatically determines compiler based on machine name * Added options for app, ccpp suite, and components * Added option for build type DEBUG, RELEASE, RELWITHDEBINFO * Added option for build jobs, default 4 * Added verbosity option for make --- devbuild.sh | 265 ++++++++++++++++++++++++++++++++++++--------- src/CMakeLists.txt | 27 ++++- 2 files changed, 233 insertions(+), 59 deletions(-) diff --git a/devbuild.sh b/devbuild.sh index 0a35409246..482e542066 100755 --- a/devbuild.sh +++ b/devbuild.sh @@ -1,76 +1,235 @@ #!/bin/bash -set -eu - -#cd to location of script -MYDIR=$(cd "$(dirname "$(readlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P) +# usage instructions usage () { - echo "Usage: " - echo " $0 PLATFORM COMPILER" - echo "" - echo "PLATFORM: Name of machine you are building on" - echo "COMPILER: (optional) compiler to use; valid options are 'intel', 'gnu'" - echo "" - echo "NOTE: This script is for internal developer use only;" - echo "See User's Guide for detailed build instructions" + printf "Usage: $0 [OPTIONS]...\n" + printf "\n" + printf "OPTIONS\n" + printf " -h, --help\n" + printf " show this help guide\n" + printf " --platform=PLATFORM\n" + printf " name of machine you are building on; defauts to hostname\n" + printf " (.e.g. cheyenne | hera | jet | orion | wcoss)\n" + printf " --compiler=COMPILER\n" + printf " compiler to use; default depends on platform\n" + printf " (.e.g. intel | gnu | cray | gccgfortran)\n" + printf " --app=APPLICATION\n" + printf " weather model application to build\n" + printf " (.e.g. ATM | ATMW | S2S | S2SW)\n" + printf " --ccpp=\"CCPP_SUITE1,CCPP_SUITE2...\"\n" + printf " CCCP suites to include in build; delimited with ','\n" + printf " --components=\"COMPONENT1,COMPONENT2...\"\n" + printf " components to include in build; delimited with ','\n" + printf " --continue\n" + printf " continue with existing build\n" + printf " --clean\n" + printf " removes existing build; overrides --continue\n" + printf " --build-dir=BUILD_DIR\n" + printf " build directory\n" + printf " --install-dir=INSTALL_DIR\n" + printf " installation prefix\n" + printf " --build-type=BUILD_TYPE\n" + printf " build type; defaults to RELEASE\n" + printf " (.e.g. DEBUG | RELEASE | RELWITHDEBINFO)\n" + printf " --build-jobs=BUILD_JOBS\n" + printf " number of build jobs; defaults to 4\n" + printf " -v, --verbose\n" + printf " build with verbose output\n" + printf "\n" + printf "NOTE: This script is for internal developer use only;\n" + printf "See User's Guide for detailed build instructions\n" } -PLATFORM="${1:-NONE}" -COMPILER="${2:-intel}" +# print settings +settings () { + printf "Settings:\n" + printf "\n" + printf " SRC_DIR=${SRC_DIR}\n" + printf " BUILD_DIR=${BUILD_DIR}\n" + printf " INSTALL_DIR=${INSTALL_DIR}\n" + printf " PLATFORM=${PLATFORM}\n" + printf " COMPILER=${COMPILER}\n" + if [ ! -z "${APPLICATION}" ]; then printf " APP=${APPLICATION}\n"; fi + if [ ! -z "${CCPP}" ]; then printf " CCPP=${CCPP}\n"; fi + if [ ! -z "${COMPONENTS}" ]; then printf " COMPONENTS=${COMPONENTS}\n"; fi + printf " CLEAN=${CLEAN}\n" + printf " CONTINUE=${CONTINUE}\n" + printf " BUILD_TYPE=${BUILD_TYPE}\n" + printf " BUILD_JOBS=${BUILD_JOBS}\n" + printf " VERBOSE=${VERBOSE}\n" + printf "\n" +} +# find system name +find_system () { + local sysname=`hostname` + sysname="${sysname//[[:digit:]]/}" + if [ "${sysname}" = "fe" ]; then + sysname="jet" + fi + echo "$sysname" +} -if [ $# -lt 1 ]; then - echo "ERROR: not enough arguments" - usage - exit 1 +# default settings +LCL_PID=$$ +SRC_DIR=$(cd "$(dirname "$(readlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P) +BUILD_DIR=${SRC_DIR}/build +INSTALL_DIR=${SRC_DIR} +PLATFORM="" +COMPILER="" +APPLICATION="" +CCPP="" +COMPONENTS="" +BUILD_TYPE="RELEASE" +BUILD_JOBS=4 +CLEAN=false +CONTINUE=false +VERBOSE=false + +# process arguments +while :; do + case $1 in + --help|-h) usage; exit 0 ;; + --platform=?*) PLATFORM=${1#*=} ;; + --platform) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --platform=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --compiler=?*) COMPILER=${1#*=} ;; + --compiler) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --compiler=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --app=?*) APPLICATION=${1#*=} ;; + --app) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --app=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --ccpp=?*) CCPP=${1#*=} ;; + --ccpp) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --ccpp=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --components=?*) COMPONENTS=${1#*=} ;; + --components) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --components=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --clean) CLEAN=true ;; + --clean=?*) printf "ERROR: $1 argument ignored.\n"; usage; exit 1 ;; + --clean=) printf "ERROR: $1 argument ignored.\n"; usage; exit 1 ;; + --continue) CONTINUE=true ;; + --continue=?*) printf "ERROR: $1 argument ignored.\n"; usage; exit 1 ;; + --continue=) printf "ERROR: $1 argument ignored.\n"; usage; exit 1 ;; + --build-dir=?*) BUILD_DIR=${1#*=} ;; + --build-dir) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --build-dir=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --install-dir=?*) INSTALL_DIR=${1#*=} ;; + --install-dir) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --install-dir=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --build-dir=?*) BUILD_DIR=${1#*=} ;; + --build-dir) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --build-dir=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --build-type=?*) BUILD_TYPE=${1#*=} ;; + --build-type) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --build-type=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --build-jobs=?*) BUILD_JOBS=$((${1#*=})) ;; + --build-jobs) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --build-jobs=) printf "ERROR: $1 requires an argument.\n"; usage; exit 1 ;; + --verbose|-v) VERBOSE=true ;; + --verbose=?*) printf "ERROR: $1 argument ignored.\n"; usage; exit 1 ;; + --verbose=) printf "ERROR: $1 argument ignored.\n"; usage; exit 1 ;; + -?*) printf "ERROR: Unknown option $1\n"; usage; exit 1 ;; + *) break + esac + shift +done + +set -eu + +# automatically determine system +if [ -z "${PLATFORM}" ] ; then + PLATFORM=$(find_system) fi -if [ $# -gt 2 ]; then - echo "ERROR: too many arguments" - usage - exit 1 + +# automatically determine compiler +if [ -z "${COMPILER}" ] ; then + case ${PLATFORM} in + jet|hera) COMPILER=intel ;; + orion) COMPILER=intel ;; + wcoss) COMPILER=cray_intel ;; + cheyenne) COMPILER=intel ;; + macos) COMPILER=gccgfortran ;; + *) printf "ERROR: Unknown platform $PLATFORM\n"; usage; exit 1 ;; + esac fi -if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then - usage - exit 0 +# print settings +if [ "${VERBOSE}" = true ] ; then + settings fi -ENV_FILE="env/build_${PLATFORM}_${COMPILER}.env" -if [ ! -f "$ENV_FILE" ]; then - echo "ERROR: environment file ($ENV_FILE) does not exist for this platform/compiler combination" - echo "PLATFORM=$PLATFORM" - echo "COMPILER=$COMPILER" - echo "" - echo "See User's Guide for detailed build instructions" +# set ENV_FILE for this platform/compiler combination +ENV_FILE="${SRC_DIR}/env/build_${PLATFORM}_${COMPILER}.env" +if [ ! -f "${ENV_FILE}" ]; then + printf "ERROR: environment file does not exist for this platform/compiler\n" + printf " ENV_FILE=${ENV_FILE}\n" + printf " PLATFORM=${PLATFORM}\n" + printf " COMPILER=${COMPILER}\n" + printf "\n" + printf "See User's Guide for detailed build instructions\n" exit 64 fi -# If build directory already exists, offer a choice -BUILD_DIR=${MYDIR}/build +# if build directory already exists then exit +if [ "${CLEAN}" = true ]; then + printf "Remove build directory\n" + printf " BUILD_DIR=${BUILD_DIR}\n" + printf "\n" + rm -rf ${BUILD_DIR} +elif [ "${CONTINUE}" = true ]; then + printf "Continue build in directory\n" + printf " BUILD_DIR=${BUILD_DIR}\n" + printf "\n" +else + if [ -d "${BUILD_DIR}" ]; then + while true; do + if [[ $(ps -o stat= -p ${LCL_PID}) != *"+"* ]] ; then + printf "ERROR: Build directory (${BUILD_DIR}) already exists!\n" + usage + exit 1 + fi + printf "Build directory (${BUILD_DIR}) already exists!\n" + printf "Please choose what to do:\n" + printf "\n" + printf "[R]emove the existing directory\n" + printf "[C]ontinue building in the existing directory\n" + printf "[Q]uit this build script\n" + read -p "Choose an option (R/C/Q):" choice + case ${choice} in + [Rr]* ) rm -rf ${BUILD_DIR}; break;; + [Cc]* ) break;; + [Qq]* ) exit;; + * ) printf "Invalid option selected.\n";; + esac + done + fi +fi -if [ -d "${BUILD_DIR}" ]; then - while true; do - echo "Build directory (${BUILD_DIR}) already exists! Please choose what to do:" - echo "" - echo "[R]emove the existing directory" - echo "[C]ontinue building in the existing directory" - echo "[Q]uit this build script" - read -p "Choose an option (R/C/Q):" choice - case $choice in - [Rr]* ) rm -rf ${BUILD_DIR}; break;; - [Cc]* ) break;; - [Qq]* ) exit;; - * ) echo "Invalid option selected.\n";; - esac - done +# cmake settings +CMAKE_SETTINGS="-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}" +CMAKE_SETTINGS="${CMAKE_SETTINGS} -DCMAKE_BUILD_TYPE=${BUILD_TYPE}" +if [ ! -z "${APPLICATION}" ]; then + CMAKE_SETTINGS="${CMAKE_SETTINGS} -DAPP=${APPLICATION}" +fi +if [ ! -z "${CCPP}" ]; then + CMAKE_SETTINGS="${CMAKE_SETTINGS} -DCCPP=${CCPP}" +fi +if [ ! -z "${COMPONENTS}" ]; then + CMAKE_SETTINGS="${CMAKE_SETTINGS} -DINCLUDE_COMPONENTS=${COMPONENTS}" fi -# Source the README file for this platform/compiler combination, then build the code -. $ENV_FILE +# make settings +MAKE_SETTINGS="-j ${BUILD_JOBS}" +if [ "${VERBOSE}" = true ]; then + MAKE_SETTINGS="${MAKE_SETTINGS} VERBOSE=1" +fi +# source the README file for this platform/compiler combination, then build the code +. ${ENV_FILE} mkdir -p ${BUILD_DIR} cd ${BUILD_DIR} -cmake .. -DCMAKE_INSTALL_PREFIX=.. 2>&1 | tee log.cmake -make -j ${BUILD_JOBS:-4} 2>&1 | tee log.make +cmake ${SRC_DIR} ${CMAKE_SETTINGS} 2>&1 | tee log.cmake +make ${MAKE_SETTINGS} 2>&1 | tee log.make exit 0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0384584b6..d77e859f6f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,11 +11,12 @@ if(NOT CCPP_SUITES) set(CCPP_SUITES "FV3_CPT_v0,FV3_GFS_2017_gfdlmp,FV3_GFS_2017_gfdlmp_regional,FV3_GSD_SAR,FV3_GSD_v0,FV3_GFS_v15p2,FV3_GFS_v16,FV3_RRFS_v1beta,FV3_HRRR,FV3_RRFS_v1alpha") endif() -ExternalProject_Add(ufs-weather-model - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ufs-weather-model - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ufs-weather-model - INSTALL_DIR ${CMAKE_INSTALL_PREFIX} - CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" +if(NOT APP) + set(APP "ATM") +endif() + +list(APPEND UFS_WEATHER_MODEL_ARGS + "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" "-DCCPP_SUITES=${CCPP_SUITES}" "-DCMAKE_C_COMPILER=${MPI_C_COMPILER}" "-DCMAKE_CXX_COMPILER=${MPI_CXX_COMPILER}" @@ -23,7 +24,21 @@ ExternalProject_Add(ufs-weather-model "-DNETCDF_DIR=$ENV{NETCDF}" "-D32BIT=ON" "-DINLINE_POST=ON" - "-DAPP=ATM" + "-DAPP=${APP}" +) + +if (INCLUDE_COMPONENTS) + string(REPLACE "," ";" INCLUDE_COMPONENTS "${INCLUDE_COMPONENTS}") + foreach (component IN ITEMS ${INCLUDE_COMPONENTS}) + list(APPEND UFS_WEATHER_MODEL_ARGS "-D${component}=ON") + endforeach() +endif() + +ExternalProject_Add(ufs-weather-model + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ufs-weather-model + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ufs-weather-model + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + CMAKE_ARGS ${UFS_WEATHER_MODEL_ARGS} INSTALL_COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/bin && cp ${CMAKE_CURRENT_BINARY_DIR}/ufs-weather-model/src/ufs-weather-model-build/ufs_model ${CMAKE_INSTALL_PREFIX}/bin/ )