#!/bin/bash #set -x # The directory where the 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 pmodule_environment='environment.bash' 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). --with=P/V Preload module P with version V. To preload multiple modules, use this option per module. Nete that 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 } # setup PATH PATH='/usr/bin:/bin:/usr/sbin:/sbin' declare -r OS=$(uname -s) if [[ "${OS}" == "Darwin" ]]; then # :FIXME: why do we need this? [[ -d "/opt/X11/bin" ]] && PATH+=':/opt/X11/bin' fi PATH+="${mydir}" # # 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 gdate 2>/dev/null || : ) if [[ $__path ]]; then alias date=$__path else alias date=$(which date 2>/dev/null) fi __path=$(which ginstall 2>/dev/null || : ) if [[ $__path ]]; then alias install=$__path else alias install=$(which install 2>/dev/null) fi __path=$(which greadlink 2>/dev/null || : ) if [[ $__path ]]; then alias readlink=$__path else alias readlink=$(which readlink 2>/dev/null) fi __path=$(which gsed 2>/dev/null || : ) if [[ $__path ]]; then alias sed=$__path else alias sed=$(which sed 2>/dev/null) fi declare ok=1 ############################################################################## # source BASH library with standard functions 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 # debug_on='no' force_rebuild='no' dry_run='no' enable_cleanup_build='yes' enable_cleanup_src='no' target='all' # array collecting all modules specified on the command line via '--with=module' with_modules=() # save arguments for building dependencies declare -rx ARGS="$@" # while (( $# > 0 )); do case $1 in -j ) JOBS=$2 shift ;; --jobs=[0-9]* ) JOBS=${1/--jobs=} ;; -v | --verbose | --debug ) debug_on='yes' ;; -f | --force-rebuild ) force_rebuild='yes' ;; -\? | -h | --help ) usage ;; --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' ;; --dry-run ) dry_run='yes' ;; --release=* ) MODULE_RELEASE=${1/--release=} ;; --with=*/* ) with_modules+=( ${1/--with=} ) ;; --prep | --configure | --compile | --install | --all ) target=$1 ;; [0-9]* ) V=$1 ;; * ) declare -rx BUILD_BLOCK=$(std::get_abspath "$1") declare -rx 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!" # source Pmodule environment configuration if [[ -r ${BUILD_BLOCK_DIR}/../config/${pmodule_environment} ]]; then # we are bootstrapping source "${BUILD_BLOCK_DIR}/../config/${pmodule_environment}" declare -rx BUILD_BASEDIR=$(std::get_abspath "${BUILD_BLOCK_DIR}/..") bootstrap='yes' elif [[ -n ${PMODULES_ROOT} ]] && [[ -n ${PMODULES_CONFIG_DIR} ]] && \ [[ -r ${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/${pmodule_environment} ]]; then source ${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/${pmodule_environment} declare -rx BUILD_BASEDIR=$(std::get_abspath "${BUILD_BLOCK_DIR}/../../..") bootstrap='no' else std::die 3 "Build environment not setup properbly!" fi declare -xr BUILD_CONFIGDIR="${BUILD_BASEDIR}/config" declare -xr BUILD_SCRIPTSDIR="${BUILD_BASEDIR}/scripts" declare -xr BUILD_TMPDIR="${BUILD_BASEDIR}/tmp" declare -xr BUILD_DOWNLOADSDIR="${BUILD_BASEDIR}/Downloads" declare -xr BUILD_VERSIONSFILE="${BUILD_CONFIGDIR}/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" # Unset all PATH's and FLAGS's which might be used by a compiler. # This includes C_INCLUDE_PATH, CFLAGS etc. pbuild::cleanup_env # load all modules passed with the '--with' argument if [[ ${bootstrap} == no ]]; then # we aren't bootstraping if [[ -r "${BUILD_BLOCK_DIR}/with_modules-$V" ]]; then with_modules+=( $(cat "${BUILD_BLOCK_DIR}/with_modules-$V") ) elif [[ -r "${BUILD_BLOCK_DIR}/with_modules" ]]; then with_modules+=( $(cat "${BUILD_BLOCK_DIR}/with_modules") ) fi source "${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/profile.bash" MODULECMD="${PMODULES_HOME}/bin/modulecmd" [[ -x ${MODULECMD} ]] || std::die 1 "${MODULECMD}: no such executable" module purge module use unstable # :FIXME: this is a hack!!! module use Libraries for m in "${with_modules[@]}"; do if pbuild::module_is_available "$m"; then echo "Loading module: ${m}" module load "${m}" else std::die 44 "$m: module not available!" fi done else # the module command is not yet available... unset PMODULES_HOME unset PMODULES_VERSION std::read_versions "${BUILD_BASEDIR}/config/versions.conf" fi P=$(basename $(dirname "${BUILD_BLOCK}")) P=${P%.*} _P=$(echo $P | tr [:lower:] [:upper:]) _P=${_P//-/_} _V=${_P}_VERSION if [[ -n ${PMODULES_DEFINED_RELEASES} ]]; then declare -r releases="${PMODULES_DEFINED_RELEASES}" else # set defaults, if file doesn't exist or isn't readable declare -r releases=":unstable:stable:deprecated:" fi # # run build # source "${BUILD_BLOCK}" # Local Variables: # mode: sh # sh-basic-offset: 8 # tab-width: 8 # End: