#!/bin/bash trap_ctrl-c() { if [ -n "${MAKE_PID}" ]; then printf '\rInterrupted, waiting for jobs to finish...\n' >&6 kill -INT ${MAKE_PID} wait ${MAKE_PID} exit ${?} fi } disp_time() { local start="${1}" local S h m s if [ "${BRMAKE_ABS_TIME}" ]; then printf '%(%T)T' -1 else S=$((${EPOCHSECONDS:-$(date +%s)}-start)) h=$((S/3600)) m=$(((S%3600)/60)) s=$((S%60)) [ "${h}" -eq 0 ] || printf '%d:' "${h}" printf '%02d:%02d' "${m}" "${s}" fi } main() { local ret start dir_found dir O log_file outsync start=${BR_START:-${EPOCHSECONDS:-$(date +%s)}} # Crude parsing to find the directory with the .config dir="$(pwd)" dir_found=false outsync=-Otarget for i in "${@}"; do ${dir_found} && { dir="${i}"; dir_found=false; continue; } case "${i}" in (-C|--directory) dir_found=true;; (-C*) dir="${i#-C}";; (--directory=*) dir="${i#--directory=}";; (O=*) O="${i#O=}";; (-O|-O*) outsync=;; esac done if [ -n "${O}" -a -e "${O}/.config" ]; then log_file="${O}/br.log" elif [ -z "${O}" -a -e "${dir}/.config" ]; then log_file="${dir}/br.log" else # No .config, don't log, and let Buildroot do its magic (i.e., whine) exec make "${@}" fi { coproc LOGGER \ { printf '\r%s' "$(disp_time "${start}")" IFS="${CR}" tee -a "${log_file}" \ |sed -u -r -e '/^.{4}(>>> .+)/!d; s//\1/' \ |while true; do if read -r -t 0.25 line; then printf '\r%s %s%s%s\n' \ "$(disp_time "${start}")" \ "${BRMAKE_PREFIX:+${BRMAKE_PREFIX} }" \ "${prev}" \ "${line}" disp_time "${start}" prev="" elif [ ${?} -gt 128 ]; then prev="${prev}${line}" printf '\r%s' "$(disp_time "${start}")" else break fi done exit 0 } >&3 } 3>&1 trap trap_ctrl-c INT exec 5>&1 16>&1 6>&2 >&${LOGGER[1]} 2>&1 4>&1 exec 16>&- ${MAKE:-make} ${outsync} "${@}" 2>&1 & MAKE_PID="${!}" wait ${MAKE_PID} ret="${?}" MAKE_PID="" exec >&5 2>&6 4>&- # bash seems to have issues closing an fd when it is an indexed-array # expansion, while it has no problem opening it (see above). eval exec "${LOGGER[1]}>&-" wait ${LOGGER_PID} printf '\r%s %s>>> ' "$(disp_time "${start}")" "${BRMAKE_PREFIX:+${BRMAKE_PREFIX} }" if [ "${BRMAKE_ABS_TIME}" ]; then printf 'Done in %s' "$(BRMAKE_ABS_TIME= disp_time "${start}")" else printf 'Finished at %(%T)T' -1 fi if [ ${ret} -ne 0 ]; then printf ' (error %d)' ${ret} fi printf '\n' return ${ret} } CR=" " main "${@}"