Skip to content

Commit

Permalink
Add arguments to devbuild.sh script
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
danrosen25 committed Jul 20, 2021
1 parent 85d2f08 commit 9247726
Show file tree
Hide file tree
Showing 2 changed files with 253 additions and 62 deletions.
272 changes: 219 additions & 53 deletions devbuild.sh
Original file line number Diff line number Diff line change
@@ -1,76 +1,242 @@
#!/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"
cat << EOF_USAGE
Usage: $0 [OPTIONS]...
OPTIONS
-h, --help
show this help guide
--platform=PLATFORM
name of machine you are building on; defauts to hostname
(e.g. cheyenne | hera | jet | orion | wcoss)
--compiler=COMPILER
compiler to use; default depends on platform
(e.g. intel | gnu | cray | gccgfortran)
--app=APPLICATION
weather model application to build
(e.g. ATM | ATMW | S2S | S2SW)
--ccpp="CCPP_SUITE1,CCPP_SUITE2..."
CCCP suites to include in build; delimited with ','
--components="COMPONENT1,COMPONENT2..."
additional components to include in build; delimited with ','
supported components are found in src/ufs-weather-model/CMakeLists.txt
(e.g. UFS_GOCART | MOM6 | CICE6 | WW3 | CDEPS | CMEPS)
--continue
continue with existing build
--clean
removes existing build; overrides --continue
--build-dir=BUILD_DIR
build directory
--install-dir=INSTALL_DIR
installation prefix
--build-type=BUILD_TYPE
build type; defaults to RELEASE
(e.g. DEBUG | RELEASE | RELWITHDEBINFO)
--build-jobs=BUILD_JOBS
number of build jobs; defaults to 4
-v, --verbose
build with verbose output
NOTE: This script is for internal developer use only;
See User's Guide for detailed build instructions
EOF_USAGE
}

PLATFORM="${1:-NONE}"
COMPILER="${2:-intel}"
# print settings
settings () {
cat << EOF_SETTINGS
Settings:
SRC_DIR=${SRC_DIR}
BUILD_DIR=${BUILD_DIR}
INSTALL_DIR=${INSTALL_DIR}
PLATFORM=${PLATFORM}
COMPILER=${COMPILER}
APP=${APPLICATION}
CCPP=${CCPP}
COMPONENTS=${COMPONENTS}
CLEAN=${CLEAN}
CONTINUE=${CONTINUE}
BUILD_TYPE=${BUILD_TYPE}
BUILD_JOBS=${BUILD_JOBS}
VERBOSE=${VERBOSE}
if [ $# -lt 1 ]; then
echo "ERROR: not enough arguments"
usage
EOF_SETTINGS
}

# print usage error and exit
usage_error () {
printf "ERROR: $1\n" >&2
usage >&2
exit 1
}

# find system name
find_system () {
if [ -f $1 ]; then
source $1
local sysname=$target
else
local sysname=`hostname`
sysname="${sysname//[[:digit:]]/}"
if [ "${sysname}" = "fe" ]; then
sysname="jet"
elif [ "${sysname}" = "hfe" ]; then
sysname="hera"
fi
fi
echo "$sysname"
}

# default settings
LCL_PID=$$
SRC_DIR=$(cd "$(dirname "$(readlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P)
MACHINE_SETUP=${SRC_DIR}/src/UFS_UTILS/sorc/machine-setup.sh
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|--platform=) usage_error "$1 requires argument." ;;
--compiler=?*) COMPILER=${1#*=} ;;
--compiler|--compiler=) usage_error "$1 requires argument." ;;
--app=?*) APPLICATION=${1#*=} ;;
--app|--app=) usage_error "$1 requires argument." ;;
--ccpp=?*) CCPP=${1#*=} ;;
--ccpp|--ccpp=) usage_error "$1 requires argument." ;;
--components=?*) COMPONENTS=${1#*=} ;;
--components|--components=) usage_error "$1 requires argument." ;;
--clean) CLEAN=true ;;
--clean=?*|--clean=) usage_error "$1 argument ignored." ;;
--continue) CONTINUE=true ;;
--continue=?*|--continue=) usage_error "$1 argument ignored." ;;
--build-dir=?*) BUILD_DIR=${1#*=} ;;
--build-dir|--build-dir=) usage_error "$1 requires argument." ;;
--install-dir=?*) INSTALL_DIR=${1#*=} ;;
--install-dir|--install-dir=) usage_error "$1 requires argument." ;;
--build-dir=?*) BUILD_DIR=${1#*=} ;;
--build-dir|--build-dir=) usage_error "$1 requires argument." ;;
--build-type=?*) BUILD_TYPE=${1#*=} ;;
--build-type|--build-type=) usage_error "$1 requires argument." ;;
--build-jobs=?*) BUILD_JOBS=$((${1#*=})) ;;
--build-jobs|--build-jobs=) usage_error "$1 requires argument." ;;
--verbose|-v) VERBOSE=true ;;
--verbose=?*|--verbose=) usage_error "$1 argument ignored." ;;
-?*) usage_error "Unknown option $1" ;;
*) break
esac
shift
done

