mirror of
https://github.com/Pmodules/Pmodules.git
synced 2026-07-01 11:49:38 +02:00
modulecmd & build-system: code review with shellcheck
This commit is contained in:
@@ -2,7 +2,6 @@ import os, re, subprocess
|
||||
|
||||
def module(*args):
|
||||
os.environ['PMODULES_MODULEFILES_DIR']='modulefiles'
|
||||
os.environ['PMODULES_CONFIG_DIR']='config'
|
||||
pm_home=os.environ['PMODULES_HOME']
|
||||
os.environ['PMODULES_DIR']=pm_home
|
||||
modulecmd=os.path.join(pm_home, 'bin', 'modulecmd')
|
||||
|
||||
+18
-19
@@ -4,7 +4,6 @@
|
||||
# unload modules if parent removed
|
||||
#
|
||||
|
||||
|
||||
if {[info exists env(PMODULES_DEBUG)] && $env(PMODULES_DEBUG)} {
|
||||
proc debug {msg} {
|
||||
set level [expr [info level] -2]
|
||||
@@ -92,7 +91,7 @@ proc module-addgroup { group } {
|
||||
debug "group=$group"
|
||||
debug "::variant=$::variant"
|
||||
set dir [file join \
|
||||
$::OverlayInfo($overlay:mod_root) \
|
||||
$::OverlayInfo($overlay:modulefiles_root) \
|
||||
$group \
|
||||
$::MODULEFILES_DIR \
|
||||
{*}$::variant]
|
||||
@@ -126,7 +125,7 @@ proc module-addgroup { group } {
|
||||
debug "mode=remove: $env(MODULEPATH)"
|
||||
foreach overlay $::UsedOverlays {
|
||||
set dir [file join \
|
||||
$::OverlayInfo($overlay:mod_root) \
|
||||
$::OverlayInfo($overlay:modulefiles_root) \
|
||||
$group \
|
||||
$::MODULEFILES_DIR \
|
||||
{*}$::variant]
|
||||
@@ -288,20 +287,20 @@ proc _find_overlay { modulefile_components } {
|
||||
debug "_find_overlay()"
|
||||
foreach ol $::UsedOverlays {
|
||||
debug "ol = $ol"
|
||||
set ol_mod_root $::OverlayInfo(${ol}:mod_root)
|
||||
if { [string range $ol_mod_root end end] == "/" } {
|
||||
set ol_mod_root [string range $ol_mod_root 0 end-1]
|
||||
set ol_modulefiles_root $::OverlayInfo(${ol}:modulefiles_root)
|
||||
if { [string range $ol_modulefiles_root end end] == "/" } {
|
||||
set ol_modulefiles_root [string range $ol_modulefiles_root 0 end-1]
|
||||
}
|
||||
debug "ol_mod_root = $ol_mod_root"
|
||||
set ol_mod_root_splitted [file split $ol_mod_root]
|
||||
debug "ol_modulefiles_root = $ol_modulefiles_root"
|
||||
set ol_modulefiles_root_splitted [file split $ol_modulefiles_root]
|
||||
set modulefile_root [file join \
|
||||
{*}[lrange \
|
||||
$modulefile_components \
|
||||
0 [expr [llength $ol_mod_root_splitted] - 1]]]
|
||||
0 [expr [llength $ol_modulefiles_root_splitted] - 1]]]
|
||||
debug "modulefile_root = $modulefile_root"
|
||||
if { [string compare $ol_mod_root $modulefile_root] == 0 } {
|
||||
debug "ol_mod_root_splitted = $ol_mod_root_splitted"
|
||||
return $ol_mod_root_splitted
|
||||
if { [string compare $ol_modulefiles_root $modulefile_root] == 0 } {
|
||||
debug "ol_modulefiles_root_splitted = $ol_modulefiles_root_splitted"
|
||||
return $ol_modulefiles_root_splitted
|
||||
}
|
||||
}
|
||||
debug "overlay not found"
|
||||
@@ -333,28 +332,28 @@ proc _pmodules_init_global_vars { } {
|
||||
|
||||
set modulefile_splitted [file split $::ModulesCurrentModulefile]
|
||||
|
||||
set ol_mod_root_splitted [_find_overlay ${modulefile_splitted}]
|
||||
set rel_modulefile [lrange $modulefile_splitted [llength $ol_mod_root_splitted] end]
|
||||
set ol_modulefiles_root_splitted [_find_overlay ${modulefile_splitted}]
|
||||
debug "init: ol_modulefiles_root_splitted=$ol_modulefiles_root_splitted"
|
||||
set rel_modulefile [lrange $modulefile_splitted [llength $ol_modulefiles_root_splitted] end]
|
||||
set group [lindex $rel_modulefile 0]
|
||||
set GROUP "${group}"
|
||||
set name [lindex $modulefile_splitted end-1]
|
||||
set version [lindex $modulefile_splitted end]
|
||||
|
||||
set suffixes [lassign [split $version _] v]
|
||||
lassign [split $v -] V_PKG V_RELEASE
|
||||
lassign [split $V_PKG .] V_MAJOR V_MINOR V_PATCHLVL
|
||||
|
||||
set variant [lrange $rel_modulefile 2 end]
|
||||
set mod_root [file join {*}$ol_mod_root_splitted]
|
||||
set ol $::Dir2OverlayMap($mod_root)
|
||||
set modulefiles_root [file join {*}$ol_modulefiles_root_splitted]
|
||||
set ol $::Dir2OverlayMap($modulefiles_root)
|
||||
|
||||
set install_prefix [file split $::OverlayInfo(${ol}:inst_root)]
|
||||
set install_prefix [file split $::OverlayInfo(${ol}:install_root)]
|
||||
set prefix "$install_prefix $group [lreverse_n $variant 2]"
|
||||
set PREFIX [file join {*}$prefix]
|
||||
set P "${name}"
|
||||
set V "${version}"
|
||||
|
||||
debug "mod_root=$mod_root"
|
||||
debug "modulefiles_root=$modulefiles_root"
|
||||
debug "ol=$ol"
|
||||
debug "PREFIX=$PREFIX"
|
||||
debug "group of module $name: $group"
|
||||
|
||||
+124
-156
@@ -6,10 +6,8 @@ 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'
|
||||
|
||||
# relative path of documentation
|
||||
# abs. path is "${PREFIX}/${_docdir}/${module_name}"
|
||||
@@ -24,7 +22,7 @@ declare -A SOURCE_UNPACK_DIRS=()
|
||||
declare -ax CONFIGURE_ARGS=()
|
||||
declare -a PATCH_FILES=()
|
||||
declare -a PATCH_STRIPS=()
|
||||
declare -a PATCH_STRIP_DEFAULT='1'
|
||||
declare -- PATCH_STRIP_DEFAULT='1'
|
||||
declare -- configure_with='auto'
|
||||
declare -- SRC_DIR=''
|
||||
declare -- BUILD_DIR=''
|
||||
@@ -32,6 +30,9 @@ declare -- is_subpkg='no'
|
||||
|
||||
declare -i group_depth=0
|
||||
|
||||
declare -- COMPILER=''
|
||||
declare -- MPI=''
|
||||
|
||||
#.............................................................................
|
||||
#
|
||||
# Exit script on errror.
|
||||
@@ -54,7 +55,7 @@ trap "_error_handler" ERR
|
||||
# write number of cores to stdout
|
||||
#
|
||||
_get_num_cores() {
|
||||
case "${OS}" in
|
||||
case "${KernelName}" in
|
||||
Linux )
|
||||
${grep} -c ^processor /proc/cpuinfo
|
||||
;;
|
||||
@@ -62,7 +63,7 @@ _get_num_cores() {
|
||||
${sysctl} -n hw.ncpu
|
||||
;;
|
||||
* )
|
||||
std::die 1 "OS ${OS} is not supported\n"
|
||||
std::die 1 "OS ${KernelName} is not supported\n"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -163,17 +164,15 @@ pbuild::add_to_group() {
|
||||
if (( $# == 0 )); then
|
||||
std::die 42 \
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
"${FUNCNAME}: missing group argument."
|
||||
"${FUNCNAME[0]}: missing group argument."
|
||||
fi
|
||||
if (( $# > 1 )); then
|
||||
std::die 42 \
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
"${FUNCNAME}: only one argument is allowed."
|
||||
fi
|
||||
if [[ ${opt_yaml} == 'yes' ]]; then
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
"${FUNCNAME[0]}: only one argument is allowed."
|
||||
fi
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
pbuild.add_to_group "$@"
|
||||
}
|
||||
readonly -f pbuild::add_to_group
|
||||
@@ -201,18 +200,17 @@ readonly -f pbuild.add_to_group
|
||||
# 1 otherwise
|
||||
#
|
||||
pbuild::module_is_avail() {
|
||||
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
|
||||
local -- name=''
|
||||
local -- release=''
|
||||
while read -r name release; do
|
||||
if [[ "${name}" == "$1" ]]; then
|
||||
if (( $# > 1 )); then
|
||||
local -n _result="$2"
|
||||
_result="${output[i+1]}"
|
||||
_result="${release}"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done < <(${modulecmd} bash avail -a -m "$1" 2>&1 1>/dev/null)
|
||||
return 1
|
||||
}
|
||||
readonly -f pbuild::module_is_avail
|
||||
@@ -252,17 +250,19 @@ pbuild::version_compare () {
|
||||
[[ $1 =~ ^[0-9]+$ ]]
|
||||
}
|
||||
|
||||
[[ $1 == $2 ]] && return 0
|
||||
local IFS=.
|
||||
local i ver1=($1) ver2=($2)
|
||||
[[ "$1" == "$2" ]] && return 0
|
||||
local ver1 ver2
|
||||
IFS='.' read -r -a ver1 <<<"$1"
|
||||
IFS='.' read -r -a ver2 <<<"$2"
|
||||
|
||||
# fill empty fields in ver1 with zeros
|
||||
local i
|
||||
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
|
||||
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
|
||||
@@ -352,9 +352,8 @@ readonly -f pbuild::version_eq
|
||||
# Default is all.
|
||||
#
|
||||
pbuild::supported_compilers() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
pbuild.supported_compilers "$@"
|
||||
}
|
||||
readonly -f pbuild::supported_compilers
|
||||
@@ -374,9 +373,8 @@ readonly -f pbuild.supported_compilers
|
||||
# Default is all.
|
||||
#
|
||||
pbuild::supported_systems() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
pbuild.supported_systems "$@"
|
||||
}
|
||||
readonly -f pbuild::supported_systems
|
||||
@@ -390,7 +388,7 @@ readonly -f pbuild.supported_systems
|
||||
#..............................................................................
|
||||
#
|
||||
pbuild::use_flag() {
|
||||
[[ "${USE_FLAGS}" =~ ":${1}:" ]]
|
||||
[[ "${USE_FLAGS}" == *:${1}:* ]]
|
||||
}
|
||||
readonly -f pbuild::use_flag
|
||||
|
||||
@@ -406,16 +404,14 @@ readonly -f pbuild::use_flag
|
||||
# $1 download URL
|
||||
# $2 optional file-name (of)
|
||||
pbuild::set_download_url() {
|
||||
if [[ ${opt_yaml} == 'yes' ]]; then
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
fi
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
local -i _i=${#SOURCE_URLS[@]}
|
||||
SOURCE_URLS[_i]=$1
|
||||
SOURCE_URLS[_i]="$1"
|
||||
if (( $# > 1 )); then
|
||||
SOURCE_NAMES[$_i]=${2:-${1##*/}}
|
||||
SOURCE_NAMES[_i]="${2:-${1##*/}}"
|
||||
else
|
||||
SOURCE_NAMES[$_i]="${1##*/}"
|
||||
SOURCE_NAMES[_i]="${1##*/}"
|
||||
fi
|
||||
SOURCE_STRIP_DIRS[_i]='1'
|
||||
}
|
||||
@@ -424,7 +420,7 @@ readonly -f pbuild::set_download_url
|
||||
pbuild.set_urls(){
|
||||
local -i _i=${#SOURCE_URLS[@]}
|
||||
SOURCE_URLS[_i]="$1"
|
||||
SOURCE_NAMES[$_i]="$2"
|
||||
SOURCE_NAMES[_i]="$2"
|
||||
SOURCE_STRIP_DIRS[_i]="$3"
|
||||
SOURCE_UNPACKER[_i]="$4"
|
||||
}
|
||||
@@ -440,9 +436,8 @@ pbuild.set_urls(){
|
||||
# Maybe we should use a dictionary in the future.
|
||||
#
|
||||
pbuild::set_sha256sum() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
SOURCE_SHA256_SUMS+=("$1")
|
||||
}
|
||||
readonly -f pbuild::set_sha256sum
|
||||
@@ -463,13 +458,12 @@ readonly -f pbuild::set_unpack_dir
|
||||
#..............................................................................
|
||||
#
|
||||
pbuild::add_patch() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
[[ -z "$1" ]] && \
|
||||
std::die 1 \
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
"${FUNCNAME}: missing argument!"
|
||||
"${FUNCNAME[0]}: missing argument!"
|
||||
PATCH_FILES+=( "$1" )
|
||||
if (( $# >= 2 )); then
|
||||
PATCH_STRIPS+=( "$2" )
|
||||
@@ -480,9 +474,8 @@ pbuild::add_patch() {
|
||||
readonly -f pbuild::add_patch
|
||||
|
||||
pbuild.add_patch_files(){
|
||||
local -a args="$@"
|
||||
local -- arg=''
|
||||
for arg in "${args[@]}"; do
|
||||
for arg in "$@"; do
|
||||
[[ -z "${arg}" ]] && continue
|
||||
if [[ ${arg} == *:* ]]; then
|
||||
PATCH_FILES+=( "${arg%%:*}" )
|
||||
@@ -498,13 +491,12 @@ readonly -f pbuild.add_patch_files
|
||||
#..............................................................................
|
||||
#
|
||||
pbuild::set_default_patch_strip() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
[[ -n "$1" ]] || \
|
||||
std::die 1 \
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
"${FUNCNAME}: missing argument!"
|
||||
"${FUNCNAME[0]}: missing argument!"
|
||||
|
||||
PATCH_STRIP_DEFAULT="$1"
|
||||
}
|
||||
@@ -606,8 +598,7 @@ pbuild::prep() {
|
||||
done
|
||||
if [[ "${dir}" == 'not found' ]]; then
|
||||
dir="${dirs[0]}"
|
||||
download_with_curl "${dir}/${fname}" "${url}"
|
||||
(( $? == 0 )) || \
|
||||
download_with_curl "${dir}/${fname}" "${url}" || \
|
||||
std::die 42 \
|
||||
"%s " \
|
||||
"${module_name}/${module_version}:" \
|
||||
@@ -675,12 +666,6 @@ pbuild::prep() {
|
||||
"error patching sources!"
|
||||
done
|
||||
}
|
||||
for fname in ${VERSIONS[@]/#/pbuild::set_download_url_}; do
|
||||
if typeset -F ${fname} 2>/dev/null; then
|
||||
$f
|
||||
break
|
||||
fi
|
||||
done
|
||||
(( ${#SOURCE_URLS[@]} == 0 )) && return 0
|
||||
${mkdir} -p "${PMODULES_DISTFILESDIR}"
|
||||
local i=0
|
||||
@@ -718,9 +703,8 @@ pbuild::prep() {
|
||||
#..............................................................................
|
||||
#
|
||||
pbuild::add_configure_args() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
CONFIGURE_ARGS+=( "$@" )
|
||||
}
|
||||
readonly -f pbuild::add_configure_args
|
||||
@@ -733,9 +717,8 @@ readonly -f pbuild.add_configure_args
|
||||
#..............................................................................
|
||||
#
|
||||
pbuild::use_autotools() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
configure_with='autotools'
|
||||
}
|
||||
readonly -f pbuild::use_autotools
|
||||
@@ -743,9 +726,8 @@ readonly -f pbuild::use_autotools
|
||||
#..............................................................................
|
||||
#
|
||||
pbuild::use_cmake() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
configure_with='cmake'
|
||||
}
|
||||
readonly -f pbuild::use_cmake
|
||||
@@ -766,7 +748,7 @@ pbuild::use_cc() {
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
"Error in setting CC:" \
|
||||
"'$1' is not an executable!"
|
||||
CC="$1"
|
||||
export CC="$1"
|
||||
}
|
||||
readonly -f pbuild::use_cc
|
||||
|
||||
@@ -780,9 +762,8 @@ readonly -f pbuild::use_cc
|
||||
declare -- compile_in_sourcetree='no'
|
||||
|
||||
pbuild::compile_in_sourcetree() {
|
||||
[[ ${opt_yaml} == 'yes' ]] && \
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
compile_in_sourcetree='yes'
|
||||
}
|
||||
readonly -f pbuild::compile_in_sourcetree
|
||||
@@ -826,7 +807,7 @@ pbuild::configure() {
|
||||
if [[ -r "${SRC_DIR}/configure" ]] && \
|
||||
[[ "${configure_with}" == 'auto' ]] || \
|
||||
[[ "${configure_with}" == 'autotools' ]]; then
|
||||
${SRC_DIR}/configure \
|
||||
"${SRC_DIR}/configure" \
|
||||
--prefix="${PREFIX}" \
|
||||
"${config_args[@]}" || \
|
||||
std::die 3 \
|
||||
@@ -890,10 +871,8 @@ pbuild::compile() {
|
||||
# $@: documentation files relative to source
|
||||
#
|
||||
pbuild::install_docfiles() {
|
||||
if [[ ${opt_yaml} == 'yes' ]]; then
|
||||
std::info \
|
||||
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
|
||||
fi
|
||||
std::info \
|
||||
"Using ${FUNCNAME[0]} is deprecated with YAML module configuration files."
|
||||
MODULE_DOCFILES+=("$@")
|
||||
}
|
||||
readonly -f pbuild::install_docfiles
|
||||
@@ -920,8 +899,9 @@ pbuild::install_shared_libs() {
|
||||
local -r pattern="${3//\//\\/}" # escape slash
|
||||
|
||||
install_shared_libs_Linux() {
|
||||
local libs=( $(ldd "${binary}" | \
|
||||
${awk} "/ => \// && /${pattern}/ {print \$3}") )
|
||||
local -a libs=()
|
||||
mapfile -t libs < <(${ldd} "${binary}" | \
|
||||
${awk} "/ => \// && /${pattern}/ {print \$3}")
|
||||
if (( ${#libs[@]} > 0 )); then
|
||||
${cp} -vL "${libs[@]}" "${dstdir}" || return $?
|
||||
fi
|
||||
@@ -930,8 +910,9 @@ pbuild::install_shared_libs() {
|
||||
|
||||
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}"))
|
||||
local -a libs=()
|
||||
mapfile -t libs < <(${otool} -L "${binary}" | \
|
||||
${awk} "/${pattern}/ {print \$1}")
|
||||
if (( ${#libs[@]} > 0 )); then
|
||||
${cp} -vL "${libs[@]}" "${dstdir}" || return $?
|
||||
fi
|
||||
@@ -943,7 +924,7 @@ pbuild::install_shared_libs() {
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
"${binary}: does not exist or is not executable!"
|
||||
${mkdir} -p "${dstdir}"
|
||||
case "${OS}" in
|
||||
case "${KernelName}" in
|
||||
Linux )
|
||||
install_shared_libs_Linux
|
||||
;;
|
||||
@@ -1028,8 +1009,9 @@ _build_module() {
|
||||
build_dependency() {
|
||||
find_build_script(){
|
||||
local p=$1
|
||||
local script=$(${find} "${BUILDBLOCK_DIR}/../.." \
|
||||
-path "*/$p/build")
|
||||
local script=''
|
||||
script=$(${find} "${BUILDBLOCK_DIR}/../.." \
|
||||
-path "*/$p/build")
|
||||
std::get_abspath "${script}"
|
||||
}
|
||||
|
||||
@@ -1044,7 +1026,7 @@ _build_module() {
|
||||
std::info "%s " \
|
||||
"$m: module does not exist, trying to build it..."
|
||||
local args=( '' )
|
||||
set -- ${ARGS[@]}
|
||||
set -- "${ARGS[@]}"
|
||||
while (( $# > 0 )); do
|
||||
case $1 in
|
||||
-j )
|
||||
@@ -1052,23 +1034,24 @@ _build_module() {
|
||||
shift
|
||||
;;
|
||||
--jobs=[0-9]* )
|
||||
args+=( $1 )
|
||||
args+=( "$1" )
|
||||
;;
|
||||
-v | --verbose)
|
||||
args+=( $1 )
|
||||
args+=( "$1" )
|
||||
;;
|
||||
--with=*/* )
|
||||
args+=( $1 )
|
||||
args+=( "$1" )
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
local buildscript=$(find_build_script "${m%/*}")
|
||||
local buildscript=''
|
||||
buildscript=$(find_build_script "${m%/*}")
|
||||
[[ -x "${buildscript}" ]] || \
|
||||
std::die 1 \
|
||||
"$m: build-block not found!"
|
||||
if ! "${buildscript}" "${m#*/}" ${args[@]}; then
|
||||
if ! "${buildscript}" "${m#*/}" "${args[@]}"; then
|
||||
std::die 1 \
|
||||
"$m: oops: build failed..."
|
||||
fi
|
||||
@@ -1111,9 +1094,6 @@ _build_module() {
|
||||
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
|
||||
@@ -1131,7 +1111,7 @@ _build_module() {
|
||||
fi
|
||||
|
||||
std::info "Loading module: ${m}"
|
||||
eval $( "${MODULECMD}" bash load "${m}" )
|
||||
eval "$( "${modulecmd}" bash load "${m}" )"
|
||||
done
|
||||
}
|
||||
|
||||
@@ -1140,13 +1120,11 @@ _build_module() {
|
||||
if [[ "${opt_yaml,,}" == 'no' ]]; then
|
||||
(( ${#SUPPORTED_SYSTEMS[@]} == 0 )) && return 0
|
||||
for sys in "${SUPPORTED_SYSTEMS[@]}"; do
|
||||
[[ ${sys,,} == ${system,,} ]] && return 0
|
||||
[[ "${sys,,}" == "${system,,}" ]] && return 0
|
||||
done
|
||||
std::die 1 \
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
"Not available for ${system}."
|
||||
else
|
||||
: debug "Systems: $Systems"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1154,7 +1132,7 @@ _build_module() {
|
||||
check_supported_compilers() {
|
||||
(( ${#SUPPORTED_COMPILERS[@]} == 0 )) && return 0
|
||||
for compiler in "${SUPPORTED_COMPILERS[@]}"; do
|
||||
[[ ${compiler,,} == ${COMPILER,,} ]] && return 0
|
||||
[[ "${compiler,,}" == "${COMPILER,,}" ]] && return 0
|
||||
done
|
||||
std::die 1 \
|
||||
"%s " "${module_name}/${module_version}:" \
|
||||
@@ -1197,8 +1175,8 @@ _build_module() {
|
||||
"module is in group '${GROUP}' but no HDF5 module loaded!"
|
||||
}
|
||||
|
||||
modulefile_dir="${ol_mod_root}/${GROUP}/${PMODULES_MODULEFILES_DIR}/"
|
||||
PREFIX="${ol_inst_root}/${GROUP}/${module_name}/${module_version}/"
|
||||
modulefile_dir="${ol_modulefiles_root}/${GROUP}/${PMODULES_MODULEFILES_DIR}/"
|
||||
PREFIX="${ol_install_root}/${GROUP}/${module_name}/${module_version}/"
|
||||
case "${GROUP}" in
|
||||
Compiler )
|
||||
[[ -v COMPILER_VERSION ]] || die_no_compiler
|
||||
@@ -1221,8 +1199,8 @@ _build_module() {
|
||||
[[ -v HDF5_VERSION ]] || die_no_hdf5
|
||||
modulefile_dir+="${COMPILER}/${COMPILER_VERSION}/"
|
||||
modulefile_dir+="${MPI}/${MPI_VERSION}/"
|
||||
modulefile_dir+="${HDF5}/${HDF5_VERSION}/"
|
||||
PREFIX+="${HDF5}/${HDF5_VERSION}/"
|
||||
modulefile_dir+="hdf5/${HDF5_VERSION}/"
|
||||
PREFIX+="hdf5/${HDF5_VERSION}/"
|
||||
PREFIX+="${MPI}/${MPI_VERSION}/"
|
||||
PREFIX+="${COMPILER}/${COMPILER_VERSION}/"
|
||||
group_depth=6
|
||||
@@ -1231,8 +1209,8 @@ _build_module() {
|
||||
[[ -v COMPILER_VERSION ]] || die_no_compiler
|
||||
[[ -v HDF5_SERIAL_VERSION ]] || die_no_hdf5
|
||||
modulefile_dir+="${COMPILER}/${COMPILER_VERSION}/"
|
||||
modulefile_dir+="${hdf5_serial}/${HDF5_SERIAL_VERSION}/"
|
||||
PREFIX+="${hdf5_serial}/${HDF5_SERIAL_VERSION}/"
|
||||
modulefile_dir+="hdf5_serial/${HDF5_SERIAL_VERSION}/"
|
||||
PREFIX+="hdf5_serial/${HDF5_SERIAL_VERSION}/"
|
||||
PREFIX+="${COMPILER}/${COMPILER_VERSION}/"
|
||||
group_depth=4
|
||||
;;
|
||||
@@ -1270,20 +1248,11 @@ _build_module() {
|
||||
"${module_name}/${module_version}:" \
|
||||
"Installing documentation to ${docdir}"
|
||||
${install} -m 0755 -d "${docdir}"
|
||||
${install} -m0644 "${BUILD_SCRIPT}" "${docdir}"
|
||||
"${MODULECMD}" bash list -t 2>&1 1>/dev/null | \
|
||||
${install} -m 0644 "${BUILD_SCRIPT}" "${docdir}"
|
||||
"${modulecmd}" bash list -t 2>&1 1>/dev/null | \
|
||||
${grep} -v "Currently Loaded" > \
|
||||
"${docdir}/dependencies" || :
|
||||
|
||||
# loop over version specific functions. In these function
|
||||
# more MODULE_DOCFILES can be defined.
|
||||
# :FIXME: maybe we find a better solution.
|
||||
for f in ${VERSIONS[@]/#/pbuild::install_docfiles_}; do
|
||||
if typeset -F "$f" 2>/dev/null; then
|
||||
$f
|
||||
break
|
||||
fi
|
||||
done
|
||||
(( ${#MODULE_DOCFILES[@]} == 0 )) && return 0
|
||||
${install} -m0644 \
|
||||
"${MODULE_DOCFILES[@]/#/${SRC_DIR}/}" \
|
||||
@@ -1307,28 +1276,29 @@ _build_module() {
|
||||
if [[ ! $dep == */* ]]; then
|
||||
# no version given: derive the version
|
||||
# from the currently loaded module
|
||||
dep=$( "${MODULECMD}" bash list -t 2>&1 1>/dev/null \
|
||||
dep=$( "${modulecmd}" bash list -t 2>&1 1>/dev/null \
|
||||
| grep "^${dep}/" )
|
||||
fi
|
||||
echo "${dep}" >> "${fname}"
|
||||
done
|
||||
}
|
||||
patch_elf_exe_and_libs(){
|
||||
local -- libdir="${OverlayInfo[${ol_name}:inst_root]}/lib64"
|
||||
local -- libdir="${OverlayInfo[${ol_name}:install_root]}/lib64"
|
||||
[[ -d "${libdir}" ]] || return 0
|
||||
local -a bin_objects=( $(std::find_executables '.' ) )
|
||||
local -a bin_objects=()
|
||||
mapfile -t bin_objects < <(std::find_executables '.')
|
||||
local -- fname=''
|
||||
local -- rpath=''
|
||||
local -i depth=0
|
||||
for fname in "${bin_objects[@]}"; do
|
||||
local -i depth=$(std::get_dir_depth "${fname}")
|
||||
(( depth+=group_depth+3 ))
|
||||
local -- rpath='$ORIGIN/'$(printf "../%.0s" $(${seq} 1 ${depth}))lib64
|
||||
(( depth=$(std::get_dir_depth "${fname}") + group_depth + 3 ))
|
||||
rpath='$ORIGIN/'$(printf "../%.0s" $(${seq} 1 ${depth}))lib64
|
||||
${patchelf} --force-rpath --set-rpath "${rpath}" "${fname}"
|
||||
done
|
||||
local -a bin_objects=( $(std::find_shared_objects '.' ) )
|
||||
mapfile -t bin_objects < <(std::find_shared_objects '.')
|
||||
for fname in "${bin_objects[@]}"; do
|
||||
local -i depth=$(std::get_dir_depth "${fname}")
|
||||
(( depth+=group_depth+3 ))
|
||||
local -- rpath='$ORIGIN/'$(printf "../%.0s" $(${seq} 1 ${depth}))lib64
|
||||
(( depth=$(std::get_dir_depth "${fname}") + group_depth + 3 ))
|
||||
rpath='$ORIGIN/'$(printf "../%.0s" $(${seq} 1 ${depth}))lib64
|
||||
${patchelf} --force-rpath --set-rpath "${rpath}" "${fname}"
|
||||
done
|
||||
}
|
||||
@@ -1340,7 +1310,7 @@ _build_module() {
|
||||
std::info \
|
||||
"%s " \
|
||||
"${module_name}/${module_version}:" \
|
||||
"running post-installation for ${OS} ..."
|
||||
"running post-installation for ${KernelName} ..."
|
||||
cd "${PREFIX}"
|
||||
[[ -d "lib" ]] && [[ ! -d "lib64" ]] && ln -s lib lib64
|
||||
patch_elf_exe_and_libs
|
||||
@@ -1350,7 +1320,7 @@ _build_module() {
|
||||
#..............................................................
|
||||
# post-install
|
||||
cd "${BUILD_DIR}"
|
||||
[[ "${OS}" == "Linux" ]] && post_install_linux
|
||||
[[ "${KernelName}" == "Linux" ]] && post_install_linux
|
||||
install_doc
|
||||
if (( ${#runtime_dependencies[@]} > 0 )); then
|
||||
write_runtime_dependencies \
|
||||
@@ -1374,7 +1344,7 @@ _build_module() {
|
||||
} # post_install
|
||||
|
||||
#......................................................................
|
||||
# Install modulefile in ${ol_mod_root}/${GROUP}/modulefiles/...
|
||||
# Install modulefile in ${ol_modulefiles_root}/${GROUP}/modulefiles/...
|
||||
# The modulefiles in the build-block can be
|
||||
# versioned like
|
||||
# modulefile-10.2.0
|
||||
@@ -1413,8 +1383,7 @@ _build_module() {
|
||||
}
|
||||
[[ "${is_subpkg}" == 'yes' ]] && return 0
|
||||
local src=''
|
||||
find_modulefile src
|
||||
if (( $? != 0 )); then
|
||||
if ! find_modulefile src; then
|
||||
std::info \
|
||||
"%s " \
|
||||
"${module_name}/${module_version}:" \
|
||||
@@ -1434,8 +1403,8 @@ _build_module() {
|
||||
local ol=''
|
||||
for ol in "${Overlays[@]}"; do
|
||||
[[ "${ol}" == "${ol_name}" ]] && continue
|
||||
local mod_root="${OverlayInfo[${ol}:mod_root]}"
|
||||
local dir="${modulefile_dir/${ol_mod_root}/${mod_root}}"
|
||||
local modulefiles_root="${OverlayInfo[${ol}:modulefiles_root]}"
|
||||
local dir="${modulefile_dir/${ol_modulefiles_root}/${modulefiles_root}}"
|
||||
local fname="${dir}/${module_version}"
|
||||
if [[ -e "${fname}" ]]; then
|
||||
std::info "%s "\
|
||||
@@ -1459,12 +1428,9 @@ _build_module() {
|
||||
|
||||
local -r legacy_config_file="${modulefile_dir}/.release-${module_version}"
|
||||
local -- status_legay_config_file='unchanged'
|
||||
local -r yaml_config_file="${modulefile_dir}/.config-${module_version}"
|
||||
local -- status_yaml_config_file='unchanged'
|
||||
|
||||
local -- relstage_legacy=''
|
||||
if [[ -r "${legacy_config_file}" ]]; then
|
||||
local relstage_legacy
|
||||
read relstage_legacy < "${legacy_config_file}"
|
||||
read -r relstage_legacy < "${legacy_config_file}"
|
||||
if [[ "${relstage_legacy}" != "${module_release}" ]]; then
|
||||
status_legay_config_file='changed'
|
||||
fi
|
||||
@@ -1476,8 +1442,10 @@ _build_module() {
|
||||
echo "${module_release}" > "${legacy_config_file}"
|
||||
fi
|
||||
|
||||
local -r yaml_config_file="${modulefile_dir}/.config-${module_version}"
|
||||
local -- status_yaml_config_file='unchanged'
|
||||
if [[ -r "${yaml_config_file}" ]]; then
|
||||
while read key value; do
|
||||
while read -r key value; do
|
||||
local -n ref="${key:0:-1}"
|
||||
ref="${value}"
|
||||
done < "${yaml_config_file}"
|
||||
@@ -1583,26 +1551,26 @@ _build_module() {
|
||||
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::pre_${target}_${system}_}" )
|
||||
targets+=( "pbuild::pre_${target}_${system}" )
|
||||
targets+=( "${VERSIONS[@]/#/pbuild::pre_${target}_${KernelName}_}" )
|
||||
targets+=( "pbuild::pre_${target}_${KernelName}" )
|
||||
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::${target}_${system}_}" )
|
||||
targets+=( "pbuild::${target}_${system}" )
|
||||
targets+=( "${VERSIONS[@]/#/pbuild::${target}_${KernelName}_}" )
|
||||
targets+=( "pbuild::${target}_${KernelName}" )
|
||||
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} )
|
||||
targets+=( "${VERSIONS[@]/#/pbuild::post_${target}_${system}_}" )
|
||||
targets+=( "pbuild::post_${target}_${system}" )
|
||||
targets+=( "${VERSIONS[@]/#/pbuild::post_${target}_${KernelName}_}" )
|
||||
targets+=( "pbuild::post_${target}_${KernelName}" )
|
||||
targets+=( "${VERSIONS[@]/#/pbuild::post_${target}_}" )
|
||||
targets+=( "pbuild::post_${target}" )
|
||||
|
||||
for t in "${targets[@]}"; do
|
||||
# We cd into the dir before calling the function -
|
||||
@@ -1661,7 +1629,7 @@ _build_module() {
|
||||
"%s " \
|
||||
"${module_name}/${module_version}:" \
|
||||
"removing all files in '${PREFIX}' ..."
|
||||
[[ "${dry_run}" == 'no' ]] && ${rm} -rf ${PREFIX}
|
||||
[[ "${dry_run}" == 'no' ]] && ${rm} -rf "${PREFIX}"
|
||||
fi
|
||||
if [[ -e "${modulefile_name}" ]]; then
|
||||
std::info \
|
||||
|
||||
+214
-171
@@ -1,16 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare PMODULES_MODULEFILES_DIR='modulefiles'
|
||||
declare PMODULES_CONFIG_DIR='config'
|
||||
declare PMODULES_VERSION='@PMODULES_VERSION@'
|
||||
declare -A GroupDepths=()
|
||||
declare -A Subcommands=()
|
||||
declare -A Options=()
|
||||
declare -A Help=()
|
||||
|
||||
declare -a Overlays=()
|
||||
declare -A OverlayInfo
|
||||
declare -a UsedOverlays
|
||||
declare -A Dir2OverlayMap
|
||||
|
||||
declare -r ol_normal='n'
|
||||
@@ -18,21 +13,6 @@ declare -r ol_hiding='h'
|
||||
declare -r ol_replacing='r'
|
||||
|
||||
|
||||
# initialize help text of 'module --version'
|
||||
Help['version']="
|
||||
Pmodules @PMODULES_VERSION@
|
||||
using Tcl Environment Modules
|
||||
VERSION = @MODULES_VERSION@
|
||||
"
|
||||
|
||||
#
|
||||
# display help text for command given in $1
|
||||
#
|
||||
print_help() {
|
||||
echo -e "${Help[$1]}" 1>&2
|
||||
std::die 1
|
||||
}
|
||||
|
||||
#
|
||||
# compute depth of modulefile directory.
|
||||
#
|
||||
@@ -50,10 +30,10 @@ compute_group_depth () {
|
||||
local group=${group##*/}
|
||||
result=$(${find} "${dir}" -depth \( -type f -o -type l \) \
|
||||
-printf "%d" -quit 2>/dev/null)
|
||||
(( result-=2 ))
|
||||
(( result-=2 )) || :
|
||||
# if a group doesn't contain a modulefile, depth is negativ
|
||||
# :FIXME: better solution?
|
||||
(( result < 0 )) && (( result = 0 ))
|
||||
(( result < 0 )) && (( result = 0 )) || :
|
||||
}
|
||||
|
||||
#
|
||||
@@ -63,173 +43,236 @@ compute_group_depth () {
|
||||
# $@: overlay names
|
||||
#
|
||||
scan_groups () {
|
||||
local ol
|
||||
local ol
|
||||
local depth
|
||||
for ol in "$@"; do
|
||||
local mod_root="${OverlayInfo[${ol}:mod_root]}"
|
||||
local modulefiles_root="${OverlayInfo[${ol}:modulefiles_root]}"
|
||||
local dir
|
||||
for dir in ${mod_root}/*/${PMODULES_MODULEFILES_DIR}; do
|
||||
for dir in "${modulefiles_root}"/*/"${PMODULES_MODULEFILES_DIR}"; do
|
||||
local group="${dir%/*}"
|
||||
group="${group##*/}"
|
||||
if [[ ! -v GroupDepths[${group}] ]]; then
|
||||
compute_group_depth depth "${dir}"
|
||||
GroupDepths[$group]=${depth}
|
||||
fi
|
||||
Dir2OverlayMap[${dir%/${PMODULES_MODULEFILES_DIR}*}]="${ol}"
|
||||
Dir2OverlayMap[${dir%/"${PMODULES_MODULEFILES_DIR}"*}]="${ol}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
pm::read_config(){
|
||||
local -a config_files=()
|
||||
declare -A DefaultPmodulesConfig=(
|
||||
['defaultgroups']='Tools:Programming'
|
||||
['default_groups']='Tools:Programming'
|
||||
['defaultreleasestages']='stable'
|
||||
['default_reltages']='stable'
|
||||
['tmpdir']="/opt/psi/var/tmp/${USER}"
|
||||
['tmp_dir']="/opt/psi/var/tmp/${USER}"
|
||||
['distfilesdir']='/opt/psi/var/distfiles'
|
||||
['distfiles_dir']='/opt/psi/var/distfiles'
|
||||
['download_dir']='/opt/psi/var/distfiles'
|
||||
['overlays']=''
|
||||
)
|
||||
|
||||
declare -A OverlayConfigKeys=(
|
||||
['install_root']='/opt/psi'
|
||||
['modulefiles_root']=''
|
||||
['excludes']=''
|
||||
['type']='n'
|
||||
)
|
||||
|
||||
pm::get_value(){
|
||||
local -- yaml_input="$1"
|
||||
local -n val="$2"
|
||||
local -- key="$3"
|
||||
local -- expected_type="$4"
|
||||
|
||||
_get_config_files(){
|
||||
#
|
||||
# return array with overlay configuration files
|
||||
#
|
||||
# Args:
|
||||
# $1 [upvar] result
|
||||
local -n fnames="$1"
|
||||
local -- type=''
|
||||
type=$( ${yq} -e ".${key} | type" 2>/dev/null <<<"${yaml_input}")
|
||||
if [[ "${type}" != "${expected_type}" ]]; then
|
||||
std::die 3 "%s" \
|
||||
"Value of '${key}' must be of type '${expected_type:2}', but is '${type:2}'!"
|
||||
fi
|
||||
val=$( ${yq} -e ".${key}" \
|
||||
2>/dev/null <<<"${yaml_input}" ) || val=''
|
||||
}
|
||||
pm::get_seq(){
|
||||
local -- yaml_input="$1"
|
||||
local -n val="$2"
|
||||
local -- key="$3"
|
||||
|
||||
# user defined via environment variable
|
||||
if [[ -v PMODULES_OVERLAYS_DEF ]]; then
|
||||
test -r "${PMODULES_OVERLAYS_DEF}" || \
|
||||
std::die 3 \
|
||||
"%s -- %s" \
|
||||
"overlay definition file is not readable" \
|
||||
"$_"
|
||||
fnames+=("${PMODULES_OVERLAYS_DEF}")
|
||||
fi
|
||||
|
||||
# user defined
|
||||
if [[ -r "${HOME}/.Pmodules/Pmodules.yaml" ]]; then
|
||||
fnames+=("${HOME}/.Pmodules/Pmodules.yaml")
|
||||
fi
|
||||
|
||||
# system config file
|
||||
test -r "${PMODULES_HOME%%/Tools*}/config/Pmodules.yaml" || \
|
||||
std::die 3 \
|
||||
"%s %s -- %s" \
|
||||
"base overlay definition file" \
|
||||
"does not exist or is not readable" \
|
||||
"$_"
|
||||
|
||||
fnames+=("${PMODULES_HOME%%/Tools*}/config/Pmodules.yaml")
|
||||
}
|
||||
|
||||
_get_ol_names(){
|
||||
#
|
||||
# get the names of all overlays
|
||||
#
|
||||
local -n fnames="$1"
|
||||
${yq} -Ne eval-all '. as $item ireduce ({}; . *+ $item) |.Overlays|keys()' \
|
||||
"${fnames[@]}" | awk '{print $2}'
|
||||
}
|
||||
|
||||
_get_install_root(){
|
||||
local -n fnames="$1"
|
||||
local -- _ol="$2"
|
||||
local -- _tmp
|
||||
_tmp=$(${yq} -Ne eval-all ". as \$item ireduce ({}; . *+ \$item) |.Overlays.${_ol}.install_root" \
|
||||
"${fnames[@]}" 2>/dev/null) || return 1
|
||||
echo "${_tmp}" | envsubst
|
||||
}
|
||||
|
||||
_get_modulefiles_root(){
|
||||
local -n fnames="$1"
|
||||
local -- _ol="$2"
|
||||
local -- _tmp
|
||||
_tmp=$(${yq} -Ne eval-all ". as \$item ireduce ({}; . *+ \$item) |.Overlays.${_ol}.modulefiles_root" \
|
||||
"${fnames[@]}" 2>/dev/null) || return 1
|
||||
echo "${_tmp}" | envsubst
|
||||
}
|
||||
|
||||
_get_excludes(){
|
||||
local -n fnames="$1"
|
||||
local -- _ol="$2"
|
||||
${yq} -Ne eval-all ". as \$item ireduce ({}; . *+ \$item) |.Overlays.${_ol}.excludes[]" \
|
||||
"${fnames[@]}" 2>/dev/null
|
||||
}
|
||||
|
||||
_get_type(){
|
||||
local -n fnames="$1"
|
||||
local -- _ol="$2"
|
||||
${yq} -Ne eval-all ". as \$item ireduce ({}; . *+ \$item) |.Overlays.${_ol}.type" \
|
||||
"${fnames[@]}" 2>/dev/null
|
||||
}
|
||||
|
||||
_join_array() {
|
||||
local IFS="$1"
|
||||
shift
|
||||
echo -n "$*"
|
||||
}
|
||||
|
||||
_get_config_files config_files
|
||||
|
||||
eval $(std::parse_yaml "${config_files[-1]}" 'cfg_')
|
||||
[[ -v cfg_DefaultGroups ]] && DefaultGroups="${cfg_DefaultGroups}"
|
||||
[[ -v cfg_DefaultReleaseStages ]] && DefaultReleaseStages="${cfg_DefaultReleaseStages}"
|
||||
[[ -v cfg_ReleaseStages ]] && ReleaseStages="${cfg_ReleaseStages}"
|
||||
[[ -v cfg_SysCollectionsDir ]] && SysCollectionsDir="${cfg_SysCollectionsDir}"
|
||||
unset ${!cfg_*}
|
||||
|
||||
#
|
||||
# loop over all overlays and save config in OverlayInfo and Dir2OverlayMap
|
||||
#
|
||||
# - at least install_root must be specified
|
||||
# - modulefiles_root default so install_root
|
||||
# - the type defaults to ${ol_normal}
|
||||
#
|
||||
Overlays=( $(_get_ol_names config_files) )
|
||||
local ol=''
|
||||
local install_root=''
|
||||
local modulefiles_root=''
|
||||
local type=''
|
||||
local excludes=()
|
||||
for ol in "${Overlays[@]}"; do
|
||||
# install_root
|
||||
install_root=$(_get_install_root config_files "${ol}") || \
|
||||
std::die 3 \
|
||||
"Install_root missing for overlay -- ${ol}"
|
||||
install_root=$(envsubst <<< "${install_root}")
|
||||
[[ -d ${install_root} ]] || \
|
||||
std::die 3 \
|
||||
"Invalid installation root directory for overlay '${ol}' -- ${install_root}"
|
||||
OverlayInfo[${ol}:inst_root]="${install_root}"
|
||||
|
||||
# modulefiles_root
|
||||
modulefiles_root=$(_get_modulefiles_root config_files "${ol}") || \
|
||||
modulefiles_root=${install_root}
|
||||
[[ -d ${modulefiles_root} ]] || \
|
||||
std::die 3 \
|
||||
"Invalid modulefiles root directory for overlay '${ol}' -- ${modulefiles_root}"
|
||||
OverlayInfo[${ol}:mod_root]="${modulefiles_root}"
|
||||
Dir2OverlayMap[${modulefiles_root}]="${ol}"
|
||||
|
||||
# type
|
||||
type=$(_get_type config_files "${ol}") || \
|
||||
type=${ol_normal}
|
||||
case ${type} in
|
||||
${ol_normal} | ${ol_replacing} | ${ol_hiding} )
|
||||
:
|
||||
;;
|
||||
* )
|
||||
std::die 3 "Invalid type for overlay '${ol}' -- ${type}"
|
||||
;;
|
||||
esac
|
||||
OverlayInfo[${ol}:type]="${type}"
|
||||
|
||||
# excludes
|
||||
excludes=$(_get_excludes config_files "${ol}") || \
|
||||
excludes=()
|
||||
OverlayInfo[${ol}:excludes]=$(_join_array ':' "${excludes[@]}")
|
||||
|
||||
# mark as unused
|
||||
OverlayInfo[${ol}:used]='no'
|
||||
done
|
||||
local -- type=''
|
||||
type=$( ${yq} ".${key} | type" 2>/dev/null <<<"${yaml_input}")
|
||||
if [[ "${type:2}" == 'null' ]]; then
|
||||
val=''
|
||||
return 0
|
||||
fi
|
||||
if [[ "${type}" != '!!seq' ]]; then
|
||||
std::die 3 "%s" \
|
||||
"Value of '${key}' must be of type 'seq', but is of type '${type:2}'!"
|
||||
fi
|
||||
val=$( ${yq} -e ".${key}[]" \
|
||||
2>/dev/null <<<"${yaml_input}" ) || val=''
|
||||
}
|
||||
|
||||
|
||||
pm::read_config(){
|
||||
: "
|
||||
Read Pmodules configuration files '${PMODULES_HOME}/config/Pmodules.yaml'
|
||||
and '${HOME}/.Pmodules/Pmodules.yaml'.
|
||||
|
||||
Args:
|
||||
none
|
||||
"
|
||||
get_config_of_overlay(){
|
||||
: "
|
||||
Get configuration of an overlay.
|
||||
|
||||
Args:
|
||||
$1 YAML config
|
||||
$2 name of overlay
|
||||
"
|
||||
local -r yaml_input="$1"
|
||||
local -r ol_name="$2"
|
||||
local -- key=''
|
||||
local -a keys=()
|
||||
local -- value=''
|
||||
# init overlay with defaults
|
||||
for key in "${!OverlayConfigKeys[@]}"; do
|
||||
OverlayInfo[${ol_name}:${key}]="${OverlayConfigKeys[${key}]}"
|
||||
done
|
||||
# get keys in YAML input
|
||||
readarray -t keys < <( ${yq} -e ".|keys|.[]" <<<"${yaml_input}" 2>/dev/null ) || \
|
||||
std::die 3 "Oops: retrieving keys from:\n${yaml_input}"
|
||||
for key in "${keys[@]}"; do
|
||||
[[ -v OverlayConfigKeys[${key,,}] ]] || \
|
||||
std::die 3 "%s -- %s\n%s" \
|
||||
"Invalid key in configuration" \
|
||||
"${key}" "${yaml_input}"
|
||||
case ${key,,} in
|
||||
install_root )
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
||||
OverlayInfo[${ol_name}:install_root]=$(${envsubst} <<< "${value}")
|
||||
[[ -d ${OverlayInfo[${ol_name}:install_root]} ]] || \
|
||||
std::die 3 \
|
||||
"Invalid installation root directory for overlay '${ol_name}' -- ${value}"
|
||||
;;
|
||||
modulefiles_root )
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
||||
OverlayInfo[${ol_name}:modulefiles_root]=$(${envsubst} <<< "${value}")
|
||||
[[ -d ${OverlayInfo[${ol_name}:modulefiles_root]} ]] || \
|
||||
std::die 3 \
|
||||
"Invalid modulefiles root directory for overlay '${ol_name}' -- ${value}"
|
||||
;;
|
||||
type )
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
||||
case ${value} in
|
||||
"${ol_normal}" | "${ol_replacing}" | "${ol_hiding}" )
|
||||
:
|
||||
;;
|
||||
* )
|
||||
std::die 3 "Invalid type for overlay '${ol_name}' -- ${type}"
|
||||
;;
|
||||
esac
|
||||
OverlayInfo[${ol_name}:type]="${value}"
|
||||
;;
|
||||
excludes )
|
||||
pm::get_seq "${yaml_input}" value "${key}" '!!seq'
|
||||
local -a tmp_array=()
|
||||
read -r -a tmp_array <<<"${value}"
|
||||
local excludes=''
|
||||
printf -v excludes "%s:" "${tmp_array[@]}"
|
||||
OverlayInfo[${ol_name}:excludes]="${excludes%:}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [[ -z "${OverlayInfo[${ol_name}:modulefiles_root]}" ]]; then
|
||||
OverlayInfo[${ol_name}:modulefiles_root]=${OverlayInfo[${ol_name}:install_root]}
|
||||
fi
|
||||
local modulefiles_root=${OverlayInfo[${ol_name}:modulefiles_root]}
|
||||
Dir2OverlayMap[${modulefiles_root}]="${ol_name}"
|
||||
}
|
||||
|
||||
get_config_of_overlays(){
|
||||
: "
|
||||
Get configuration of overlays in YAML input.
|
||||
|
||||
Args:
|
||||
$1 YAML input
|
||||
"
|
||||
local -r yaml_input="$1"
|
||||
local -- ol_name=''
|
||||
readarray -t Overlays < <( ${yq} -e '.|keys|.[]' <<<"${yaml_input}" )
|
||||
for ol_name in "${Overlays[@]}"; do
|
||||
local yaml_tmp
|
||||
pm::get_value "${yaml_input}" yaml_tmp "${ol_name}" '!!map'
|
||||
get_config_of_overlay "${yaml_tmp}" "${ol_name}"
|
||||
done
|
||||
}
|
||||
|
||||
get_config(){
|
||||
: "
|
||||
Get Pmodules configuration.
|
||||
|
||||
Args:
|
||||
$1 Pmodules configuration file
|
||||
"
|
||||
local -r config_file="$1"
|
||||
local -- yaml_input=''
|
||||
yaml_input=$( ${yq} -Ne e "." "${config_file}" 2>/dev/null ) || \
|
||||
std::die 3 "Cannot read configuration file '${config_file}'!"
|
||||
|
||||
local -a keys=()
|
||||
readarray -t keys < <( ${yq} -e ".|keys().[]" <<<"${yaml_input}" 2>/dev/null ) || \
|
||||
std::die 3 "Oops: retrieving keys from:\n${yaml_input}"
|
||||
|
||||
for key in "${keys[@]}"; do
|
||||
[[ -v DefaultPmodulesConfig[${key,,}] ]] || \
|
||||
std::die 3 "%s -- %s\n%s" \
|
||||
"Invalid key in configuration" \
|
||||
"${key}" "${yaml_input}"
|
||||
case ${key,,} in
|
||||
defaultgroups | default_groups )
|
||||
pm::get_value "${yaml_input}" DefaultGroups "${key}" '!!str'
|
||||
;;
|
||||
defaultreleasestages | default_reltages )
|
||||
pm::get_value "${yaml_input}" DefaultReleaseStages "${key}" '!!str'
|
||||
;;
|
||||
tmpdir | tmp_dir )
|
||||
pm::get_value "${yaml_input}" TmpDir "${key}" '!!str'
|
||||
;;
|
||||
distfilesdir | download_dir )
|
||||
pm::get_value "${yaml_input}" DistfilesDir "${key}" '!!str'
|
||||
;;
|
||||
overlays )
|
||||
local tmp_str=''
|
||||
pm::get_value "${yaml_input}" tmp_str "${key}" '!!map'
|
||||
get_config_of_overlays "${tmp_str}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# system config file
|
||||
local -r sys_config_file="${PMODULES_HOME%%/Tools*}/config/Pmodules.yaml"
|
||||
test -r "${sys_config_file}" || \
|
||||
std::die 3 \
|
||||
"%s %s -- %s" \
|
||||
"base overlay definition file" \
|
||||
"does not exist or is not readable" \
|
||||
"$_"
|
||||
DefaultGroups="${DefaultPmodulesConfig['default_groups']}"
|
||||
DefaultReleaseStages="${DefaultPmodulesConfig['default_reltages']}"
|
||||
TmpDir="${DefaultPmodulesConfig['tmp_dir']}"
|
||||
DistfilesDir="${DefaultPmodulesConfig['download_dir']}"
|
||||
|
||||
get_config "${sys_config_file}"
|
||||
|
||||
local -r usr_config_file="${HOME}/.Pmodules/Pmodules.yaml"
|
||||
if [[ -r "${usr_config_file}" ]]; then
|
||||
get_config "${usr_config_file}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# mode: sh
|
||||
# sh-basic-offset: 8
|
||||
|
||||
+61
-162
@@ -27,7 +27,7 @@ std::debug() {
|
||||
std::die() {
|
||||
local -ri ec=$1
|
||||
shift
|
||||
if [[ -n $@ ]]; then
|
||||
if (( ${#@} > 0 )); then
|
||||
local -r fmt=$1
|
||||
shift
|
||||
std::log 2 "$fmt" "$@"
|
||||
@@ -39,16 +39,51 @@ std::def_cmd(){
|
||||
which "$1" 2>/dev/null || std::die 255 "'$1' not found!"
|
||||
}
|
||||
|
||||
std::def_cmds(){
|
||||
local path="$1"
|
||||
shift
|
||||
for cmd in "$@"; do
|
||||
eval declare -gr ${cmd}=$(PATH="${path}" /usr/bin/which $cmd 2>/dev/null)
|
||||
if [[ -z "${!cmd}" ]]; then
|
||||
std::die 255 "${cmd} not found"
|
||||
fi
|
||||
done
|
||||
}
|
||||
awk=$(std::def_cmd 'awk'); declare -r awk
|
||||
base64=$(std::def_cmd 'base64'); declare -r base64
|
||||
bash=$(std::def_cmd 'bash'); declare -r bash
|
||||
cat=$(std::def_cmd 'cat'); declare -r cat
|
||||
cp=$(std::def_cmd 'cp'); declare -r cp
|
||||
curl=$(std::def_cmd 'curl'); declare -r curl
|
||||
envsubst=$(std::def_cmd 'envsubst'); declare -r envsubst
|
||||
dirname=$(std::def_cmd 'dirname'); declare -r dirname
|
||||
file=$(std::def_cmd 'file'); declare -r file
|
||||
find=$(std::def_cmd 'find'); declare -r find
|
||||
getopt=$(std::def_cmd 'getopt'); declare -r getopt
|
||||
grep=$(std::def_cmd 'grep'); declare -r grep
|
||||
install=$(std::def_cmd 'install'); declare -r install
|
||||
logger=$(std::def_cmd 'logger'); declare -r logger
|
||||
make=$(std::def_cmd 'make'); declare -r make
|
||||
mkdir=$(std::def_cmd 'mkdir'); declare -r mkdir
|
||||
mktemp=$(std::def_cmd 'mktemp'); declare -r mktemp
|
||||
modulecmd=$(std::def_cmd 'modulecmd'); declare -- modulecmd
|
||||
patch=$(std::def_cmd 'patch'); declare -r patch
|
||||
pwd=$(std::def_cmd 'pwd'); declare -r pwd
|
||||
rm=$(std::def_cmd 'rm'); declare -r rm
|
||||
rmdir=$(std::def_cmd 'rmdir'); declare -r rmdir
|
||||
sed=$(std::def_cmd 'sed'); declare -r sed
|
||||
seq=$(std::def_cmd 'seq'); declare -r seq
|
||||
sevenz=$(std::def_cmd 'sevenz'); declare -r sevenz
|
||||
sort=$(std::def_cmd 'sort'); declare -r sort
|
||||
tar=$(std::def_cmd 'tar'); declare -r tar
|
||||
tee=$(std::def_cmd 'tee'); declare -r tee
|
||||
tput=$(std::def_cmd 'tput'); declare -r tput
|
||||
uname=$(std::def_cmd 'uname'); declare -r uname
|
||||
yq=$(std::def_cmd 'yq'); declare -r yq
|
||||
|
||||
KernelName=$(${uname} -s); declare -r KernelName
|
||||
if [[ ${KernelName} == 'Darwin' ]]; then
|
||||
PATH+=':/opt/local/bin'
|
||||
otool=$(std::def_cmd 'otool'); declare -r otool
|
||||
shasum=$(std::def_cmd 'shasum');declare -r shasum
|
||||
sysctl=$(std::def_cmd 'sysctl');declare -r sysctl
|
||||
declare -r sha256sum="${shasum -a 256}"
|
||||
else
|
||||
ldd=$(std::def_cmd 'ldd'); declare -r ldd
|
||||
patchelf=$(std::def_cmd 'patchelf'); declare -r patchelf
|
||||
sha256sum=$(std::def_cmd 'sha256sum');
|
||||
declare -r sha256sum
|
||||
fi
|
||||
|
||||
#
|
||||
# get answer to yes/no question
|
||||
@@ -58,7 +93,7 @@ std::def_cmds(){
|
||||
std::get_YN_answer() {
|
||||
local -r prompt="$1"
|
||||
local ans
|
||||
read -p "${prompt}" ans
|
||||
read -r -p "${prompt}" ans
|
||||
case ${ans} in
|
||||
y|Y )
|
||||
return 0;;
|
||||
@@ -71,14 +106,16 @@ std::get_YN_answer() {
|
||||
# return normalized abolute pathname
|
||||
# $1: filename
|
||||
std::get_abspath() {
|
||||
local -r fname=$1
|
||||
local -r fname="$1"
|
||||
local -- abspath=''
|
||||
#[[ -r "${fname}" ]] || return 1
|
||||
if [[ -d ${fname} ]]; then
|
||||
echo $(cd "${fname}" && pwd)
|
||||
abspath=$(cd "${fname}" && pwd -L)
|
||||
else
|
||||
local -r dname=$(dirname "${fname}")
|
||||
echo $(cd "${dname}" && pwd)/$(basename "${fname}")
|
||||
abspath=$(cd "${dname}" && pwd -L)/$(basename "${fname}")
|
||||
fi
|
||||
echo "${abspath}"
|
||||
}
|
||||
|
||||
std::append_path () {
|
||||
@@ -117,135 +154,20 @@ std::prepend_path () {
|
||||
}
|
||||
|
||||
std::remove_path() {
|
||||
local -nr P="$1"
|
||||
local -nr path="$1"
|
||||
shift 1
|
||||
local -ar dirs="$@"
|
||||
local -ar remove_dirs=("$@")
|
||||
local new_path=''
|
||||
local -r _P=( ${P//:/ } )
|
||||
local -a _path=()
|
||||
IFS=':' read -r -a _path <<<"${path}"
|
||||
local dir=''
|
||||
for dir in "${dirs[@]}"; do
|
||||
for dir in "${remove_dirs[@]}"; do
|
||||
# loop over all entries in path
|
||||
for entry in "${_P[@]}"; do
|
||||
for entry in "${_path[@]}"; do
|
||||
[[ "${entry}" != "${dir}" ]] && new_path+=":${entry}"
|
||||
done
|
||||
done
|
||||
P="${new_path:1}" # remove leading ':'
|
||||
}
|
||||
|
||||
#
|
||||
# Replace or remove a directory in a path variable.
|
||||
#
|
||||
# To remove a dir:
|
||||
# std::replace_path PATH <pattern>
|
||||
#
|
||||
# To replace a dir:
|
||||
# std::replace_path PATH <pattern> /replacement/path
|
||||
#
|
||||
# Args:
|
||||
# $1 name of the shell variable to set (e.g. PATH)
|
||||
# $2 a grep pattern identifying the element to be removed/replaced
|
||||
# $3 the replacement string (use "" for removal)
|
||||
#
|
||||
# Based on solution published here:
|
||||
# https://stackoverflow.com/questions/273909/how-do-i-manipulate-path-elements-in-shell-scripts
|
||||
#
|
||||
std::replace_path () {
|
||||
local -r path="$1"
|
||||
local -r removepat="$2"
|
||||
local -r replacestr="${3:-''}"
|
||||
|
||||
local -r removestr=$(echo "${!path}" | tr ":" "\n" | grep -m 1 "^$removepat\$")
|
||||
export $path="$(echo "${!path}" | tr ":" "\n" | sed "s:^${removestr}\$:${replacestr}:" |
|
||||
sed '/^\s*$/d' | tr "\n" ":" | sed -e 's|^:||' -e 's|:$||')"
|
||||
}
|
||||
|
||||
#
|
||||
# Functions to split a path into its components.
|
||||
#
|
||||
# Args:
|
||||
# $1 upvar
|
||||
# $2 absolute or relative path (depends on the function)
|
||||
# $3 opt upvar: number of components
|
||||
#
|
||||
# Notes:
|
||||
# std::split_path()
|
||||
# if the path is absolute, the first element of the returned array is empty.
|
||||
#
|
||||
# std::split_abspath()
|
||||
# the path must begin with a slash, otherwise std::die() is called with
|
||||
# an internal error message.
|
||||
#
|
||||
# std::split_relpath()
|
||||
# analog to std::split_abspath() with a relative path.
|
||||
#
|
||||
std::split_path() {
|
||||
local -n parts="$1"
|
||||
local -r path="$2"
|
||||
|
||||
IFS='/'
|
||||
local std__split_path_result=( ${std__split_path_tmp} )
|
||||
unset IFS
|
||||
parts="${std__split_path_result[@]}"
|
||||
if (( $# >= 3 )); then
|
||||
# return number of parts
|
||||
local -n num="$3"
|
||||
num="${#std__split_path_result[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
std::split_abspath() {
|
||||
local -n parts="$1"
|
||||
local -r path="$2"
|
||||
if [[ "${path:0:1}" == '/' ]]; then
|
||||
local -r std__split_path_tmp="${path:1}"
|
||||
else
|
||||
std::die 255 "Oops: Internal error in '${FUNCNAME[0]}' called by '${FUNCNAME[1]}' }"
|
||||
fi
|
||||
|
||||
IFS='/'
|
||||
local std__split_path_result=( ${std__split_path_tmp} )
|
||||
unset IFS
|
||||
parts="${std__split_path_result[@]}"
|
||||
if (( $# >= 3 )); then
|
||||
# return number of parts
|
||||
local -n num="$3"
|
||||
num="${#std__split_path_result[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
std::split_relpath() {
|
||||
local -n parts="$1"
|
||||
local -r path="$2"
|
||||
if [[ "${path:0:1}" == '/' ]]; then
|
||||
std::die 255 "Oops: Internal error in '${FUNCNAME[0]}' called by '${FUNCNAME[1]}' }"
|
||||
else
|
||||
local -r std__split_path_tmp="${path}"
|
||||
fi
|
||||
|
||||
IFS='/'
|
||||
local std__split_path_result=( ${std__split_path_tmp} )
|
||||
unset IFS
|
||||
parts="${std__split_path_result[@]}"
|
||||
if (( $# >= 3 )); then
|
||||
# return number of parts
|
||||
local -n num="$3"
|
||||
num="${#std__split_path_result[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
std::read_versions() {
|
||||
local -r fname="$1"
|
||||
local varname=''
|
||||
while read _name _version; do
|
||||
[[ -z ${_name} ]] && continue
|
||||
[[ -z ${_version} ]] && continue
|
||||
[[ "${_name:0:1}" == '#' ]] && continue
|
||||
var_name=$(echo ${_name} | tr [:lower:] [:upper:])_VERSION
|
||||
# don't set version, if already set
|
||||
if [[ -z ${!var_name} ]]; then
|
||||
eval ${var_name}="${_version}"
|
||||
fi
|
||||
done < "${fname}"
|
||||
path="${new_path:1}" # remove leading ':'
|
||||
}
|
||||
|
||||
std.get_os_release_linux() {
|
||||
@@ -288,7 +210,8 @@ std::get_os_release() {
|
||||
}
|
||||
|
||||
std::get_type() {
|
||||
local -a signature=( $(typeset -p "$1") )
|
||||
local -a signature=()
|
||||
read -r -a signature <(typeset -p "$1")
|
||||
case ${signature[1]} in
|
||||
-Ai* )
|
||||
echo 'int dict'
|
||||
@@ -314,30 +237,6 @@ std::get_type() {
|
||||
esac
|
||||
}
|
||||
|
||||
std::parse_yaml() {
|
||||
#
|
||||
# parse a YAML file
|
||||
# See: https://gist.github.com/pkuczynski/8665367
|
||||
#
|
||||
local -r fname="$1"
|
||||
local -r prefix="$2"
|
||||
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
|
||||
sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
|
||||
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "${fname}" |
|
||||
awk -F$fs '{
|
||||
indent = length($1)/2;
|
||||
vname[indent] = $2;
|
||||
for (i in vname) {
|
||||
if (i > indent) {delete vname[i]}
|
||||
}
|
||||
if (length($3) > 0) {
|
||||
vn="";
|
||||
for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
|
||||
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
std::is_member_of_array(){
|
||||
local -- item="$1"
|
||||
local -n array="$2"
|
||||
|
||||
+113
-324
@@ -7,58 +7,32 @@
|
||||
#
|
||||
#.............................................................................
|
||||
|
||||
declare VERSION='@PMODULES_VERSION@'
|
||||
declare -r VERSION='@PMODULES_VERSION@'
|
||||
|
||||
unset CDPATH # unset CDPATH, otherwise 'cd' prints the directoy!
|
||||
unset IFS # use default IFS
|
||||
|
||||
#set -e # exit on error
|
||||
set -o pipefail
|
||||
set -o nounset
|
||||
shopt -s nocaseglob
|
||||
shopt -s extglob
|
||||
shopt -s nullglob
|
||||
|
||||
# get absolute path of script
|
||||
declare mydir=$(dirname "$0")
|
||||
declare -r mydir=$(cd ${mydir} && pwd -P)
|
||||
mydir=$(cd "$(/usr/bin/dirname "$0")" && pwd -P)
|
||||
prefix=$(/usr/bin/dirname "${mydir}")
|
||||
|
||||
source "${mydir}/../lib/libstd.bash" || {
|
||||
PATH="${prefix}/bin:${prefix}/libexec:/bin:/usr/bin:/sbin:/usr/sbin"
|
||||
source "${prefix}/lib/libstd.bash" || {
|
||||
echo "Oops: cannot source library -- '$_'" 1>&2; exit 3;
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# check availability of used commands and set environment variables
|
||||
# cmd=$(which cmd)
|
||||
# in the following we use these environment variable to call binaries.
|
||||
#
|
||||
declare -r MODULECMD="${PMODULES_HOME}/bin/modulecmd"
|
||||
[[ -x ${MODULECMD} ]] || \
|
||||
std::die 1 "Oops: modulecmd binary not available!"
|
||||
|
||||
std::def_cmds "${mydir}/../libexec" \
|
||||
'patchelf' 'sevenz' 'yq'
|
||||
|
||||
std::def_cmds '/usr/bin:/bin:/usr/sbin:/sbin' \
|
||||
'awk' 'base64' 'cat' 'cp' 'envsubst' 'file' 'find' 'getopt' 'grep' \
|
||||
'install' 'logger' 'make' 'mkdir' 'mktemp' 'patch' 'pwd' \
|
||||
'rm' 'rmdir' 'seq' 'sort' 'tar' 'tee' 'uname'
|
||||
|
||||
declare -r OS="$(${uname} -s)"
|
||||
if [[ ${OS} == 'Darwin' ]]; then
|
||||
std::def_cmds '/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin' \
|
||||
'curl' 'otool' 'shasum' 'sysctl'
|
||||
declare -r sha256sum="${shasum -a 256}"
|
||||
else
|
||||
std::def_cmds '/usr/bin:/bin:/usr/sbin:/sbin' \
|
||||
'ldd' 'curl' 'sha256sum'
|
||||
fi
|
||||
|
||||
# for the time being, we still set PATH. Just in case we forgot a binary
|
||||
PATH="${PMODULES_HOME}/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
|
||||
##############################################################################
|
||||
source "${mydir}/../lib/libpbuild.bash" || \
|
||||
source "${prefix}/lib/libpmodules.bash" || \
|
||||
std::die 3 "Oops: cannot source library -- '$_'"
|
||||
source "${mydir}/../lib/libpmodules.bash" || \
|
||||
source "${prefix}/lib/libpbuild.bash" || \
|
||||
std::die 3 "Oops: cannot source library -- '$_'"
|
||||
|
||||
##############################################################################
|
||||
set -o nounset
|
||||
shopt -s nocaseglob
|
||||
shopt -s extglob
|
||||
shopt -s nullglob
|
||||
unset mydir
|
||||
unset prefix
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -143,13 +117,6 @@ MISCELLANEOUS OPTIONS:
|
||||
--tmpdir
|
||||
Directory used for building a module.
|
||||
|
||||
--legacy
|
||||
Use legacy configuration files.
|
||||
|
||||
--overlay
|
||||
Install in this overlay. Defaults to the base overlay. This
|
||||
option can only be used with legacy configuration file.
|
||||
|
||||
DOCUMENTATION:
|
||||
Full documentation is available at
|
||||
http://pmodules.gitpages.psi.ch
|
||||
@@ -166,7 +133,7 @@ DOCUMENTATION:
|
||||
# last default
|
||||
|
||||
# save arguments, required for building dependencies
|
||||
declare -r ARGS="$@"
|
||||
declare -ra ARGS=( "$@" )
|
||||
|
||||
# versions to be build, '.*' or none means all
|
||||
declare versions_to_build=''
|
||||
@@ -178,14 +145,12 @@ declare opt_force_rebuild='no'
|
||||
declare -i opt_jobs=0
|
||||
declare opt_update_modulefiles='no'
|
||||
declare opt_system=''
|
||||
declare opt_overlay=''
|
||||
declare opt_verbose='no'
|
||||
# array collecting all modules specified on the command line via '--with=module'
|
||||
declare -a opt_with_modules=() # :FIXME: legacy build should also use the dict
|
||||
declare -a opt_with_modules=()
|
||||
declare -A opt_with_dict=()
|
||||
declare -- opt_config_file=''
|
||||
declare -- opt_debug='no'
|
||||
declare -- opt_yaml='yes'
|
||||
declare -- opt_check_mode='no'
|
||||
declare -- opt_variant=''
|
||||
declare -- opt_clean_install='no'
|
||||
@@ -193,7 +158,6 @@ declare -- opt_parent_prefix=''
|
||||
|
||||
declare -- BUILD_SCRIPT=''
|
||||
declare -- yaml_config_file=''
|
||||
declare -a legacy_config_files=()
|
||||
declare -- module_name=''
|
||||
declare -- module_type='module'
|
||||
declare -- echo=':'
|
||||
@@ -272,23 +236,9 @@ parse_args() {
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--overlay | --overlay=* )
|
||||
if [[ $1 == *=* ]]; then
|
||||
opt_overlay="${1#--*=}"
|
||||
else
|
||||
opt_overlay="$2"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--yaml )
|
||||
opt_yaml='yes'
|
||||
;;
|
||||
--check-mode )
|
||||
opt_check_mode='yes'
|
||||
;;
|
||||
--legacy )
|
||||
opt_yaml='no'
|
||||
;;
|
||||
--use-flags | --use-flags=* )
|
||||
if [[ $1 == *=* ]]; then
|
||||
USE_FLAGS=":${1#--*=}:"
|
||||
@@ -334,9 +284,9 @@ parse_args() {
|
||||
;;
|
||||
--parent-prefix | --parent-prefix=* )
|
||||
if [[ $1 == *=* ]]; then
|
||||
opt_parent_prefix=( "${1#--*=}" )
|
||||
opt_parent_prefix="${1#--*=}"
|
||||
else
|
||||
opt_parent_prefix=( "$2" )
|
||||
opt_parent_prefix="$2"
|
||||
shift
|
||||
fi
|
||||
module_type='sub_package'
|
||||
@@ -375,152 +325,13 @@ parse_args() {
|
||||
opt_system="${opt_system:-$(std::get_os_release)}"
|
||||
|
||||
# set config file
|
||||
if [[ ${opt_yaml,,} == 'no' ]]; then
|
||||
# look for legacy config files
|
||||
if [[ -n ${opt_config_file} ]]; then
|
||||
legacy_config_files=( "${opt_config_file}" )
|
||||
else
|
||||
shopt -q nullglob || :
|
||||
local -i nullglob_set=$?
|
||||
|
||||
legacy_config_files=( "${BUILDBLOCK_DIR}"/*/variants.${opt_system} )
|
||||
legacy_config_files+=( "${BUILDBLOCK_DIR}"/*/variants."$(uname -s)" )
|
||||
legacy_config_files+=( "${BUILDBLOCK_DIR}"/*/variants )
|
||||
(( nullglob_set == 1 )) && shopt -u nullglob
|
||||
fi
|
||||
(( ${#legacy_config_files[@]} == 0 )) && \
|
||||
std::die 1 "No legacy configuration file found!"
|
||||
std::info "Using legacy variants files."
|
||||
opt_overlay="${opt_overlay:-'base'}"
|
||||
else
|
||||
yaml_config_file="${opt_config_file:-${BUILDBLOCK_DIR}/files/config.yaml}"
|
||||
[[ -r "${yaml_config_file}" ]] || \
|
||||
std::die 2 \
|
||||
"%s -- %s" \
|
||||
"YAML config file doesn't exist or is not readable" \
|
||||
"${yaml_config_file}"
|
||||
[[ "${opt_overlay}" == 'yes' ]] && \
|
||||
std::die 2 \
|
||||
"opt '--overlay' can only be used together with legacy config files!"
|
||||
std::info "Using YAML configuration file - ${yaml_config_file}"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# bash brace expansion of given args. Input args like:
|
||||
#
|
||||
# "text" "gcc/{9.3.0,10.3.0}" "openmpi/{4.0.5,4.1.0}"
|
||||
#
|
||||
# will be expanded to the following four lines:
|
||||
#
|
||||
# "text gcc/9.3.0 openmpi/4.0.5"
|
||||
# "text gcc/9.3.0 openmpi/4.1.0"
|
||||
# "text gcc/10.3.0 openmpi/4.0.5"
|
||||
# "text gcc/10.3.0 openmpi/4.1.0"
|
||||
#
|
||||
bash_expand(){
|
||||
local text="$1"
|
||||
shift
|
||||
local to_expand=( "${@}" )
|
||||
if (( ${#to_expand[@]} == 0 )); then
|
||||
echo ${text}
|
||||
else
|
||||
local list
|
||||
eval list=( ${to_expand[0]} )
|
||||
local s
|
||||
for s in ${list[*]}; do
|
||||
bash_expand "${text} ${s}" "${to_expand[@]:1}"
|
||||
done;
|
||||
fi;
|
||||
}
|
||||
|
||||
build_modules_legacy() {
|
||||
local -a files=( "${legacy_config_files[@]}" )
|
||||
local -A mod_overlays=()
|
||||
|
||||
expand_variants_file(){
|
||||
local -r input="$1"
|
||||
local -a toks=()
|
||||
while read -a toks; do
|
||||
# skip empty and comment lines
|
||||
(( ${#toks[@]} == 0 )) && continue
|
||||
[[ ${toks[0]:0:1} == '#' ]] && continue
|
||||
local -a deps=( ${toks[*]:2} )
|
||||
bash_expand "${toks[0]} ${toks[1]}" "${deps[@]}"
|
||||
done < "${input}"
|
||||
}
|
||||
|
||||
local name="$1"
|
||||
local version="$2"
|
||||
local exact_match='no'
|
||||
if [[ "${version:0:1}" == "=" ]]; then
|
||||
exact_match='yes'
|
||||
version="${version:1}"
|
||||
fi
|
||||
shift 2
|
||||
local with_modules=( $* )
|
||||
|
||||
# if we have to build a dependency, we might have less dependencies
|
||||
# on it. Or in other words: the list of "with modules" might be
|
||||
# overdetermined. In the loop below we check, which dependencies
|
||||
# specified with '--with' are required.
|
||||
local m
|
||||
local pattern="/^${name}\/${version}[[:blank:]]/"
|
||||
for m in "${with_modules[@]}"; do
|
||||
if [[ -n $(${awk} "/${m%/*}[\/ ]/" "${files[@]}") ]]; then
|
||||
pattern+=" && /${m//\//\\/}/"
|
||||
fi
|
||||
done
|
||||
|
||||
local variants=()
|
||||
for f in "${files[@]}"; do
|
||||
local line=''
|
||||
while read line; do
|
||||
variants+=( "${line}" )
|
||||
done < <(expand_variants_file "${f}" | ${awk} "${pattern}")
|
||||
done
|
||||
if (( ${#variants[@]} == 0 )); then
|
||||
std::info "%s " \
|
||||
"${name}/${version}:" \
|
||||
"no suitable variant found!"
|
||||
std::die 10 "Aborting..."
|
||||
elif (( ${#variants[@]} > 1 )) && [[ ${exact_match} == 'yes' ]]; then
|
||||
std::info "%s " \
|
||||
"Multiple variants found:"
|
||||
for variant in "${variants[@]}"; do
|
||||
std::info "${variant}"
|
||||
done
|
||||
std::die 10 "Aborting..."
|
||||
fi
|
||||
[[ -v OverlayInfo[${opt_overlay}:inst_root] ]] || \
|
||||
std::die 2 "%s" \
|
||||
"Overlay doesn't exist - ${opt_overlay}"
|
||||
local ol_name="${opt_overlay}"
|
||||
declare ol_inst_root="${OverlayInfo[${opt_overlay}:inst_root]}"
|
||||
declare ol_mod_root="${OverlayInfo[${opt_overlay}:mod_root]}"
|
||||
local -i i=0
|
||||
local -i num_variants=${#variants[@]}
|
||||
for ((i = 0; i < num_variants; i++)); do
|
||||
local tokens=( ${variants[i]} )
|
||||
local name="${tokens[0]%/*}"
|
||||
version="${tokens[0]#*/}"
|
||||
release="${tokens[1]}"
|
||||
case ${release} in
|
||||
unstable|stable|deprecated|remove|removed)
|
||||
:
|
||||
;;
|
||||
* )
|
||||
std::info "%s " \
|
||||
"${name}/${version}:" \
|
||||
"invalid release stage '${release}'!"
|
||||
std::die 10 "Aborting..."
|
||||
;;
|
||||
esac
|
||||
with_modules=( "${tokens[@]:2}" )
|
||||
pbuild.build_module_legacy \
|
||||
"${name}" "${version}" \
|
||||
"${release}" "${with_modules[@]}"
|
||||
done
|
||||
yaml_config_file="${opt_config_file:-${BUILDBLOCK_DIR}/files/config.yaml}"
|
||||
[[ -r "${yaml_config_file}" ]] || \
|
||||
std::die 2 \
|
||||
"%s -- %s" \
|
||||
"YAML config file doesn't exist or is not readable" \
|
||||
"${yaml_config_file}"
|
||||
std::info "Using YAML configuration file - ${yaml_config_file}"
|
||||
}
|
||||
|
||||
get_yaml_file_fmt(){
|
||||
@@ -560,23 +371,23 @@ read_yaml_config_file() {
|
||||
echo "${yaml}"
|
||||
}
|
||||
|
||||
build_modules_yaml(){
|
||||
build_modules(){
|
||||
local -- name="$1"
|
||||
local -- version="$2"
|
||||
shift 2
|
||||
local -a with_modules=( $* )
|
||||
local -a with_modules=( "$*" )
|
||||
|
||||
|
||||
if [[ "${opt_check_mode}" == 'yes' ]]; then
|
||||
local -- yamllint
|
||||
if ! which yamllint > /dev/null 2>&1; then
|
||||
eval $( "${MODULECMD}" bash load yamllint/1.28.0 )
|
||||
eval $( "${modulecmd}" bash load yamllint/1.28.0 )
|
||||
fi
|
||||
which yamllint > /dev/null 2>&1 || \
|
||||
std::die 3 "yamllint not found"
|
||||
yamllint "${yaml_config_file}"
|
||||
fi
|
||||
local -- file_fmt=$(get_yaml_file_fmt "${yaml_config_file}")
|
||||
local -- file_fmt=''
|
||||
file_fmt=$(get_yaml_file_fmt "${yaml_config_file}")
|
||||
|
||||
local -- yaml_mod_config=''
|
||||
yaml_mod_config=$(read_yaml_config_file "${yaml_config_file}" "${name}")
|
||||
@@ -601,17 +412,17 @@ build_modules_yaml(){
|
||||
# none
|
||||
#
|
||||
init_module_environment(){
|
||||
eval $( "${MODULECMD}" bash use unstable )
|
||||
eval $( "${MODULECMD}" bash use deprecated )
|
||||
eval $( "${MODULECMD}" bash purge )
|
||||
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?
|
||||
if [[ -e "${PMODULES_HOME%%/Tools*}/Libraries" ]]; then
|
||||
eval $( "${MODULECMD}" bash use Libraries )
|
||||
eval $( "${modulecmd}" bash use Libraries )
|
||||
fi
|
||||
if [[ -e "${PMODULES_HOME%%/Tools*}/System" ]]; then
|
||||
eval $( "${MODULECMD}" bash use System )
|
||||
eval $( "${modulecmd}" bash use System )
|
||||
fi
|
||||
unset C_INCLUDE_PATH
|
||||
unset CPLUS_INCLUDE_PATH
|
||||
@@ -636,7 +447,7 @@ init_module_environment(){
|
||||
parse_version() {
|
||||
local v="$1"
|
||||
V="$1"
|
||||
: ${USE_FLAGS:=''} # architectures (or empty)
|
||||
USE_FLAGS=${USE_FLAGS:-''}
|
||||
|
||||
local tmp=''
|
||||
|
||||
@@ -667,16 +478,17 @@ parse_version() {
|
||||
|
||||
VERSIONS=()
|
||||
if [[ -n ${V_RELEASE} ]]; then
|
||||
VERSIONS+=( ${V_PKG}-${V_RELEASE} )
|
||||
VERSIONS+=( "${V_PKG}-${V_RELEASE}" )
|
||||
fi
|
||||
if [[ -n ${V_PATCHLVL} ]]; then
|
||||
VERSIONS+=( ${V_MAJOR}.${V_MINOR}.${V_PATCHLVL} )
|
||||
VERSIONS+=( "${V_MAJOR}.${V_MINOR}.${V_PATCHLVL}" )
|
||||
fi
|
||||
if [[ -n ${V_MINOR} ]]; then
|
||||
VERSIONS+=( ${V_MAJOR}.${V_MINOR} )
|
||||
VERSIONS+=( "${V_MAJOR}.${V_MINOR}" )
|
||||
fi
|
||||
VERSIONS+=( ${V_MAJOR} )
|
||||
VERSIONS+=( "${V_MAJOR}" )
|
||||
}
|
||||
|
||||
# these variables must be export for envsubst(1)
|
||||
declare -x P=''
|
||||
declare -x V=''
|
||||
@@ -763,7 +575,7 @@ build_modules_yaml_v1(){
|
||||
local -- name="$2"
|
||||
local -- version="$3"
|
||||
shift 3
|
||||
local -a with_modules=( $* )
|
||||
local -a with_modules=( "$@" )
|
||||
|
||||
check_yaml_keys(){
|
||||
local -n valid_yaml_keys="$1"
|
||||
@@ -771,8 +583,8 @@ build_modules_yaml_v1(){
|
||||
used_yaml_keys=()
|
||||
local -- key=''
|
||||
local -a keys=()
|
||||
keys=( $(${yq} '.|keys().[]' 2>/dev/null) )
|
||||
debug "top-level keys: ${keys[@]}"
|
||||
readarray -t keys < <( ${yq} '.|keys().[]' 2>/dev/null)
|
||||
debug "top-level keys: ${keys[*]}"
|
||||
for key in "${keys[@]}"; do
|
||||
[[ -v valid_yaml_keys[${key}] ]] || \
|
||||
std::die 3 "Invalid key in YAML configuration file -- ${key}"
|
||||
@@ -780,37 +592,6 @@ build_modules_yaml_v1(){
|
||||
done
|
||||
}
|
||||
|
||||
get_value(){
|
||||
local -- yaml_input="$1"
|
||||
local -n val="$2"
|
||||
local -- key="$3"
|
||||
local -- expected_type="$4"
|
||||
|
||||
local -- type=''
|
||||
type=$( ${yq} ".${key} | type" 2>/dev/null <<<"${yaml_input}")
|
||||
if [[ "${type}" != "${expected_type}" ]]; then
|
||||
std::die 3 "%s" \
|
||||
"Value of '${key}' must be of type '${expected_type:2}', but is '${type:2}'!"
|
||||
fi
|
||||
val=$( ${yq} -e ".${key}" \
|
||||
2>/dev/null <<<"${yaml_input}" ) || val=''
|
||||
}
|
||||
|
||||
get_seq(){
|
||||
local -- yaml_input="$1"
|
||||
local -n val="$2"
|
||||
local -- key="$3"
|
||||
|
||||
local -- type=''
|
||||
type=$( ${yq} ".${key} | type" 2>/dev/null <<<"${yaml_input}")
|
||||
if [[ "${type}" != '!!seq' ]]; then
|
||||
std::die 3 "%s" \
|
||||
"Value of '${key}' must be of type 'seq', but is of type '${type:2}'!"
|
||||
fi
|
||||
val=$( ${yq} -e ".${key}[]" \
|
||||
2>/dev/null <<<"${yaml_input}" ) || val=''
|
||||
}
|
||||
|
||||
get_config(){
|
||||
local -- yaml_input="$1"
|
||||
local -n cfg="$2" # ref. to return configuration
|
||||
@@ -827,9 +608,9 @@ build_modules_yaml_v1(){
|
||||
fi
|
||||
|
||||
local -a keys=()
|
||||
keys=( $( ${yq} -e ".|keys().[]" <<<"${yaml_input}" 2>/dev/null )) || \
|
||||
readarray -t keys < <( ${yq} -e ".|keys().[]" <<<"${yaml_input}" 2>/dev/null ) || \
|
||||
std::die 3 "Oops: retrieving keys from:\n${yaml_input}"
|
||||
debug "config keys: ${keys[@]}"
|
||||
debug "config keys: ${keys[*]}"
|
||||
for key in "${keys[@]}"; do
|
||||
[[ -v dfl[${key,,}] ]] || \
|
||||
std::die 3 "%s -- %s\n%s" \
|
||||
@@ -837,7 +618,7 @@ build_modules_yaml_v1(){
|
||||
"${key}" "${yaml_input}"
|
||||
case ${key} in
|
||||
compile_in_sourcetree )
|
||||
get_value "${yaml_input}" value "${key}" '!!bool'
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!bool'
|
||||
case ${value,,} in
|
||||
true )
|
||||
cfg[${key,,}]='yes'
|
||||
@@ -848,13 +629,13 @@ build_modules_yaml_v1(){
|
||||
* )
|
||||
std::die 3 "%s '%s' -- %s" \
|
||||
"Invalid value for" \
|
||||
'${key}' \
|
||||
"${key}" \
|
||||
"${value}"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
configure_with )
|
||||
get_value "${yaml_input}" value "${key}" '!!str'
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
||||
case ${value,,} in
|
||||
auto | cmake | autotools )
|
||||
cfg[${key,,}]="${value,,}"
|
||||
@@ -868,15 +649,15 @@ build_modules_yaml_v1(){
|
||||
esac
|
||||
;;
|
||||
default_variant | download_dir | group | overlay | script | suffix )
|
||||
get_value "${yaml_input}" value "${key}" '!!str'
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
||||
cfg[${key,,}]="${value}"
|
||||
;;
|
||||
group_deps )
|
||||
get_value "${yaml_input}" value "${key}" '!!map'
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!map'
|
||||
cfg[${key,,}]="${value}"
|
||||
;;
|
||||
relstage )
|
||||
get_value "${yaml_input}" value "${key}" '!!str'
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
||||
case ${value,,} in
|
||||
unstable | stable | deprecated )
|
||||
cfg[${key,,}]="${value,,}"
|
||||
@@ -893,15 +674,15 @@ build_modules_yaml_v1(){
|
||||
esac
|
||||
;;
|
||||
urls | sub_packages )
|
||||
get_value "${yaml_input}" value "${key}" '!!seq'
|
||||
pm::get_value "${yaml_input}" value "${key}" '!!seq'
|
||||
cfg[${key,,}]="${value}"
|
||||
;;
|
||||
build_requires|configure_args|docfiles|patch_files|runtime_deps|systems|target_cpus|variant )
|
||||
get_seq "${yaml_input}" value "${key}"
|
||||
build_requires|configure_args|docfiles|patch_files|runtime_deps|systems|variant )
|
||||
pm::get_seq "${yaml_input}" value "${key}"
|
||||
cfg[${key,,}]="${value}"
|
||||
;;
|
||||
kernels )
|
||||
get_seq "${yaml_input}" value "${key}"
|
||||
pm::get_seq "${yaml_input}" value "${key}"
|
||||
set -o noglob
|
||||
local -a items=( "${value,,}" )
|
||||
set +o noglob
|
||||
@@ -917,7 +698,7 @@ build_modules_yaml_v1(){
|
||||
cfg[${key,,}]="${value}"
|
||||
;;
|
||||
target_cpus )
|
||||
get_seq "${yaml_input}" value "${key}"
|
||||
pm::get_seq "${yaml_input}" value "${key}"
|
||||
set -o noglob
|
||||
local -a items=( "${value,,}" )
|
||||
set +o noglob
|
||||
@@ -933,7 +714,7 @@ build_modules_yaml_v1(){
|
||||
cfg[${key,,}]="${value}"
|
||||
;;
|
||||
'configure_args+' | 'docfiles+' | 'patch_files+' )
|
||||
get_seq "${yaml_input}" value "${key}"
|
||||
pm::get_seq "${yaml_input}" value "${key}"
|
||||
key="${key:0:-1}"
|
||||
if [[ -z "${cfg[${key,,}]}" ]]; then
|
||||
cfg[${key,,}]="${value}"
|
||||
@@ -946,7 +727,7 @@ build_modules_yaml_v1(){
|
||||
std::die 3 "%s '%s' in %s" \
|
||||
"Oops unhandled key" \
|
||||
"${key}" \
|
||||
"${FUNCNAME}"
|
||||
"${FUNCNAME[0]}"
|
||||
esac
|
||||
done
|
||||
}
|
||||
@@ -959,7 +740,7 @@ build_modules_yaml_v1(){
|
||||
local version="$2"
|
||||
|
||||
local -a keys=()
|
||||
keys=( $( ${yq} -e '.versions|keys().[]' 2>/dev/null) ) || \
|
||||
readarray -t keys < <( ${yq} -e '.versions|keys().[]' 2>/dev/null ) || \
|
||||
std::die 3 "No version keys in configuration file!"
|
||||
|
||||
refvar=()
|
||||
@@ -969,7 +750,7 @@ build_modules_yaml_v1(){
|
||||
for k in ${key//;/ }; do
|
||||
# brace expansion of key
|
||||
local list=()
|
||||
eval list=( $k )
|
||||
list=( $(${bash} -c "echo $k") )
|
||||
if [[ ${list[@]} =~ ${version} ]]; then
|
||||
refvar+=("${key}")
|
||||
break
|
||||
@@ -1000,7 +781,8 @@ build_modules_yaml_v1(){
|
||||
}
|
||||
|
||||
get_num_variants(){
|
||||
local -i n=$(${yq} '.|length' 2>/dev/null)
|
||||
local -i n=0
|
||||
n=$(${yq} '.|length' 2>/dev/null)
|
||||
echo "$n"
|
||||
}
|
||||
|
||||
@@ -1027,7 +809,7 @@ build_modules_yaml_v1(){
|
||||
|
||||
# query all specified group dependencies
|
||||
local -a keys=()
|
||||
keys=( $(${yq} ".|keys|.[]" <<<"${yaml}" 2>/dev/null) )
|
||||
readarray -t keys < <( ${yq} ".|keys|.[]" <<<"${yaml}" 2>/dev/null )
|
||||
|
||||
local -- key=''
|
||||
for key in "${keys[@]}"; do
|
||||
@@ -1039,7 +821,7 @@ build_modules_yaml_v1(){
|
||||
die_invalid_group_dep "${name}" "${version}" "${group}"
|
||||
done
|
||||
# are all required group dependencies defined?
|
||||
for key in "${hierarchical_groups[${group,,}]}"; do
|
||||
for key in ${hierarchical_groups[${group,,}]}; do
|
||||
is_in_array "${key,,}" "${keys[@]}" || \
|
||||
die_missing_group_dep "${name}" "${version}" "${group}"
|
||||
done
|
||||
@@ -1052,11 +834,11 @@ build_modules_yaml_v1(){
|
||||
|
||||
local -a modules=()
|
||||
local keys=()
|
||||
keys=( $(${yq} ".${group,,}|keys|.[]" <<<"${yaml}" 2>/dev/null) )
|
||||
readarray -t keys < <( ${yq} ".${group,,}|keys|.[]" <<<"${yaml}" 2>/dev/null )
|
||||
local key
|
||||
for key in "${keys[@]}"; do
|
||||
local versions=()
|
||||
versions=( $( ${yq} -e ".${group,,}.${key}[]" <<<"${yaml}" 2>/dev/null) )
|
||||
readarray -t versions < <( ${yq} -e ".${group,,}.${key}[]" <<<"${yaml}" 2>/dev/null )
|
||||
local version
|
||||
for version in "${versions[@]}"; do
|
||||
if [[ -v opt_with_dict[${key}/${version}] ]]; then
|
||||
@@ -1165,8 +947,8 @@ build_modules_yaml_v1(){
|
||||
&& continue
|
||||
|
||||
debug "build $module_name/$module_version with $compiler and $hdf5"
|
||||
debug " runtime deps: ${runtime_deps[@]}"
|
||||
debug " build requires: ${build_requires[@]}"
|
||||
debug " runtime deps: ${runtime_deps[*]}"
|
||||
debug " build requires: ${build_requires[*]}"
|
||||
pbuild.build_module_yaml \
|
||||
"${module_name}" "${module_version}" \
|
||||
"$3" \
|
||||
@@ -1201,8 +983,8 @@ build_modules_yaml_v1(){
|
||||
&& continue
|
||||
|
||||
debug "build $module_name/$module_version with $compiler and $mpi"
|
||||
debug " runtime deps: ${runtime_deps[@]}"
|
||||
debug " build requires: ${build_requires[@]}"
|
||||
debug " runtime deps: ${runtime_deps[*]}"
|
||||
debug " build requires: ${build_requires[*]}"
|
||||
pbuild.build_module_yaml \
|
||||
"${module_name}" "${module_version}" \
|
||||
"$3" \
|
||||
@@ -1236,8 +1018,8 @@ build_modules_yaml_v1(){
|
||||
for mpi in "${with_mpi[@]}"; do
|
||||
for hdf5 in "${with_hdf5[@]}"; do
|
||||
debug "build $module_name/$module_version with $compiler, $mpi and $hdf5"
|
||||
debug " runtime deps: ${runtime_deps[@]}"
|
||||
debug " build requires: ${build_requires[@]}"
|
||||
debug " runtime deps: ${runtime_deps[*]}"
|
||||
debug " build requires: ${build_requires[*]}"
|
||||
|
||||
# build if opt_with_modules is empty or compiler is in this array
|
||||
(( ${#opt_with_modules[@]} != 0 )) \
|
||||
@@ -1300,7 +1082,7 @@ build_modules_yaml_v1(){
|
||||
local unpacker=''
|
||||
local key=''
|
||||
local value=''
|
||||
while read key value; do
|
||||
while read -r key value; do
|
||||
key=${key:0:-1}
|
||||
case "${key}" in
|
||||
url )
|
||||
@@ -1359,6 +1141,12 @@ build_modules_yaml_v1(){
|
||||
pbuild.add_patch_files "${args[@]}"
|
||||
}
|
||||
|
||||
die_sub_package_name_missing(){
|
||||
std::die 3 "Name of sub-package not specified in \n===\n$1\n===\n"
|
||||
}
|
||||
die_sub_package_version_missing(){
|
||||
std::die 3 "Version of sub-package not specified in \n===\n$1\n===\n"
|
||||
}
|
||||
build_sub_packages(){
|
||||
local -- yaml="$1"
|
||||
local -i l=0
|
||||
@@ -1374,20 +1162,20 @@ build_modules_yaml_v1(){
|
||||
local -- pkg_version=''
|
||||
local -a pkg_build_args=()
|
||||
local -a keys=()
|
||||
keys=( $( ${yq} -e ".|keys().[]" <<<"${pkgs_yaml}" 2>/dev/null )) || \
|
||||
readarray -t keys < <( ${yq} -e ".|keys().[]" <<<"${pkgs_yaml}" 2>/dev/null ) || \
|
||||
die_parsing "${pkgs_yaml}"
|
||||
local -- key=''
|
||||
for key in "${keys[@]}"; do
|
||||
case ${key,,} in
|
||||
'name' )
|
||||
get_value "${pkgs_yaml}" pkg_name "${key}" '!!str'
|
||||
pm::get_value "${pkgs_yaml}" pkg_name "${key}" '!!str'
|
||||
;;
|
||||
'version' )
|
||||
get_value "${pkgs_yaml}" pkg_version "${key}" '!!str'
|
||||
pm::get_value "${pkgs_yaml}" pkg_version "${key}" '!!str'
|
||||
;;
|
||||
'build_args' )
|
||||
local -- value=''
|
||||
get_seq "${pkgs_yaml}" value "${key}"
|
||||
pm::get_seq "${pkgs_yaml}" value "${key}"
|
||||
readarray -t pkg_build_args <<< "${value}"
|
||||
;;
|
||||
* )
|
||||
@@ -1398,6 +1186,11 @@ build_modules_yaml_v1(){
|
||||
;;
|
||||
esac
|
||||
done
|
||||
[[ -n "${pkg_name}" ]] || \
|
||||
die_sub_package_name_missing "${pkgs_yaml}"
|
||||
[[ -n "${pkg_version}" ]] || \
|
||||
die_sub_package_version_missing "${pkgs_yaml}"
|
||||
|
||||
[[ "${opt_verbose}" == 'yes' ]] && \
|
||||
pkg_build_args+=( '--verbose' )
|
||||
[[ "${opt_debug}" == 'yes' ]] && \
|
||||
@@ -1444,10 +1237,10 @@ build_modules_yaml_v1(){
|
||||
local -- kernel=''
|
||||
for kernel in "${kernels[@]}"; do
|
||||
[[ ${kernel} == 'any' ]] && return 0
|
||||
[[ ${kernel} == ${OS,,} ]] & return 0
|
||||
[[ ${kernel} == ${KernelName,,} ]] & return 0
|
||||
done
|
||||
std::info "Skipping variant '${module_version}':"
|
||||
std::info " The kernel of this systems is: ${OS}"
|
||||
std::info " The kernel of this systems is: ${KernelName}"
|
||||
std::info " But the variant is for the following kernels: ${module_config['kernels']}"
|
||||
return 1
|
||||
}
|
||||
@@ -1489,11 +1282,11 @@ build_modules_yaml_v1(){
|
||||
debug "build variant ${module_name}/${module_version}"
|
||||
|
||||
local ol_name="${module_config['overlay']}"
|
||||
[[ -v OverlayInfo[${ol_name}:inst_root] ]] || \
|
||||
[[ -v OverlayInfo[${ol_name}:install_root] ]] || \
|
||||
std::die 2 "%s" \
|
||||
"Overlay doesn't exist - ${ol_name}"
|
||||
declare ol_inst_root="${OverlayInfo[${ol_name}:inst_root]}"
|
||||
declare ol_mod_root="${OverlayInfo[${ol_name}:mod_root]}"
|
||||
declare ol_install_root="${OverlayInfo[${ol_name}:install_root]}"
|
||||
declare ol_modulefiles_root="${OverlayInfo[${ol_name}:modulefiles_root]}"
|
||||
|
||||
module_version+="${module_config['suffix']}"
|
||||
|
||||
@@ -1554,7 +1347,7 @@ build_modules_yaml_v1(){
|
||||
# do curly brackets expansion {}
|
||||
local l
|
||||
local list=()
|
||||
eval list=( $k )
|
||||
list=( $(${bash} -c "echo $k" ) )
|
||||
for l in "${list[@]}"; do
|
||||
if [[ $l =~ ${version} ]]; then
|
||||
ev_result+=("${l}")
|
||||
@@ -1580,15 +1373,16 @@ build_modules_yaml_v1(){
|
||||
get_config "${yaml_input}" default_config Yaml_default_config
|
||||
|
||||
if [[ -v used_keys['shasums'] ]]; then
|
||||
local yaml_input=$(${yq} '.shasums' <<<"${yaml_mod_config}" 2>/dev/null)
|
||||
while read key value; do
|
||||
local yaml_input=''
|
||||
yaml_input=$(${yq} '.shasums' <<<"${yaml_mod_config}" 2>/dev/null)
|
||||
while read -r key value; do
|
||||
[[ -z ${key} ]] && continue
|
||||
SHASUMS[${key//:}]="${value}"
|
||||
done <<<"${yaml_input}"
|
||||
fi
|
||||
if [[ -v used_keys['type'] ]]; then
|
||||
local -- value=''
|
||||
get_value "${yaml_mod_config}" value 'type' '!!str'
|
||||
pm::get_value "${yaml_mod_config}" value 'type' '!!str'
|
||||
case "${value,,}" in
|
||||
'module' )
|
||||
[[ "${module_type}" == 'sub_package' ]] && \
|
||||
@@ -1605,7 +1399,8 @@ build_modules_yaml_v1(){
|
||||
fi
|
||||
get_matching_version_keys version_keys "${version}" <<<"${yaml_mod_config}"
|
||||
for version_key in "${version_keys[@]}"; do
|
||||
local yaml_vk_config=$(get_yaml_vk_config "${version_key}" <<<"${yaml_mod_config}")
|
||||
local yaml_vk_config=''
|
||||
yaml_vk_config=$(get_yaml_vk_config "${version_key}" <<<"${yaml_mod_config}")
|
||||
|
||||
# check keys: allowed are 'config' and 'variants'
|
||||
used_keys=()
|
||||
@@ -1621,8 +1416,10 @@ build_modules_yaml_v1(){
|
||||
# reminder: if YAML input is empty, next line copies defaults to 'vk_config'
|
||||
get_config "${yaml_input}" vk_config default_config
|
||||
|
||||
local -- yaml_variants=$(get_variants <<<"${yaml_vk_config}")
|
||||
local -i num_variants=$(get_num_variants <<<"${yaml_variants}")
|
||||
local -- yaml_variants=''
|
||||
yaml_variants=$(get_variants <<<"${yaml_vk_config}")
|
||||
local -i num_variants=0
|
||||
num_variants=$(get_num_variants <<<"${yaml_variants}")
|
||||
local versions=()
|
||||
expand_version_key versions "${version_key}" "${version}"
|
||||
local v=''
|
||||
@@ -1647,15 +1444,7 @@ build_modules_yaml_v1(){
|
||||
fi
|
||||
done
|
||||
done
|
||||
} # build_modules_yaml()
|
||||
|
||||
build_modules() {
|
||||
if [[ "${opt_yaml}" == 'yes' ]]; then
|
||||
build_modules_yaml "$@"
|
||||
else
|
||||
build_modules_legacy "$@"
|
||||
fi
|
||||
}
|
||||
} # build_modules()
|
||||
|
||||
debug(){
|
||||
${echo} "INFO: " "$@" 1>&2
|
||||
@@ -1686,8 +1475,8 @@ pm::read_config
|
||||
# or
|
||||
# ${overlay}/var/distfiles
|
||||
# ?
|
||||
: ${PMODULES_DISTFILESDIR:="${PMODULES_HOME%%/Tools*}/var/distfiles"}
|
||||
: ${PMODULES_TMPDIR:=/var/tmp/${USER}}
|
||||
PMODULES_DISTFILESDIR=${PMODULES_DISTFILESDIR:-"${PMODULES_HOME%%/Tools*}/var/distfiles"}
|
||||
PMODULES_TMPDIR="${PMODULES_TMPDIR:-/var/tmp/${USER}}"
|
||||
export PMODULES_DISTFILESDIR PMODULES_TMPDIR
|
||||
|
||||
declare -r BUILD_SCRIPT
|
||||
|
||||
@@ -1,747 +0,0 @@
|
||||
#!@BASH@ --noprofile
|
||||
|
||||
PATH='/bin:/usr/bin'
|
||||
unset CDPATH # unset CDPATH, otherwise 'cd' prints the directoy!
|
||||
unset IFS # use default IFS
|
||||
|
||||
shopt -s nullglob
|
||||
shopt -s extglob
|
||||
|
||||
# used for some output only
|
||||
declare -r CMD='modmanage'
|
||||
|
||||
declare mydir=$(cd $(dirname "$0") && pwd)
|
||||
declare prefix=$(dirname "${mydir}")
|
||||
declare libdir="${prefix}/lib"
|
||||
declare libexecdir="${prefix}/libexec"
|
||||
declare -r bindir="${prefix}/bin"
|
||||
|
||||
source "${libdir}/libstd.bash"
|
||||
source "${libdir}/libpmodules.bash"
|
||||
|
||||
_exit () {
|
||||
std::die 1 "\nInterrupted..."
|
||||
}
|
||||
trap '_exit' INT TERM
|
||||
|
||||
_err () {
|
||||
std::info "\nOops: got an error in function '${FUNCNAME[1]}', line ${BASH_LINENO[0]}"
|
||||
std::die 1 "Aborting ..."
|
||||
}
|
||||
trap '_err' ERR
|
||||
|
||||
path="/bin:/usr/bin:${bindir}"
|
||||
[[ $(uname -s) == 'Darwin' ]] && path+=":${libexecdir}"
|
||||
std::def_cmds "${path}" 'chown' 'dirname' 'mkdir' 'rsync' 'rm' 'getopt' 'find' 'modulecmd'
|
||||
|
||||
unset mydir
|
||||
unset prefix
|
||||
unset libdir
|
||||
unset libexecdir
|
||||
# bindir we still need
|
||||
|
||||
declare PMODULES_VERSION='@PMODULES_VERSION@'
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# help [module|sub-command]
|
||||
#
|
||||
Subcommands[help]='help'
|
||||
Options[help]='-o hHV\? -l version -l help'
|
||||
Help[help]='
|
||||
USAGE:
|
||||
modmanage [switches] subcommand [subcommand-args]...
|
||||
|
||||
SWITCHES:
|
||||
-h|-H|-?|--help this usage info
|
||||
-V|--version modules version & configuration options
|
||||
--debug enable debug output
|
||||
--dry-run dry run
|
||||
|
||||
SUBCOMMANDS:
|
||||
+ init [switches] TARGET_DIR
|
||||
+ install [switches] module...
|
||||
+ search [switches] [string|pattern]...
|
||||
+ help [subcommand]
|
||||
'
|
||||
|
||||
subcommand_help() {
|
||||
local -r subcommand='help'
|
||||
local -a args=()
|
||||
while (( $# > 0 )); do
|
||||
case $1 in
|
||||
-h | -\? | -H | --help )
|
||||
print_help "${subcommand}"
|
||||
;;
|
||||
-V | --version )
|
||||
print_help 'version'
|
||||
;;
|
||||
-- )
|
||||
shift 1
|
||||
args+=( "$@" )
|
||||
break
|
||||
;;
|
||||
* )
|
||||
args+=( "$1" )
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
for arg in "${args[@]}"; do
|
||||
if [[ -n "${Help[${arg}]}" ]] ; then
|
||||
print_help "${arg}"
|
||||
else
|
||||
std::die 1 "Unknown sub-command -- ${subcommand}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Derive the module installation path from the modulefile path.
|
||||
# The passed modulefile must be absolute.
|
||||
#
|
||||
# Arguments:
|
||||
# $1: absolute module file path
|
||||
#
|
||||
get_module_prefix() {
|
||||
"${modulecmd}" bash show "$1" 2>&1 \
|
||||
|awk '/_HOME |_PREFIX / {print $3; exit}'
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Derive the module release-file path from the module file-path.
|
||||
#
|
||||
# Arguments:
|
||||
# $1: module file-path
|
||||
#
|
||||
get_releasefile_name() {
|
||||
echo "$(${dirname} "$1")/.release-$(basename "$1")"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Sync a module from one Pmodules environment to another:
|
||||
# - sync module installation
|
||||
# - sync modulefile
|
||||
# - sync release file
|
||||
#
|
||||
# Arguments:
|
||||
# $1: relative modulefile path (something like: Tools/gnuplot/5.0.0)
|
||||
# $2: source prefix of Pmodule environment
|
||||
# $3: target prefix of Pmodule environment
|
||||
#
|
||||
sync_module() {
|
||||
local -r rel_modulefile="$1"
|
||||
local -r src_root="$2"
|
||||
local -r target_root="$3"
|
||||
|
||||
local -r src_prefix=$( get_module_prefix "${src_root}/${rel_modulefile}" )
|
||||
local -r rel_prefix=${src_prefix#${src_root}/}
|
||||
local -r target_prefix="${target_root}/${rel_prefix}"
|
||||
|
||||
# install/update module
|
||||
if [[ ! -d "${target_prefix}" ]] || [[ "${force}" == 'yes' ]]; then
|
||||
${mkdir} -p "${target_prefix}" || exit $?
|
||||
${rsync} --links --perms --recursive --delete \
|
||||
"${src_prefix}/" \
|
||||
"${target_prefix}/" || exit $?
|
||||
fi
|
||||
|
||||
# create modulefile direcrory and install modulefile
|
||||
local -r src_modulefile="${src_root}/${rel_modulefile}"
|
||||
local -r target_modulefile="${target_root}/${rel_modulefile}"
|
||||
|
||||
${mkdir} -p "$(${dirname} "${target_modulefile}")" || exit $?
|
||||
|
||||
if [[ -e "${src_modulefile}" ]]; then
|
||||
${rsync} --links --perms --recursive \
|
||||
"${src_modulefile}" "${target_modulefile}" || exit $?
|
||||
fi
|
||||
|
||||
# install release-file
|
||||
local -r rel_releasefile=$( get_releasefile_name "${rel_modulefile}" )
|
||||
local -r src_releasefile="${src_root}/${rel_releasefile}"
|
||||
local -r target_releasefile="${target_root}/${rel_releasefile}"
|
||||
|
||||
if [[ -e "${src_releasefile}" ]]; then
|
||||
${rsync} --links --perms --recursive \
|
||||
"${src_releasefile}" "${target_releasefile}" || exit $?
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# initialize a new module environment
|
||||
#
|
||||
#
|
||||
#
|
||||
Subcommands[init]='init'
|
||||
Options[init]='-o \?hfy -l src: -l user: -l help -l force -l yes'
|
||||
Help[init]="
|
||||
USAGE:
|
||||
modmanage init [switches] TARGET_DIR
|
||||
Initialize a new minimal Pmodule environment in TARGET_DIR.
|
||||
A user must be specified with '--user=<USER>' if the
|
||||
programm is executed as root.
|
||||
|
||||
SWITCHES:
|
||||
--user <USER>
|
||||
If this scripts runs with root privileges, a user name
|
||||
ore ID must be specified.
|
||||
--force|--yes|-f|-y
|
||||
re-initialise an already existing Pmodule environment.
|
||||
"
|
||||
|
||||
subcommand_init() {
|
||||
check_env() {
|
||||
[[ -n "${PMODULES_ROOT}" ]] &&
|
||||
[[ -d "${PMODULES_ROOT}" ]] &&
|
||||
[[ -n "${PMODULES_HOME}" ]] &&
|
||||
[[ -n "${PMODULES_VERSION}" ]] || \
|
||||
std::die 1 "
|
||||
Error: the module environment you are going to use as source has not been
|
||||
initialized properly!"
|
||||
}
|
||||
|
||||
#.....................................................................
|
||||
#
|
||||
# Sync the Pmodules configuration and templates
|
||||
#
|
||||
# Arguments:
|
||||
# $1: source prefix of Pmodule environment
|
||||
# $2: target prefix of Pmodule environment
|
||||
#
|
||||
sync_config() {
|
||||
src="$1/${PMODULES_CONFIG_DIR}/"
|
||||
dst="$2/${PMODULES_CONFIG_DIR}/"
|
||||
${rsync} --links --perms \
|
||||
"${src}"/profile.{bash,csh,zsh} "${dst}" \
|
||||
|| return $?
|
||||
${rsync} --links --perms \
|
||||
"${src}"/profile.{bash,csh,zsh}-"${PMODULES_VERSION}" "${dst}" \
|
||||
|| return $?
|
||||
${rsync} --links --perms \
|
||||
"${src}/Pmodules.conf" "${dst}" \
|
||||
|| return $?
|
||||
${rsync} --links --perms \
|
||||
"${src}/modbuild.conf" "${dst}" \
|
||||
|| return $?
|
||||
}
|
||||
|
||||
local target_root=()
|
||||
local user=''
|
||||
while (($# > 0)); do
|
||||
case $1 in
|
||||
-h | -H | -\? | --help | -help )
|
||||
print_help "${subcommand}"
|
||||
;;
|
||||
--force | --yes | -f | -y )
|
||||
force='yes'
|
||||
;;
|
||||
--user | --user=* )
|
||||
if [[ "$1" == '--user' ]]; then
|
||||
user="$2"
|
||||
shift
|
||||
else
|
||||
user="${1#--*=}"
|
||||
fi
|
||||
;;
|
||||
-- )
|
||||
:
|
||||
;;
|
||||
* )
|
||||
# assign and remove trailing slashes
|
||||
target_root="${1%%*([\/])}"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
if [[ -z ${target_root} ]]; then
|
||||
std::die 1 "Error: no target directory specified!"
|
||||
fi
|
||||
|
||||
local -i euid=$(id -u)
|
||||
if (( euid == 0 )); then
|
||||
[[ -n "${user}" ]] || \
|
||||
std::die 1 "Error: --user parameter is required!"
|
||||
id -u "${user}" > /dev/null 2>&1 || \
|
||||
std::die 1 "Error: Unable to retrieve user id of user '${user}'"
|
||||
else
|
||||
[[ -z "${user}" ]] || \
|
||||
std::die 1 "Error: --user option is only allowed if running as root!"
|
||||
fi
|
||||
|
||||
local src_root="$(std::get_abspath "${bindir}/../../../..")"
|
||||
local config_file="${src_root}/${PMODULES_CONFIG_DIR}/profile.bash"
|
||||
if [[ -r "${config_file}" ]]; then
|
||||
source "${config_file}"
|
||||
fi
|
||||
check_env || \
|
||||
std::die 1 "Giving up..."
|
||||
|
||||
echo "Creating a minimal Pmodule environment from the environment at"
|
||||
echo " ${PMODULES_ROOT}"
|
||||
echo "in"
|
||||
echo " ${target_root}"
|
||||
if [[ -d "${target_root}" ]] && [[ ${force} == no ]]; then
|
||||
echo "Warning: ${target_root} already exists."
|
||||
std::get_YN_answer \
|
||||
"Do you really want to re-run the initialization? (y/N) " \
|
||||
|| std::die 1 "Abort ..."
|
||||
fi
|
||||
force='yes'
|
||||
echo "Creating target directory '${target_root}'..."
|
||||
${mkdir} -p "${target_root}" || \
|
||||
std::die 1 "Error: make directory failed!"
|
||||
|
||||
echo "Syncing configuration ..."
|
||||
sync_config "${src_root}" \
|
||||
"${target_root}" || \
|
||||
std::die 1 "Error: configuration synchronization failed!"
|
||||
|
||||
echo "Syncing Pmodules ${PMODULES_VERSION} from '${src_root}' to '${target_root}'..."
|
||||
sync_module "Tools/${PMODULES_MODULEFILES_DIR}/Pmodules/${PMODULES_VERSION}" \
|
||||
"${src_root}" \
|
||||
"${target_root}" || \
|
||||
std::die 1 "Error: sync Pmodules failed!"
|
||||
|
||||
for d in "${src_root}"/*/${PMODULES_MODULEFILES_DIR}; do
|
||||
${mkdir} -p "${target_root}/${d#${src_root}/}"
|
||||
done
|
||||
|
||||
if [[ -n "${user}" ]]; then
|
||||
echo "Changing user of new module environment to '${user}'..."
|
||||
${chown} -R "${user}" "${target_root}" || \
|
||||
std::die 1 "Error: changing owner failed!"
|
||||
echo
|
||||
fi
|
||||
echo "SourceRoot=${src_root}" > "${target_root}/${PMODULES_CONFIG_DIR}/modmanage.conf"
|
||||
echo "New minimal module environment created at '${target_root}'."
|
||||
echo "To use this environment, execute"
|
||||
echo " sudo ln -fs ${target_root} /opt/psi"
|
||||
echo " source /opt/psi/${PMODULES_CONFIG_DIR}/profile.bash"
|
||||
|
||||
}
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# sub-command 'install'
|
||||
#
|
||||
# Arguments:
|
||||
Subcommands[install]='install'
|
||||
Options[install]='-o hf -l force -l with: -l help -l src: -l target:'
|
||||
Help[install]='
|
||||
USAGE:
|
||||
modmanage install [switches] <module>...
|
||||
Install modules
|
||||
|
||||
SWITCHES:
|
||||
--force] | -f
|
||||
Install module even it already exists
|
||||
|
||||
--src <src>
|
||||
Install from module environment in <src>
|
||||
|
||||
--with <module>
|
||||
Install module(s) in this sub-group only
|
||||
|
||||
<module_pattern>
|
||||
Install modules matching given pattern
|
||||
'
|
||||
|
||||
subcommand_install() {
|
||||
local -r subcommand='install'
|
||||
local opts=''
|
||||
local -a with=()
|
||||
local -a module_pattern=()
|
||||
local src_root="${PMODULES_INSTALL_SOURCE}"
|
||||
local target_root="${PMODULES_ROOT}"
|
||||
local modulefile=''
|
||||
local -A modules_to_install
|
||||
local -A dependencies_to_install
|
||||
local -A group_map
|
||||
local -a modulepath=()
|
||||
|
||||
#......................................................................
|
||||
#
|
||||
set_initial_modulepath() {
|
||||
local group
|
||||
for group in "${!GroupDepths[@]}"; do
|
||||
(( ${GroupDepths[${group}]} == 0 )) || continue
|
||||
modulepath+=( "${src_root}/${group}/${PMODULES_MODULEFILES_DIR}" )
|
||||
done
|
||||
}
|
||||
|
||||
#......................................................................
|
||||
#
|
||||
create_group_map() {
|
||||
#
|
||||
# For the dependency resolution we need to know, whether a
|
||||
# module - if loaded - adds a hierarchical group to MODULEPATH
|
||||
# or not.
|
||||
#
|
||||
# Examples:
|
||||
# Loading a compiler adds the hierarchical group for
|
||||
# this compiler. The command
|
||||
# module load gcc/10.3.0
|
||||
# prepends
|
||||
# <pmodules_root>/Compiler/modulefiles/gcc/10.3.0
|
||||
# to MODULEPATH.
|
||||
#
|
||||
# The dependency files do not convey the information whether
|
||||
# loading a module extends MODULEPATH or not. What we need to
|
||||
# know is
|
||||
# 1) does loading a specific module extends MODULEPATH?
|
||||
# 2) if yes: what is the hierarchical group?
|
||||
#
|
||||
# Example:
|
||||
# If we know that loading 'gcc/10.3.0' adds a directory
|
||||
# in the hierarchical group 'Compiler' to MODULEPATH, we
|
||||
# know that this directory is
|
||||
# <pmodules_root>/Compiler/modulefiles/gcc/10.3.0
|
||||
#
|
||||
# This information we store in the dictionary 'group_map'.
|
||||
# For concinience reasons we store the string 'src_root/group'.
|
||||
# So, 'group_map' maps
|
||||
# module/version -> src_root/group
|
||||
#
|
||||
# Example:
|
||||
# group_map[gcc/10.3.0]="${src_root}/Compiler"
|
||||
#
|
||||
local group=''
|
||||
for group in "${!GroupDepths[@]}"; do
|
||||
(( ${GroupDepths[${group}]} > 0 )) || continue
|
||||
local fname=''
|
||||
while read fname; do
|
||||
local -a parts=()
|
||||
std::split_relpath parts "${fname}"
|
||||
if (( ${#parts[@]} - 2 != ${GroupDepths[${group}]} )); then
|
||||
std::warn "error in source group ${group}:"
|
||||
std::warn "modulefile: ${fname}"
|
||||
continue
|
||||
fi
|
||||
if [[ ${#parts[@]} < 4 ]]; then
|
||||
echo "${group} ${parts[@]}"
|
||||
fi
|
||||
local key="${parts[-4]}/${parts[-3]}"
|
||||
[[ -z "${group_map[${key}]}" ]] || continue
|
||||
group_map[${key}]="${src_root}/${group}"
|
||||
done < <(${find} -L "${src_root}/${group}/${PMODULES_MODULEFILES_DIR}" \
|
||||
\( -type l -o -type f \) \
|
||||
\! -name ".*" \
|
||||
-printf "%P\n" \
|
||||
)
|
||||
done
|
||||
}
|
||||
|
||||
#......................................................................
|
||||
#
|
||||
# Resolve dependencies to given module
|
||||
#
|
||||
# Arguments:
|
||||
# $1 absolute module file name
|
||||
#
|
||||
# Notes:
|
||||
# Following variables from the enclosing function are used:
|
||||
# modulepath
|
||||
# group_map (read-only)
|
||||
#
|
||||
resolve_dependencies () {
|
||||
local -r modulefile="$1"
|
||||
|
||||
local -- prefix=$(get_module_prefix "${modulefile}")
|
||||
local -a rdeps=()
|
||||
local -- rdeps_file="${prefix}/.dependencies"
|
||||
local -a ideps=()
|
||||
local -- ideps_file="${prefix}/.install_dependencies"
|
||||
|
||||
if [[ -r "${rdeps_file}" ]]; then
|
||||
mapfile -t rdeps < <(grep -v '^ *#' "${rdeps_file}" )
|
||||
fi
|
||||
if [[ -r "${ideps_file}" ]]; then
|
||||
mapfile -t ideps < <(grep -v '^ *#' "${ideps_file}" )
|
||||
fi
|
||||
|
||||
# loop over all dependecies
|
||||
local dep
|
||||
for dep in "${rdeps[@]}" "${ideps}"; do
|
||||
[[ -n ${dep} ]] || continue
|
||||
# search module with current modulepath
|
||||
local modulename=$(${find} "${modulepath[@]}" -path "*/${dep}" \
|
||||
-print -quit 2>/dev/null)
|
||||
[[ -n ${modulename} ]] || \
|
||||
std::die 3 "Oops: required module '${dep}' not found!"
|
||||
|
||||
local rel_modulename="${modulename#${src_root}/}"
|
||||
dependencies_to_install[${rel_modulename}]='.'
|
||||
resolve_dependencies "${modulename}"
|
||||
[[ -v group_map[${dep}] ]] || continue
|
||||
local dir="${group_map[${dep}]}" # = ${src_root}/<group>
|
||||
dir+="/${rel_modulename##+([!/])/}" # += rel.name with group removed
|
||||
modulepath+=( "${dir}" )
|
||||
done
|
||||
}
|
||||
|
||||
#......................................................................
|
||||
#
|
||||
# Print list of modules which will be installed and ask user wheter
|
||||
# he wants to continue or abort.
|
||||
#
|
||||
# Arguments:
|
||||
# none
|
||||
#
|
||||
# Notes:
|
||||
# Following variables from the enclosing function are used:
|
||||
# target_root (read-only)
|
||||
# modules_to_install (read-only)
|
||||
# dependencies_to_install (read-only)
|
||||
#
|
||||
print_modules() {
|
||||
local modulefile
|
||||
for modulefile in "$@"; do
|
||||
local -a parts
|
||||
std::split_relpath parts "${modulefile}"
|
||||
local s=''
|
||||
if (( ${#parts[@]} >= 6 )); then
|
||||
s="(${parts[2]}/${parts[3]}"
|
||||
for ((i = 4; i < ${#parts[@]}-2; i+=2)); do
|
||||
s+=" ${parts[i]}/${parts[i+1]}"
|
||||
done
|
||||
s+=')'
|
||||
fi
|
||||
std::info "%-20s %s" "${parts[-2]}/${parts[-1]}" "$s"
|
||||
done 2>&1 | sort
|
||||
}
|
||||
print_modules_to_install() {
|
||||
std::info "The following modules will be installed/updated:"
|
||||
print_modules "${!modules_to_install[@]}"
|
||||
if (( ${#dependencies_to_install[@]} > 0 )); then
|
||||
std::info "\nThe following dependencies will be installed/updated:"
|
||||
print_modules "${!dependencies_to_install[@]}"
|
||||
fi
|
||||
std::info ""
|
||||
std::get_YN_answer "Do you want to continue? [n] " || \
|
||||
std::die 1 "Aborting..."
|
||||
std::info ""
|
||||
}
|
||||
|
||||
while (($# > 0)); do
|
||||
case $1 in
|
||||
-h | -H | -\? | --help | -help )
|
||||
print_help "${subcommand}"
|
||||
;;
|
||||
--force | -f )
|
||||
force='yes'
|
||||
;;
|
||||
--src | --src=*)
|
||||
if [[ $1 == --src ]]; then
|
||||
src_root="$2"
|
||||
shift
|
||||
else
|
||||
src_root="${1#--*=}"
|
||||
fi
|
||||
;;
|
||||
--target | --target=*)
|
||||
if [[ $1 == --target ]]; then
|
||||
target_root="$2"
|
||||
shift
|
||||
else
|
||||
target_root="${1#--*=}"
|
||||
fi
|
||||
;;
|
||||
--with | --with=* )
|
||||
if [[ "$1" == --with ]]; then
|
||||
with+=( "$2" )
|
||||
shift
|
||||
else
|
||||
with+=( "${1#--*=}" )
|
||||
fi
|
||||
;;
|
||||
-- )
|
||||
:
|
||||
;;
|
||||
* )
|
||||
module_pattern+=( "$1" )
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -z ${src_root} ]]; then
|
||||
local conf_file="${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/modmanage.conf"
|
||||
if [[ -r ${conf_file} ]]; then
|
||||
source "${conf_file}"
|
||||
src_root="${SourceRoot}"
|
||||
fi
|
||||
fi
|
||||
[[ -n ${src_root} ]] \
|
||||
|| std::die 3 "Oops: no installation source given."
|
||||
[[ -d ${src_root} ]] \
|
||||
|| std::die 3 "Oops: '${src_root}' is not a valid installation source."
|
||||
|
||||
source "${src_root}/${PMODULES_CONFIG_DIR}/profile.bash"
|
||||
scan_groups "${src_root}"
|
||||
set_initial_modulepath
|
||||
create_group_map
|
||||
|
||||
# search for to be installed modules and their dependencies
|
||||
while read modulefile; do
|
||||
modules_to_install["${modulefile#${src_root}/}"]+='.'
|
||||
resolve_dependencies "${modulefile}"
|
||||
done < <("${modulecmd}" bash search \
|
||||
"${module_pattern[@]}" \
|
||||
"${with[@]/#/--with=}" \
|
||||
-a --glob \
|
||||
--no-header --print-modulefiles \
|
||||
--src="${src_root}" 2>&1 1>/dev/null)
|
||||
(( ${#modules_to_install[@]} == 0 )) && \
|
||||
std::die 0 "No matching modules found ..."
|
||||
print_modules_to_install
|
||||
|
||||
# install/update ...
|
||||
for modulefile in "${!modules_to_install[@]}" "${!dependencies_to_install[@]}"; do
|
||||
std::split_relpath parts "${modulefile}"
|
||||
std::info " ${parts[-2]}/${parts[-1]}"
|
||||
sync_module "${modulefile}" "${src_root}" "${target_root}"
|
||||
done
|
||||
std::info "\nDone!\n"
|
||||
} # subcommand_install
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# sub-command 'search'
|
||||
#
|
||||
Subcommands[search]='search'
|
||||
Options[search]='-o \?h -l with: -l help -l all-dep -l wrap -l glob -l src:'
|
||||
Help[install]='
|
||||
USAGE:
|
||||
modmanage search [switches] <string>...
|
||||
search modules
|
||||
|
||||
SWITCHES:
|
||||
--src <src>
|
||||
Search modules in environment <src>.
|
||||
Default is the source defined in modmanage.conf.
|
||||
|
||||
--with <module>
|
||||
Search module(s) in this sub-group.
|
||||
|
||||
<string>
|
||||
Search modules matching given string.
|
||||
|
||||
<pattern>
|
||||
Search modules matching given shell glob-pattern.
|
||||
'
|
||||
|
||||
subcommand_search() {
|
||||
local -a args=()
|
||||
while (($# > 0)); do
|
||||
case $1 in
|
||||
-h | -H | -\? | --help | -help )
|
||||
print_help "${subcommand}"
|
||||
;;
|
||||
--src | --src=*)
|
||||
if [[ $1 == --src ]]; then
|
||||
src_root="$2"
|
||||
shift
|
||||
else
|
||||
src_root="${1#--*=}"
|
||||
fi
|
||||
;;
|
||||
--with | --with=* )
|
||||
if [[ "$1" == --with ]]; then
|
||||
args+=( '--with' "$2" )
|
||||
shift
|
||||
else
|
||||
args+=( "$1" )
|
||||
fi
|
||||
;;
|
||||
--all-deps | --glob | --wrap )
|
||||
args+=( "$1" )
|
||||
;;
|
||||
-- )
|
||||
:
|
||||
;;
|
||||
* )
|
||||
args+=( "$1" )
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
if [[ -z ${src_root} ]]; then
|
||||
local conf_file="${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/modmanage.conf"
|
||||
if [[ -r ${conf_file} ]]; then
|
||||
source "${conf_file}"
|
||||
src_root="${SourceRoot}"
|
||||
fi
|
||||
fi
|
||||
[[ -n ${src_root} ]] \
|
||||
|| std::die 3 "Oops: no installation source given."
|
||||
[[ -d ${src_root} ]] \
|
||||
|| std::die 3 "Oops: '${src_root}' is not a valid installation source."
|
||||
${modulecmd} bash search --src="${src_root}" --all-release-stages \
|
||||
"${args[@]}" 2>&1 1>/dev/null
|
||||
}
|
||||
|
||||
declare force='no'
|
||||
declare subcommand=''
|
||||
declare -a opts=()
|
||||
while (($# > 0)); do
|
||||
case $1 in
|
||||
-h | -H | -\? | --help | -help )
|
||||
print_help 'help'
|
||||
;;
|
||||
-V | --version )
|
||||
print_help 'version'
|
||||
;;
|
||||
--debug )
|
||||
set -x
|
||||
;;
|
||||
--dry-run )
|
||||
chown="echo ${chown}"
|
||||
mkdir="echo ${mkdir}"
|
||||
rsync="echo ${rsync}"
|
||||
;;
|
||||
-* )
|
||||
opts+=( "$1" )
|
||||
;;
|
||||
* )
|
||||
subcommand="$1"
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift || :
|
||||
done
|
||||
|
||||
if [[ -z "${subcommand}" ]]; then
|
||||
std::die 1 "${CMD}: no sub-command specified.\n"
|
||||
print_help 'help'
|
||||
fi
|
||||
|
||||
if [[ -z "${Subcommands[${subcommand}]}" ]]; then
|
||||
std::die 1 "${CMD}: unknown sub-command -- ${subcommand}\n"
|
||||
fi
|
||||
|
||||
if [[ "${subcommand}" != "init" ]] && [[ -z "${PMODULES_ROOT}" ]]; then
|
||||
std::die 1 "Error: No current module environment configured!"
|
||||
fi
|
||||
|
||||
tmp=$("${getopt}" --name="${CMD}" ${Options[${subcommand}]} -- "${opts[@]}" "$@" ) \
|
||||
|| print_help "${subcommand}"
|
||||
eval args=( "$tmp" )
|
||||
unset tmp
|
||||
|
||||
umask 022
|
||||
|
||||
subcommand_${Subcommands[$subcommand]} "${args[@]}"
|
||||
|
||||
# Local Variables:
|
||||
# mode: sh
|
||||
# sh-basic-offset: 8
|
||||
# tab-width: 8
|
||||
# End:
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
unset BASH_ENV
|
||||
|
||||
declare mydir=$(cd $(dirname "$0") && pwd)
|
||||
declare libexecdir="$(dirname "${mydir}")/libexec"
|
||||
|
||||
declare bash="${libexecdir}/bash"
|
||||
declare modmanage="${libexecdir}/modmanage.bash"
|
||||
|
||||
"${bash}" --noprofile --norc "${modmanage}" "$@"
|
||||
+472
-453
File diff suppressed because it is too large
Load Diff
@@ -25,8 +25,6 @@ shopt -s nullglob
|
||||
declare -r BOOTSTRAP_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
declare -r SRC_DIR="${BOOTSTRAP_DIR}/Pmodules"
|
||||
|
||||
source "${SRC_DIR}/libstd.bash" || { echo "Oops!" 1>&2; exit 42; }
|
||||
|
||||
declare -r PMOD_DIR="Tools/Pmodules/${VERSION}"
|
||||
# config directory and file relative to install root
|
||||
declare -rx CONFIG_DIR='config'
|
||||
@@ -40,6 +38,61 @@ declare -rx DEFAULT_INSTALL_ROOT='/opt/psi'
|
||||
declare -rx DEFAULT_DISTFILES_DIR='var/distfiles'
|
||||
declare -rx DEFAULT_TMP_DIR='var/tmp/${USER}'
|
||||
|
||||
std::log() {
|
||||
local -ri fd=$1
|
||||
local -r fmt="$2"
|
||||
shift 2
|
||||
printf -- "${fmt}" "$@" 1>&$fd
|
||||
printf -- "\n" 1>&$fd
|
||||
}
|
||||
|
||||
std::info() {
|
||||
std::log 2 "$1" "${@:2}"
|
||||
}
|
||||
|
||||
std::error() {
|
||||
std::log 2 "$1" "${@:2}"
|
||||
}
|
||||
|
||||
std::debug() {
|
||||
[[ -v PMODULES_DEBUG ]] || return 0
|
||||
std::log 2 "$@"
|
||||
}
|
||||
|
||||
std::die() {
|
||||
local -ri ec=$1
|
||||
shift
|
||||
if [[ -n $@ ]]; then
|
||||
local -r fmt=$1
|
||||
shift
|
||||
std::log 2 "$fmt" "$@"
|
||||
fi
|
||||
exit $ec
|
||||
}
|
||||
std::parse_yaml() {
|
||||
#
|
||||
# parse a YAML file
|
||||
# See: https://gist.github.com/pkuczynski/8665367
|
||||
#
|
||||
local -r fname="$1"
|
||||
local -r prefix="$2"
|
||||
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
|
||||
sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
|
||||
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "${fname}" |
|
||||
awk -F$fs '{
|
||||
indent = length($1)/2;
|
||||
vname[indent] = $2;
|
||||
for (i in vname) {
|
||||
if (i > indent) {delete vname[i]}
|
||||
}
|
||||
if (length($3) > 0) {
|
||||
vn="";
|
||||
for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
|
||||
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
read_config_file() {
|
||||
@@ -477,13 +530,6 @@ build::install() {
|
||||
> "${PREFIX}/bin/modbuild"
|
||||
chmod 0755 "${PREFIX}/bin/modbuild"
|
||||
|
||||
sed "${sed_cmd}" "${SRC_DIR}/modmanage.in" \
|
||||
> "${PREFIX}/bin/modmanage"
|
||||
chmod 0755 "${PREFIX}/bin/modmanage"
|
||||
sed "${sed_cmd}" "${SRC_DIR}/modmanage.bash.in" \
|
||||
> "${PREFIX}/libexec/modmanage.bash"
|
||||
chmod 0755 "${PREFIX}/libexec/modmanage.bash"
|
||||
|
||||
test -e "${INSTALL_ROOT}/${CONFIG_FILE}" || \
|
||||
install -m 0644 "$_" "${INSTALL_ROOT}/${CONFIG_DIR}"
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
DefaultGroups: Tools:Programming
|
||||
DefaultReleaseStages: stable
|
||||
ReleaseStages: unstable:stable:deprecated
|
||||
TmpDir: @PMODULES_TMPDIR@
|
||||
DistfilesDir: @PMODULES_DISTFILESDIR@
|
||||
SysCollectionsDir: @INSTALL_ROOT@/collections
|
||||
Overlays:
|
||||
base:
|
||||
install_root: @INSTALL_ROOT@
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ cd 'CPP/7zip/Bundles/Alone2'
|
||||
#---
|
||||
# compile & install
|
||||
make -j -f ../../cmpl_gcc.mak
|
||||
cp b/g/7zz "${PREFIX}/${UTILBIN_DIR}"
|
||||
cp b/g/7zz "${PREFIX}/${UTILBIN_DIR}/sevenz"
|
||||
|
||||
#---
|
||||
# post-install
|
||||
|
||||
Reference in New Issue
Block a user