Files
Pmodules/Pmodules/modbuild
T

389 lines
7.9 KiB
Bash
Executable File

#!/bin/bash
# The directory where this programm is installed will be added to PATH and
# to the search path of BASH libraries.
declare -r mydir=$(dirname "$0")
declare -r libpbuild='libpbuild.bash'
declare -r libstd='libstd.bash'
declare -r pmodules_build_config='modbuild.conf'
declare -ra bash_libpath=("${mydir}" "${mydir}/../lib")
##############################################################################
#
# set an error handler. If a function _exit() exists, it will be called
# with the passed exit code.
#
# $1 exit code
#
set -o errexit
_exit() {
:
}
error_handler() {
local -i ec=$?
_exit ${ec}
exit ${ec}
}
trap "error_handler" ERR
# disable auto-echo feature of 'cd'
unset CDPATH
##############################################################################
#
usage() {
std::error "
Usage: $0 [OPTIONS..] [BUILD_BLOCK] [VERSION]
VERSION
Version of module to compile.
-? | -h | --help
Print usage
-v | --verbose )
Verbose output
-j N | --jobs=N
Run N parallel make jobs
-f | --force-rebuild
Force rebuild of module.
--dry-run
Dry run.
--enable-cleanup-build
Cleanup files in the build directory (default).
--enable-cleanup-src
Cleanup files in the source directory.
--disable-cleanup
Keep files in build and source directory
--disable-cleanup-build
Keep files in build directory.
--disable-cleanup-src
Keep files in source directory (default).
--variants-file
Specify which variants file to use
--with=P/V
Preload module P with version V. To preload multiple modules,
use this option per module. Order may matter!
--release=stable|unstable|deprecated
--prep
Unpack sources only.
--configure
Unpack sources and configure build.
--compile
Unpack sources, configure build and compile software
--install
Unpack sources, configure build, compile software and install.
--all
Do everything, this step includes cleanup files and setting
the symbolic link to the modulefile.
"
exit 1
}
#
# We need GNU versions of the following utilities. This code works
# well on Linux and Mac OS X with MacPorts.
# :FIXME: implement a smarter, portable solution.
#
shopt -s expand_aliases
unalias -a
__path=$(which gsed 2>/dev/null || : )
if [[ $__path ]]; then
alias sed=$__path
else
alias sed=$(which sed 2>/dev/null)
fi
##############################################################################
#
# source BASH library with standard functions
declare ok=1
for dir in "${bash_libpath[@]}"; do
if [[ -r ${dir}/${libstd} ]]; then
source "${dir}/${libstd}"
ok=0
break
fi
done
if (( ok != 0 )); then
echo "Oops: required BASH library '${libstd}' not found" 1>&2
exit 1
fi
##############################################################################
#
# parse arguments
#
# number of parallel make jobs
declare -i JOBS=3
declare debug_on='no'
declare force_rebuild='no'
declare dry_run='no'
declare enable_cleanup_build='yes'
declare enable_cleanup_src='no'
declare target=''
declare bootstrap='no'
declare variants_file=''
# array collecting all modules specified on the command line via '--with=module'
with_modules=()
# save arguments, we might need later again
declare -r ARGS="$@"
# OS/system default
declare OS=$(uname -s)
#
while (( $# > 0 )); do
case $1 in
-j )
JOBS=$2
shift
;;
--jobs=[0-9]* )
JOBS=${1/--jobs=}
;;
-v | --verbose )
debug_on='yes'
;;
--debug )
set -x
;;
-f | --force-rebuild )
force_rebuild='yes'
;;
-\? | -h | --help )
usage
;;
--dry-run )
dry_run='yes'
;;
--disable-cleanup )
enable_cleanup_build='no'
enable_cleanup_src='no'
;;
--enable-cleanup-build )
enable_cleanup_build='yes'
;;
--disable-cleanup-build )
enable_cleanup_build='no'
;;
--enable-cleanup-src )
enable_cleanup_src='yes'
;;
--disable-cleanup-src )
enable_cleanup_src='no'
;;
--distdir )
PMODULES_DISTFILESDIR=$2
shift
;;
--distdir=* )
PMODULES_DISTFILESDIR=${1/--distdir=}
;;
--tmpdir )
PMODULES_TMPDIR=$2
shift
;;
--tmpdir=* )
PMODULES_TMPDIR=${1/--tmpdir=}
;;
--variants-file )
variants_file="$2"
shift
;;
--variants-file=* )
variants_file="${1/--variants-file=}"
;;
--with )
with_modules+=( "$2" )
shift
;;
--with=*/* )
m="${1/--with=}"
with_modules+=( ${m} )
;;
--prep | --configure | --compile | --install | --all )
target=${1:2}
;;
--system )
OS="$2"
shift
;;
--system=* )
OS="${1/--system=}"
;;
--version | -V )
V=$2
shift
;;
--version= )
V=${1/--version=}
;;
--bootstrap )
bootstrap='yes'
;;
[0-9]* )
V=$1
;;
* )
declare -r BUILD_BLOCK=$(std::get_abspath "$1")
declare -r BUILD_BLOCK_DIR=$(dirname "${BUILD_BLOCK}")
;;
esac
shift
done
if [[ ${debug_on} == yes ]]; then
trap 'echo "$BASH_COMMAND"' DEBUG
fi
[[ -n ${BUILD_BLOCK} ]] || std::die 1 "No build-block specified!"
[[ -r ${BUILD_BLOCK} ]] || std::die 1 "${BUILD_BLOCK}: no such file!"
declare -r OS
# assemble default path. We have to do this here, before
# including the modbuild configuration file.
PATH="/usr/bin:/bin:/usr/sbin:/sbin:${PMODULES_DIR}/bin"
# source Pmodule environment configuration
if [[ "${bootstrap}" == "yes" ]]; then
[[ -r ${BUILD_BLOCK_DIR}/../config/${pmodules_build_config} ]] || \
std::die 1 "Cannot read configuration file!"
source "${BUILD_BLOCK_DIR}/../config/${pmodules_build_config}"
declare -r BUILD_BASEDIR=$(std::get_abspath "${BUILD_BLOCK_DIR}/..")
elif [[ -n "${PMODULES_ROOT}" ]] && [[ -n "${PMODULES_CONFIG_DIR}" ]] && \
[[ -r "${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/modbuild.conf" ]]; then
source "${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/modbuild.conf"
declare -r BUILD_BASEDIR=$(std::get_abspath "${BUILD_BLOCK_DIR}/../..")
else
std::die 3 "Build environment not setup properbly!"
fi
: ${PMODULES_TMPDIR:="${BUILD_BASEDIR}/tmp"}
: ${PMODULES_DISTFILESDIR:="${BUILD_BASEDIR}/Downloads"}
declare -x PMODULES_TMPDIR
declare -x PMODULES_DISTFILESDIR
mkdir -p "${PMODULES_DISTFILESDIR}"
declare -r BUILD_SCRIPTSDIR="${BUILD_BASEDIR}/scripts"
declare -r BUILD_VERSIONSFILE="${BUILD_BASEDIR}/config/versions.conf"
# source BASH library with standard functions
((ok=1))
for dir in "${bash_libpath[@]}"; do
if [[ -r ${dir}/${libpbuild} ]]; then
source "${dir}/${libpbuild}"
ok=0
break
fi
done
(( ok == 0 )) || std::die 3 "Oops: required BASH library '${libpbuild}' not found"
if [[ ${bootstrap} == no ]]; then
if [[ -n "${variants_file}" ]]; then
if [[ ! -r "${variants_file}" ]]; then
std::die 1 "${variants_file}: variants file does not exist or is not readable!"
fi
else
search_variants_file || std::die 2 "No usable variants file found!"
fi
# initialize module environment
MODULECMD="${PMODULES_HOME}/bin/modulecmd"
[[ -x ${MODULECMD} ]] || std::die 1 "${MODULECMD}: no such executable"
eval $( "${MODULECMD}" bash purge )
eval $( "${MODULECMD}" bash use unstable )
eval $( "${MODULECMD}" bash use deprecated )
# :FIXME: this is a hack!!!
eval $( "${MODULECMD}" bash use Libraries )
# if version is not specified, use version from last line of variants file
if [[ -z "$V" ]]; then
declare tmp=$(awk 'END{print $1}' "${variants_file}")
V="${tmp#*/}"
fi
else
unset PMODULES_HOME
unset PMODULES_VERSION
std::read_versions "${BUILD_BASEDIR}/config/versions.conf"
if [[ -z ${V} ]]; then
_P=$(echo $P | tr [:lower:] [:upper:])
_P=${_P//-/_}
_V=${_P}_VERSION
V=${!_V}
fi
fi
declare V_MAJOR=''
declare V_MINOR=''
declare V_PATCHLVL=''
declare V_PKG="${V%%-*}"
declare V_RELEASE="${V#*-}"
declare tmp="${V_PKG}"
case "${tmp}" in
*.*.* )
V_MAJOR="${tmp%%.*}"
tmp="${tmp#*.}"
V_MINOR="${tmp%%.*}"
V_PATCHLVL="${tmp#*.}"
;;
*.* )
V_MAJOR="${tmp%.*}"
V_MINOR="${tmp#*.}"
;;
* )
V_MAJOR="${tmp}"
;;
esac
P=$(basename $(dirname "${BUILD_BLOCK}"))
[[ -z ${V} ]] && std::die 1 "Module version must be specified on command line!"
#
# run build
#
source "${BUILD_BLOCK}"
std::info "${P}/${V}: Done ..."
# Local Variables:
# mode: sh
# sh-basic-offset: 8
# tab-width: 8
# End: