| #!/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)" | |
| ######################################################################### | |
| ## AT91 Systems | |
| ######################################################################### | |
| LIST_at91="$(targets_by_soc at91)" | |
| ######################################################################### | |
| ## Xscale Systems | |
| ######################################################################### | |
| LIST_pxa="$(targets_by_cpu pxa)" | |
| LIST_ixp="$(targets_by_cpu ixp)" | |
| ######################################################################### | |
| ## SPEAr Systems | |
| ######################################################################### | |
| LIST_spear="$(targets_by_soc spear)" | |
| ######################################################################### | |
| ## ARM groups | |
| ######################################################################### | |
| LIST_arm="$(targets_by_arch arm)" | |
| ######################################################################### | |
| ## MIPS Systems (default = big endian) | |
| ######################################################################### | |
| LIST_mips4kc=" \ | |
| incaip \ | |
| incaip_100MHz \ | |
| incaip_133MHz \ | |
| incaip_150MHz \ | |
| qemu_mips \ | |
| vct_platinum \ | |
| vct_platinum_small \ | |
| vct_platinum_onenand \ | |
| vct_platinum_onenand_small \ | |
| vct_platinumavc \ | |
| vct_platinumavc_small \ | |
| vct_platinumavc_onenand \ | |
| vct_platinumavc_onenand_small \ | |
| vct_premium \ | |
| vct_premium_small \ | |
| vct_premium_onenand \ | |
| vct_premium_onenand_small \ | |
| " | |
| LIST_au1xx0=" \ | |
| dbau1000 \ | |
| dbau1100 \ | |
| dbau1500 \ | |
| dbau1550 \ | |
| " | |
| LIST_mips=" \ | |
| ${LIST_mips4kc} \ | |
| ${LIST_mips5kc} \ | |
| ${LIST_au1xx0} \ | |
| " | |
| ######################################################################### | |
| ## MIPS Systems (little endian) | |
| ######################################################################### | |
| LIST_au1xx0_el=" \ | |
| dbau1550_el \ | |
| pb1000 \ | |
| " | |
| LIST_mips_el=" \ | |
| ${LIST_au1xx0_el} \ | |
| " | |
| ######################################################################### | |
| ## 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)" | |
| #----------------------------------------------------------------------- | |
| 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 | |
| export BUILD_DIR="${output_dir}" | |
| 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 | |
| ${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 tidy | |
| 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 |