set -eu

# automatically determine system
if [ -z "${PLATFORM}" ] ; then
PLATFORM=$(find_system "$MACHINE_SETUP")
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" >&2; usage >&2; 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 platform/compiler\n" >&2
printf " ENV_FILE=${ENV_FILE}\n" >&2
printf " PLATFORM=${PLATFORM}\n" >&2
printf " COMPILER=${COMPILER}\n\n" >&2
usage >&2
exit 64
fi

# If build directory already exists, offer a choice
BUILD_DIR=${MYDIR}/build

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
# if build directory already exists then exit
if [ "${CLEAN}" = true ]; then
printf "Remove build directory\n"
printf " BUILD_DIR=${BUILD_DIR}\n\n"
rm -rf ${BUILD_DIR}
elif [ "${CONTINUE}" = true ]; then
printf "Continue build in directory\n"
printf " BUILD_DIR=${BUILD_DIR}\n\n"
else
if [ -d "${BUILD_DIR}" ]; then
while true; do
if [[ $(ps -o stat= -p ${LCL_PID}) != *"+"* ]] ; then
printf "ERROR: Build directory already exists\n" >&2
printf " BUILD_DIR=${BUILD_DIR}\n\n" >&2
usage >&2
exit 64
fi
# interactive selection
printf "Build directory (${BUILD_DIR}) already exists\n"
printf "Please choose what to do:\n\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

# Source the README file for this platform/compiler combination, then build the code
. $ENV_FILE
# 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

# 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
43 changes: 34 additions & 9 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,44 @@ 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()

if(NOT APP)
set(APP "ATM")
endif()

if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RELEASE")
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}"
"-DCMAKE_Fortran_COMPILER=${MPI_Fortran_COMPILER}"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DNETCDF_DIR=$ENV{NETCDF}"
"-D32BIT=ON"
"-DINLINE_POST=ON"
"-DAPP=${APP}"
)

string(TOUPPER "${CMAKE_BUILD_TYPE}" TOUPPER_CMAKE_BUILD_TYPE)
if (TOUPPER_CMAKE_BUILD_TYPE MATCHES "DEBUG")
list(APPEND UFS_WEATHER_MODEL_ARGS "-DDEBUG=ON")
endif()

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 "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
"-DCCPP_SUITES=${CCPP_SUITES}"
"-DCMAKE_C_COMPILER=${MPI_C_COMPILER}"
"-DCMAKE_CXX_COMPILER=${MPI_CXX_COMPILER}"
"-DCMAKE_Fortran_COMPILER=${MPI_Fortran_COMPILER}"
"-DNETCDF_DIR=$ENV{NETCDF}"
"-D32BIT=ON"
"-DINLINE_POST=ON"
"-DAPP=ATM"
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/
)

Expand Down

0 comments on commit 9247726

Please sign in to comment.