Files
Pmodules/build
T
2020-10-30 18:25:47 +01:00

529 lines
14 KiB
Python
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
#
if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then
echo "BASH version >= 4 is required and must be available in PATH!" 1>&2
exit 1
fi
declare BOOTSTRAP_DIR=$(dirname "$0")
source "${BOOTSTRAP_DIR}/Pmodules/libstd.bash" || { echo "Oops!" 1>&2; exit 42; }
declare -r BOOTSTRAP_DIR=$(std::get_abspath "${BOOTSTRAP_DIR}")
declare -r SRC_DIR="${BOOTSTRAP_DIR}/Pmodules"
# these variables need to be defined but must be initialized with an empty string
declare -x PMODULES_ROOT=''
PMODULES_HOME=''
declare -x PMODULES_DISTFILESDIR=''
declare -x PMODULES_TMPDIR=''
declare -rx CONFIG_DIR='config'
declare -rx CONFIG_FILE='modbuild.conf'
# defaults
declare -rx DEFAULT_PMODULES_ROOT='/opt/psi'
declare -rx DEFAULT_DISTFILES_DIR="var/distfiles"
declare -rx DEFAULT_VERSIONS_CONFIG="${CONFIG_DIR}/versions.conf"
declare -rx DEFAULT_TMPDIR='var/tmp/${USER}'
#-----------------------------------------------------------------------------
#
get_version() {
local -r name="$1"
echo $(awk "/^$1[[:blank:]]/ {print \$2}" "${DEFAULT_VERSIONS_CONFIG}")
}
declare -rx PMODULES_VERSION=$(get_version 'Pmodules')
#-----------------------------------------------------------------------------
#
usage() {
echo "
build [OPTIONS] configure|compile|install
"
std::die 1 ""
}
#-----------------------------------------------------------------------------
#
pmodules::help_help() {
echo "Usage:
$(basename $0) help help|configure|compile|install
"
std::die 1 ""
}
#-----------------------------------------------------------------------------
#
pmodules::help() {
if (( $# > 1 )); then
pmodules::help_help
fi
case $1 in
help|configure|compile|install )
pmodules::help_$1
;;
* )
pmodules::help_help
;;
esac
}
#-----------------------------------------------------------------------------
#
read_config_file() {
local var="$1"
local fname="${!var}"
if [[ -n "${fname}" ]] && [[ -n "${PMODULES_ROOT}" ]]; then
std::die 1 "You cannot use the options '--config' and '--pmodules-root at the same time!"
fi
if [[ -n "${PMODULES_ROOT}" ]]; then
fname="${PMODULES_ROOT}/${CONFIG_DIR}/${CONFIG_FILE}"
elif [[ -n "${fname}" ]]; then
:
else
fname="${BOOTSTRAP_DIR}/${CONFIG_DIR}/${CONFIG_FILE}"
fi
if [[ ! -r "${fname}" ]]; then
std::die 1 "Configuration file '${fname}' does not exist or is not readable!"
fi
source "${fname}" || std::die 1 "Cannot read configuration file '${fname}'"
# we have to make these variables global, otherwise they are not set
# in the calling function
declare -g PMODULES_ROOT="${PMODULES_ROOT}"
declare -g PMODULES_HOME="${PMODULES_HOME}"
declare -g PMODULES_DISTFILESDIR="${PMODULES_DISTFILESDIR}"
declare -g PMODULES_TMPDIR="${PMODULES_TMPDIR}"
if [[ -z "${PMODULES_ROOT}" ]]; then
std::die 1 "Error in configuration file '${fname}': PMODULE_ROOT not defined!"
fi
if [[ -z "${PMODULES_VERSION}" ]]; then
std::die 1 "Error in configuration file '${fname}': PMODULE_VERSION not defined!"
fi
if [[ -z "${PMODULES_DISTFILESDIR}" ]]; then
std::die 1 "Error in configuration file '${fname}': PMODULES_DISTFILESDIR not defined!"
fi
if [[ -z "${PMODULES_TMPDIR}" ]]; then
std::die 1 "Error in configuration file '${fname}': PMODULE_TMPDIR not defined!"
fi
std::upvar "${var}" "${fname}"
}
#-----------------------------------------------------------------------------
#
pmodules::help_configure() {
echo "
Usage: $(basename $0) configure [OPTION...]
Configure and setup a new Pmodules environment. You need permissions
to write to the installation root.
Options:
--config=FILE
Specify a different configuration filename to create. This option
can be used if you want to install multiple Pmodules environments
on the same system. The file will actually be created as a sym-
bolic link in
'${BOOTSSTRAP_DIR}/config'
to
'\${PMODULES_ROOT}/config/modbuild.conf'
Whereby '\${PMODULES_ROOT}' is the root of the Pmodules environment.
The default is '${DEFAULT_MODBUILD_CONFIG}'.
--pmodules-root=DIR
Root of the Pmodules environment installation. Everything will be
installed in a directory hierarchy with 'DIR' as prefix.
The default is '${DEFAULT_PMODULES_ROOT}'.
--distfilesdir=DIR
Directory where downloaded files are stored.
The default is '${DEFAULT_PMODULES_DISTFILESDIR}' in the
Pmodules root directory.
--tmpdir=DIR
Directory for temporary files.
The default is '${DEFAULT_PMODULES_TMPDIR}'
--help
Print this help text.
" 1>&2
std::die 1 ""
}
#-----------------------------------------------------------------------------
#
pmodules::configure() {
local pmodules_root="${DEFAULT_PMODULES_ROOT}"
local distfilesdir=''
local tmpdir=''
local config_file=''
local opt_force='no'
while (( $# > 0 )); do
case "$1" in
--config )
config_file="$2"
shift 1
;;
--config=* )
config_file="${1#*=}"
;;
--pmodules-root )
pmodules_root="$2"
shift 1
;;
--pmodules-root=* )
pmodules_root="${1#*=}"
;;
--distfilesdir )
distfilesdir="$2"
shift 1
;;
--distfilesdir=* )
distfilesdir="${1#*=}"
;;
-f | --force )
opt_force='yes'
;;
--tmpdir )
tmpdir="$2"
shift 1
;;
--tmpdir=* )
tmpdir="${1#*=}"
;;
--help | -h | -\? )
pmodules::help_configure
;;
-* )
std::die 1 "$1: illegal option"
;;
* )
std::die 1 "$1: illegal argument to sub-command 'configure'."
;;
esac
shift 1
done
if [[ -n "${config_file}" ]]; then
config_file=$(std::get_abspath "${config_file}")
if [[ $(dirname "${config_file}") != "${BOOTSTRAP_DIR}/${CONFIG_DIR}" ]]; then
echo "Invalid directory for The configuration file." 1>&2
std::die 1 "The configuration file must be in '${BOOTSTRAP_DIR}/${CONFIG_DIR}'!"
fi
else
config_file="${BOOTSTRAP_DIR}/${CONFIG_DIR}/${CONFIG_FILE}"
fi
if [[ ! -d ${pmodules_root} ]]; then
echo "The root directory '${pmodules_root}' does not exist, trying to create it..."
if ! mkdir -p "${pmodules_root}"; then
std::die 1 "Creating the root directory failed!\nAborting..."
fi
fi
if [[ ! -w ${pmodules_root} ]]; then
std::die 1 "The root directory '${pmodules_root}' is not writable!\nAborting..."
fi
mkdir -p "${pmodules_root}/${CONFIG_DIR}" || \
std::die 1 "Aborting..."
if [[ "${opt_force}" == 'yes' ]]; then
rm -f "${config_file}"
fi
if [[ -L "${config_file}" ]]; then
std::die 1 "The Pmodules environment has already been configured!
Use the option --force to override.\nAborting..."
fi
[[ -z "${distfilesdir}" ]] && distfilesdir="${pmodules_root}/${DEFAULT_DISTFILES_DIR}"
[[ -z "${tmpdir}" ]] && tmpdir="${pmodules_root}/${DEFAULT_TMPDIR}"
sed_cmd="s:@PMODULES_ROOT@:${pmodules_root}:g;"
sed_cmd+="s:@PMODULES_DISTFILESDIR@:${distfilesdir}:g;"
sed_cmd+="s:@PMODULES_TMPDIR@:${tmpdir}:g;"
sed_cmd+="s:@PMODULES_VERSION@:${PMODULES_VERSION}:g"
sed "${sed_cmd}" "${BOOTSTRAP_DIR}/${CONFIG_DIR}/${CONFIG_FILE}.in" \
> "${pmodules_root}/${CONFIG_DIR}/${CONFIG_FILE}" || \
std::die 1 "Cannot create configuration file in Pmodules root\nAborting..."
ln -s "${pmodules_root}/${CONFIG_DIR}/${CONFIG_FILE}" \
"${config_file}" || \
std::die 1 "Aborting..."
read_config_file 'config_file'
install -d -m 0755 "${PMODULES_HOME}/bin"
install -d -m 0755 "${PMODULES_HOME}/config"
install -d -m 0755 "${PMODULES_HOME}/init"
install -d -m 0755 "${PMODULES_HOME}/lib"
install -d -m 0755 "${PMODULES_HOME}/libexec"
install -d -m 0755 "${PMODULES_HOME}/sbin"
echo "Configuration:"
echo " root of Pmodules environment: ${pmodules_root}"
echo " Pmodule prefix: ${PMODULES_HOME}"
echo " tmp directory: ${tmpdir}"
echo " store for downloaded files: ${distfilesdir}"
echo "Done..."
}
#-----------------------------------------------------------------------------
#
pmodules::help_compile() {
echo "Usage:
$(basename $0) compile [OPTION...]
"
std::die 1 ""
}
pmodules::compile() {
build () {
local -r name="$1"
local -r version=$(get_version "${name}")
shift
"${BOOTSTRAP_DIR}/Pmodules/modbuild" \
"--config=${config_file}" \
"--enable-cleanup" \
"--force-rebuild" \
"${BOOTSTRAP_DIR}/Tools/${name}/build" \
"${build_opts[@]}" "$@" "${version}" || \
std::die 3 "Compiling '${name}' failed!"
}
local opt_force='no'
local config_file=''
while (( $# > 0 )); do
case $1 in
--disable-cleanup )
build_opts+=( "$1" )
;;
--debug )
build_opts+=( "$1" )
;;
--config )
config_file=$(std::get_abspath "$2")
shift 1
;;
--config=* )
config_file=$(std::get_abspath "${1#*=}")
;;
--pmodules-root )
PMODULES_ROOT="$2"
shift 1
;;
--pmodules-root=* )
PMODULES_ROOT="${1#*=}"
;;
-f | --force )
opt_force='yes'
;;
-* )
std::die 1 "$1: illegal option"
;;
* )
std::die 1 "$1: illegal argument for sub-command 'compile'."
;;
esac
shift 1
done
echo "Configuration:"
echo " root of Pmodules environment: ${pmodules_root}"
echo " Pmodule prefix: ${PMODULES_HOME}"
read_config_file config_file
if [[ ! -f "${PMODULES_HOME}/sbin/base64" ]] || [[ ${opt_force} == 'yes' ]]; then
build coreutils
fi
if [[ ! -f "${PMODULES_HOME}/sbin/xgettext" ]] || [[ ${opt_force} == 'yes' ]]; then
build gettext
fi
if [[ ! -f "${PMODULES_HOME}/sbin/getopt" ]] || [[ ${opt_force} == 'yes' ]]; then
build getopt
fi
if [[ ! -f "${PMODULES_HOME}/sbin/bash" ]] || [[ ${opt_force} == 'yes' ]]; then
build bash
fi
if [[ ! -e "${PMODULES_HOME}/sbin/tclsh" ]] || [[ ${opt_force} == 'yes' ]]; then
build Tcl
fi
if [[ ! -e "${PMODULES_HOME}/libexec/modulecmd.bin" ]] || [[ ${opt_force} == 'yes' ]]; then
build modules
fi
echo "Done..."
}
#-----------------------------------------------------------------------------
#
pmodules::help_install() {
echo "Usage:
$(basename $0) install [OPTION...]
"
std::die 1 ""
}
pmodules::install() {
local config_file=''
local opt_force='no'
while (( $# > 0 )); do
case $1 in
--debug )
set -x
;;
--config )
config_file="$2"
shift 1
;;
--config=* )
config_file="${1#*=}"
;;
--debug )
set -x
;;
--pmodules-root )
PMODULES_ROOT="$2"
shift 1
;;
--pmodules-root=* )
PMODULES_ROOT="${1#*=}"
;;
-f | --force )
opt_force='yes'
;;
-* )
std::die 1 "$1: illegal option"
;;
* )
std::die 1 "$1: illegal argument to sub-command 'install'."
;;
esac
shift 1
done
read_config_file 'config_file'
###
#
# begin installation
#
echo "Configuration:"
echo " root of Pmodules environment: ${PMODULES_ROOT}"
echo " Pmodule prefix: ${PMODULES_HOME}"
sed_cmd="s:@PMODULES_HOME@:${PMODULES_HOME}:g;"
sed_cmd+="s:@PMODULES_VERSION@:${PMODULES_VERSION}:g;"
sed_cmd+="s:@MODULES_VERSION@:${MODULES_VERSION}:g;"
sed_cmd+="s:@PMODULES_DISTFILESDIR@:${PMODULES_DISTFILESDIR}:g;"
sed_cmd+="s:@PMODULES_TMPDIR@:${PMODULES_TMPDIR}:g;"
sed_cmd+="s:@TCLSHDIR@:${PMODULES_HOME}/sbin:g;"
sed_cmd+="s:@pager@::g;"
sed_cmd+="s:@pageropts@::g;"
sed_cmd+="s:@etcdir@:/opt/psi/config:g;"
sed_cmd+="s:@VERSIONING@:#:g;"
sed_cmd+="s:@prefix@:${PMODULES_HOME}:g;"
sed_cmd+="s:@initdir@:${PMODULES_HOME}/init:g;"
sed_cmd+="s:@MODULES_RELEASE@:${PMODULES_VERSION}:g;"
sed "${sed_cmd}" "${SRC_DIR}/profile.bash.in" > "${PMODULES_ROOT}/${CONFIG_DIR}/profile.bash-${PMODULES_VERSION}"
sed "${sed_cmd}" "${SRC_DIR}/profile.csh.in" > "${PMODULES_ROOT}/${CONFIG_DIR}/profile.csh-${PMODULES_VERSION}"
sed "${sed_cmd}" "${SRC_DIR}/profile.zsh.in" > "${PMODULES_ROOT}/${CONFIG_DIR}/profile.zsh-${PMODULES_VERSION}"
chmod 0644 "${PMODULES_ROOT}/${CONFIG_DIR}"/*-${PMODULES_VERSION}
test -e "${PMODULES_ROOT}/${CONFIG_DIR}/profile.bash" || \
install -m 0644 "$_-${PMODULES_VERSION}" "$_"
test -e "${PMODULES_ROOT}/${CONFIG_DIR}/profile.csh" || \
install -m 0644 "$_-${PMODULES_VERSION}" "$_"
test -e "${PMODULES_ROOT}/${CONFIG_DIR}/profile.zsh" || \
install -m 0644 "$_-${PMODULES_VERSION}" "$_"
sed "${sed_cmd}" "${SRC_DIR}/modulecmd.bash.in" > "${PMODULES_HOME}/libexec/modulecmd.bash"
chmod 0755 "${PMODULES_HOME}/libexec/modulecmd.bash"
sed "${sed_cmd}" "${SRC_DIR}/modulecmd.tcl.in" > "${PMODULES_HOME}/libexec/modulecmd.tcl"
chmod 0755 "${PMODULES_HOME}/libexec/modulecmd.tcl"
sed "${sed_cmd}" "${SRC_DIR}/modbuild.in" > "${PMODULES_HOME}/bin/modbuild"
chmod 0755 "${PMODULES_HOME}/bin/modbuild"
sed "${sed_cmd}" "${SRC_DIR}/modmanage.bash.in" > "${PMODULES_HOME}/libexec/modmanage.bash"
chmod 0755 "${PMODULES_HOME}/libexec/modmanage.bash"
install -m 0755 "${SRC_DIR}/modulecmd" "${PMODULES_HOME}/bin"
install -m 0755 "${SRC_DIR}/modmanage" "${PMODULES_HOME}/bin"
install -m 0644 "${SRC_DIR}/bash" "${PMODULES_HOME}/init"
install -m 0644 "${SRC_DIR}/bash_completion" "${PMODULES_HOME}/init"
install -m 0644 "${SRC_DIR}/csh" "${PMODULES_HOME}/init"
install -m 0644 "${SRC_DIR}/zsh" "${PMODULES_HOME}/init"
install -m 0644 "${SRC_DIR}/libpmodules.bash" "${PMODULES_HOME}/lib"
install -m 0644 "${SRC_DIR}/libpbuild.bash" "${PMODULES_HOME}/lib"
install -m 0644 "${SRC_DIR}/libpbuild_dyn.bash" "${PMODULES_HOME}/lib"
install -m 0644 "${SRC_DIR}/libstd.bash" "${PMODULES_HOME}/lib"
install -m 0755 -d "${PMODULES_HOME}/lib/Pmodules"
install -m 0644 "${SRC_DIR}/libmodules.tcl" "${PMODULES_HOME}/lib/Pmodules"
{
PATH="${PMODULES_HOME}/sbin:${PATH}"
cd "${PMODULES_HOME}/lib/Pmodules"
"${BOOTSTRAP_DIR}/mkindex.tcl"
}
mkdir -p "${PMODULES_ROOT}/Tools/modulefiles"
mkdir -p "${PMODULES_ROOT}/Libraries/modulefiles"
echo "Done..."
}
#=============================================================================
#
declare -a build_opts=()
build_opts+=( '--bootstrap' )
declare subcmd=''
declare -a subcmd_args=()
while (( $# > 0 )); do
case "$1" in
--help | -h | -\? )
usage
;;
--debug )
set -x
;;
-* )
std::die 1 "$1: illegal option"
;;
help | configure | compile | install )
subcmd="$1"
shift 1
subcmd_args=( "$@" )
shift $#
;;
* )
std::die 1 "$1: Unknown sub-command."
;;
esac
shift 1
done
[[ -n "${subcmd}" ]] || std::die 1 "Missing sub-command.\n\nUse 'build --help' to get some help..."
if [[ "${SRC_DIR}/modbuild" -ot "${SRC_DIR}/modbuild.in" ]]; then
sed "${sed_cmd}" "${SRC_DIR}/modbuild.in" > "${SRC_DIR}/modbuild"
chmod 0755 "${SRC_DIR}/modbuild"
fi
pmodules::${subcmd} "${subcmd_args[@]}"