mirror of
https://github.com/Pmodules/Pmodules.git
synced 2026-06-28 02:19:39 +02:00
b082bfcaf4
the name of the hierarchical group for modules compiled with a serial HDF5 is HDF5_serial not HDF5_SERIAL
1497 lines
36 KiB
Bash
1497 lines
36 KiB
Bash
#!/bin/bash
|
||
|
||
#.............................................................................
|
||
#
|
||
# We need GNU versions of the following utilities. This code works
|
||
# well on Linux and Mac OS X with MacPorts.
|
||
# :FIXME: implement a smarter, portable solution.
|
||
#
|
||
shopt -s expand_aliases
|
||
unalias -a
|
||
|
||
__path=$(which gsed 2>/dev/null || : )
|
||
if [[ $__path ]]; then
|
||
alias sed=$__path
|
||
else
|
||
alias sed=$(which sed 2>/dev/null)
|
||
fi
|
||
unset __path
|
||
|
||
#.............................................................................
|
||
# disable auto-echo feature of 'cd'
|
||
unset CDPATH
|
||
|
||
#.............................................................................
|
||
# define constants
|
||
declare -r BNAME_VARIANTS='variants'
|
||
declare -r FNAME_RDEPS='.dependencies'
|
||
declare -r FNAME_IDEPS='.install_dependencies'
|
||
declare -r FNAME_BDEPS='.build_dependencies'
|
||
|
||
#.............................................................................
|
||
declare -A SOURCE_UNPACK_DIRS
|
||
|
||
#.............................................................................
|
||
#
|
||
# Exit script on errror.
|
||
#
|
||
# $1 exit code
|
||
#
|
||
set -o errexit
|
||
|
||
error_handler() {
|
||
local -i ec=$?
|
||
|
||
std::die ${ec} "Oops"
|
||
}
|
||
|
||
trap "error_handler" ERR
|
||
|
||
declare configure_with='undef'
|
||
|
||
#..............................................................................
|
||
#
|
||
# compare two version numbers
|
||
#
|
||
# original implementation found on stackoverflow:
|
||
# https://stackoverflow.com/questions/4023830/how-to-compare-two-strings-in-dot-separated-version-format-in-bash
|
||
#
|
||
pbuild::version_compare () {
|
||
is_uint() {
|
||
[[ $1 =~ ^[0-9]+$ ]]
|
||
}
|
||
|
||
[[ $1 == $2 ]] && return 0
|
||
local IFS=.
|
||
local i ver1=($1) ver2=($2)
|
||
|
||
# fill empty fields in ver1 with zeros
|
||
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
|
||
ver1[i]=0
|
||
done
|
||
for ((i=0; i<${#ver1[@]}; i++)); do
|
||
[[ -z ${ver2[i]} ]] && ver2[i]=0
|
||
if is_uint ${ver1[i]} && is_uint ${ver2[i]}; then
|
||
((10#${ver1[i]} > 10#${ver2[i]})) && return 1
|
||
((10#${ver1[i]} < 10#${ver2[i]})) && return 2
|
||
else
|
||
[[ ${ver1[i]} > ${ver2[i]} ]] && return 1
|
||
[[ ${ver1[i]} < ${ver2[i]} ]] && return 2
|
||
fi
|
||
done
|
||
return 0
|
||
}
|
||
|
||
pbuild::version_lt() {
|
||
pbuild::version_compare "$1" "$2"
|
||
(( $? == 2 ))
|
||
}
|
||
|
||
pbuild::version_le() {
|
||
pbuild::version_compare "$1" "$2"
|
||
local -i exit_code=$?
|
||
(( exit_code == 0 || exit_code == 2 ))
|
||
}
|
||
|
||
|
||
pbuild::version_gt() {
|
||
pbuild::version_compare "$1" "$2"
|
||
(( $? == 1 ))
|
||
local -i exit_code=$?
|
||
(( exit_code == 0 || exit_code == 1 ))
|
||
}
|
||
|
||
pbuild::version_eq() {
|
||
pbuild::version_compare "$1" "$2"
|
||
}
|
||
|
||
#..............................................................................
|
||
#
|
||
# The following variables are available in build-blocks and set read-only
|
||
# :FIXME: do we have to export them?
|
||
|
||
# install prefix of module.
|
||
declare -x PREFIX=''
|
||
|
||
declare -r OS=$(uname -s)
|
||
|
||
pbuild::get_num_cores() {
|
||
case "${OS}" in
|
||
Linux )
|
||
echo $(grep -c ^processor /proc/cpuinfo)
|
||
;;
|
||
Darwin )
|
||
echo $(sysctl -n hw.ncpu)
|
||
;;
|
||
* )
|
||
std::die 1 "OS ${OS} is not supported\n"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
#..............................................................................
|
||
# global variables which can be set/overwritten by command line args
|
||
|
||
declare force_rebuild=''
|
||
pbuild.force_rebuild() {
|
||
force_rebuild="$1"
|
||
}
|
||
|
||
declare dry_run=''
|
||
pbuild.dry_run() {
|
||
dry_run="$1"
|
||
}
|
||
|
||
declare enable_cleanup_build=''
|
||
pbuild.enable_cleanup_build() {
|
||
enable_cleanup_build="$1"
|
||
}
|
||
|
||
declare enable_cleanup_src=''
|
||
pbuild.enable_cleanup_src() {
|
||
enable_cleanup_src="$1"
|
||
}
|
||
|
||
declare build_target=''
|
||
pbuild.build_target() {
|
||
build_target="$1"
|
||
}
|
||
|
||
declare opt_update_modulefiles=''
|
||
pbuild.update_modulefiles() {
|
||
opt_update_modulefiles="$1"
|
||
}
|
||
|
||
# number of parallel make jobs
|
||
declare -i JOBS=$(pbuild::get_num_cores)
|
||
pbuild.jobs() {
|
||
if (( $1 == 0 )); then
|
||
JOBS=$(pbuild::get_num_cores)
|
||
(( JOBS > 10 )) && JOBS=10 || :
|
||
else
|
||
JOBS="$1"
|
||
fi
|
||
}
|
||
|
||
declare system=''
|
||
pbuild.system() {
|
||
system="$1"
|
||
}
|
||
|
||
declare verbose=''
|
||
pbuild.verbose() {
|
||
verbose="$1"
|
||
}
|
||
|
||
|
||
# group this module is in (ex: 'Programming')
|
||
declare -x GROUP=''
|
||
|
||
# name, version and release of module
|
||
declare -x module_name=''
|
||
declare -x module_version=''
|
||
declare -x module_release=''
|
||
|
||
# relative path of documentation
|
||
# abs. path is "${PREFIX}/${_docdir}/${module_name}"
|
||
declare -r _DOCDIR='share/doc'
|
||
|
||
##############################################################################
|
||
#
|
||
# Set flag to build module in source tree.
|
||
#
|
||
# Arguments:
|
||
# none
|
||
#
|
||
pbuild::compile_in_sourcetree() {
|
||
BUILD_DIR="${SRC_DIR}"
|
||
}
|
||
|
||
##############################################################################
|
||
#
|
||
# Check whether the script is running on a supported OS.
|
||
#
|
||
# Arguments:
|
||
# $@: supported opertating systems (something like RHEL6, macOS10.14, ...).
|
||
# Default is all.
|
||
#
|
||
pbuild::supported_systems() {
|
||
SUPPORTED_SYSTEMS+=( "$@" )
|
||
}
|
||
|
||
##############################################################################
|
||
#
|
||
# Check whether the script is running on a supported OS.
|
||
#
|
||
# Arguments:
|
||
# $@: supported opertating systems (like Linux, Darwin).
|
||
# Default is all.
|
||
#
|
||
pbuild::supported_os() {
|
||
SUPPORTED_OS+=( "$@" )
|
||
}
|
||
|
||
##############################################################################
|
||
#
|
||
# Check whether the loaded compiler is supported.
|
||
#
|
||
# Arguments:
|
||
# $@: supported compiler (like GCC, Intel, PGI).
|
||
# Default is all.
|
||
#
|
||
pbuild::supported_compilers() {
|
||
SUPPORTED_COMPILERS+=( "$@" )
|
||
}
|
||
|
||
##############################################################################
|
||
#
|
||
# Install module in given group.
|
||
#
|
||
# Arguments:
|
||
# $1: group
|
||
#
|
||
pbuild::add_to_group() {
|
||
if [[ -z ${1} ]]; then
|
||
std::die 42 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"${FUNCNAME}: missing group argument."
|
||
fi
|
||
GROUP="$1"
|
||
}
|
||
|
||
##############################################################################
|
||
#
|
||
# Set documentation file to be installed.
|
||
#
|
||
# Arguments:
|
||
# $@: documentation files relative to source
|
||
#
|
||
pbuild::install_docfiles() {
|
||
MODULE_DOCFILES+=("$@")
|
||
}
|
||
|
||
##############################################################################
|
||
#
|
||
# Test whether a module with the given name is available. If yes, return
|
||
# release
|
||
#
|
||
# Arguments:
|
||
# $1: module name
|
||
# $2: optional variable name to return release via upvar
|
||
#
|
||
# Notes:
|
||
# The passed module name must be NAME/VERSION!
|
||
#
|
||
pbuild::module_is_avail() {
|
||
local "$2"
|
||
local uvar="$2"
|
||
[[ -n "${uvar}" ]] || uvar="__unused__"
|
||
local output=( $("${MODULECMD}" bash avail -a -m "$1" \
|
||
2>&1 1>/dev/null) )
|
||
local i
|
||
for (( i = 0; i < ${#output[@]}; i += 2 )); do
|
||
if [[ "${output[$i]}" == "$1" ]]; then
|
||
std::upvar "${uvar}" "${output[i+1]}"
|
||
return 0
|
||
fi
|
||
done
|
||
return 1
|
||
}
|
||
|
||
pbuild::set_download_url() {
|
||
local -i _i=${#SOURCE_URLS[@]}
|
||
SOURCE_URLS[_i]="$1"
|
||
SOURCE_NAMES[_i]="$2"
|
||
}
|
||
|
||
pbuild::set_sha256sum() {
|
||
SOURCE_SHA256_SUMS+=("$1")
|
||
}
|
||
|
||
pbuild::set_unpack_dir() {
|
||
SOURCE_UNPACK_DIRS[$1]=$2
|
||
}
|
||
|
||
pbuild::use_cc() {
|
||
[[ -x "$1" ]] || std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Error in setting CC:" \
|
||
"'$1' is not an executable!"
|
||
CC="$1"
|
||
}
|
||
|
||
pbuild::pre_prep() {
|
||
:
|
||
}
|
||
|
||
pbuild::post_prep() {
|
||
:
|
||
}
|
||
|
||
###############################################################################
|
||
#
|
||
# extract sources. For the time being only tar-files are supported.
|
||
#
|
||
pbuild::prep() {
|
||
#......................................................................
|
||
#
|
||
# Find/download tarball for given module.
|
||
#
|
||
# Arguments:
|
||
# $1: store file name with upvar here
|
||
# $2: download URL
|
||
# $3: output filename (can be empty string)
|
||
# $4...: download directories
|
||
#
|
||
# Returns:
|
||
# 0 on success otherwise a value > 0
|
||
#
|
||
download_with_curl() {
|
||
local -r output="$1"
|
||
local -r url="$2"
|
||
curl \
|
||
-L \
|
||
--output "${output}" \
|
||
"${url}"
|
||
if (( $? != 0 )); then
|
||
curl \
|
||
--insecure \
|
||
--output "${output}" \
|
||
"${url}"
|
||
fi
|
||
}
|
||
|
||
check_hash_sum() {
|
||
local -r fname="$1"
|
||
local -r expected_hash_sum="$2"
|
||
local hash_sum=''
|
||
|
||
if which 'sha256sum' 1>/dev/null; then
|
||
hash_sum=$(sha256sum "${fname}" | awk '{print $1}')
|
||
elif which 'shasum' 1>/dev/null; then
|
||
hash_sum=$(shasum -a 256 "${fname}" | awk '{print $1}')
|
||
else
|
||
std::die 42 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Binary to compute SHA256 sum missing!"
|
||
fi
|
||
test "${hash_sum}" == "${expected_hash_sum}" || \
|
||
std::die 42 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"hash-sum missmatch for file '%s'" "${fname}"
|
||
}
|
||
|
||
download_source_file() {
|
||
local "$1"
|
||
local var="$1"
|
||
local -r url="$2"
|
||
local fname="$3"
|
||
shift 3
|
||
dirs+=( "$@" )
|
||
|
||
[[ -n "${fname}" ]] || fname="${url##*/}"
|
||
local expr='s/.*\(.tar.bz2\|.tbz2\|.tar.gz\|.tgz\|.tar.xz\|.zip\)/\1/'
|
||
local -r extension=$(echo ${fname} | sed "${expr}")
|
||
local dir=''
|
||
dirs+=( 'not found' )
|
||
for dir in "${dirs[@]}"; do
|
||
[[ -r "${dir}/${fname}" ]] && break
|
||
done
|
||
if [[ "${dir}" == 'not found' ]]; then
|
||
dir="${dirs[0]}"
|
||
local -r method="${url%:*}"
|
||
case "${method}" in
|
||
http | https | ftp )
|
||
download_with_curl "${dir}/${fname}" "${url}"
|
||
;;
|
||
* )
|
||
std::die 4 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Error in download URL:" \
|
||
"unknown download method '${method}'!"
|
||
;;
|
||
esac
|
||
fi
|
||
local sha256_sum=''
|
||
local hash=''
|
||
for hash in "${SOURCE_SHA256_SUMS[@]}"; do
|
||
if [[ ${hash} =~ $fname: ]]; then
|
||
sha256_sum="${hash#*:}"
|
||
fi
|
||
done
|
||
if [[ -n "${sha256_sum}" ]]; then
|
||
check_hash_sum "${dir}/${fname}" "${sha256_sum}"
|
||
fi
|
||
std::upvar "${var}" "${dir}/${fname}"
|
||
[[ -r "${dir}/${fname}" ]]
|
||
}
|
||
|
||
unpack() {
|
||
local -r file="$1"
|
||
local -r dir="${2:-${SRC_DIR}}"
|
||
tar --directory="${dir}" -xv --strip-components 1 -f "${file}" || {
|
||
rm -f "${file}"
|
||
std::die 4 \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"cannot unpack sources!"
|
||
}
|
||
}
|
||
|
||
patch_sources() {
|
||
cd "${SRC_DIR}"
|
||
local i=0
|
||
for ((_i = 0; _i < ${#PATCH_FILES[@]}; _i++)); do
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"Appling patch '${PATCH_FILES[_i]}' ..."
|
||
local -i strip_val="${PATCH_STRIPS[_i]:-${PATCH_STRIP_DEFAULT}}"
|
||
patch -p${strip_val} < "${BUILDBLOCK_DIR}/${PATCH_FILES[_i]}" || \
|
||
std::die 4 \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"error patching sources!"
|
||
done
|
||
}
|
||
if [[ -z "${SOURCE_URLS}" ]]; then
|
||
for fname in ${VERSIONS[@]/#/pbuild::set_download_url_}; do
|
||
if typeset -F ${fname} 2>/dev/null; then
|
||
$f
|
||
break
|
||
fi
|
||
done
|
||
fi
|
||
[[ -z "${SOURCE_URLS}" ]] && \
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Download source not set!"
|
||
mkdir -p "${PMODULES_DISTFILESDIR}"
|
||
local i=0
|
||
local source_fname
|
||
for ((i = 0; i < ${#SOURCE_URLS[@]}; i++)); do
|
||
download_source_file \
|
||
source_fname \
|
||
"${SOURCE_URLS[i]}" \
|
||
"${SOURCE_NAMES[i]}" \
|
||
"${PMODULES_DISTFILESDIR}" \
|
||
"${BUILDBLOCK_DIR}" ||
|
||
std::die 4 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"sources for not found."
|
||
unpack "${source_fname}" "${SOURCE_UNPACK_DIRS[${source_fname##*/}]}"
|
||
done
|
||
patch_sources
|
||
# create build directory
|
||
mkdir -p "${BUILD_DIR}"
|
||
}
|
||
|
||
pbuild::add_patch() {
|
||
[[ -z "$1" ]] && \
|
||
std::die 1 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"${FUNCNAME}: missing argument!"
|
||
PATCH_FILES+=( "$1" )
|
||
PATCH_STRIPS+=( "$2" )
|
||
}
|
||
|
||
pbuild::set_default_patch_strip() {
|
||
[[ -n "$1" ]] || \
|
||
std::die 1 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"${FUNCNAME}: missing argument!"
|
||
|
||
PATCH_STRIP_DEFAULT="$1"
|
||
}
|
||
|
||
pbuild::use_flag() {
|
||
[[ "${USE_FLAGS}" =~ ":${1}:" ]]
|
||
}
|
||
|
||
###############################################################################
|
||
#
|
||
#
|
||
pbuild::pre_configure() {
|
||
:
|
||
}
|
||
|
||
pbuild::set_configure_args() {
|
||
CONFIGURE_ARGS+=( "$@" )
|
||
}
|
||
|
||
pbuild::add_configure_args() {
|
||
CONFIGURE_ARGS+=( "$@" )
|
||
}
|
||
|
||
pbuild::use_autotools() {
|
||
configure_with='autotools'
|
||
}
|
||
|
||
pbuild::use_cmake() {
|
||
configure_with='cmake'
|
||
}
|
||
|
||
pbuild::configure() {
|
||
case "${configure_with}" in
|
||
autotools )
|
||
if [[ ! -r "${SRC_DIR}/configure" ]]; then
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"${FNCNAME[0]}:" \
|
||
"autotools configuration not available, aborting..."
|
||
fi
|
||
;;
|
||
cmake )
|
||
if [[ ! -r "${SRC_DIR}/CMakeLists.txt" ]]; then
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"${FNCNAME[0]}:" \
|
||
"CMake script not available, aborting..."
|
||
fi
|
||
;;
|
||
esac
|
||
if [[ -r "${SRC_DIR}/configure" ]] && \
|
||
[[ "${configure_with}" == 'undef' ]] || \
|
||
[[ "${configure_with}" == 'autotools' ]]; then
|
||
${SRC_DIR}/configure \
|
||
--prefix="${PREFIX}" \
|
||
"${CONFIGURE_ARGS[@]}" || \
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"configure failed"
|
||
elif [[ -r "${SRC_DIR}/CMakeLists.txt" ]] && \
|
||
[[ "${configure_with}" == 'undef' ]] || \
|
||
[[ "${configure_with}" == "cmake" ]]; then
|
||
cmake \
|
||
-DCMAKE_INSTALL_PREFIX="${PREFIX}" \
|
||
"${CONFIGURE_ARGS[@]}" \
|
||
"${SRC_DIR}" || \
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"cmake failed"
|
||
else
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"${FUNCNAME[0]}: skipping..."
|
||
fi
|
||
}
|
||
|
||
pbuild::post_configure() {
|
||
:
|
||
}
|
||
|
||
pbuild::pre_compile() {
|
||
:
|
||
}
|
||
|
||
pbuild::compile() {
|
||
make -j${JOBS} || \
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"compilation failed!"
|
||
}
|
||
|
||
pbuild::post_compile() {
|
||
:
|
||
}
|
||
|
||
pbuild::pre_install() {
|
||
:
|
||
}
|
||
|
||
pbuild::install() {
|
||
make install || \
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"compilation failed!"
|
||
}
|
||
|
||
pbuild::install_shared_libs() {
|
||
local -r binary="$1"
|
||
local -r dstdir="$2"
|
||
local -r pattern="${3//\//\\/}" # escape slash
|
||
|
||
install_shared_libs_Linux() {
|
||
local libs=( $(ldd "${binary}" | \
|
||
awk "/ => \// && /${pattern}/ {print \$3}") )
|
||
if [[ -n "${libs}" ]]; then
|
||
cp -vL "${libs[@]}" "${dstdir}" || return $?
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
install_shared_libs_Darwin() {
|
||
# https://stackoverflow.com/questions/33991581/install-name-tool-to-update-a-executable-to-search-for-dylib-in-mac-os-x
|
||
local libs=( $(otool -L "${binary}" | \
|
||
awk "/${pattern}/ {print \$1}"))
|
||
if [[ -n "${libs}" ]]; then
|
||
cp -vL "${libs[@]}" "${dstdir}" || return $?
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
test -e "${binary}" || \
|
||
std::die 3 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"${binary}: does not exist or is not executable!"
|
||
mkdir -p "${dstdir}"
|
||
case "${OS}" in
|
||
Linux )
|
||
install_shared_libs_Linux
|
||
;;
|
||
Darwin )
|
||
install_shared_libs_Darwin
|
||
;;
|
||
esac
|
||
}
|
||
|
||
pbuild::post_install() {
|
||
:
|
||
}
|
||
|
||
#
|
||
# The 'do it all' function.
|
||
#
|
||
pbuild::make_all() {
|
||
source "${BUILD_SCRIPT}"
|
||
|
||
set -e
|
||
local -r logfile="${BUILDBLOCK_DIR}/pbuild.log"
|
||
# module name including path in hierarchy and version
|
||
# (ex: 'gcc/6.1.0/openmpi/1.10.2' for openmpi compiled with gcc 6.1.0)
|
||
local modulefile_dir=''
|
||
local modulefile_name=''
|
||
|
||
#
|
||
# To be able to set environment variables in one of the 'pbuild::TARGET'
|
||
# function we cannot use PIPE's like
|
||
# pbuild::configure | tee -a ...
|
||
#
|
||
rm -f "${logfile}"
|
||
if [[ "${verbose}" == 'yes' ]]; then
|
||
exec > >(tee -a "${logfile}")
|
||
else
|
||
exec > >(cat >> "${logfile}")
|
||
fi
|
||
exec 2> >(tee -a "${logfile}" >&2)
|
||
|
||
#
|
||
# everything set up?
|
||
#
|
||
[[ -n ${GROUP} ]] || \
|
||
std::die 5 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Module group not set! Aborting ..."
|
||
|
||
|
||
#
|
||
# helper functions
|
||
#
|
||
|
||
#......................................................................
|
||
check_supported_systems() {
|
||
[[ -z "${SUPPORTED_SYSTEMS}" ]] && return 0
|
||
for sys in "${SUPPORTED_SYSTEMS[@]}"; do
|
||
[[ ${sys,,} == ${system,,} ]] && return 0
|
||
done
|
||
std::die 1 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Not available for ${system}."
|
||
}
|
||
|
||
#......................................................................
|
||
check_supported_os() {
|
||
[[ -z "${SUPPORTED_OS}" ]] && return 0
|
||
for os in "${SUPPORTED_OS[@]}"; do
|
||
[[ ${os,,} == ${OS,,} ]] && return 0
|
||
done
|
||
std::die 1 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Not available for ${OS}."
|
||
}
|
||
|
||
#......................................................................
|
||
check_supported_compilers() {
|
||
[[ -z "${SUPPORTED_COMPILERS}" ]] && return 0
|
||
for compiler in "${SUPPORTED_COMPILERS[@]}"; do
|
||
[[ ${compiler,,} == ${COMPILER,,} ]] && return 0
|
||
done
|
||
std::die 1 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Not available for ${COMPILER}."
|
||
}
|
||
|
||
#......................................................................
|
||
#
|
||
# compute full module name and installation prefix
|
||
#
|
||
# The following variables are expected to be set:
|
||
# GROUP module group
|
||
# P module name
|
||
# V module version
|
||
# variables defining the hierarchical environment like
|
||
# COMPILER and COMPILER_VERSION
|
||
#
|
||
# The following variables are set in this function
|
||
# modulefile_dir
|
||
# modulefile_name
|
||
# PREFIX
|
||
#
|
||
set_full_module_name_and_prefix() {
|
||
join_by() {
|
||
local IFS="$1"
|
||
shift
|
||
echo "$*"
|
||
}
|
||
|
||
[[ -n ${GROUP} ]] || std::die 1 \
|
||
"${module_name}/${module_version}:" \
|
||
"group not set."
|
||
|
||
# define defaults if not set in configuration file
|
||
: ${Compiler_HIERARCHY:='${COMPILER}/${COMPILER_VERSION}'}
|
||
: ${CUDA_HIERARCHY:='${COMPILER}/${COMPILER_VERSION} cuda/${CUDA_VERSION}'}
|
||
: ${MPI_HIERARCHY:='${COMPILER}/${COMPILER_VERSION} ${MPI}/${MPI_VERSION}'}
|
||
: ${HDF5_HIERARCHY:='${COMPILER}/${COMPILER_VERSION} ${MPI}/${MPI_VERSION} hdf5/${HDF5_VERSION}'}
|
||
: ${HDF5_serial_HIERARCHY:='${COMPILER}/${COMPILER_VERSION} hdf5_serial/${HDF5_SERIAL_VERSION}'}
|
||
|
||
# evaluate
|
||
local names=()
|
||
local vname="${GROUP}_HIERARCHY"
|
||
if [[ -n ${!vname} ]]; then
|
||
names=( $(eval echo ${!vname}) )
|
||
fi
|
||
|
||
modulefile_dir=$(join_by '/' \
|
||
"${PMODULES_ROOT}/${GROUP}/${PMODULES_MODULEFILES_DIR}" \
|
||
"${names[@]}" \
|
||
"${module_name}")
|
||
modulefile_name="${modulefile_dir}/${module_version}"
|
||
PREFIX="${PMODULES_ROOT}/${GROUP}/${module_name}/${module_version}"
|
||
local -i i=0
|
||
for ((i=${#names[@]}-1; i >= 0; i--)); do
|
||
PREFIX+="/${names[i]}"
|
||
done
|
||
}
|
||
|
||
#......................................................................
|
||
# Select the modulefile to install. Modulefiles can be versioned like
|
||
# modulefile-10.2.0
|
||
# modulefile-10.2
|
||
# modulefile-10
|
||
# modulefile
|
||
# the most specific modulefile will be selected. Example:
|
||
# For a version 10.2.1 the file moduelfile-10.2 would be selected.
|
||
#
|
||
# Arguments:
|
||
# $1 upvar to return the filename
|
||
#
|
||
# Used gloabal variables:
|
||
# VERSIONS
|
||
# BUILDBLOCK_DIR
|
||
#
|
||
find_modulefile() {
|
||
local "$1"
|
||
local fname=''
|
||
local modulefile=''
|
||
for fname in "${VERSIONS[@]/#/modulefile-}" 'modulefile'; do
|
||
if [[ -r "${BUILDBLOCK_DIR}/${fname}" ]]; then
|
||
modulefile="${BUILDBLOCK_DIR}/${fname}"
|
||
break;
|
||
fi
|
||
done
|
||
std::upvar $1 "${modulefile}"
|
||
[[ -n "${modulefile}" ]]
|
||
}
|
||
|
||
#......................................................................
|
||
# non-redefinable post-install. Install:
|
||
# - documentation files as defined in the build-script
|
||
# - modulefile and file with release
|
||
# .
|
||
post_install() {
|
||
#..............................................................
|
||
# install the doc-files specified in the build-script
|
||
#
|
||
# Arguments:
|
||
# none
|
||
#
|
||
install_doc() {
|
||
if [[ -z "${MODULE_DOCFILES}" ]]; then
|
||
for f in ${VERSIONS[@]/#/pbuild::install_docfiles_}; do
|
||
if typeset -F "$f" 2>/dev/null; then
|
||
$f
|
||
break
|
||
fi
|
||
done
|
||
|
||
fi
|
||
[[ -n "${MODULE_DOCFILES}" ]] || return 0
|
||
local -r docdir="${PREFIX}/${_DOCDIR}/${module_name}"
|
||
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"Installing documentation to ${docdir}"
|
||
install -m 0755 -d \
|
||
"${docdir}"
|
||
install -m0444 \
|
||
"${MODULE_DOCFILES[@]/#/${SRC_DIR}/}" \
|
||
"${docdir}"
|
||
return 0
|
||
}
|
||
|
||
#..............................................................
|
||
# install build-block files
|
||
# - modulefile
|
||
# - build-script
|
||
# - run-time and build dependencies
|
||
# in ${PREFIX}/share/${GROUP}/${module_name}
|
||
#
|
||
# Arguments:
|
||
# none
|
||
#
|
||
install_pmodules_files() {
|
||
local modulefile=''
|
||
find_modulefile modulefile || return 0
|
||
|
||
local -r target_dir="${PREFIX}/share/$GROUP/${module_name}"
|
||
mkdir -p "${target_dir}"
|
||
install -m0444 \
|
||
"${BUILD_SCRIPT}" \
|
||
"${target_dir}"
|
||
install -m0444 \
|
||
"${modulefile}" \
|
||
"${target_dir}"
|
||
#install -m 0755 \
|
||
# -d "${target_dir}/files"
|
||
#install -m0444 \
|
||
# "${variants_file}" \
|
||
# "${target_dir}/files"
|
||
|
||
local -r fname="${target_dir}/dependencies"
|
||
"${MODULECMD}" bash list -t 2>&1 1>/dev/null | \
|
||
grep -v "Currently Loaded" > "${fname}" || :
|
||
}
|
||
|
||
#..............................................................
|
||
# write run time dependencies to file
|
||
write_runtime_dependencies() {
|
||
local -r fname="$1"
|
||
shift
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"writing run-time dependencies to ${fname} ..."
|
||
local dep
|
||
echo -n "" > "${fname}"
|
||
for dep in "$@"; do
|
||
[[ -z $dep ]] && continue
|
||
if [[ ! $dep == */* ]]; then
|
||
# no version given: derive the version
|
||
# from the currently loaded module
|
||
dep=$( "${MODULECMD}" bash list -t 2>&1 1>/dev/null \
|
||
| grep "^${dep}/" )
|
||
fi
|
||
echo "${dep}" >> "${fname}"
|
||
done
|
||
}
|
||
|
||
#..............................................................
|
||
# for Linux we need a special post-install to solve the
|
||
# multilib problem with LIBRARY_PATH on 64-bit systems
|
||
post_install_linux() {
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"running post-installation for ${OS} ..."
|
||
cd "${PREFIX}"
|
||
[[ -d "lib" ]] && [[ ! -d "lib64" ]] && ln -s lib lib64
|
||
return 0
|
||
}
|
||
|
||
#..............................................................
|
||
cd "${BUILD_DIR}"
|
||
[[ "${OS}" == "Linux" ]] && post_install_linux
|
||
install_doc
|
||
install_pmodules_files
|
||
if [[ -n "${runtime_dependencies}" ]]; then
|
||
write_runtime_dependencies \
|
||
"${PREFIX}/${FNAME_RDEPS}" \
|
||
"${runtime_dependencies[@]}"
|
||
fi
|
||
if [[ -n "${install_dependencies}" ]]; then
|
||
write_runtime_dependencies \
|
||
"${PREFIX}/${FNAME_IDEPS}" \
|
||
"${install_dependencies[@]}"
|
||
fi
|
||
if [[ "${bootstrap}" == 'no' ]]; then
|
||
install_modulefile
|
||
install_release_file
|
||
fi
|
||
cleanup_build
|
||
cleanup_src
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"Done ..."
|
||
return 0
|
||
}
|
||
|
||
#......................................................................
|
||
# Install modulefile in ${PMODULES_ROOT}/${GROUP}/modulefiles/...
|
||
#
|
||
# Arguments
|
||
# none
|
||
install_modulefile() {
|
||
local src=''
|
||
find_modulefile src
|
||
if (( $? != 0 )); then
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"skipping modulefile installation ..."
|
||
return
|
||
fi
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"installing modulefile '${modulefile_name}' ..."
|
||
mkdir -p "${modulefile_dir}"
|
||
install -m 0444 "${src}" "${modulefile_name}"
|
||
}
|
||
|
||
install_release_file() {
|
||
local -r release_file="${modulefile_dir}/.release-${module_version}"
|
||
|
||
if [[ -r "${release_file}" ]]; then
|
||
local release
|
||
read release < "${release_file}"
|
||
if [[ "${release}" != "${module_release}" ]]; then
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"changing release from" \
|
||
"'${release}' to '${module_release}' ..."
|
||
echo "${module_release}" > "${release_file}"
|
||
fi
|
||
else
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"setting release to '${module_release}' ..."
|
||
echo "${module_release}" > "${release_file}"
|
||
fi
|
||
}
|
||
|
||
cleanup_build() {
|
||
[[ ${enable_cleanup_build} == yes ]] || return 0
|
||
[[ "${BUILD_DIR}" == "${SRC_DIR}" ]] && return 0
|
||
{
|
||
cd "/${BUILD_DIR}/.." || std::die 42 "Internal error"
|
||
[[ "$(pwd)" == "/" ]] && \
|
||
std::die 1 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Oops: internal error:" \
|
||
"BUILD_DIR is set to '/'"
|
||
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"Cleaning up '${BUILD_DIR}'..."
|
||
rm -rf "${BUILD_DIR##*/}"
|
||
};
|
||
return 0
|
||
}
|
||
|
||
cleanup_src() {
|
||
[[ ${enable_cleanup_src} == yes ]] || return 0
|
||
{
|
||
cd "/${SRC_DIR}/.." || std::die 42 "Internal error"
|
||
[[ $(pwd) == / ]] && \
|
||
std::die 1 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"Oops: internal error:" \
|
||
"SRC_DIR is set to '/'"
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"Cleaning up '${SRC_DIR}'..."
|
||
rm -rf "${SRC_DIR##*/}"
|
||
};
|
||
return 0
|
||
}
|
||
|
||
build_target() {
|
||
local dir="$1" # src or build directory, depends on target
|
||
local target="$2" # prep, configure, compile or install
|
||
|
||
if [[ -e "${BUILD_DIR}/.${target}" ]] && \
|
||
[[ ${force_rebuild} != 'yes' ]]; then
|
||
return 0
|
||
fi
|
||
local targets=()
|
||
targets+=( ${VERSIONS[@]/#/pbuild::pre_${target}_${system}_} )
|
||
targets+=( pbuild::pre_${target}_${system} )
|
||
targets+=( ${VERSIONS[@]/#/pbuild::pre_${target}_${OS}_} )
|
||
targets+=( pbuild::pre_${target}_${OS} )
|
||
targets+=( ${VERSIONS[@]/#/pbuild::pre_${target}_} )
|
||
targets+=( pbuild::pre_${target} )
|
||
|
||
targets+=( ${VERSIONS[@]/#/pbuild::${target}_${system}_} )
|
||
targets+=( pbuild::${target}_${system} )
|
||
targets+=( ${VERSIONS[@]/#/pbuild::${target}_${OS}_} )
|
||
targets+=( pbuild::${target}_${OS} )
|
||
targets+=( ${VERSIONS[@]/#/pbuild::${target}_} )
|
||
targets+=( pbuild::${target} )
|
||
|
||
targets+=( ${VERSIONS[@]/#/pbuild::post_${target}_${system}_} )
|
||
targets+=( pbuild::post_${target}_${system} )
|
||
targets+=( ${VERSIONS[@]/#/pbuild::post_${target}_${OS}_} )
|
||
targets+=( pbuild::post_${target}_${OS} )
|
||
targets+=( ${VERSIONS[@]/#/pbuild::post_${target}_} )
|
||
targets+=( pbuild::post_${target} )
|
||
|
||
for t in "${targets[@]}"; do
|
||
# We cd into the dir before calling the function -
|
||
# just to be sure we are in the right directory.
|
||
#
|
||
# Executing the function in a sub-process doesn't
|
||
# work because in some function global variables
|
||
# might/need to be set.
|
||
#
|
||
cd "${dir}"
|
||
typeset -F "$t" 2>/dev/null && "$t" || :
|
||
done
|
||
touch "${BUILD_DIR}/.${target}"
|
||
}
|
||
|
||
#......................................................................
|
||
# build module ${module_name}/${module_version}
|
||
build_module() {
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"start building" \
|
||
${with_modules:+with ${with_modules[@]}} \
|
||
"..."
|
||
[[ ${dry_run} == yes ]] && std::die 0 ""
|
||
|
||
mkdir -p "${SRC_DIR}"
|
||
mkdir -p "${BUILD_DIR}"
|
||
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"preparing sources ..."
|
||
# write stdout and stderr to logfile, stderr to terminal
|
||
# write all to logfile and terminal
|
||
build_target "${SRC_DIR}" prep
|
||
[[ "${build_target}" == "prep" ]] && return 0
|
||
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"configuring ..."
|
||
build_target "${BUILD_DIR}" configure
|
||
[[ "${build_target}" == "configure" ]] && return 0
|
||
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"compiling ..."
|
||
build_target "${BUILD_DIR}" compile
|
||
[[ "${build_target}" == "compile" ]] && return 0
|
||
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"installing ..."
|
||
mkdir -p "${PREFIX}"
|
||
build_target "${BUILD_DIR}" install
|
||
post_install
|
||
}
|
||
|
||
remove_module() {
|
||
if [[ -d "${PREFIX}" ]]; then
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"removing all files in '${PREFIX}' ..."
|
||
[[ "${dry_run}" == 'no' ]] && rm -rf ${PREFIX}
|
||
fi
|
||
if [[ -e "${modulefile_name}" ]]; then
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"removing modulefile '${modulefile_name}' ..."
|
||
[[ "${dry_run}" == 'no' ]] && rm -v "${modulefile_name}"
|
||
fi
|
||
local release_file="${modulefile_dir}/.release-${module_version}"
|
||
if [[ -e "${release_file}" ]]; then
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
"removing release file '${release_file}' ..."
|
||
[[ "${dry_run}" == 'no' ]] && rm -v "${release_file}"
|
||
fi
|
||
rmdir -p "${modulefile_dir}" 2>/dev/null || :
|
||
}
|
||
|
||
########################################################################
|
||
#
|
||
# here we really start with make_all()
|
||
#
|
||
|
||
# setup module specific environment
|
||
if [[ "${bootstrap}" == 'no' ]]; then
|
||
check_supported_systems
|
||
check_supported_os
|
||
check_supported_compilers
|
||
set_full_module_name_and_prefix
|
||
if [[ -e "${modulefile_name}" ]] \
|
||
&& [[ -d ${PREFIX} ]] \
|
||
&& [[ ${force_rebuild} != 'yes' ]]; then
|
||
if [[ "${module_release}" == 'removed' ]]; then
|
||
remove_module
|
||
else
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
${with_modules:+with ${with_modules[@]}} \
|
||
"already exists, not rebuilding ..."
|
||
if [[ "${opt_update_modulefiles}" == "yes" ]]; then
|
||
install_modulefile
|
||
fi
|
||
install_release_file
|
||
fi
|
||
else
|
||
if [[ "${module_release}" == 'deprecated' ]]; then
|
||
std::info \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
${with_modules:+with ${with_modules[@]}} \
|
||
"is deprecated, skiping!"
|
||
install_release_file
|
||
else
|
||
build_module
|
||
fi
|
||
fi
|
||
else
|
||
build_module
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
pbuild.init_env() {
|
||
#......................................................................
|
||
#
|
||
# parse the passed version string
|
||
#
|
||
# the following global variables will be set in this function:
|
||
# V_MAJOR
|
||
# V_MINOR
|
||
# V_PATCHLVL
|
||
# V_RELEASE
|
||
# USE_FLAGS
|
||
#
|
||
parse_version() {
|
||
local v="$1"
|
||
V_MAJOR='' # first number in version string
|
||
V_MINOR='' # second number in version string (or empty)
|
||
V_PATCHLVL='' # third number in version string (or empty)
|
||
V_RELEASE='' # module release (or empty)
|
||
: ${USE_FLAGS:=''} # architectures (or empty)
|
||
|
||
local tmp=''
|
||
|
||
if [[ "$v" =~ "_" ]]; then
|
||
tmp="${v#*_}"
|
||
USE_FLAGS+=":${tmp//_/:}:"
|
||
v="${v%%_*}"
|
||
fi
|
||
V_PKG="${v%%-*}" # version without the release number
|
||
if [[ $v == *-* ]]; then
|
||
V_RELEASE="${v#*-}" # release number
|
||
else
|
||
V_RELEASE=''
|
||
fi
|
||
case "${V_PKG}" in
|
||
*.*.* )
|
||
V_MAJOR="${V_PKG%%.*}"
|
||
tmp="${V_PKG#*.}"
|
||
V_MINOR="${tmp%%.*}"
|
||
V_PATCHLVL="${tmp#*.}"
|
||
;;
|
||
*.* )
|
||
V_MAJOR="${V_PKG%.*}"
|
||
V_MINOR="${V_PKG#*.}"
|
||
;;
|
||
* )
|
||
V_MAJOR="${V_PKG}"
|
||
;;
|
||
esac
|
||
|
||
VERSIONS=( ${V_MAJOR} )
|
||
if [[ -n ${V_MINOR} ]]; then
|
||
VERSIONS=( ${V_MAJOR}.${V_MINOR} ${VERSIONS[@]} )
|
||
fi
|
||
if [[ -n ${V_PATCHLVL} ]]; then
|
||
VERSIONS=( ${V_MAJOR}.${V_MINOR}.${V_PATCHLVL} ${VERSIONS[@]} )
|
||
fi
|
||
if [[ -n ${V_RELEASE} ]]; then
|
||
VERSIONS=( ${V_MAJOR}.${V_MINOR}.${V_PATCHLVL}-${V_RELEASE} ${VERSIONS[@]} )
|
||
fi
|
||
}
|
||
|
||
local -r module_name="$1"
|
||
local -r module_version="$2"
|
||
|
||
SRC_DIR="${PMODULES_TMPDIR}/${module_name}-${module_version}/src"
|
||
BUILD_DIR="${PMODULES_TMPDIR}/${module_name}-${module_version}/build"
|
||
|
||
# P and V can be used in the build-script, so we have to set them here
|
||
P="${module_name}"
|
||
V="${module_version}"
|
||
parse_version "${module_version}"
|
||
|
||
SOURCE_URLS=()
|
||
SOURCE_SHA256_SUMS=()
|
||
SOURCE_NAMES=()
|
||
CONFIGURE_ARGS=()
|
||
SUPPORTED_SYSTEMS=()
|
||
SUPPORTED_OS=()
|
||
SUPPORTED_COMPILERS=()
|
||
PATCH_FILES=()
|
||
PATCH_STRIPS=()
|
||
PATCH_STRIP_DEFAULT='1'
|
||
MODULE_DOCFILES=()
|
||
configure_with='undef'
|
||
}
|
||
|
||
pbuild.build_module() {
|
||
module_name="$1"
|
||
module_version="$2"
|
||
module_release="$3"
|
||
shift 3
|
||
with_modules=( "$@" )
|
||
|
||
# used in pbuild::make_all
|
||
declare bootstrap='no'
|
||
declare -a runtime_dependencies=()
|
||
declare -a install_dependencies=()
|
||
|
||
#......................................................................
|
||
#
|
||
# test whether a module is loaded or not
|
||
#
|
||
# $1: module name
|
||
#
|
||
is_loaded() {
|
||
[[ :${LOADEDMODULES}: =~ :$1: ]]
|
||
}
|
||
|
||
#......................................................................
|
||
#
|
||
# build a dependency
|
||
#
|
||
# $1: name of module to build
|
||
#
|
||
# :FIXME: needs testing
|
||
#
|
||
build_dependency() {
|
||
local -r m=$1
|
||
std::debug "${m}: module not available"
|
||
local rels=( ${ReleaseStages//:/ } )
|
||
[[ ${dry_run} == yes ]] && \
|
||
std::die 1 \
|
||
"%s " \
|
||
"${m}: module does not exist," \
|
||
"cannot continue with dry run..."
|
||
|
||
std::info "%s " \
|
||
"$m: module does not exist, trying to build it..."
|
||
local args=( '' )
|
||
set -- ${ARGS[@]}
|
||
while (( $# > 0 )); do
|
||
case $1 in
|
||
-j )
|
||
args+=( "-j $2" )
|
||
shift
|
||
;;
|
||
--jobs=[0-9]* )
|
||
args+=( $1 )
|
||
;;
|
||
-v | --verbose)
|
||
args+=( $1 )
|
||
;;
|
||
--with=*/* )
|
||
args+=( $1 )
|
||
;;
|
||
esac
|
||
shift
|
||
done
|
||
|
||
find_build_script(){
|
||
local p=$1
|
||
local script=$(find "${BUILDBLOCK_DIR}/../.." -path "*/$p/build")
|
||
std::get_abspath "${script}"
|
||
}
|
||
local buildscript=$(find_build_script "${m%/*}")
|
||
[[ -x "${buildscript}" ]] || \
|
||
std::die 1 \
|
||
"$m: build-block not found!"
|
||
if ! "${buildscript}" "${m#*/}" ${args[@]}; then
|
||
std::die 1 \
|
||
"$m: oops: build failed..."
|
||
fi
|
||
}
|
||
|
||
#......................................................................
|
||
#
|
||
# Load build- and run-time dependencies.
|
||
#
|
||
# Arguments:
|
||
# none
|
||
#
|
||
# Variables
|
||
# [r] module_release set if defined in a variants file
|
||
# runtime_dependencies runtime dependencies from variants added
|
||
#
|
||
load_build_dependencies() {
|
||
local m=''
|
||
for m in "${with_modules[@]}"; do
|
||
|
||
# module name prefixes in dependency declarations:
|
||
# 'b:' this is a build dependency
|
||
# 'r:' this a run-time dependency, *not* required for
|
||
# building
|
||
# without prefix: this is a build and
|
||
# run-time dependency
|
||
if [[ "${m:0:2}" == "b:" ]]; then
|
||
m=${m#*:} # remove 'b:'
|
||
elif [[ "${m:0:2}" == "r:" ]]; then
|
||
m=${m#*:} # remove 'r:'
|
||
runtime_dependencies+=( "$m" )
|
||
elif [[ "${m:0:2}" == "R:" ]]; then
|
||
m=${m#*:} # remove 'R:'
|
||
install_dependencies+=( "$m" )
|
||
continue
|
||
else
|
||
runtime_dependencies+=( "$m" )
|
||
fi
|
||
is_loaded "$m" && continue
|
||
|
||
# 'module avail' might output multiple matches if module
|
||
# name and version are not fully specified or in case
|
||
# modules with and without a release number exist.
|
||
# Example:
|
||
# mpc/1.1.0 and mpc/1.1.0-1. Since we get a sorted list
|
||
# from 'module avail' and the full version should be set
|
||
# in the variants file, we look for the first exact
|
||
# match.
|
||
local release_of_dependency=''
|
||
if ! pbuild::module_is_avail "$m" release_of_dependency; then
|
||
build_dependency "$m"
|
||
pbuild::module_is_avail "$m" release_of_dependency || \
|
||
std::die 6 "Oops"
|
||
fi
|
||
# should be set, just in case it is not...
|
||
: ${release_of_dependency:='unstable'}
|
||
|
||
# for a stable module all dependencies must be stable
|
||
if [[ "${module_release}" == 'stable' ]] \
|
||
&& [[ "${release_of_dependency}" != 'stable' ]]; then
|
||
std::die 5 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"release cannot be set to '${module_release}'" \
|
||
"since the dependency '$m' is ${release_of_dependency}"
|
||
# for a unstable module no dependency must be deprecated
|
||
elif [[ "${module_release}" == 'unstable' ]] \
|
||
&& [[ "${release_of_dependency}" == 'deprecated' ]]; then
|
||
std::die 5 \
|
||
"%s " "${module_name}/${module_version}:" \
|
||
"release cannot be set to '${module_release}'" \
|
||
"since the dependency '$m' is ${release_of_dependency}"
|
||
fi
|
||
|
||
std::info "Loading module: ${m}"
|
||
eval $( "${MODULECMD}" bash load "${m}" )
|
||
done
|
||
}
|
||
|
||
std::info \
|
||
"%s " \
|
||
"${module_name}/${module_version}:" \
|
||
${with_modules:+with ${with_modules[@]}} \
|
||
"building ..."
|
||
MODULECMD="${PMODULES_HOME}/bin/modulecmd"
|
||
[[ -x ${MODULECMD} ]] || \
|
||
std::die 2 "No such file or executable -- '${MODULECMD}'"
|
||
|
||
eval $( "${MODULECMD}" bash use unstable )
|
||
eval $( "${MODULECMD}" bash use deprecated )
|
||
eval $( "${MODULECMD}" bash purge )
|
||
|
||
# :FIXME: this is a hack!!!
|
||
# shouldn't this be set in the build-script?
|
||
eval $( "${MODULECMD}" bash use Libraries )
|
||
eval $( "${MODULECMD}" bash use System )
|
||
|
||
unset C_INCLUDE_PATH
|
||
unset CPLUS_INCLUDE_PATH
|
||
unset CPP_INCLUDE_PATH
|
||
unset LIBRARY_PATH
|
||
unset LD_LIBRARY_PATH
|
||
unset DYLD_LIBRARY_PATH
|
||
|
||
unset CFLAGS
|
||
unset CPPFLAGS
|
||
unset CXXFLAGS
|
||
unset LIBS
|
||
unset LDFLAGS
|
||
|
||
unset CC
|
||
unset CXX
|
||
unset FC
|
||
unset F77
|
||
unset F90
|
||
|
||
load_build_dependencies
|
||
|
||
pbuild.init_env "${module_name}" "${module_version}"
|
||
pbuild::make_all
|
||
std::info "* * * * *\n"
|
||
}
|
||
|
||
pbuild.bootstrap() {
|
||
local -r module_name="$1"
|
||
local -r module_version="$2"
|
||
|
||
# used in pbuild::make_all
|
||
bootstrap='yes'
|
||
|
||
pbuild.init_env "${module_name}" "${module_version}"
|
||
|
||
MODULECMD=$(which true)
|
||
GROUP='Tools'
|
||
PREFIX="${PMODULES_ROOT}/${GROUP}/Pmodules/${PMODULES_VERSION}"
|
||
|
||
C_INCLUDE_PATH="${PREFIX}/include"
|
||
CPLUS_INCLUDE_PATH="${PREFIX}/include"
|
||
CPP_INCLUDE_PATH="${PREFIX}/include"
|
||
LIBRARY_PATH="${PREFIX}/lib"
|
||
LD_LIBRARY_PATH="${PREFIX}/lib"
|
||
DYLD_LIBRARY_PATH="${PREFIX}/lib"
|
||
|
||
PATH+=":${PREFIX}/bin"
|
||
PATH+=":${PREFIX}/sbin"
|
||
pbuild::make_all
|
||
}
|
||
|
||
# Local Variables:
|
||
# mode: sh
|
||
# sh-basic-offset: 8
|
||
# tab-width: 8
|
||
# End:
|