# HG changeset patch # User "Yann E. MORIN" # Date 1179668906 0 # Node ID ea15433daba016b7556413d5fa4360ac4c77f833 # Parent 2e16b9fc302de7004a64067676237162d20f1bab Ah! I finally have a progress bar that doesn't stall the build! - pipe size in Linux is only 8*512=4096 bytes - pipe size is not setable - when the feeding process spits out data faster than the eating process can read it, then the feeding process stalls after 4KiB of data sent to the pipe - for us, the progress bar would spawn a sub-shell every line, and the sub-shell would in turn spawn a 'date' command. Which was sloooww as hell, and would cause some kind of a starvation: the pipe was full most of the time, and the feeding process was stalled all this time. Now, we use internal variables and a little hack based onan offset to determine the elapsed time. Much faster this way, but still CPU-intensive. diff -r 2e16b9fc302d -r ea15433daba0 config/global.in --- a/config/global.in Sun May 20 09:28:16 2007 +0000 +++ b/config/global.in Sun May 20 13:48:26 2007 +0000 @@ -255,13 +255,15 @@ default n depends on ! LOG_ALL help - This option will print a "rotating bar" (/-\|) below the last log line - to show work is not stalled. + If you say 'y' here, you'll be able to see the elapsed time. - Available when not in DEBUG log level. - - WARNING! Very CPU intensive! If you have spare CPU, then you can use it, - otherwise, refrain from using it. + As a bonus, you'll also get a rotating bar (/-\|) showing you + that the build is not stalled (the bar rotates 1/4 every 10 lines + of components build log). + + Note that the elapsed time can stall for a little while if a + component has long commands, as the elapsed time is only updated + each line. config LOG_TO_FILE bool diff -r 2e16b9fc302d -r ea15433daba0 scripts/crosstool.sh --- a/scripts/crosstool.sh Sun May 20 09:28:16 2007 +0000 +++ b/scripts/crosstool.sh Sun May 20 13:48:26 2007 +0000 @@ -27,8 +27,12 @@ CT_STAR_DATE=`CT_DoDate +%s%N` CT_STAR_DATE_HUMAN=`CT_DoDate +%Y%m%d.%H%M%S` -# Log to a temporary file until we have built our environment -CT_ACTUAL_LOG_FILE="${CT_TOP_DIR}/$$.log" +# Log policy: +# - what goes to the log file goes to fd #1 (stdout) +# - what goes to the screen goes to fd #6 +tmp_log_file="${CT_TOP_DIR}/$$.log" +exec 6>&1 +exec >>"${tmp_log_file}" # Are we configured? We'll need that later... CT_TestOrAbort "Configuration file not found. Please create one." -f "${CT_TOP_DIR}/.config" @@ -182,22 +186,22 @@ # It's quite understandable that the log file will be installed in the install # directory, so we must first ensure it exists and is writeable (above) before # we can log there +exec >/dev/null case "${CT_LOG_TO_FILE},${CT_LOG_FILE}" in - ,*) rm -f "${CT_ACTUAL_LOG_FILE}" - CT_ACTUAL_LOG_FILE=/dev/null + ,*) rm -f "${tmp_log_file}" ;; y,/*) mkdir -p "`dirname \"${CT_LOG_FILE}\"`" - mv "${CT_ACTUAL_LOG_FILE}" "${CT_LOG_FILE}" - CT_ACTUAL_LOG_FILE="${CT_LOG_FILE}" + mv "${tmp_log_file}" "${CT_LOG_FILE}" + exec >>"${CT_LOG_FILE}" ;; y,*) mkdir -p "`pwd`/`dirname \"${CT_LOG_FILE}\"`" - mv "${CT_ACTUAL_LOG_FILE}" "`pwd`/${CT_LOG_FILE}" - CT_ACTUAL_LOG_FILE="`pwd`/${CT_LOG_FILE}" + mv "${tmp_log_file}" "`pwd`/${CT_LOG_FILE}" + exec >>"${CT_LOG_FILE}" ;; esac # Determine build system if not set by the user -CT_Test "You did not specify the build system. Guessing." -z "${CT_BUILD}" +CT_Test "You did not specify the build system. That's OK, I can guess..." -z "${CT_BUILD}" CT_BUILD="`${CT_TOP_DIR}/tools/config.sub \"${CT_BUILD:-\`${CT_TOP_DIR}/tools/config.guess\`}\"`" # Arrange paths depending on wether we use sys-root or not. diff -r 2e16b9fc302d -r ea15433daba0 scripts/functions --- a/scripts/functions Sun May 20 09:28:16 2007 +0000 +++ b/scripts/functions Sun May 20 13:48:26 2007 +0000 @@ -12,7 +12,7 @@ for((depth=2; ${BASH_LINENO[$((${depth}-1))]}>0; depth++)); do CT_DoLog ERROR " called from \"${BASH_SOURCE[${depth}]}\" at line # ${BASH_LINENO[${depth}-1]} in function \"${FUNCNAME[${depth}]}\"" done - CT_DoLog ERROR "Look at \"${CT_ACTUAL_LOG_FILE}\" for more info on this error." + [ "${CT_LOG_TO_FILE}" = "y" ] && CT_DoLog ERROR "Look at \"${CT_LOG_FILE}\" for more info on this error." CT_STEP_COUNT=1 CT_DoEnd ERROR exit $ret @@ -54,30 +54,31 @@ cat - else echo "${1}" - fi |( IFS="\n" # We want the full lines, even leading spaces + fi |( offset=$((`CT_DoDate +%s`+(CT_STAR_DATE/(1000*1000*1000)))) + IFS="\n" # We want the full lines, even leading spaces CT_PROG_BAR_CPT=0 indent=$((2*CT_STEP_COUNT)) while read line; do case "${CT_LOG_SEE_TOOLS_WARN},${line}" in y,*"warning:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};; + y,*"WARNING:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};; *"error:"*) cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};; *"make["?*"]:"*"Stop.") cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};; *) cur_L="${LEVEL}"; cur_l="${level}";; esac l="`printf \"[%-5s]%*s%s%s\" \"${cur_L}\" \"${indent}\" \" \" \"${line}\"`" # There will always be a log file, be it /dev/null - echo -e "${l}" >>"${CT_ACTUAL_LOG_FILE}" + echo -e "${l}" if [ ${cur_l} -le ${max_level} ]; then - echo -e "\r${l}" + echo -e "\r${l}" >&6 fi if [ "${CT_LOG_PROGRESS_BAR}" = "y" ]; then - str=`CT_DoDate +%s` - elapsed=$((str-(CT_STAR_DATE/(1000*1000*1000)))) + elapsed=$((SECONDS+OFFSET)) [ ${CT_PROG_BAR_CPT} -eq 0 ] && bar="/" [ ${CT_PROG_BAR_CPT} -eq 10 ] && bar="-" [ ${CT_PROG_BAR_CPT} -eq 20 ] && bar="\\" [ ${CT_PROG_BAR_CPT} -eq 30 ] && bar="|" - printf "\r[%02d:%02d] %s " $((elapsed/60)) $((elapsed%60)) "${bar}" + printf "\r[%02d:%02d] %s " $((elapsed/60)) $((elapsed%60)) "${bar}" >&6 CT_PROG_BAR_CPT=$(((CT_PROG_BAR_CPT+1)%40)) fi done