Version 0.2 of make_cp2k.sh

- Add more flags and checks
- Minor fixes
This commit is contained in:
Matthias Krack 2026-01-21 11:01:04 +01:00
parent 1faee7cb7e
commit 631f12d81a

View file

@ -47,10 +47,11 @@
# Authors: Matthias Krack (MK)
# Version: 0.1
# Version: 0.2
# History: - Creation (19.12.2025, MK)
# - Version 0.1 (09.01.2026, MK)
# - Version 0.1: First working version (09.01.2026, MK)
# - Version 0.2: Add more flags and checks (19.01.2026, MK)
# set -uo pipefail # can be useful for debugging this script
@ -70,8 +71,32 @@ else
EXIT_CMD="exit"
fi
# Check platform
if [[ "$(uname -s)" == "Darwin" ]]; then
echo "ERROR: Apple (Darwin, Homebrew) is not supported yet"
echo " Build CP2K within a container, e.g. using Ubuntu"
${EXIT_CMD} 1
fi
# Check bash version
if ((BASH_VERSINFO < 4)); then
echo "ERROR: The employed bash version ${BASH_VERSION} is too old (from 2004)"
echo " Install a newer bash version"
if [[ "$(uname -s)" == "Darwin" ]]; then
echo "HINT: Use the bash command provided by Homebrew with Apple"
echo " /opt/homebrew/bin should precede /bin/bash in the PATH"
echo " In sourcing mode, run /opt/homebrew/bin/bash first before sourcing this script"
fi
${EXIT_CMD} 1
elif ((BASH_VERSINFO < 5)); then
echo "WARNING: The employed bash version ${BASH_VERSION} is quite old (from 2009)"
else
echo "INFO: Using bash version ${BASH_VERSION}"
fi
# Default values
BUILD_DEPS="no"
BUILD_TYPE="RelWithDebInfo"
HELP="no"
INSTALL_MESSAGE="NEVER"
if command -v nproc &> /dev/null; then
@ -82,8 +107,8 @@ fi
RUN_TEST="no"
TESTOPTS=""
VERBOSE=0
VERBOSE_FLAG="--quiet"
VERBOSE_MAKEFILE="OFF"
VERBOSE_NINJA="--quiet"
export CP2K_ENV="cp2k_env"
export CP2K_ROOT=${PWD}
@ -96,6 +121,10 @@ while [[ $# -gt 0 ]]; do
-bd | --build_deps)
BUILD_DEPS="yes"
;;
-bt | --build_type)
BUILD_TYPE="${2}"
shift 2
;;
-cv | --cp2k_version)
CP2K_VERSION="${2}"
shift 2
@ -120,8 +149,8 @@ while [[ $# -gt 0 ]]; do
-v | --verbose)
VERBOSE=1
INSTALL_MESSAGE="LAZY"
VERBOSE_FLAG="--verbose"
VERBOSE_MAKEFILE="ON"
VERBOSE_NINJA="--verbose"
shift 1
;;
--)
@ -138,12 +167,13 @@ while [[ $# -gt 0 ]]; do
esac
done
export INSTALL_MESSAGE NUM_PROCS RUN_TEST TESTOPTS VERBOSE VERBOSE_MAKEFILE VERBOSE_NINJA
export BUILD_TYPE INSTALL_MESSAGE NUM_PROCS RUN_TEST TESTOPTS VERBOSE VERBOSE_FLAG VERBOSE_MAKEFILE
# Show help if requested
if [[ "${HELP}" == "yes" ]]; then
echo ""
echo "Usage: ${SCRIPT_NAME} [-bd|--build_deps] [-cv|--cp2k_version (psmp|ssmp)] [-h|--help] [-ip|--install_path PATH]"
echo "Usage: ${SCRIPT_NAME} [-bd|--build_deps] [-bt|--build_type (Debug|Release|RelWithDebInfo|MinSizeRel)]"
echo " [-cv|--cp2k_version (psmp|ssmp)] [-h|--help] [-ip|--install_path PATH]"
echo " [-j|--num_procs #processes] [-t|test \"TESTOPTS\"] [-v|--verbose]"
echo ""
echo "Hints:"
@ -154,27 +184,35 @@ if [[ "${HELP}" == "yes" ]]; then
${EXIT_CMD} 0
fi
echo "CMAKE_BUILD_TYPE = ${BUILD_TYPE}"
echo "CP2K_VERSION = ${CP2K_VERSION}"
echo "INSTALL_PREFIX = ${INSTALL_PREFIX}"
echo "INSTALL_MESSAGE = ${INSTALL_MESSAGE}"
echo "NUM_PROCS = ${NUM_PROCS} (processes)"
echo "RUN_TEST = ${RUN_TEST}"
if [[ "${RUN_TEST}" == "yes" ]]; then
echo "TESTOPTS = ${TESTOPTS}"
echo "TESTOPTS = \"${TESTOPTS}\""
fi
echo "VERBOSE_FLAG = ${VERBOSE_FLAG}"
echo "VERBOSE_MAKEFILE = ${VERBOSE_MAKEFILE}"
echo "VERBOSE_NINJA = ${VERBOSE_NINJA}"
echo "VERBOSE = ${VERBOSE}"
if (($# > 0)); then
echo "Remaining args =" "$@" "(not used yet)"
fi
# Spack versions
export SPACK_VERSION="${SPACK_VERSION:-1.1.0}"
export SPACK_PACKAGES_VERSION="${SPACK_PACKAGES_VERSION:-2025.11.0}"
# Check if a valid CMake build type is selected
case "${BUILD_TYPE}" in
Debug | Release | RelWithDebInfo | MinSizeRel)
true
;;
*)
echo -e "\nERROR: Invalid CMake build type \"${BUILD_TYPE}\" selected"
${EXIT_CMD} 1
;;
esac
# Check if all mandatory packages for the Spack/CMake build are installed in the environment
for package in bzip2 g++ gcc gfortran git gzip patch python3 update-ca-certificates wget; do
for package in bzip2 g++ gcc gfortran git gmake gzip patch python3 tar wget xz zip; do
if ! command -v "${package}" &> /dev/null; then
echo "ERROR: The package \"${package}\" is mandatory to build CP2K with Spack/CMake"
echo " Install the missing package and re-run the script"
@ -182,20 +220,31 @@ for package in bzip2 g++ gcc gfortran git gzip patch python3 update-ca-certifica
fi
done
# Check if python is available
# Check if all recommended packages for the Spack/CMake build are installed in the environment
for package in autoconf automake bison flex libtool m4 pkg-config; do
if ! command -v "${package}" &> /dev/null; then
echo "INFO: The package \"${package}\" was not found but is recommended with Spack/CMake"
fi
done
# Check if python3 is available
if ! command -v python3 &> /dev/null; then
echo "ERROR: python3 NOT found"
${EXIT_CMD} 1
fi
# Check if the python version is new enough
# Check if the Pthon version is new enough
if ! python3 -c 'import sys; sys.exit(not(sys.version_info >= (3, 9)))'; then
echo "ERROR: python version is NOT >= 3.9"
echo "ERROR: Python version is NOT >= 3.9 (needed for Spack cache)"
${EXIT_CMD} 1
fi
### Build CP2K dependencies with Spack if needed or requested ###
# Spack versions
export SPACK_VERSION="${SPACK_VERSION:-1.1.0}"
export SPACK_PACKAGES_VERSION="${SPACK_PACKAGES_VERSION:-2025.11.0}"
export SPACK_BUILD_PATH="${CP2K_ROOT}/spack"
export SPACK_ROOT="${SPACK_BUILD_PATH}/spack-${SPACK_VERSION}"
@ -204,9 +253,30 @@ export SPACK_ROOT="${SPACK_BUILD_PATH}/spack-${SPACK_VERSION}"
if [[ ! -d "${SPACK_BUILD_PATH}" ]]; then
# Install Spack
[[ ! -d "${SPACK_BUILD_PATH}" ]] && mkdir -p "${SPACK_BUILD_PATH}"
# Create a new local spack folder
mkdir -p "${SPACK_BUILD_PATH}"
cd "${SPACK_BUILD_PATH}" || ${EXIT_CMD} 1
# The package podman is required for using a local Spack cache
if command -v podman &> /dev/null; then
((VERBOSE > 0)) && echo "Installing virtual environment for Python packages"
HAS_PODMAN="yes"
# Create and activate a virtual environment for Python packages
python3 -m venv "${SPACK_BUILD_PATH}/venv"
export PATH="${SPACK_BUILD_PATH}/venv/bin:${PATH}"
pip3 install "${VERBOSE_FLAG}" --upgrade pip
pip3 install "${VERBOSE_FLAG}" boto3==1.38.11 google-cloud-storage==3.1.0
# Start Spack cache
"${CP2K_ROOT}"/tools/docker/spack_cache_start.sh
else
HAS_PODMAN="no"
echo "INFO: podman was not found"
echo "INFO: Install the package podman to take advantage of a Spack cache"
echo "INFO: This accelerates a rebuild of the CP2K dependencies, significantly"
fi
# Install Spack
((VERBOSE > 0)) && echo "Installing Spack ${SPACK_VERSION}"
export SPACK_REPO="https://github.com/spack/spack"
if [[ ! -d "${SPACK_ROOT}" ]]; then
wget -q "${SPACK_REPO}/archive/v${SPACK_VERSION}.tar.gz"
@ -215,27 +285,6 @@ if [[ ! -d "${SPACK_BUILD_PATH}" ]]; then
fi
export PATH="${SPACK_ROOT}/bin:${PATH}"
# Initialize Spack shell hooks
source "${SPACK_ROOT}/share/spack/setup-env.sh"
# The package podman is required for using a local Spack cache
if command -v podman &> /dev/null; then
HAS_PODMAN="yes"
# Create and activate a virtual environment for Python packages
python3 -m venv "${SPACK_BUILD_PATH}/venv"
export PATH="${SPACK_BUILD_PATH}/venv/bin:${PATH}"
pip3 install --quiet --upgrade pip
pip3 install --quiet boto3==1.38.11 google-cloud-storage==3.1.0
# (Re)start Spack cache
"${CP2K_ROOT}"/tools/docker/spack_cache_start.sh
podman container list
else
HAS_PODMAN="no"
echo "INFO: podman was not found"
echo "INFO: Install the package podman to take advantage of a Spack cache"
echo "INFO: This accelerates a rebuild of the CP2K dependencies, significantly"
fi
# Isolate user config/cache
export SPACK_DISABLE_LOCAL_CONFIG=true
export SPACK_USER_CONFIG_PATH="${SPACK_BUILD_PATH}"
@ -243,15 +292,33 @@ if [[ ! -d "${SPACK_BUILD_PATH}" ]]; then
mkdir -p "${SPACK_USER_CACHE_PATH}"
# Install Spack packages
((VERBOSE > 0)) && echo "Installing Spack packages ${SPACK_PACKAGES_VERSION}"
export SPACK_PACKAGES_REPO="https://github.com/spack/spack-packages"
export SPACK_PACKAGES_ROOT="${SPACK_BUILD_PATH}/spack-packages-${SPACK_PACKAGES_VERSION}"
wget -q "${SPACK_PACKAGES_REPO}/archive/v${SPACK_PACKAGES_VERSION}.tar.gz"
tar -xzf "v${SPACK_PACKAGES_VERSION}.tar.gz"
rm -f "v${SPACK_PACKAGES_VERSION}.tar.gz"
# Add local Spack cache if podman is available
if [[ "${HAS_PODMAN}" == "yes" ]]; then
export SPACK_CACHE="s3://spack-cache --s3-endpoint-url=http://localhost:9000"
if ! spack mirror list | grep -q "local-cache"; then
echo "Setting up Spack cache"
"${CP2K_ROOT}"/tools/docker/scripts/setup_spack_cache.sh
fi
((VERBOSE > 0)) && "${CP2K_ROOT}"/tools/docker/spack_cache_list.sh
else
echo "INFO: A local Spack cache is NOT used"
fi
# Initialize Spack shell hooks
source "${SPACK_ROOT}/share/spack/setup-env.sh"
# Prepare the CP2K Spack configuration file
export CP2K_CONFIG_FILE="${SPACK_BUILD_PATH}/cp2k_deps_${CP2K_VERSION}.yaml"
sed -e "s|root: /opt/spack|root: ${SPACK_ROOT}/opt/spack|" "${CP2K_ROOT}/tools/spack/cp2k_deps_${CP2K_VERSION}.yaml" > "${CP2K_CONFIG_FILE}"
sed -e "s|root: /opt/spack|root: ${SPACK_ROOT}/opt/spack|" \
-e "/\"build_type=/s|build_type=[^\"]*|build_type=${BUILD_TYPE}|" \
"${CP2K_ROOT}/tools/spack/cp2k_deps_${CP2K_VERSION}.yaml" > "${CP2K_CONFIG_FILE}"
# Activate CP2K environment if needed
if spack env list | grep -q "${CP2K_ENV}"; then
@ -270,7 +337,7 @@ if [[ ! -d "${SPACK_BUILD_PATH}" ]]; then
# Add Spack packages builtin repository when missing
if ! spack repo list | grep -q "builtin"; then
spack repo add --scope env:cp2k_env "${SPACK_PACKAGES_ROOT}/repos/spack_repo/builtin"
spack repo add --scope env:"${CP2K_ENV}" "${SPACK_PACKAGES_ROOT}/repos/spack_repo/builtin"
else
echo "Spack built-in repo already present ... skipping add"
fi
@ -278,7 +345,7 @@ if [[ ! -d "${SPACK_BUILD_PATH}" ]]; then
# Add the local CP2K development Spack repository when missing
export CP2K_REPO="cp2k_dev"
if ! spack repo list | grep -q "${CP2K_REPO}"; then
spack repo add --scope env:cp2k_env "${CP2K_ROOT}/tools/spack/spack_repo/${CP2K_REPO}"
spack repo add --scope "env:${CP2K_ENV}" "${CP2K_ROOT}/tools/spack/spack_repo/${CP2K_REPO}"
else
echo "The CP2K development repo ${CP2K_REPO} is already present ... skipping add"
fi
@ -288,43 +355,13 @@ if [[ ! -d "${SPACK_BUILD_PATH}" ]]; then
# Find all compilers
spack compiler find
# Install the newest available compiler version
GCC_VERSION="$(spack compilers | awk '/gcc/ {print $2}' | sort -V | tail -n 1)"
spack install --add "${GCC_VERSION}"
echo "Using GCC compiler version ${GCC_VERSION}"
GCC_VERSION_SELECTED="$(echo "${GCC_VERSION}" | sed -E 's/.*@([0-9]+).*/\1/' | cut -d. -f1)"
# Check if the compiler version is new enough
GCC_VERSION_REQUIRED="9"
if ((GCC_VERSION_SELECTED < GCC_VERSION_REQUIRED)); then
echo "ERROR: The selected GCC compiler version ${GCC_VERSION_SELECTED} is too old, because at least version ${GCC_VERSION_REQUIRED} is required"
${EXIT_CMD}
fi
# Check if the compiler version is newer than the suggested version
GCC_VERSION_SUGGESTED="12"
if ((GCC_VERSION_SELECTED < GCC_VERSION_SUGGESTED)); then
echo "WARNING: The selected GCC compiler version ${GCC_VERSION_SELECTED} is quite old. At least version ${GCC_VERSION_SUGGESTED} is suggested"
fi
spack find -c
# Find all external packages
spack -C "${SPACK_USER_CONFIG_PATH}" external find --not-buildable
# Add local Spack cache if podman is available
if [[ "${HAS_PODMAN}" == "yes" ]]; then
export SPACK_CACHE="s3://spack-cache --s3-endpoint-url=http://localhost:9000"
if ! spack mirror list | grep -q "local-cache"; then
"${CP2K_ROOT}"/tools/docker/scripts/setup_spack_cache.sh
fi
if ((VERBOSE > 0)); then
"${CP2K_ROOT}"/tools/docker/spack_cache_list.sh
fi
else
echo "INFO: A local Spack cache is NOT used"
fi
# Install CP2K dependencies via Spack
spack -e "${CP2K_ENV}" concretize -f
spack -e "${CP2K_ENV}" --no-user-config --no-system-config concretize -f
spack -e "${CP2K_ENV}" env depfile -o spack_makefile
make -j"${NUM_PROCS}" --file=spack_makefile SPACK_COLOR=never --output-sync=recurse
@ -335,6 +372,13 @@ else
# Initialize Spack shell hooks
source "${SPACK_ROOT}"/share/spack/setup-env.sh
if [[ "${HAS_PODMAN}" == "yes" ]]; then
# Start Spack cache
"${CP2K_ROOT}"/tools/docker/spack_cache_start.sh
podman container list
((VERBOSE > 0)) && "${CP2K_ROOT}"/tools/docker/spack_cache_list.sh
fi
fi
### End of build CP2K dependencies ###
@ -343,7 +387,7 @@ fi
spack env list
spack env status
eval "$(spack env activate --sh "${CP2K_ENV}")"
eval "$(spack env activate --sh ${CP2K_ENV})"
# CMake configuration step
export CMAKE_BUILD_PATH="${CP2K_ROOT}/build"
@ -358,30 +402,38 @@ if [[ ! -d "${CMAKE_BUILD_PATH}" ]]; then
"psmp")
cmake -S "${CP2K_ROOT}" -B "${CMAKE_BUILD_PATH}" \
-GNinja \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
-DCMAKE_INSTALL_MESSAGE="${INSTALL_MESSAGE}" \
-DCMAKE_SKIP_RPATH=ON \
-DCMAKE_VERBOSE_MAKEFILE="${VERBOSE_MAKEFILE}" \
-DCP2K_USE_EVERYTHING=ON \
-DCP2K_USE_DLAF=OFF \
-DCP2K_USE_LIBXSMM=OFF \
-DCP2K_USE_LIBXSMM=ON \
-DCP2K_USE_MPI=ON \
-DCP2K_USE_OPENPMD=ON \
-DCP2K_USE_TBLITE=OFF \
-Werror=dev |&
tee "${CMAKE_BUILD_PATH}/cmake.log"
EXIT_CODE=$?
;;
"ssmp")
cmake -S "${CP2K_ROOT}" -B "${CMAKE_BUILD_PATH}" \
-GNinja \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
-DCMAKE_INSTALL_MESSAGE="${INSTALL_MESSAGE}" \
-DCMAKE_SKIP_RPATH=ON \
-DCMAKE_VERBOSE_MAKEFILE="${VERBOSE_MAKEFILE}" \
-DCP2K_USE_EVERYTHING=ON \
-DCP2K_USE_DLAF=OFF \
-DCP2K_USE_LIBXSMM=ON \
-DCP2K_USE_MPI=OFF \
-DCP2K_USE_LIBXSMM=OFF \
-DCP2K_USE_OPENPMD=OFF \
-DCP2K_USE_TBLITE=OFF \
-Werror=dev |&
tee "${CMAKE_BUILD_PATH}/cmake.log"
EXIT_CODE=$?
;;
*)
echo "ERROR: Unknown CP2K version ${CP2K_VERSION} specified"
@ -390,13 +442,29 @@ if [[ ! -d "${CMAKE_BUILD_PATH}" ]]; then
esac
fi
if ((EXIT_CODE != 0)); then
echo "ERROR: The CMake configuration step failed with the error code ${EXIT_CODE}"
echo " You can try to remove the build folder with 'rm -rf build' and re-run"
${EXIT_CMD} "${EXIT_CODE}"
fi
# CMake build step
echo -e '\n*** Compiling CP2K ***\n'
cmake --build "${CMAKE_BUILD_PATH}" --parallel "${NUM_PROCS}" -- "${VERBOSE_NINJA}" |& tee "${CMAKE_BUILD_PATH}/ninja.log"
cmake --build "${CMAKE_BUILD_PATH}" --parallel "${NUM_PROCS}" -- "${VERBOSE_FLAG}" |& tee "${CMAKE_BUILD_PATH}/ninja.log"
EXIT_CODE=$?
if ((EXIT_CODE != 0)); then
echo "ERROR: The CMake build step failed with the error code ${EXIT_CODE}"
${EXIT_CMD} "${EXIT_CODE}"
fi
# CMake install step
echo -e '\n*** Installing CP2K ***\n'
cmake --install "${CMAKE_BUILD_PATH}" |& tee "${CMAKE_BUILD_PATH}/install.log"
EXIT_CODE=$?
if ((EXIT_CODE != 0)); then
echo "ERROR: The CMake installation step failed with the error code ${EXIT_CODE}"
${EXIT_CMD} "${EXIT_CODE}"
fi
# Retrieve paths to "hidden" libraries
if ldd "${INSTALL_PREFIX}/bin/cp2k.${CP2K_VERSION}" | grep -q "not found"; then
@ -404,7 +472,7 @@ if ldd "${INSTALL_PREFIX}/bin/cp2k.${CP2K_VERSION}" | grep -q "not found"; then
ldd "${INSTALL_PREFIX}/bin/cp2k.${CP2K_VERSION}" | grep "not found"
echo -e "\n*** Trying to update the LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}\n"
for libname in $(ldd "${INSTALL_PREFIX}/bin/cp2k.${CP2K_VERSION}" | grep "not found" | awk '{print $1}' | sort | uniq); do
library=$(find -L "${SPACK_ROOT}/opt/spack/view ${INSTALL_PREFIX}/lib" -name "${libname}" | tail -n 1)
library=$(find -L "${SPACK_ROOT}/opt/spack/view" "${INSTALL_PREFIX}/lib" -name "${libname}" | tail -n 1)
library_path="$(dirname "${library}")"
if [[ -n "${library_path}" ]]; then
case ":${LD_LIBRARY_PATH}:" in
@ -424,7 +492,7 @@ if ldd "${INSTALL_PREFIX}/bin/cp2k.${CP2K_VERSION}" | grep -q "not found"; then
else
echo -e "\n*** The update of the LD_LIBRARY_PATH was NOT successful"
echo -e "\n*** The following libraries were NOT found:"
ldd "${INSTALL_PREFIX}"/bin/cp2k."${CP2K_VERSION}" | grep "not found" | sort | uniq
ldd "${INSTALL_PREFIX}/bin/cp2k.${CP2K_VERSION}" | grep "not found" | sort | uniq
fi
export LD_LIBRARY_PATH
fi
@ -437,15 +505,20 @@ ulimit -c 0 -s unlimited
export OMP_STACKSIZE=64M
export PATH=${INSTALL_PREFIX}/bin:${PATH}
export LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}
ldd "${INSTALL_PREFIX}"/bin/cp2k."${CP2K_VERSION}" | grep "not found" | sort | uniq
ldd "${INSTALL_PREFIX}/bin/cp2k.${CP2K_VERSION}" | grep "not found" | sort | uniq
${CP2K_ROOT}/tests/do_regtest.py ${TESTOPTS} \$* ${INSTALL_PREFIX}/bin ${CP2K_VERSION}
***
chmod 750 "${INSTALL_PREFIX}"/bin/run_tests
chmod 750 "${INSTALL_PREFIX}/bin/run_tests"
# Optionally, launch test run
if [[ "${RUN_TEST}" == "yes" ]]; then
echo -e "\n*** Launching regression test run using the script ${INSTALL_PREFIX}/bin/run_tests\n"
"${INSTALL_PREFIX}"/bin/run_tests
EXIT_CODE=$?
if ((EXIT_CODE != 0)); then
echo "ERROR: The regression test run failed with the error code ${EXIT_CODE}"
${EXIT_CMD} "${EXIT_CODE}"
fi
else
echo -e "\n*** A regression test run can be launched using the script ${INSTALL_PREFIX}/bin/run_tests\n"
fi