#!/usr/bin/env bash # Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced # at the Lawrence Livermore National Laboratory. All Rights reserved. See files # LICENSE and NOTICE for details. LLNL-CODE-806117. # # This file is part of the MFEM library. For more information and source code # availability visit https://mfem.org. # # MFEM is free software; you can redistribute it and/or modify it under the # terms of the BSD-3 license. We welcome feedback and contributions, see file # CONTRIBUTING.md for details. set -o errexit set -o nounset script_name=$(basename $0) function usage() { echo "MFEM CI build and test driver" echo "" echo "Syntax:" echo "> ${script_name} --spec \"spack spec\" [--deps-only] [--data]" echo " [--data-dir=/path/to/mfem/data]" echo "" echo "> ${script_name} --build-only [--data]" echo " [--data-dir=/path/to/mfem/data]" echo "" echo "> ${script_name} --test-only [--data]" echo " [--data-dir=/path/to/mfem/data]" echo "" echo "Options:" echo " --spec" echo " The most common usage is to pass a spack spec to the script." echo " This spec may or may not specify \"mfem\" as the package, since it" echo " is the default." echo "" echo " --deps-only" echo " Only install MFEM dependencies. Will clone mfem-uberenv to drive a" echo " local instance on spack with which we install the dependencies." echo " This local spack instance is tuned to be completely independent" echo " from the user environment." echo "" echo " --build-only" echo " Only build MFEM, based on the existing configuration." echo "" echo " --test-only" echo " Only test MFEM, based on the existing configuration." echo "" echo " --data" echo " Make running tests with \"--data\" a requirement: will fail in the" echo " data directory is not present in the parent of the mfem root directory." echo " Note: default behavior is to run data tests if data dir is present." echo "" echo " --data-dir=/path/to/mfem/data" echo " Path to a clone of the MFEM/data repo: https://github.com/mfem/data" echo " The default path is: '../data'." echo "" } project_dir="$(pwd)" mode="" spec="" data_dir="" with_data=false sys_type=${SYS_TYPE:-""} threads=${THREADS:-""} # Options while [[ $# -gt 0 ]] do key="$1" case $key in --spec) spec="$2" shift # past argument shift # past value ;; --deps-only|--build-only|--test-only) mode="$key" shift # past argument ;; --data) with_data=true shift # past argument ;; --data-dir) data_dir="$2" shift # past argument shift # past value ;; -h|--help) usage exit 0; ;; *) # unknown option echo "ERROR: option $key is unknown" exit 1; ;; esac done # Dependencies if [[ "${mode}" != "--build-only" && "${mode}" != "--test-only" ]] then echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "~~~~~ Building Dependencies" echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" if [[ -z ${spec} ]] then echo "--spec is mandatory to build dependencies, aborting..." exit 1 fi upstream_opt="" if [[ ${sys_type} != "" ]] then upstream_opt="--upstream=/usr/workspace/mfem/mfem-dependencies/install" fi prefix_opt="" # Do not run on /dev/shm if only installing dependencies: they will be lost # otherwise. if [[ -d "/dev/shm" && "${mode}" != "--deps-only" ]] then prefix="/dev/shm/${USER}_${CI_PIPELINE_ID:-"NONE"}_${RANDOM}" mkdir -p ${prefix} # clean up ${prefix} at exit: trap 'rm -rf "${prefix}"' EXIT prefix_opt="--prefix=${prefix}" fi echo ${spec} > spec.txt echo "Fetching uberenv." tests/gitlab/get_mfem_uberenv || { echo "Error fetching Uberenv"; exit 1; } echo "Removing existing configuration" make distclean echo "Installing dependencies." command -v python > /dev/null && python_cmd=python || python_cmd=python3 $python_cmd tests/uberenv/uberenv.py --spec="${spec}" "${upstream_opt}" \ "${prefix_opt}" # Make sure that a configuration was generated by spack (part 1). cp config/config.mk config/spack-config.mk cp config/_config.hpp config/spack_config.hpp fi # Configuration if [[ "${mode}" != "--deps-only" ]] then # Host config file # Make sure that a configuration was generated by spack (part 2). # Without this running the rest of the script would generate a new config. if [[ -f "config/spack-config.mk" && -f "config/spack_config.hpp" ]] then cp config/spack-config.mk config/config.mk cp config/spack_config.hpp config/_config.hpp else echo "No result for at least one of" echo " ${project_dir}/config/spack-config.mk" echo " ${project_dir}/config/spack_config.hpp" echo "ERROR: Spack generated configuration not found." exit 1 fi # Setup the MFEM/data repository directory # Some additional unit tests are enabled when '../data' is present if [[ -z "${data_dir}" ]] then # By default, data_dir is ../data. data_dir="../data" else # data_dir is specified, so we need to link its content into the # project parent dir. if [[ -e "../data" ]]; then if [[ -L "../data" ]]; then echo "'../data' link already exists. Deleting." rm "../data" else echo "Error: '../data' already exists and it's NOT a link" exit 1 fi fi ln -sf "${data_dir}" "../data" fi # The PUMI examples expect the PUMI datafiles to be in 'data/pumi' if [[ -d "../data/pumi" ]]; then ln -sf "../../data/pumi" "data" fi if [[ "$with_data" == "true" && ! -d "../data" ]] then echo "ERROR: '$data_dir' is not a directory while asking for --data" exit 1 fi fi # Build (also build when asked for testing, to make sure we test what we want) if [[ "${mode}" != "--deps-only" ]] then echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "~ Project Dir: ${project_dir}" echo "~ Data Dir: ${data_dir}" echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "~~~~~ MFEM configuration" echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" make info echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "~~~~~ Building MFEM" echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" make all -j ${threads} fi # Test if [[ "${mode}" != "--deps-only" && "${mode}" != "--build-only" ]] then echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "~~~~~ Testing MFEM" echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" make test test_status=$? echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "~~~~~ Cleaning MFEM" echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" if make distclean > distclean.log 2>&1; then echo "[make distclean]: OK" else cat distclean.log echo echo "[make distclean]: FAILED (see above)" fi rm -f distclean.log exit $test_status fi