#!/bin/bash # desc: # stages, builds, installs # make variables persist in subprocesses for logging function set -a # ---------------------------------------------------------------------- # Configuration: # ---------------------------------------------------------------------- # the name of this application APPNAME="binutils" # the version of this application #VERSION="2.25" VERSION="2.40" # ---------------------------------------------------------------------- # Variables and functions sourced from Environment: # ---------------------------------------------------------------------- # assert_zero() # Checks if $1 is 0. If non-0 value, halts the execution of the script. # # LOGS_ROOT # The parent directory where logs from this project will go. # # TEMP_STAGE_DIR # The parent directory of where source archives are extracted to. # register mode selections ARGUMENT_LIST=( "stage" "build_pass1" "install_pass1" "pass1" "build_pass2" "install_pass2" "pass2" "help" ) # modes to associate with switches # assumes you want nothing done unless you ask for it. MODE_STAGE=false MODE_BUILD_PASS1=false MODE_INSTALL_PASS1=false MODE_PASS1=false MODE_BUILD_PASS2=false MODE_INSTALL_PASS2=false MODE_PASS2=false MODE_HELP=false # the file to log to LOGFILE="${APPNAME}.log" # ISO 8601 variation TIMESTAMP="$(date +%Y-%m-%d_%H:%M:%S)" # the path where logs are written to # note: LOGS_ROOT is sourced from environment LOG_DIR="${dir_logs}/${APPNAME}-${TIMESTAMP}" # the path where the source will be located when complete # note: TEMP_STAGE_DIR is sourced from environment T_SOURCE_DIR="${TEMP_STAGE_DIR}/${APPNAME}" # read defined arguments opts=$(getopt \ --longoptions "$(printf "%s," "${ARGUMENT_LIST[@]}")" \ --name "$APPNAME" \ --options "" \ -- "$@" ) # sourced from environment TEMP_STAGE_DIR=${TEMP_STAGE_DIR} whoami ls -l ${TEMP_STAGE_DIR}/../ | grep ${TEMP_STAGE_DIR} mkdir -p ${TEMP_STAGE_DIR} # process supplied arguments into flags that enable execution modes eval set --$opts while [[ $# -gt 0 ]]; do case "$1" in --stage) MODE_STAGE=true shift 1 ;; --build_pass1) MODE_BUILD_PASS1=true shift 1 ;; --install_pass1) MODE_INSTALL_PASS1=true shift 1 ;; --pass1) MODE_PASS1=true shift 1 ;; --build_pass2) MODE_BUILD_PASS2=true shift 1 ;; --install_pass2) MODE_INSTALL_PASS2=true shift 1 ;; --pass2) MODE_PASS2=true shift 1 ;; --help) MODE_HELP=true shift 1 ;; *) break ;; esac done # print to stdout, print to log logprint() { mkdir -p "${LOG_DIR}" echo "[$(date +%Y-%m-%d_%H:%M:%S)] [${APPNAME}] $1" \ | tee -a "${LOG_DIR}/${LOGFILE}" } # Tell the user we're alive... logprint "Initializing the ${APPNAME} utility..." # when the stage mode is enabled, this will execute mode_stage() { logprint "Starting stage of ${APPNAME}..." logprint "Removing any pre-existing staging for ${APPNAME}." rm -Rf "${T_SOURCE_DIR}"* logprint "Extracting ${APPNAME}-${VERSION} source archive to ${TEMP_STAGE_DIR}" tar xf "${SOURCES_DIR}/${APPNAME}-${VERSION}.tar."* -C "${TEMP_STAGE_DIR}" \ || $( logprint "Couldn't locate source tarball. Did you run \`make download_sources\`?" \ && assert_zero 127 ) logprint "Extraction complete...Renaming directory " # conditionally rename if it needs it stat "${T_SOURCE_DIR}-"* && mv "${T_SOURCE_DIR}-"* "${T_SOURCE_DIR}" assert_zero $? logprint "Staging operation complete." } # when the build_pass1 mode is enabled, this will execute mode_build_pass1() { logprint "Starting build of ${APPNAME}..." logprint "Entering build dir." pushd "${T_SOURCE_DIR}" # sourced from environment: checks $? -- aborts script execution if non-zero assert_zero $? mkdir -p build pushd build assert_zero $? logprint "Configuring binutils pass1..." ../configure \ --prefix=${CROSSTOOLS_DIR} \ --with-sysroot=${T_SYSROOT} \ --target=${T_TRIPLET} \ --disable-nls \ --disable-werror assert_zero $? logprint "Compiling..." make assert_zero $? logprint "Build operation complete." } mode_build_pass2() { logprint "Starting build of ${APPNAME}..." logprint "Entering build dir." pushd "${T_SOURCE_DIR}" # sourced from environment: checks $? -- aborts script execution if non-zero assert_zero $? logprint "Entering build subdir" mkdir -p build pushd build assert_zero $? # might be wrong, check if --enable-64-bit-bfd is needed on 64-bit targets logprint "Configuring binutils pass2..." ../configure \ --prefix=/usr \ --build=$(../config.guess) \ --host=${T_TRIPLET} \ --disable-nls \ --enable-shared \ --disable-werror \ --enable-64-bit-bfd assert_zero $? logprint "Compiling..." make -j1 assert_zero $? logprint "Build operation complete." } mode_install_pass1() { logprint "Starting install of ${APPNAME}..." pushd "${T_SOURCE_DIR}/build" assert_zero $? make -j1 install assert_zero $? logprint "Install operation complete." } mode_install_pass2() { logprint "Starting install of ${APPNAME}..." pushd "${T_SOURCE_DIR}/build" assert_zero $? make -j1 DESTDIR=${T_SYSROOT} install assert_zero $? logprint "Clean up items..." logprint "Applying hotfix for libctf.so / host zlib bug" install -vm755 libctf/.libs/libctf.so.0.0.0 ${T_SYSROOT}/usr/lib assert_zero $? logprint "Install operation complete." } mode_help() { echo "${APPNAME} [ --stage ] [ --build_pass1 ] [ --install_pass1 ] [ --pass1 ] [ --build_pass2 ] [ --install_pass2 ] [ --pass2 ][ --help ]" exit 0 } # MODE_PASS1 is a meta toggle for all pass1 modes. Modes will always # run in the correct order. if [ "$MODE_PASS1" = "true" ]; then MODE_STAGE=true MODE_BUILD_PASS1=true MODE_INSTALL_PASS1=true fi if [ "$MODE_PASS2" = "true" ]; then MODE_STAGE=true MODE_BUILD_PASS2=true MODE_INSTALL_PASS2=true fi # if no options were selected, then show help and exit if \ [ "$MODE_HELP" != "true" ] && \ [ "$MODE_STAGE" != "true" ] && \ [ "$MODE_BUILD_PASS1" != "true" ] && \ [ "$MODE_INSTALL_PASS1" != "true" ] && \ [ "$MODE_BUILD_PASS2" != "true" ] && \ [ "$MODE_INSTALL_PASS2" != "true" ] then logprint "No option selected during execution." mode_help fi # if help was supplied at all, show help and exit if [ "$MODE_HELP" = "true" ]; then logprint "Help option selected. Printing options and exiting." mode_help fi if [ "$MODE_STAGE" = "true" ]; then logprint "Staging option selected." mode_stage assert_zero $? fi if [ "$MODE_BUILD_PASS1" = "true" ]; then logprint "Build of PASS1 selected." mode_build_pass1 assert_zero $? fi if [ "$MODE_INSTALL_PASS1" = "true" ]; then logprint "Install of PASS1 selected." mode_install_pass1 assert_zero $? fi if [ "$MODE_BUILD_PASS2" = "true" ]; then logprint "Build of PASS2 selected." mode_build_pass2 assert_zero $? fi if [ "$MODE_INSTALL_PASS2" = "true" ]; then logprint "Install of PASS2 selected." mode_install_pass2 assert_zero $? fi logprint "Execution of ${APPNAME} completed."