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