1#!/bin/bash 2# Tool mainly for U-Boot Quality Assurance: build one or more board 3# configurations with minimal verbosity, showing only warnings and 4# errors. 5# 6# SPDX-License-Identifier: GPL-2.0+ 7 8usage() 9{ 10 # if exiting with 0, write to stdout, else write to stderr 11 local ret=${1:-0} 12 [ "${ret}" -eq 1 ] && exec 1>&2 13 cat <<-EOF 14 Usage: MAKEALL [options] [--] [boards-to-build] 15 16 Options: 17 -a ARCH, --arch ARCH Build all boards with arch ARCH 18 -c CPU, --cpu CPU Build all boards with cpu CPU 19 -v VENDOR, --vendor VENDOR Build all boards with vendor VENDOR 20 -s SOC, --soc SOC Build all boards with soc SOC 21 -l, --list List all targets to be built 22 -m, --maintainers List all targets and maintainer email 23 -M, --mails List all targets and all affilated emails 24 -C, --check Enable build checking 25 -n, --continue Continue (skip boards already built) 26 -r, --rebuild-errors Rebuild any boards that errored 27 -h, --help This help output 28 29 Selections by these options are logically ANDed; if the same option 30 is used repeatedly, such selections are ORed. So "-v FOO -v BAR" 31 will select all configurations where the vendor is either FOO or 32 BAR. Any additional arguments specified on the command line are 33 always build additionally. See the boards.cfg file for more info. 34 35 If no boards are specified, then the default is "powerpc". 36 37 Environment variables: 38 BUILD_NCPUS number of parallel make jobs (default: auto) 39 CROSS_COMPILE cross-compiler toolchain prefix (default: "") 40 CROSS_COMPILE_<ARCH> cross-compiler toolchain prefix for 41 architecture "ARCH". Substitute "ARCH" for any 42 supported architecture (default: "") 43 MAKEALL_LOGDIR output all logs to here (default: ./LOG/) 44 BUILD_DIR output build directory (default: ./) 45 BUILD_NBUILDS number of parallel targets (default: 1) 46 47 Examples: 48 - build all Power Architecture boards: 49 MAKEALL -a powerpc 50 MAKEALL --arch powerpc 51 MAKEALL powerpc 52 - build all PowerPC boards manufactured by vendor "esd": 53 MAKEALL -a powerpc -v esd 54 - build all PowerPC boards manufactured either by "keymile" or "siemens": 55 MAKEALL -a powerpc -v keymile -v siemens 56 - build all Freescale boards with MPC83xx CPUs, plus all 4xx boards: 57 MAKEALL -c mpc83xx -v freescale 4xx 58 EOF 59 exit ${ret} 60} 61 62SHORT_OPTS="ha:c:v:s:lmMCnr" 63LONG_OPTS="help,arch:,cpu:,vendor:,soc:,list,maintainers,mails,check,continue,rebuild-errors" 64 65# Option processing based on util-linux-2.13/getopt-parse.bash 66 67# Note that we use `"$@"' to let each command-line parameter expand to a 68# separate word. The quotes around `$@' are essential! 69# We need TEMP as the `eval set --' would nuke the return value of 70# getopt. 71TEMP=`getopt -o ${SHORT_OPTS} --long ${LONG_OPTS} \ 72 -n 'MAKEALL' -- "$@"` 73 74[ $? != 0 ] && usage 1 75 76# Note the quotes around `$TEMP': they are essential! 77eval set -- "$TEMP" 78 79SELECTED='' 80ONLY_LIST='' 81PRINT_MAINTS='' 82MAINTAINERS_ONLY='' 83CONTINUE='' 84REBUILD_ERRORS='' 85 86while true ; do 87 case "$1" in 88 -a|--arch) 89 # echo "Option ARCH: argument \`$2'" 90 if [ "$opt_a" ] ; then 91 opt_a="${opt_a%)} || \$2 == \"$2\")" 92 else 93 opt_a="(\$2 == \"$2\")" 94 fi 95 SELECTED='y' 96 shift 2 ;; 97 -c|--cpu) 98 # echo "Option CPU: argument \`$2'" 99 if [ "$opt_c" ] ; then 100 opt_c="${opt_c%)} || \$3 == \"$2\" || \$3 ~ /$2:/)" 101 else 102 opt_c="(\$3 == \"$2\" || \$3 ~ /$2:/)" 103 fi 104 SELECTED='y' 105 shift 2 ;; 106 -s|--soc) 107 # echo "Option SoC: argument \`$2'" 108 if [ "$opt_s" ] ; then 109 opt_s="${opt_s%)} || \$4 == \"$2\" || \$4 ~ /$2/)" 110 else 111 opt_s="(\$4 == \"$2\" || \$4 ~ /$2/)" 112 fi 113 SELECTED='y' 114 shift 2 ;; 115 -v|--vendor) 116 # echo "Option VENDOR: argument \`$2'" 117 if [ "$opt_v" ] ; then 118 opt_v="${opt_v%)} || \$5 == \"$2\")" 119 else 120 opt_v="(\$5 == \"$2\")" 121 fi 122 SELECTED='y' 123 shift 2 ;; 124 -C|--check) 125 CHECK='C=1' 126 shift ;; 127 -n|--continue) 128 CONTINUE='y' 129 shift ;; 130 -r|--rebuild-errors) 131 REBUILD_ERRORS='y' 132 shift ;; 133 -l|--list) 134 ONLY_LIST='y' 135 shift ;; 136 -m|--maintainers) 137 ONLY_LIST='y' 138 PRINT_MAINTS='y' 139 MAINTAINERS_ONLY='y' 140 shift ;; 141 -M|--mails) 142 ONLY_LIST='y' 143 PRINT_MAINTS='y' 144 shift ;; 145 -h|--help) 146 usage ;; 147 --) 148 shift ; break ;; 149 *) 150 echo "Internal error!" >&2 ; exit 1 ;; 151 esac 152done 153# echo "Remaining arguments:" 154# for arg do echo '--> '"\`$arg'" ; done 155 156FILTER="\$1 !~ /^#/" 157[ "$opt_a" ] && FILTER="${FILTER} && $opt_a" 158[ "$opt_c" ] && FILTER="${FILTER} && $opt_c" 159[ "$opt_s" ] && FILTER="${FILTER} && $opt_s" 160[ "$opt_v" ] && FILTER="${FILTER} && $opt_v" 161 162if [ "$SELECTED" ] ; then 163 SELECTED=$(awk '('"$FILTER"') { print $7 }' boards.cfg) 164 165 # Make sure some boards from boards.cfg are actually found 166 if [ -z "$SELECTED" ] ; then 167 echo "Error: No boards selected, invalid arguments" 168 exit 1 169 fi 170fi 171 172######################################################################### 173 174# Print statistics when we exit 175trap exit 1 2 3 15 176trap print_stats 0 177 178# Determine number of CPU cores if no default was set 179: ${BUILD_NCPUS:="`getconf _NPROCESSORS_ONLN`"} 180 181if [ "$BUILD_NCPUS" -gt 1 ] 182then 183 JOBS="-j $((BUILD_NCPUS + 1))" 184else 185 JOBS="" 186fi 187 188if [ "${MAKEALL_LOGDIR}" ] ; then 189 LOG_DIR=${MAKEALL_LOGDIR} 190else 191 LOG_DIR="LOG" 192fi 193 194: ${BUILD_NBUILDS:=1} 195BUILD_MANY=0 196 197if [ "${BUILD_NBUILDS}" -gt 1 ] ; then 198 BUILD_MANY=1 199 : ${BUILD_DIR:=./build} 200 mkdir -p "${BUILD_DIR}/ERR" 201 find "${BUILD_DIR}/ERR/" -type f -exec rm -f {} + 202fi 203 204: ${BUILD_DIR:=.} 205 206OUTPUT_PREFIX="${BUILD_DIR}" 207 208[ -d ${LOG_DIR} ] || mkdir "${LOG_DIR}" || exit 1 209if [ "$CONTINUE" != 'y' -a "$REBUILD_ERRORS" != 'y' ] ; then 210 find "${LOG_DIR}/" -type f -exec rm -f {} + 211fi 212 213LIST="" 214 215# Keep track of the number of builds and errors 216ERR_CNT=0 217ERR_LIST="" 218WRN_CNT=0 219WRN_LIST="" 220TOTAL_CNT=0 221SKIP_CNT=0 222CURRENT_CNT=0 223OLDEST_IDX=1 224RC=0 225 226# Helper funcs for parsing boards.cfg 227boards_by_field() 228{ 229 FS="[ \t]+" 230 [ -n "$3" ] && FS="$3" 231 awk \ 232 -v field="$1" \ 233 -v select="$2" \ 234 -F "$FS" \ 235 '($1 !~ /^#/ && $field == select) { print $7 }' \ 236 boards.cfg 237} 238boards_by_arch() { boards_by_field 2 "$@" ; } 239boards_by_cpu() { boards_by_field 3 "$@" "[: \t]+" ; } 240boards_by_soc() { boards_by_field 4 "$@" ; } 241 242######################################################################### 243## MPC5xx Systems 244######################################################################### 245 246LIST_5xx="$(boards_by_cpu mpc5xx)" 247 248######################################################################### 249## MPC5xxx Systems 250######################################################################### 251 252LIST_5xxx="$(boards_by_cpu mpc5xxx)" 253 254######################################################################### 255## MPC512x Systems 256######################################################################### 257 258LIST_512x="$(boards_by_cpu mpc512x)" 259 260######################################################################### 261## MPC8xx Systems 262######################################################################### 263 264LIST_8xx="$(boards_by_cpu mpc8xx)" 265 266######################################################################### 267## PPC4xx Systems 268######################################################################### 269 270LIST_4xx="$(boards_by_cpu ppc4xx)" 271 272######################################################################### 273## MPC824x Systems 274######################################################################### 275 276LIST_824x="$(boards_by_cpu mpc824x)" 277 278######################################################################### 279## MPC8260 Systems (includes 8250, 8255 etc.) 280######################################################################### 281 282LIST_8260="$(boards_by_cpu mpc8260)" 283 284######################################################################### 285## MPC83xx Systems (includes 8349, etc.) 286######################################################################### 287 288LIST_83xx="$(boards_by_cpu mpc83xx)" 289 290######################################################################### 291## MPC85xx Systems (includes 8540, 8560 etc.) 292######################################################################### 293 294LIST_85xx="$(boards_by_cpu mpc85xx)" 295 296######################################################################### 297## MPC86xx Systems 298######################################################################### 299 300LIST_86xx="$(boards_by_cpu mpc86xx)" 301 302######################################################################### 303## 74xx/7xx Systems 304######################################################################### 305 306LIST_74xx_7xx="$(boards_by_cpu 74xx_7xx)" 307 308######################################################################### 309## PowerPC groups 310######################################################################### 311 312LIST_TSEC=" \ 313 ${LIST_83xx} \ 314 ${LIST_85xx} \ 315 ${LIST_86xx} \ 316" 317 318LIST_powerpc=" \ 319 ${LIST_5xx} \ 320 ${LIST_512x} \ 321 ${LIST_5xxx} \ 322 ${LIST_8xx} \ 323 ${LIST_824x} \ 324 ${LIST_8260} \ 325 ${LIST_83xx} \ 326 ${LIST_85xx} \ 327 ${LIST_86xx} \ 328 ${LIST_4xx} \ 329 ${LIST_74xx_7xx}\ 330" 331 332# Alias "ppc" -> "powerpc" to not break compatibility with older scripts 333# still using "ppc" instead of "powerpc" 334LIST_ppc=" \ 335 ${LIST_powerpc} \ 336" 337 338######################################################################### 339## StrongARM Systems 340######################################################################### 341 342LIST_SA="$(boards_by_cpu sa1100)" 343 344######################################################################### 345## ARM7 Systems 346######################################################################### 347 348LIST_ARM7="$(boards_by_cpu arm720t)" 349 350######################################################################### 351## ARM9 Systems 352######################################################################### 353 354LIST_ARM9="$(boards_by_cpu arm920t) \ 355 $(boards_by_cpu arm926ejs) \ 356 $(boards_by_cpu arm946es) \ 357" 358 359######################################################################### 360## ARM11 Systems 361######################################################################### 362LIST_ARM11="$(boards_by_cpu arm1136) \ 363 $(boards_by_cpu arm1176) \ 364" 365 366######################################################################### 367## ARMV7 Systems 368######################################################################### 369 370LIST_ARMV7="$(boards_by_cpu armv7)" 371 372######################################################################### 373## AT91 Systems 374######################################################################### 375 376LIST_at91="$(boards_by_soc at91)" 377 378######################################################################### 379## Xscale Systems 380######################################################################### 381 382LIST_pxa="$(boards_by_cpu pxa)" 383 384LIST_ixp="$(boards_by_cpu ixp)" 385 386######################################################################### 387## SPEAr Systems 388######################################################################### 389 390LIST_spear="$(boards_by_soc spear)" 391 392######################################################################### 393## ARM groups 394######################################################################### 395 396LIST_arm="$(boards_by_arch arm)" 397 398######################################################################### 399## MIPS Systems (default = big endian) 400######################################################################### 401 402LIST_mips4kc=" \ 403 incaip \ 404 incaip_100MHz \ 405 incaip_133MHz \ 406 incaip_150MHz \ 407 qemu_mips \ 408 vct_platinum \ 409 vct_platinum_small \ 410 vct_platinum_onenand \ 411 vct_platinum_onenand_small \ 412 vct_platinumavc \ 413 vct_platinumavc_small \ 414 vct_platinumavc_onenand \ 415 vct_platinumavc_onenand_small \ 416 vct_premium \ 417 vct_premium_small \ 418 vct_premium_onenand \ 419 vct_premium_onenand_small \ 420" 421 422LIST_au1xx0=" \ 423 dbau1000 \ 424 dbau1100 \ 425 dbau1500 \ 426 dbau1550 \ 427" 428 429LIST_mips=" \ 430 ${LIST_mips4kc} \ 431 ${LIST_mips5kc} \ 432 ${LIST_au1xx0} \ 433" 434 435######################################################################### 436## MIPS Systems (little endian) 437######################################################################### 438 439LIST_au1xx0_el=" \ 440 dbau1550_el \ 441 pb1000 \ 442" 443LIST_mips_el=" \ 444 ${LIST_au1xx0_el} \ 445" 446######################################################################### 447## OpenRISC Systems 448######################################################################### 449 450LIST_openrisc="$(boards_by_arch openrisc)" 451 452######################################################################### 453## x86 Systems 454######################################################################### 455 456LIST_x86="$(boards_by_arch x86)" 457 458######################################################################### 459## Nios-II Systems 460######################################################################### 461 462LIST_nios2="$(boards_by_arch nios2)" 463 464######################################################################### 465## MicroBlaze Systems 466######################################################################### 467 468LIST_microblaze="$(boards_by_arch microblaze)" 469 470######################################################################### 471## ColdFire Systems 472######################################################################### 473 474LIST_m68k="$(boards_by_arch m68k)" 475LIST_coldfire=${LIST_m68k} 476 477######################################################################### 478## AVR32 Systems 479######################################################################### 480 481LIST_avr32="$(boards_by_arch avr32)" 482 483######################################################################### 484## Blackfin Systems 485######################################################################### 486 487LIST_blackfin="$(boards_by_arch blackfin)" 488 489######################################################################### 490## SH Systems 491######################################################################### 492 493LIST_sh2="$(boards_by_cpu sh2)" 494LIST_sh3="$(boards_by_cpu sh3)" 495LIST_sh4="$(boards_by_cpu sh4)" 496 497LIST_sh="$(boards_by_arch sh)" 498 499######################################################################### 500## SPARC Systems 501######################################################################### 502 503LIST_sparc="$(boards_by_arch sparc)" 504 505######################################################################### 506## NDS32 Systems 507######################################################################### 508 509LIST_nds32="$(boards_by_arch nds32)" 510 511#----------------------------------------------------------------------- 512 513get_target_location() { 514 local target=$1 515 local BOARD_NAME="" 516 local CONFIG_NAME="" 517 local board="" 518 local vendor="" 519 520 # Automatic mode 521 local line=`awk -F '\ +' '\$7 == "'"$target"'" { print \$0 }' boards.cfg` 522 if [ -z "${line}" ] ; then echo "" ; return ; fi 523 524 set ${line} 525 526 CONFIG_NAME="${7%_config}" 527 528 [ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}" 529 530 if [ $# -gt 5 ]; then 531 if [ "$6" = "-" ] ; then 532 board=${BOARD_NAME} 533 else 534 board="$6" 535 fi 536 fi 537 538 [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5" 539 [ $# -gt 6 ] && [ "$8" != "-" ] && { 540 tmp="${8%:*}" 541 if [ "$tmp" ] ; then 542 CONFIG_NAME="$tmp" 543 fi 544 } 545 546 # Assign board directory to BOARDIR variable 547 if [ "${vendor}" == "-" ] ; then 548 BOARDDIR=${board} 549 else 550 BOARDDIR=${vendor}/${board} 551 fi 552 553 echo "${CONFIG_NAME}:${BOARDDIR}:${BOARD_NAME}" 554} 555 556get_target_maintainers() { 557 local name=`echo $1 | cut -d : -f 3` 558 559 local line=`awk -F '\ +' '\$7 == "'"$target"'" { print \$0 }' boards.cfg` 560 if [ -z "${line}" ]; then 561 echo "" 562 return ; 563 fi 564 565 local mails=`echo ${line} | cut -d ' ' -f 9- | sed -e 's/[^<]*<//' -e 's/>.*</ /' -e 's/>[^>]*$//'` 566 [ "$mails" == "-" ] && mails="" 567 echo "$mails" 568} 569 570get_target_arch() { 571 local target=$1 572 573 # Automatic mode 574 local line=`egrep -i "^[[:space:]]*${target}[[:space:]]" boards.cfg` 575 576 if [ -z "${line}" ] ; then echo "" ; return ; fi 577 578 set ${line} 579 echo "$2" 580} 581 582list_target() { 583 if [ "$PRINT_MAINTS" != 'y' ] ; then 584 echo "$1" 585 return 586 fi 587 588 echo -n "$1:" 589 590 local loc=`get_target_location $1` 591 592 if [ -z "${loc}" ] ; then echo "ERROR" ; return ; fi 593 594 local maintainers_result=`get_target_maintainers ${loc} | tr " " "\n"` 595 596 if [ "$MAINTAINERS_ONLY" != 'y' ] ; then 597 598 local dir=`echo ${loc} | cut -d ":" -f 2` 599 local cfg=`echo ${loc} | cut -d ":" -f 1` 600 local git_result=`git log --format=%aE board/${dir} \ 601 include/configs/${cfg}.h | grep "@"` 602 local git_result_recent=`echo ${git_result} | tr " " "\n" | \ 603 head -n 3` 604 local git_result_top=`echo ${git_result} | tr " " "\n" | \ 605 sort | uniq -c | sort -nr | head -n 3 | \ 606 sed "s/^ \+[0-9]\+ \+//"` 607 608 echo -e "$git_result_recent\n$git_result_top\n$maintainers_result" | \ 609 sort -u | tr "\n" " " | sed "s/ $//" ; 610 else 611 echo -e "$maintainers_result" | sort -u | tr "\n" " " | \ 612 sed "s/ $//" ; 613 fi 614 615 echo "" 616} 617 618# Each finished build will have a file called ${donep}${n}, 619# where n is the index of the build. Each build 620# we've already noted as finished will have ${skipp}${n}. 621# The code managing the build process will use this information 622# to ensure that only BUILD_NBUILDS builds are in flight at once 623donep="${LOG_DIR}/._done_" 624skipp="${LOG_DIR}/._skip_" 625 626build_target_killed() { 627 echo "Aborted $target build." 628 # Remove the logs for this board since it was aborted 629 rm -f ${LOG_DIR}/$target.MAKELOG ${LOG_DIR}/$target.ERR 630 exit 631} 632 633build_target() { 634 target=$1 635 build_idx=$2 636 637 if [ "$ONLY_LIST" == 'y' ] ; then 638 list_target ${target} 639 return 640 fi 641 642 if [ $BUILD_MANY == 1 ] ; then 643 output_dir="${OUTPUT_PREFIX}/${target}" 644 mkdir -p "${output_dir}" 645 trap build_target_killed TERM 646 else 647 output_dir="${OUTPUT_PREFIX}" 648 fi 649 650 export BUILD_DIR="${output_dir}" 651 652 target_arch=$(get_target_arch ${target}) 653 eval cross_toolchain=\$CROSS_COMPILE_`echo $target_arch | tr '[:lower:]' '[:upper:]'` 654 if [ "${cross_toolchain}" ] ; then 655 MAKE="make CROSS_COMPILE=${cross_toolchain}" 656 elif [ "${CROSS_COMPILE}" ] ; then 657 MAKE="make CROSS_COMPILE=${CROSS_COMPILE}" 658 else 659 MAKE=make 660 fi 661 662 ${MAKE} distclean >/dev/null 663 ${MAKE} -s ${target}_config 664 665 ${MAKE} ${JOBS} ${CHECK} all \ 666 >${LOG_DIR}/$target.MAKELOG 2> ${LOG_DIR}/$target.ERR 667 668 # Check for 'make' errors 669 if [ ${PIPESTATUS[0]} -ne 0 ] ; then 670 RC=1 671 fi 672 673 if [ $BUILD_MANY == 1 ] ; then 674 trap - TERM 675 676 ${MAKE} -s tidy 677 678 if [ -s ${LOG_DIR}/${target}.ERR ] ; then 679 cp ${LOG_DIR}/${target}.ERR ${OUTPUT_PREFIX}/ERR/${target} 680 else 681 rm ${LOG_DIR}/${target}.ERR 682 fi 683 else 684 if [ -s ${LOG_DIR}/${target}.ERR ] ; then 685 if grep -iw error ${LOG_DIR}/${target}.ERR ; then 686 : $(( ERR_CNT += 1 )) 687 ERR_LIST="${ERR_LIST} $target" 688 else 689 : $(( WRN_CNT += 1 )) 690 WRN_LIST="${WRN_LIST} $target" 691 fi 692 else 693 rm ${LOG_DIR}/${target}.ERR 694 fi 695 fi 696 697 OBJS=${output_dir}/u-boot 698 if [ -e ${output_dir}/spl/u-boot-spl ]; then 699 OBJS="${OBJS} ${output_dir}/spl/u-boot-spl" 700 fi 701 702 ${CROSS_COMPILE}size ${OBJS} | tee -a ${LOG_DIR}/$target.MAKELOG 703 704 [ -e "${LOG_DIR}/${target}.ERR" ] && cat "${LOG_DIR}/${target}.ERR" 705 706 touch "${donep}${build_idx}" 707} 708 709manage_builds() { 710 search_idx=${OLDEST_IDX} 711 if [ "$ONLY_LIST" == 'y' ] ; then return ; fi 712 713 while true; do 714 if [ -e "${donep}${search_idx}" ] ; then 715 : $(( CURRENT_CNT-- )) 716 [ ${OLDEST_IDX} -eq ${search_idx} ] && 717 : $(( OLDEST_IDX++ )) 718 719 # Only want to count it once 720 rm -f "${donep}${search_idx}" 721 touch "${skipp}${search_idx}" 722 elif [ -e "${skipp}${search_idx}" ] ; then 723 [ ${OLDEST_IDX} -eq ${search_idx} ] && 724 : $(( OLDEST_IDX++ )) 725 fi 726 : $(( search_idx++ )) 727 if [ ${search_idx} -gt ${TOTAL_CNT} ] ; then 728 if [ ${CURRENT_CNT} -ge ${BUILD_NBUILDS} ] ; then 729 search_idx=${OLDEST_IDX} 730 sleep 1 731 else 732 break 733 fi 734 fi 735 done 736} 737 738build_targets() { 739 for t in "$@" ; do 740 # If a LIST_xxx var exists, use it. But avoid variable 741 # expansion in the eval when a board name contains certain 742 # characters that the shell interprets. 743 case ${t} in 744 *[-+=]*) list= ;; 745 *) list=$(eval echo '${LIST_'$t'}') ;; 746 esac 747 if [ -n "${list}" ] ; then 748 build_targets ${list} 749 else 750 : $((TOTAL_CNT += 1)) 751 : $((CURRENT_CNT += 1)) 752 rm -f "${donep}${TOTAL_CNT}" 753 rm -f "${skipp}${TOTAL_CNT}" 754 if [ "$CONTINUE" = 'y' -a -e ${LOG_DIR}/$t.MAKELOG ] ; then 755 : $((SKIP_CNT += 1)) 756 touch "${donep}${TOTAL_CNT}" 757 elif [ "$REBUILD_ERRORS" = 'y' -a ! -e ${LOG_DIR}/$t.ERR ] ; then 758 : $((SKIP_CNT += 1)) 759 touch "${donep}${TOTAL_CNT}" 760 else 761 if [ $BUILD_MANY == 1 ] ; then 762 build_target ${t} ${TOTAL_CNT} & 763 else 764 CUR_TGT="${t}" 765 build_target ${t} ${TOTAL_CNT} 766 CUR_TGT='' 767 fi 768 fi 769 fi 770 771 # We maintain a running count of all the builds we have done. 772 # Each finished build will have a file called ${donep}${n}, 773 # where n is the index of the build. Each build 774 # we've already noted as finished will have ${skipp}${n}. 775 # We track the current index via TOTAL_CNT, and the oldest 776 # index. When we exceed the maximum number of parallel builds, 777 # We look from oldest to current for builds that have completed, 778 # and update the current count and oldest index as appropriate. 779 # If we've gone through the entire list, wait a second, and 780 # reprocess the entire list until we find a build that has 781 # completed 782 if [ ${CURRENT_CNT} -ge ${BUILD_NBUILDS} ] ; then 783 manage_builds 784 fi 785 done 786} 787 788#----------------------------------------------------------------------- 789 790kill_children() { 791 local OS=$(uname -s) 792 local children="" 793 case "${OS}" in 794 "Darwin") 795 # Mac OS X is known to have BSD style ps 796 local pgid=$(ps -p $$ -o pgid | sed -e "/PGID/d") 797 children=$(ps -g $pgid -o pid | sed -e "/PID\|$$\|$pgid/d") 798 ;; 799 *) 800 # everything else tries the GNU style 801 local pgid=$(ps -p $$ --no-headers -o "%r" | tr -d ' ') 802 children=$(pgrep -g $pgid | sed -e "/$$\|$pgid/d") 803 ;; 804 esac 805 806 kill $children 2> /dev/null 807 wait $children 2> /dev/null 808 809 exit 810} 811 812print_stats() { 813 if [ "$ONLY_LIST" == 'y' ] ; then return ; fi 814 815 # Only count boards that completed 816 : $((TOTAL_CNT = `find ${skipp}* 2> /dev/null | wc -l`)) 817 818 rm -f ${donep}* ${skipp}* 819 820 if [ $BUILD_MANY == 1 ] && [ -e "${OUTPUT_PREFIX}/ERR" ] ; then 821 ERR_LIST=`grep -riwl error ${OUTPUT_PREFIX}/ERR/` 822 ERR_LIST=`for f in $ERR_LIST ; do echo -n " $(basename $f)" ; done` 823 ERR_CNT=`echo $ERR_LIST | wc -w | awk '{print $1}'` 824 WRN_LIST=`grep -riwL error ${OUTPUT_PREFIX}/ERR/` 825 WRN_LIST=`for f in $WRN_LIST ; do echo -n " $(basename $f)" ; done` 826 WRN_CNT=`echo $WRN_LIST | wc -w | awk '{print $1}'` 827 else 828 # Remove the logs for any board that was interrupted 829 rm -f ${LOG_DIR}/${CUR_TGT}.MAKELOG ${LOG_DIR}/${CUR_TGT}.ERR 830 fi 831 832 : $((TOTAL_CNT -= ${SKIP_CNT})) 833 echo "" 834 echo "--------------------- SUMMARY ----------------------------" 835 if [ "$CONTINUE" = 'y' -o "$REBUILD_ERRORS" = 'y' ] ; then 836 echo "Boards skipped: ${SKIP_CNT}" 837 fi 838 echo "Boards compiled: ${TOTAL_CNT}" 839 if [ ${ERR_CNT} -gt 0 ] ; then 840 echo "Boards with errors: ${ERR_CNT} (${ERR_LIST} )" 841 fi 842 if [ ${WRN_CNT} -gt 0 ] ; then 843 echo "Boards with warnings but no errors: ${WRN_CNT} (${WRN_LIST} )" 844 fi 845 echo "----------------------------------------------------------" 846 847 if [ $BUILD_MANY == 1 ] ; then 848 kill_children 849 fi 850 851 exit $RC 852} 853 854#----------------------------------------------------------------------- 855 856# Build target groups selected by options, plus any command line args 857set -- ${SELECTED} "$@" 858# run PowerPC by default 859[ $# = 0 ] && set -- powerpc 860build_targets "$@" 861wait 862