Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / MAKEALL
diff --git a/qemu/roms/u-boot/MAKEALL b/qemu/roms/u-boot/MAKEALL
new file mode 100755 (executable)
index 0000000..020e65f
--- /dev/null
@@ -0,0 +1,846 @@
+#!/bin/bash
+# Tool mainly for U-Boot Quality Assurance: build one or more board
+# configurations with minimal verbosity, showing only warnings and
+# errors.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+
+usage()
+{
+       # if exiting with 0, write to stdout, else write to stderr
+       local ret=${1:-0}
+       [ "${ret}" -eq 1 ] && exec 1>&2
+       cat <<-EOF
+       Usage: MAKEALL [options] [--] [boards-to-build]
+
+       Options:
+         -a ARCH,   --arch ARCH       Build all boards with arch ARCH
+         -c CPU,    --cpu CPU         Build all boards with cpu CPU
+         -v VENDOR, --vendor VENDOR   Build all boards with vendor VENDOR
+         -s SOC,    --soc SOC         Build all boards with soc SOC
+         -b BOARD,  --board BOARD     Build all boards with board name BOARD
+         -l,        --list            List all targets to be built
+         -m,        --maintainers     List all targets and maintainer email
+         -M,        --mails           List all targets and all affilated emails
+         -C,        --check           Enable build checking
+         -n,        --continue        Continue (skip boards already built)
+         -r,        --rebuild-errors  Rebuild any boards that errored
+         -h,        --help            This help output
+
+       Selections by these options are logically ANDed; if the same option
+       is used repeatedly, such selections are ORed.  So "-v FOO -v BAR"
+       will select all configurations where the vendor is either FOO or
+       BAR.  Any additional arguments specified on the command line are
+       always build additionally.  See the boards.cfg file for more info.
+
+       If no boards are specified, then the default is "powerpc".
+
+       Environment variables:
+         BUILD_NCPUS      number of parallel make jobs (default: auto)
+         CROSS_COMPILE    cross-compiler toolchain prefix (default: "")
+         CROSS_COMPILE_<ARCH> cross-compiler toolchain prefix for
+                          architecture "ARCH".  Substitute "ARCH" for any
+                          supported architecture (default: "")
+         MAKEALL_LOGDIR   output all logs to here (default: ./LOG/)
+         BUILD_DIR        output build directory (default: ./)
+         BUILD_NBUILDS    number of parallel targets (default: 1)
+
+       Examples:
+         - build all Power Architecture boards:
+             MAKEALL -a powerpc
+             MAKEALL --arch powerpc
+             MAKEALL powerpc
+         - build all PowerPC boards manufactured by vendor "esd":
+             MAKEALL -a powerpc -v esd
+         - build all PowerPC boards manufactured either by "keymile" or "siemens":
+             MAKEALL -a powerpc -v keymile -v siemens
+         - build all Freescale boards with MPC83xx CPUs, plus all 4xx boards:
+             MAKEALL -c mpc83xx -v freescale 4xx
+       EOF
+       exit ${ret}
+}
+
+SHORT_OPTS="ha:c:v:s:b:lmMCnr"
+LONG_OPTS="help,arch:,cpu:,vendor:,soc:,board:,list,maintainers,mails,check,continue,rebuild-errors"
+
+# Option processing based on util-linux-2.13/getopt-parse.bash
+
+# Note that we use `"$@"' to let each command-line parameter expand to a
+# separate word. The quotes around `$@' are essential!
+# We need TEMP as the `eval set --' would nuke the return value of
+# getopt.
+TEMP=`getopt -o ${SHORT_OPTS} --long ${LONG_OPTS} \
+     -n 'MAKEALL' -- "$@"`
+
+[ $? != 0 ] && usage 1
+
+# Note the quotes around `$TEMP': they are essential!
+eval set -- "$TEMP"
+
+SELECTED=''
+ONLY_LIST=''
+PRINT_MAINTS=''
+MAINTAINERS_ONLY=''
+CONTINUE=''
+REBUILD_ERRORS=''
+
+while true ; do
+       case "$1" in
+       -a|--arch)
+               # echo "Option ARCH: argument \`$2'"
+               if [ "$opt_a" ] ; then
+                       opt_a="${opt_a%)} || \$2 == \"$2\")"
+               else
+                       opt_a="(\$2 == \"$2\")"
+               fi
+               SELECTED='y'
+               shift 2 ;;
+       -c|--cpu)
+               # echo "Option CPU: argument \`$2'"
+               if [ "$opt_c" ] ; then
+                       opt_c="${opt_c%)} || \$3 == \"$2\" || \$3 ~ /$2:/)"
+               else
+                       opt_c="(\$3 == \"$2\" || \$3 ~ /$2:/)"
+               fi
+               SELECTED='y'
+               shift 2 ;;
+       -s|--soc)
+               # echo "Option SoC: argument \`$2'"
+               if [ "$opt_s" ] ; then
+                       opt_s="${opt_s%)} || \$4 == \"$2\" || \$4 ~ /$2/)"
+               else
+                       opt_s="(\$4 == \"$2\" || \$4 ~ /$2/)"
+               fi
+               SELECTED='y'
+               shift 2 ;;
+       -v|--vendor)
+               # echo "Option VENDOR: argument \`$2'"
+               if [ "$opt_v" ] ; then
+                       opt_v="${opt_v%)} || \$5 == \"$2\")"
+               else
+                       opt_v="(\$5 == \"$2\")"
+               fi
+               SELECTED='y'
+               shift 2 ;;
+       -b|--board)
+               # echo "Option BOARD: argument \`$2'"
+               if [ "$opt_b" ] ; then
+                       opt_b="${opt_b%)} || \$6 == \"$2\" || \$7 == \"$2\")"
+               else
+                       # We need to check the 7th field too
+                       # for boards whose 6th field is "-"
+                       opt_b="(\$6 == \"$2\" || \$7 == \"$2\")"
+               fi
+               SELECTED='y'
+               shift 2 ;;
+       -C|--check)
+               CHECK='C=1'
+               shift ;;
+       -n|--continue)
+               CONTINUE='y'
+               shift ;;
+       -r|--rebuild-errors)
+               REBUILD_ERRORS='y'
+               shift ;;
+       -l|--list)
+               ONLY_LIST='y'
+               shift ;;
+       -m|--maintainers)
+               ONLY_LIST='y'
+               PRINT_MAINTS='y'
+               MAINTAINERS_ONLY='y'
+               shift ;;
+       -M|--mails)
+               ONLY_LIST='y'
+               PRINT_MAINTS='y'
+               shift ;;
+       -h|--help)
+               usage ;;
+       --)
+               shift ; break ;;
+       *)
+               echo "Internal error!" >&2 ; exit 1 ;;
+       esac
+done
+# echo "Remaining arguments:"
+# for arg do echo '--> '"\`$arg'" ; done
+
+FILTER="\$1 !~ /^#/"
+[ "$opt_a" ] && FILTER="${FILTER} && $opt_a"
+[ "$opt_c" ] && FILTER="${FILTER} && $opt_c"
+[ "$opt_s" ] && FILTER="${FILTER} && $opt_s"
+[ "$opt_v" ] && FILTER="${FILTER} && $opt_v"
+[ "$opt_b" ] && FILTER="${FILTER} && $opt_b"
+
+if [ "$SELECTED" ] ; then
+       SELECTED=$(awk '('"$FILTER"') { print $7 }' boards.cfg)
+
+       # Make sure some boards from boards.cfg are actually found
+       if [ -z "$SELECTED" ] ; then
+               echo "Error: No boards selected, invalid arguments"
+               exit 1
+       fi
+fi
+
+#########################################################################
+
+# Print statistics when we exit
+trap exit 1 2 3 15
+trap print_stats 0
+
+# Determine number of CPU cores if no default was set
+: ${BUILD_NCPUS:="`getconf _NPROCESSORS_ONLN`"}
+
+if [ "$BUILD_NCPUS" -gt 1 ]
+then
+       JOBS="-j $((BUILD_NCPUS + 1))"
+else
+       JOBS=""
+fi
+
+if [ "${MAKEALL_LOGDIR}" ] ; then
+       LOG_DIR=${MAKEALL_LOGDIR}
+else
+       LOG_DIR="LOG"
+fi
+
+: ${BUILD_NBUILDS:=1}
+BUILD_MANY=0
+
+if [ "${BUILD_NBUILDS}" -gt 1 ] ; then
+       BUILD_MANY=1
+       : ${BUILD_DIR:=./build}
+       mkdir -p "${BUILD_DIR}/ERR"
+       find "${BUILD_DIR}/ERR/" -type f -exec rm -f {} +
+fi
+
+: ${BUILD_DIR:=.}
+
+OUTPUT_PREFIX="${BUILD_DIR}"
+
+[ -d ${LOG_DIR} ] || mkdir "${LOG_DIR}" || exit 1
+if [ "$CONTINUE" != 'y' -a "$REBUILD_ERRORS" != 'y' ] ; then
+       find "${LOG_DIR}/" -type f -exec rm -f {} +
+fi
+
+LIST=""
+
+# Keep track of the number of builds and errors
+ERR_CNT=0
+ERR_LIST=""
+WRN_CNT=0
+WRN_LIST=""
+TOTAL_CNT=0
+SKIP_CNT=0
+CURRENT_CNT=0
+OLDEST_IDX=1
+RC=0
+
+# Helper funcs for parsing boards.cfg
+targets_by_field()
+{
+       field=$1
+       regexp=$2
+
+       awk '($1 !~ /^#/ && $'"$field"' ~ /^'"$regexp"'$/) { print $7 }' \
+                                                               boards.cfg
+}
+
+targets_by_arch() { targets_by_field 2 "$@" ; }
+targets_by_cpu()  { targets_by_field 3 "$@" ; targets_by_field 3 "$@:.*" ; }
+targets_by_soc()  { targets_by_field 4 "$@" ; }
+
+#########################################################################
+## MPC5xx Systems
+#########################################################################
+
+LIST_5xx="$(targets_by_cpu mpc5xx)"
+
+#########################################################################
+## MPC5xxx Systems
+#########################################################################
+
+LIST_5xxx="$(targets_by_cpu mpc5xxx)"
+
+#########################################################################
+## MPC512x Systems
+#########################################################################
+
+LIST_512x="$(targets_by_cpu mpc512x)"
+
+#########################################################################
+## MPC8xx Systems
+#########################################################################
+
+LIST_8xx="$(targets_by_cpu mpc8xx)"
+
+#########################################################################
+## PPC4xx Systems
+#########################################################################
+
+LIST_4xx="$(targets_by_cpu ppc4xx)"
+
+#########################################################################
+## MPC824x Systems
+#########################################################################
+
+LIST_824x="$(targets_by_cpu mpc824x)"
+
+#########################################################################
+## MPC8260 Systems (includes 8250, 8255 etc.)
+#########################################################################
+
+LIST_8260="$(targets_by_cpu mpc8260)"
+
+#########################################################################
+## MPC83xx Systems (includes 8349, etc.)
+#########################################################################
+
+LIST_83xx="$(targets_by_cpu mpc83xx)"
+
+#########################################################################
+## MPC85xx Systems (includes 8540, 8560 etc.)
+#########################################################################
+
+LIST_85xx="$(targets_by_cpu mpc85xx)"
+
+#########################################################################
+## MPC86xx Systems
+#########################################################################
+
+LIST_86xx="$(targets_by_cpu mpc86xx)"
+
+#########################################################################
+## 74xx/7xx Systems
+#########################################################################
+
+LIST_74xx_7xx="$(targets_by_cpu 74xx_7xx)"
+
+#########################################################################
+## PowerPC groups
+#########################################################################
+
+LIST_TSEC="            \
+       ${LIST_83xx}    \
+       ${LIST_85xx}    \
+       ${LIST_86xx}    \
+"
+
+LIST_powerpc="         \
+       ${LIST_5xx}     \
+       ${LIST_512x}    \
+       ${LIST_5xxx}    \
+       ${LIST_8xx}     \
+       ${LIST_824x}    \
+       ${LIST_8260}    \
+       ${LIST_83xx}    \
+       ${LIST_85xx}    \
+       ${LIST_86xx}    \
+       ${LIST_4xx}     \
+       ${LIST_74xx_7xx}\
+"
+
+# Alias "ppc" -> "powerpc" to not break compatibility with older scripts
+# still using "ppc" instead of "powerpc"
+LIST_ppc="             \
+       ${LIST_powerpc} \
+"
+
+#########################################################################
+## StrongARM Systems
+#########################################################################
+
+LIST_SA="$(targets_by_cpu sa1100)"
+
+#########################################################################
+## ARM7 Systems
+#########################################################################
+
+LIST_ARM7="$(targets_by_cpu arm720t)"
+
+#########################################################################
+## ARM9 Systems
+#########################################################################
+
+LIST_ARM9="$(targets_by_cpu arm920t)   \
+       $(targets_by_cpu arm926ejs)     \
+       $(targets_by_cpu arm946es)      \
+"
+
+#########################################################################
+## ARM11 Systems
+#########################################################################
+LIST_ARM11="$(targets_by_cpu arm1136)  \
+       $(targets_by_cpu arm1176)       \
+"
+
+#########################################################################
+## ARMV7 Systems
+#########################################################################
+
+LIST_ARMV7="$(targets_by_cpu armv7)"
+
+#########################################################################
+## ARMV8 Systems
+#########################################################################
+
+LIST_ARMV8="$(targets_by_cpu armv8)"
+
+#########################################################################
+## AT91 Systems
+#########################################################################
+
+LIST_at91="$(targets_by_soc at91)"
+
+#########################################################################
+## Xscale Systems
+#########################################################################
+
+LIST_pxa="$(targets_by_cpu pxa)"
+
+#########################################################################
+## SPEAr Systems
+#########################################################################
+
+LIST_spear="$(targets_by_soc spear)"
+
+#########################################################################
+## ARM groups
+#########################################################################
+
+LIST_arm="$(targets_by_arch arm |              \
+       for ARMV8_TARGET in $LIST_ARMV8;        \
+               do sed "/$ARMV8_TARGET/d";      \
+       done)                                   \
+"
+
+#########################################################################
+## MIPS Systems                (default = big endian)
+#########################################################################
+
+LIST_mips="$(targets_by_arch mips)"
+
+#########################################################################
+## OpenRISC Systems
+#########################################################################
+
+LIST_openrisc="$(targets_by_arch openrisc)"
+
+#########################################################################
+## x86 Systems
+#########################################################################
+
+LIST_x86="$(targets_by_arch x86)"
+
+#########################################################################
+## Nios-II Systems
+#########################################################################
+
+LIST_nios2="$(targets_by_arch nios2)"
+
+#########################################################################
+## MicroBlaze Systems
+#########################################################################
+
+LIST_microblaze="$(targets_by_arch microblaze)"
+
+#########################################################################
+## ColdFire Systems
+#########################################################################
+
+LIST_m68k="$(targets_by_arch m68k)"
+LIST_coldfire=${LIST_m68k}
+
+#########################################################################
+## AVR32 Systems
+#########################################################################
+
+LIST_avr32="$(targets_by_arch avr32)"
+
+#########################################################################
+## Blackfin Systems
+#########################################################################
+
+LIST_blackfin="$(targets_by_arch blackfin)"
+
+#########################################################################
+## SH Systems
+#########################################################################
+
+LIST_sh2="$(targets_by_cpu sh2)"
+LIST_sh3="$(targets_by_cpu sh3)"
+LIST_sh4="$(targets_by_cpu sh4)"
+
+LIST_sh="$(targets_by_arch sh)"
+
+#########################################################################
+## SPARC Systems
+#########################################################################
+
+LIST_sparc="$(targets_by_arch sparc)"
+
+#########################################################################
+## NDS32 Systems
+#########################################################################
+
+LIST_nds32="$(targets_by_arch nds32)"
+
+#########################################################################
+## ARC Systems
+#########################################################################
+
+LIST_arc="$(targets_by_arch arc)"
+
+#-----------------------------------------------------------------------
+
+get_target_location() {
+       local target=$1
+       local BOARD_NAME=""
+       local CONFIG_NAME=""
+       local board=""
+       local vendor=""
+
+       # Automatic mode
+       local line=`awk '\$7 == "'"$target"'" { print \$0 }' boards.cfg`
+       if [ -z "${line}" ] ; then echo "" ; return ; fi
+
+       set ${line}
+
+       CONFIG_NAME="${7%_config}"
+
+       [ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}"
+
+       if [ $# -gt 5 ]; then
+               if [ "$6" = "-" ] ; then
+                       board=${BOARD_NAME}
+               else
+                       board="$6"
+               fi
+       fi
+
+       [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
+       [ $# -gt 6 ] && [ "$8" != "-" ] && {
+               tmp="${8%:*}"
+               if [ "$tmp" ] ; then
+                       CONFIG_NAME="$tmp"
+               fi
+       }
+
+       # Assign board directory to BOARDIR variable
+       if [ "${vendor}" == "-" ] ; then
+           BOARDDIR=${board}
+       else
+           BOARDDIR=${vendor}/${board}
+       fi
+
+       echo "${CONFIG_NAME}:${BOARDDIR}:${BOARD_NAME}"
+}
+
+get_target_maintainers() {
+       local name=`echo $1 | cut -d : -f 3`
+
+       local line=`awk '\$7 == "'"$target"'" { print \$0 }' boards.cfg`
+       if [ -z "${line}" ]; then
+               echo ""
+               return ;
+       fi
+
+       local mails=`echo ${line} | cut -d ' ' -f 9- | sed -e 's/[^<]*<//' -e 's/>.*</ /' -e 's/>[^>]*$//'`
+       [ "$mails" == "-" ] && mails=""
+       echo "$mails"
+}
+
+get_target_arch() {
+       local target=$1
+
+       # Automatic mode
+       local line=`awk '\$7 == "'"$target"'" { print \$0 }' boards.cfg`
+
+       if [ -z "${line}" ] ; then echo "" ; return ; fi
+
+       set ${line}
+       echo "$2"
+}
+
+list_target() {
+       if [ "$PRINT_MAINTS" != 'y' ] ; then
+               echo "$1"
+               return
+       fi
+
+       echo -n "$1:"
+
+       local loc=`get_target_location $1`
+
+       if [ -z "${loc}" ] ; then echo "ERROR" ; return ; fi
+
+       local maintainers_result=`get_target_maintainers ${loc} | tr " " "\n"`
+
+       if [ "$MAINTAINERS_ONLY" != 'y' ] ; then
+
+               local dir=`echo ${loc} | cut -d ":" -f 2`
+               local cfg=`echo ${loc} | cut -d ":" -f 1`
+               local git_result=`git log --format=%aE board/${dir} \
+                               include/configs/${cfg}.h | grep "@"`
+               local git_result_recent=`echo ${git_result} | tr " " "\n" | \
+                                               head -n 3`
+               local git_result_top=`echo ${git_result} | tr " " "\n" | \
+                       sort | uniq -c | sort -nr | head -n 3 | \
+                       sed "s/^ \+[0-9]\+ \+//"`
+
+               echo -e "$git_result_recent\n$git_result_top\n$maintainers_result" | \
+                       sort -u | tr "\n" " " | sed "s/ $//" ;
+       else
+               echo -e "$maintainers_result" | sort -u | tr "\n" " " | \
+                                               sed "s/ $//" ;
+       fi
+
+       echo ""
+}
+
+# Each finished build will have a file called ${donep}${n},
+# where n is the index of the build. Each build
+# we've already noted as finished will have ${skipp}${n}.
+# The code managing the build process will use this information
+# to ensure that only BUILD_NBUILDS builds are in flight at once
+donep="${LOG_DIR}/._done_"
+skipp="${LOG_DIR}/._skip_"
+
+build_target_killed() {
+       echo "Aborted $target build."
+       # Remove the logs for this board since it was aborted
+       rm -f ${LOG_DIR}/$target.MAKELOG ${LOG_DIR}/$target.ERR
+       exit
+}
+
+build_target() {
+       target=$1
+       build_idx=$2
+
+       if [ "$ONLY_LIST" == 'y' ] ; then
+               list_target ${target}
+               return
+       fi
+
+       if [ $BUILD_MANY == 1 ] ; then
+               output_dir="${OUTPUT_PREFIX}/${target}"
+               mkdir -p "${output_dir}"
+               trap build_target_killed TERM
+       else
+               output_dir="${OUTPUT_PREFIX}"
+       fi
+
+       target_arch=$(get_target_arch ${target})
+       eval cross_toolchain=\$CROSS_COMPILE_`echo $target_arch | tr '[:lower:]' '[:upper:]'`
+       if [ "${cross_toolchain}" ] ; then
+           MAKE="make CROSS_COMPILE=${cross_toolchain}"
+       elif [ "${CROSS_COMPILE}" ] ; then
+           MAKE="make CROSS_COMPILE=${CROSS_COMPILE}"
+       else
+           MAKE=make
+       fi
+
+       if [  "${output_dir}" != "." ] ; then
+               MAKE="${MAKE} O=${output_dir}"
+       fi
+
+       ${MAKE} distclean >/dev/null
+       ${MAKE} -s ${target}_config
+
+       ${MAKE} ${JOBS} ${CHECK} all \
+               >${LOG_DIR}/$target.MAKELOG 2> ${LOG_DIR}/$target.ERR
+
+       # Check for 'make' errors
+       if [ ${PIPESTATUS[0]} -ne 0 ] ; then
+               RC=1
+       fi
+
+       if [ $BUILD_MANY == 1 ] ; then
+               trap - TERM
+
+               ${MAKE} -s clean
+
+               if [ -s ${LOG_DIR}/${target}.ERR ] ; then
+                       cp ${LOG_DIR}/${target}.ERR ${OUTPUT_PREFIX}/ERR/${target}
+               else
+                       rm ${LOG_DIR}/${target}.ERR
+               fi
+       else
+               if [ -s ${LOG_DIR}/${target}.ERR ] ; then
+                       if grep -iw error ${LOG_DIR}/${target}.ERR ; then
+                               : $(( ERR_CNT += 1 ))
+                               ERR_LIST="${ERR_LIST} $target"
+                       else
+                               : $(( WRN_CNT += 1 ))
+                               WRN_LIST="${WRN_LIST} $target"
+                       fi
+               else
+                       rm ${LOG_DIR}/${target}.ERR
+               fi
+       fi
+
+       OBJS=${output_dir}/u-boot
+       if [ -e ${output_dir}/spl/u-boot-spl ]; then
+               OBJS="${OBJS} ${output_dir}/spl/u-boot-spl"
+       fi
+
+       ${CROSS_COMPILE}size ${OBJS} | tee -a ${LOG_DIR}/$target.MAKELOG
+
+       [ -e "${LOG_DIR}/${target}.ERR" ] && cat "${LOG_DIR}/${target}.ERR"
+
+       touch "${donep}${build_idx}"
+}
+
+manage_builds() {
+       search_idx=${OLDEST_IDX}
+       if [ "$ONLY_LIST" == 'y' ] ; then return ; fi
+
+       while true; do
+               if [ -e "${donep}${search_idx}" ] ; then
+                       : $(( CURRENT_CNT-- ))
+                       [ ${OLDEST_IDX} -eq ${search_idx} ] &&
+                               : $(( OLDEST_IDX++ ))
+
+                       # Only want to count it once
+                       rm -f "${donep}${search_idx}"
+                       touch "${skipp}${search_idx}"
+               elif [ -e "${skipp}${search_idx}" ] ; then
+                       [ ${OLDEST_IDX} -eq ${search_idx} ] &&
+                               : $(( OLDEST_IDX++ ))
+               fi
+               : $(( search_idx++ ))
+               if [ ${search_idx} -gt ${TOTAL_CNT} ] ; then
+                       if [ ${CURRENT_CNT} -ge ${BUILD_NBUILDS} ] ; then
+                               search_idx=${OLDEST_IDX}
+                               sleep 1
+                       else
+                               break
+                       fi
+               fi
+       done
+}
+
+build_targets() {
+       for t in "$@" ; do
+               # If a LIST_xxx var exists, use it.  But avoid variable
+               # expansion in the eval when a board name contains certain
+               # characters that the shell interprets.
+               case ${t} in
+                       *[-+=]*) list= ;;
+                       *)       list=$(eval echo '${LIST_'$t'}') ;;
+               esac
+               if [ -n "${list}" ] ; then
+                       build_targets ${list}
+               else
+                       : $((TOTAL_CNT += 1))
+                       : $((CURRENT_CNT += 1))
+                       rm -f "${donep}${TOTAL_CNT}"
+                       rm -f "${skipp}${TOTAL_CNT}"
+                       if [ "$CONTINUE" = 'y' -a -e ${LOG_DIR}/$t.MAKELOG ] ; then
+                               : $((SKIP_CNT += 1))
+                               touch "${donep}${TOTAL_CNT}"
+                       elif [ "$REBUILD_ERRORS" = 'y' -a ! -e ${LOG_DIR}/$t.ERR ] ; then
+                               : $((SKIP_CNT += 1))
+                               touch "${donep}${TOTAL_CNT}"
+                       else
+                               if [ $BUILD_MANY == 1 ] ; then
+                                       build_target ${t} ${TOTAL_CNT} &
+                               else
+                                       CUR_TGT="${t}"
+                                       build_target ${t} ${TOTAL_CNT}
+                                       CUR_TGT=''
+                               fi
+                       fi
+               fi
+
+               # We maintain a running count of all the builds we have done.
+               # Each finished build will have a file called ${donep}${n},
+               # where n is the index of the build. Each build
+               # we've already noted as finished will have ${skipp}${n}.
+               # We track the current index via TOTAL_CNT, and the oldest
+               # index. When we exceed the maximum number of parallel builds,
+               # We look from oldest to current for builds that have completed,
+               # and update the current count and oldest index as appropriate.
+               # If we've gone through the entire list, wait a second, and
+               # reprocess the entire list until we find a build that has
+               # completed
+               if [ ${CURRENT_CNT} -ge ${BUILD_NBUILDS} ] ; then
+                       manage_builds
+               fi
+       done
+}
+
+#-----------------------------------------------------------------------
+
+kill_children() {
+       local OS=$(uname -s)
+       local children=""
+       case "${OS}" in
+               "Darwin")
+                       # Mac OS X is known to have BSD style ps
+                       local pgid=$(ps -p $$ -o pgid | sed -e "/PGID/d")
+                       children=$(ps -g $pgid -o pid | sed -e "/PID\|$$\|$pgid/d")
+                       ;;
+               *)
+                       # everything else tries the GNU style
+                       local pgid=$(ps -p $$ --no-headers -o "%r" | tr -d ' ')
+                       children=$(pgrep -g $pgid | sed -e "/$$\|$pgid/d")
+                       ;;
+       esac
+
+       kill $children 2> /dev/null
+       wait $children 2> /dev/null
+
+       exit
+}
+
+print_stats() {
+       if [ "$ONLY_LIST" == 'y' ] ; then return ; fi
+
+       # Only count boards that completed
+       : $((TOTAL_CNT = `find ${skipp}* 2> /dev/null | wc -l`))
+
+       rm -f ${donep}* ${skipp}*
+
+       if [ $BUILD_MANY == 1 ] && [ -e "${OUTPUT_PREFIX}/ERR" ] ; then
+               ERR_LIST=`grep -riwl error ${OUTPUT_PREFIX}/ERR/`
+               ERR_LIST=`for f in $ERR_LIST ; do echo -n " $(basename $f)" ; done`
+               ERR_CNT=`echo $ERR_LIST | wc -w | awk '{print $1}'`
+               WRN_LIST=`grep -riwL error ${OUTPUT_PREFIX}/ERR/`
+               WRN_LIST=`for f in $WRN_LIST ; do echo -n " $(basename $f)" ; done`
+               WRN_CNT=`echo $WRN_LIST | wc -w | awk '{print $1}'`
+       else
+               # Remove the logs for any board that was interrupted
+               rm -f ${LOG_DIR}/${CUR_TGT}.MAKELOG ${LOG_DIR}/${CUR_TGT}.ERR
+       fi
+
+       : $((TOTAL_CNT -= ${SKIP_CNT}))
+       echo ""
+       echo "--------------------- SUMMARY ----------------------------"
+       if [ "$CONTINUE" = 'y' -o "$REBUILD_ERRORS" = 'y' ] ; then
+               echo "Boards skipped: ${SKIP_CNT}"
+       fi
+       echo "Boards compiled: ${TOTAL_CNT}"
+       if [ ${ERR_CNT} -gt 0 ] ; then
+               echo "Boards with errors: ${ERR_CNT} (${ERR_LIST} )"
+       fi
+       if [ ${WRN_CNT} -gt 0 ] ; then
+               echo "Boards with warnings but no errors: ${WRN_CNT} (${WRN_LIST} )"
+       fi
+       echo "----------------------------------------------------------"
+
+       if [ $BUILD_MANY == 1 ] ; then
+               kill_children
+       fi
+
+       exit $RC
+}
+
+#-----------------------------------------------------------------------
+
+# Build target groups selected by options, plus any command line args
+set -- ${SELECTED} "$@"
+# run PowerPC by default
+[ $# = 0 ] && set -- powerpc
+build_targets "$@"
+wait