build.sh revision 1.122
1#! /usr/bin/env sh 2# $NetBSD: build.sh,v 1.122 2003/10/26 03:12:21 lukem Exp $ 3# 4# Copyright (c) 2001-2003 The NetBSD Foundation, Inc. 5# All rights reserved. 6# 7# This code is derived from software contributed to The NetBSD Foundation 8# by Todd Vierling and Luke Mewburn. 9# 10# Redistribution and use in source and binary forms, with or without 11# modification, are permitted provided that the following conditions 12# are met: 13# 1. Redistributions of source code must retain the above copyright 14# notice, this list of conditions and the following disclaimer. 15# 2. Redistributions in binary form must reproduce the above copyright 16# notice, this list of conditions and the following disclaimer in the 17# documentation and/or other materials provided with the distribution. 18# 3. All advertising materials mentioning features or use of this software 19# must display the following acknowledgement: 20# This product includes software developed by the NetBSD 21# Foundation, Inc. and its contributors. 22# 4. Neither the name of The NetBSD Foundation nor the names of its 23# contributors may be used to endorse or promote products derived 24# from this software without specific prior written permission. 25# 26# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36# POSSIBILITY OF SUCH DAMAGE. 37# 38# 39# Top level build wrapper, for a system containing no tools. 40# 41# This script should run on any POSIX-compliant shell. For systems 42# with a strange /bin/sh, "ksh" or "bash" may be an ample alternative. 43# 44# Note, however, that due to the way the interpreter is invoked above, 45# if a POSIX-compliant shell is the first in the PATH, you won't have 46# to take any further action. 47# 48 49progname=${0##*/} 50toppid=$$ 51results=/dev/null 52trap "exit 1" 1 2 3 15 53 54bomb() 55{ 56 cat >&2 <<ERRORMESSAGE 57 58ERROR: $@ 59*** BUILD ABORTED *** 60ERRORMESSAGE 61 kill ${toppid} # in case we were invoked from a subshell 62 exit 1 63} 64 65 66statusmsg() 67{ 68 ${runcmd} echo "===> $@" | tee -a "${results}" 69} 70 71initdefaults() 72{ 73 cd "$(dirname $0)" 74 [ -d usr.bin/make ] || 75 bomb "build.sh must be run from the top source level" 76 [ -f share/mk/bsd.own.mk ] || 77 bomb "src/share/mk is missing; please re-fetch the source tree" 78 79 uname_s=$(uname -s 2>/dev/null) 80 uname_m=$(uname -m 2>/dev/null) 81 82 # If $PWD is a valid name of the current directory, POSIX mandates 83 # that pwd return it by default which causes problems in the 84 # presence of symlinks. Unsetting PWD is simpler than changing 85 # every occurrence of pwd to use -P. 86 # 87 # XXX Except that doesn't work on Solaris. 88 # 89 unset PWD 90 if [ "${uname_s}" = "SunOS" ]; then 91 TOP=$(pwd -P) 92 else 93 TOP=$(pwd) 94 fi 95 96 # Set defaults. 97 # 98 toolprefix=nb 99 100 # Some systems have a small ARG_MAX. -X prevents make(1) from 101 # exporting variables in the environment redundantly. 102 # 103 case "${uname_s}" in 104 Darwin | FreeBSD | CYGWIN*) 105 MAKEFLAGS=-X 106 ;; 107 *) 108 MAKEFLAGS= 109 ;; 110 esac 111 112 makeenv= 113 makewrapper= 114 makewrappermachine= 115 runcmd= 116 operations= 117 removedirs= 118 do_expertmode=false 119 do_rebuildmake=false 120 do_removedirs=false 121 122 # do_{operation}=true if given operation is requested. 123 # 124 do_tools=false 125 do_obj=false 126 do_build=false 127 do_distribution=false 128 do_release=false 129 do_kernel=false 130 do_releasekernel=false 131 do_install=false 132 do_sets=false 133 do_sourcesets=false 134 do_params=false 135 136 # Create scratch directory 137 # 138 tmpdir="${TMPDIR-/tmp}/nbbuild$$" 139 mkdir "${tmpdir}" || bomb "Cannot mkdir: ${tmpdir}" 140 trap "cd /; rm -r -f \"${tmpdir}\"" 0 141 results="${tmpdir}/build.sh.results" 142 143 # Set source directories 144 # 145 setmakeenv NETBSDSRCDIR "${TOP}" 146} 147 148getarch() 149{ 150 # Translate a MACHINE into a default MACHINE_ARCH. 151 # 152 case "${MACHINE}" in 153 154 acorn26|acorn32|cats|evbarm|hpcarm|netwinder|shark) 155 MACHINE_ARCH=arm 156 ;; 157 158 hp700) 159 MACHINE_ARCH=hppa 160 ;; 161 162 sun2) 163 MACHINE_ARCH=m68000 164 ;; 165 166 amiga|atari|cesfic|hp300|luna68k|mac68k|mvme68k|news68k|next68k|sun3|x68k) 167 MACHINE_ARCH=m68k 168 ;; 169 170 evbmips-e[bl]|sbmips-e[bl]) 171 MACHINE_ARCH=mips${MACHINE##*-} 172 makewrappermachine=${MACHINE} 173 MACHINE=${MACHINE%-e[bl]} 174 ;; 175 176 evbmips|sbmips) # no default MACHINE_ARCH 177 ;; 178 179 mipsco|newsmips|sgimips) 180 MACHINE_ARCH=mipseb 181 ;; 182 183 algor|arc|cobalt|hpcmips|playstation2|pmax) 184 MACHINE_ARCH=mipsel 185 ;; 186 187 pc532) 188 MACHINE_ARCH=ns32k 189 ;; 190 191 amigappc|bebox|evbppc|ibmnws|macppc|mvmeppc|ofppc|pmppc|prep|sandpoint) 192 MACHINE_ARCH=powerpc 193 ;; 194 195 evbsh3-e[bl]) 196 MACHINE_ARCH=sh3${MACHINE##*-} 197 makewrappermachine=${MACHINE} 198 MACHINE=${MACHINE%-e[bl]} 199 ;; 200 201 evbsh3) # no default MACHINE_ARCH 202 ;; 203 204 mmeye) 205 MACHINE_ARCH=sh3eb 206 ;; 207 208 dreamcast|hpcsh) 209 MACHINE_ARCH=sh3el 210 ;; 211 212 evbsh5) 213 MACHINE_ARCH=sh5el 214 ;; 215 amd64) 216 MACHINE_ARCH=x86_64 217 ;; 218 219 alpha|i386|sparc|sparc64|vax) 220 MACHINE_ARCH=${MACHINE} 221 ;; 222 223 *) 224 bomb "Unknown target MACHINE: ${MACHINE}" 225 ;; 226 227 esac 228} 229 230validatearch() 231{ 232 # Ensure that the MACHINE_ARCH exists (and is supported by build.sh). 233 # 234 case "${MACHINE_ARCH}" in 235 236 alpha|arm|armeb|hppa|i386|m68000|m68k|mipse[bl]|ns32k|powerpc|sh[35]e[bl]|sparc|sparc64|vax|x86_64) 237 ;; 238 239 "") 240 bomb "No MACHINE_ARCH provided" 241 ;; 242 243 *) 244 bomb "Unknown target MACHINE_ARCH: ${MACHINE_ARCH}" 245 ;; 246 247 esac 248 249 # Determine valid MACHINE_ARCHs for MACHINE 250 # 251 case "${MACHINE}" in 252 253 evbarm) 254 arches="arm armeb" 255 ;; 256 257 evbmips|sbmips) 258 arches="mipseb mipsel" 259 ;; 260 261 evbsh3) 262 arches="sh3eb sh3el" 263 ;; 264 265 evbsh5) 266 arches="sh5eb sh5el" 267 ;; 268 269 *) 270 oma="${MACHINE_ARCH}" 271 getarch 272 arches="${MACHINE_ARCH}" 273 MACHINE_ARCH="${oma}" 274 ;; 275 276 esac 277 278 # Ensure that MACHINE_ARCH supports MACHINE 279 # 280 archok=false 281 for a in ${arches}; do 282 if [ "${a}" = "${MACHINE_ARCH}" ]; then 283 archok=true 284 break 285 fi 286 done 287 ${archok} || 288 bomb "MACHINE_ARCH '${MACHINE_ARCH}' does not support MACHINE '${MACHINE}'" 289} 290 291raw_getmakevar() 292{ 293 [ -x "${make}" ] || bomb "raw_getmakevar $1: ${make} is not executable" 294 "${make}" -m ${TOP}/share/mk -s -f- _x_ <<EOF 295_x_: 296 echo \${$1} 297.include <bsd.prog.mk> 298.include <bsd.kernobj.mk> 299EOF 300} 301 302getmakevar() 303{ 304 # raw_getmakevar() doesn't work properly if $make hasn't yet been 305 # built, which can happen when running with the "-n" option. 306 # getmakevar() deals with this by emitting a literal '$' 307 # followed by the variable name, instead of trying to find the 308 # variable's value. 309 # 310 if [ -x "${make}" ]; then 311 raw_getmakevar "$1" 312 else 313 echo "\$$1" 314 fi 315} 316 317setmakeenv() 318{ 319 eval "$1='$2'; export $1" 320 makeenv="${makeenv} $1" 321} 322 323unsetmakeenv() 324{ 325 eval "unset $1" 326 makeenv="${makeenv} $1" 327} 328 329resolvepath() 330{ 331 case "${OPTARG}" in 332 /*) 333 ;; 334 *) 335 OPTARG="${TOP}/${OPTARG}" 336 ;; 337 esac 338} 339 340usage() 341{ 342 if [ -n "$*" ]; then 343 echo "" 344 echo "${progname}: $*" 345 fi 346 cat <<_usage_ 347 348Usage: ${progname} [-EnorUu] [-a arch] [-B buildid] [-D dest] [-j njob] 349 [-M obj] [-m mach] [-N noisy] [-O obj] [-R release] [-T tools] 350 [-V var=[value]] [-w wrapper] [-Z var] operation [...] 351 352 Build operations (all imply "obj" and "tools"): 353 build Run "make build" 354 distribution Run "make distribution" (includes DESTDIR/etc/ files) 355 release Run "make release" (includes kernels & distrib media) 356 357 Other operations: 358 help Show this message (and exit) 359 makewrapper Create ${toolprefix}make-\${MACHINE} wrapper and ${toolprefix}make. 360 (Always done) 361 obj Run "make obj" (default unless -o is used) 362 tools Build and install tools 363 install=idir Run "make installworld" to \`idir' 364 (useful after 'distribution' or 'release') 365 kernel=conf Build kernel with config file \`conf' 366 releasekernel=conf Install kernel built by kernel=conf to RELEASEDIR 367 sets Create binary sets in RELEASEDIR/MACHINE/binary/sets 368 sourcesets Create source sets in RELEASEDIR/source/sets 369 params Display various make(1) parameters 370 371 Options: 372 -a arch Set MACHINE_ARCH to arch (otherwise deduced from MACHINE) 373 -B buildId Set BUILDID to buildId 374 -D dest Set DESTDIR to dest. [Default: destdir.MACHINE] 375 -E Set "expert" mode; disables various safety checks. 376 Should not be used without expert knowledge of the build system 377 -j njob Run up to njob jobs in parallel; see make(1) 378 -M obj Set obj root directory to obj (sets MAKEOBJDIRPREFIX) 379 Unsets MAKEOBJDIR. 380 -m mach Set MACHINE to mach (not required if NetBSD native) 381 -N noisy Set the noisyness level of the build: 382 0 Quiet 383 1 Operations are described, commands are suppressed 384 2 Full output 385 [Default: 2] 386 -n Show commands that would be executed, but do not execute them 387 -O obj Set obj root directory to obj (sets a MAKEOBJDIR pattern). 388 Unsets MAKEOBJDIRPREFIX. 389 -o Set MKOBJDIRS=no (do not create objdirs at start of build) 390 -R release Set RELEASEDIR to release. [Default: releasedir] 391 -r Remove contents of TOOLDIR and DESTDIR before building 392 -T tools Set TOOLDIR to tools. If unset, and TOOLDIR is not set in 393 the environment, ${toolprefix}make will be (re)built unconditionally 394 -U Set MKUNPRIVED=yes (build without requiring root privileges; 395 install from an UNPRIVED build with proper file permissions) 396 -u Set MKUPDATE=yes (do not run "make clean" first). 397 Without this, everything is rebuilt, including the tools. 398 -V v=[val] Set variable \`v' to \`val' 399 -w wrapper Create ${toolprefix}make script as wrapper 400 [Default: \${TOOLDIR}/bin/${toolprefix}make-\${MACHINE}] 401 -Z v Unset ("zap") variable \`v' 402 403_usage_ 404 exit 1 405} 406 407parseoptions() 408{ 409 opts='a:B:bD:dEhi:j:k:M:m:N:nO:oR:rT:tUuV:w:Z:' 410 opt_a=no 411 412 if type getopts >/dev/null 2>&1; then 413 # Use POSIX getopts. 414 # 415 getoptcmd='getopts ${opts} opt && opt=-${opt}' 416 optargcmd=':' 417 optremcmd='shift $((${OPTIND} -1))' 418 else 419 type getopt >/dev/null 2>&1 || 420 bomb "/bin/sh shell is too old; try ksh or bash" 421 422 # Use old-style getopt(1) (doesn't handle whitespace in args). 423 # 424 args="$(getopt ${opts} $*)" 425 [ $? = 0 ] || usage 426 set -- ${args} 427 428 getoptcmd='[ $# -gt 0 ] && opt="$1" && shift' 429 optargcmd='OPTARG="$1"; shift' 430 optremcmd=':' 431 fi 432 433 # Parse command line options. 434 # 435 while eval ${getoptcmd}; do 436 case ${opt} in 437 438 -a) 439 eval ${optargcmd} 440 MACHINE_ARCH=${OPTARG} 441 opt_a=yes 442 ;; 443 444 -B) 445 eval ${optargcmd} 446 BUILDID=${OPTARG} 447 ;; 448 449 -b) 450 usage "'-b' has been replaced by 'makewrapper'" 451 ;; 452 453 -D) 454 eval ${optargcmd}; resolvepath 455 setmakeenv DESTDIR "${OPTARG}" 456 ;; 457 458 -d) 459 usage "'-d' has been replaced by 'distribution'" 460 ;; 461 462 -E) 463 do_expertmode=true 464 ;; 465 466 -i) 467 usage "'-i idir' has been replaced by 'install=idir'" 468 ;; 469 470 -j) 471 eval ${optargcmd} 472 parallel="-j ${OPTARG}" 473 ;; 474 475 -k) 476 usage "'-k conf' has been replaced by 'kernel=conf'" 477 ;; 478 479 -M) 480 eval ${optargcmd}; resolvepath 481 makeobjdir="${OPTARG}" 482 unsetmakeenv MAKEOBJDIR 483 setmakeenv MAKEOBJDIRPREFIX "${OPTARG}" 484 ;; 485 486 # -m overrides MACHINE_ARCH unless "-a" is specified 487 -m) 488 eval ${optargcmd} 489 MACHINE="${OPTARG}" 490 [ "${opt_a}" != "yes" ] && getarch 491 ;; 492 493 -N) 494 eval ${optargcmd} 495 case "${OPTARG}" in 496 0|1|2) 497 setmakeenv MAKEVERBOSE "${OPTARG}" 498 ;; 499 *) 500 usage "'${OPTARG}' is not a valid value for -N" 501 ;; 502 esac 503 ;; 504 505 -n) 506 runcmd=echo 507 ;; 508 509 -O) 510 eval ${optargcmd}; resolvepath 511 makeobjdir="${OPTARG}" 512 unsetmakeenv MAKEOBJDIRPREFIX 513 setmakeenv MAKEOBJDIR "\${.CURDIR:C,^$TOP,$OPTARG,}" 514 ;; 515 516 -o) 517 MKOBJDIRS=no 518 ;; 519 520 -R) 521 eval ${optargcmd}; resolvepath 522 setmakeenv RELEASEDIR "${OPTARG}" 523 ;; 524 525 -r) 526 do_removedirs=true 527 do_rebuildmake=true 528 ;; 529 530 -T) 531 eval ${optargcmd}; resolvepath 532 TOOLDIR="${OPTARG}" 533 export TOOLDIR 534 ;; 535 536 -t) 537 usage "'-t' has been replaced by 'tools'" 538 ;; 539 540 -U) 541 setmakeenv MKUNPRIVED yes 542 ;; 543 544 -u) 545 setmakeenv MKUPDATE yes 546 ;; 547 548 -V) 549 eval ${optargcmd} 550 case "${OPTARG}" in 551 # XXX: consider restricting which variables can be changed? 552 [a-zA-Z_][a-zA-Z_0-9]*=*) 553 setmakeenv "${OPTARG%%=*}" "${OPTARG#*=}" 554 ;; 555 *) 556 usage "-V argument must be of the form 'var=[value]'" 557 ;; 558 esac 559 ;; 560 561 -w) 562 eval ${optargcmd}; resolvepath 563 makewrapper="${OPTARG}" 564 ;; 565 566 -Z) 567 eval ${optargcmd} 568 # XXX: consider restricting which variables can be unset? 569 unsetmakeenv "${OPTARG}" 570 ;; 571 572 --) 573 break 574 ;; 575 576 -'?'|-h) 577 usage 578 ;; 579 580 esac 581 done 582 583 # Validate operations. 584 # 585 eval ${optremcmd} 586 while [ $# -gt 0 ]; do 587 op=$1; shift 588 operations="${operations} ${op}" 589 590 case "${op}" in 591 592 help) 593 usage 594 ;; 595 596 makewrapper|obj|tools|build|distribution|release|sets|sourcesets|params) 597 ;; 598 599 kernel=*|releasekernel=*) 600 arg=${op#*=} 601 op=${op%%=*} 602 [ -n "${arg}" ] || 603 bomb "Must supply a kernel name with \`${op}=...'" 604 ;; 605 606 install=*) 607 arg=${op#*=} 608 op=${op%%=*} 609 [ -n "${arg}" ] || 610 bomb "Must supply a directory with \`install=...'" 611 ;; 612 613 *) 614 usage "Unknown operation \`${op}'" 615 ;; 616 617 esac 618 eval do_${op}=true 619 done 620 [ -n "${operations}" ] || usage "Missing operation to perform." 621 622 # Set up MACHINE*. On a NetBSD host, these are allowed to be unset. 623 # 624 if [ -z "${MACHINE}" ]; then 625 [ "${uname_s}" = "NetBSD" ] || 626 bomb "MACHINE must be set, or -m must be used, for cross builds." 627 MACHINE=${uname_m} 628 fi 629 [ -n "${MACHINE_ARCH}" ] || getarch 630 validatearch 631 632 # Set up default make(1) environment. 633 # 634 setmakeenv LC_ALL C 635 makeenv="${makeenv} TOOLDIR MACHINE MACHINE_ARCH MAKEFLAGS" 636 [ -z "${BUILDID}" ] || makeenv="${makeenv} BUILDID" 637 MAKEFLAGS="-de -m ${TOP}/share/mk ${MAKEFLAGS} MKOBJDIRS=${MKOBJDIRS-yes}" 638 export MAKEFLAGS MACHINE MACHINE_ARCH 639} 640 641rebuildmake() 642{ 643 # Test make source file timestamps against installed ${toolprefix}make 644 # binary, if TOOLDIR is pre-set. 645 # 646 # Note that we do NOT try to grovel "mk.conf" here to find out if 647 # TOOLDIR is set there, because it can contain make variable 648 # expansions and other stuff only parseable *after* we have a working 649 # ${toolprefix}make. So this logic can only work if the user has 650 # pre-set TOOLDIR in the environment or used the -T option to build.sh. 651 # 652 make="${TOOLDIR-nonexistent}/bin/${toolprefix}make" 653 if [ -x "${make}" ]; then 654 for f in usr.bin/make/*.[ch] usr.bin/make/lst.lib/*.[ch]; do 655 if [ "${f}" -nt "${make}" ]; then 656 statusmsg "${make} outdated (older than ${f}), needs building." 657 do_rebuildmake=true 658 break 659 fi 660 done 661 else 662 statusmsg "No ${make}, needs building." 663 do_rebuildmake=true 664 fi 665 666 # Build bootstrap ${toolprefix}make if needed. 667 if ${do_rebuildmake}; then 668 statusmsg "Bootstrapping ${toolprefix}make" 669 ${runcmd} cd "${tmpdir}" 670 ${runcmd} env CC="${HOST_CC-cc}" CPPFLAGS="${HOST_CPPFLAGS}" \ 671 CFLAGS="${HOST_CFLAGS--O}" LDFLAGS="${HOST_LDFLAGS}" \ 672 sh "${TOP}/tools/make/configure" || 673 bomb "Configure of ${toolprefix}make failed" 674 ${runcmd} sh buildmake.sh || 675 bomb "Build of ${toolprefix}make failed" 676 make="${tmpdir}/${toolprefix}make" 677 ${runcmd} cd "${TOP}" 678 ${runcmd} rm -f usr.bin/make/*.o usr.bin/make/lst.lib/*.o 679 fi 680} 681 682validatemakeparams() 683{ 684 if [ "${runcmd}" = "echo" ]; then 685 TOOLCHAIN_MISSING=no 686 EXTERNAL_TOOLCHAIN="" 687 else 688 TOOLCHAIN_MISSING=$(raw_getmakevar TOOLCHAIN_MISSING) 689 EXTERNAL_TOOLCHAIN=$(raw_getmakevar EXTERNAL_TOOLCHAIN) 690 fi 691 if [ "${TOOLCHAIN_MISSING}" = "yes" ] && \ 692 [ -z "${EXTERNAL_TOOLCHAIN}" ]; then 693 ${runcmd} echo "ERROR: build.sh (in-tree cross-toolchain) is not yet available for" 694 ${runcmd} echo " MACHINE: ${MACHINE}" 695 ${runcmd} echo " MACHINE_ARCH: ${MACHINE_ARCH}" 696 ${runcmd} echo "" 697 ${runcmd} echo "All builds for this platform should be done via a traditional make" 698 ${runcmd} echo "If you wish to use an external cross-toolchain, set" 699 ${runcmd} echo " EXTERNAL_TOOLCHAIN=<path to toolchain root>" 700 ${runcmd} echo "in either the environment or mk.conf and rerun" 701 ${runcmd} echo " ${progname} $*" 702 exit 1 703 fi 704 705 # Normalise MKOBJDIRS, MKUNPRIVED, and MKUPDATE 706 # These may be set as build.sh options or in "mk.conf". 707 # Don't export them as they're only used for tests in build.sh. 708 # 709 MKOBJDIRS=$(getmakevar MKOBJDIRS) 710 MKUNPRIVED=$(getmakevar MKUNPRIVED) 711 MKUPDATE=$(getmakevar MKUPDATE) 712 713 if [ "${MKOBJDIRS}" != "no" ]; then 714 # If setting -M or -O to the root of an obj dir, make sure 715 # the base directory is made before continuing as <bsd.own.mk> 716 # will need this to pick up _SRC_TOP_OBJ_ 717 # 718 if [ ! -z "${makeobjdir}" ]; then 719 ${runcmd} mkdir -p "${makeobjdir}" 720 fi 721 722 # make obj in tools to ensure that the objdir for the top-level 723 # of the source tree and for "tools" is available, in case the 724 # default TOOLDIR setting from <bsd.own.mk> is used, or the 725 # build.sh default DESTDIR and RELEASEDIR is to be used. 726 # 727 ${runcmd} cd tools 728 ${runcmd} "${make}" -m ${TOP}/share/mk obj NOSUBDIR= || 729 bomb "Failed to make obj in tools" 730 ${runcmd} cd "${TOP}" 731 fi 732 733 statusmsg "MACHINE: ${MACHINE}" 734 statusmsg "MACHINE_ARCH: ${MACHINE_ARCH}" 735 736 # Find TOOLDIR, DESTDIR, and RELEASEDIR. 737 # 738 TOOLDIR=$(getmakevar TOOLDIR) 739 statusmsg "TOOLDIR path: ${TOOLDIR}" 740 DESTDIR=$(getmakevar DESTDIR) 741 RELEASEDIR=$(getmakevar RELEASEDIR) 742 if ! $do_expertmode; then 743 _SRC_TOP_OBJ_=$(getmakevar _SRC_TOP_OBJ_) 744 : ${DESTDIR:=${_SRC_TOP_OBJ_}/destdir.${MACHINE}} 745 : ${RELEASEDIR:=${_SRC_TOP_OBJ_}/releasedir} 746 makeenv="${makeenv} DESTDIR RELEASEDIR" 747 fi 748 export TOOLDIR DESTDIR RELEASEDIR 749 statusmsg "DESTDIR path: ${DESTDIR}" 750 statusmsg "RELEASEDIR path: ${RELEASEDIR}" 751 752 # Check validity of TOOLDIR and DESTDIR. 753 # 754 if [ -z "${TOOLDIR}" ] || [ "${TOOLDIR}" = "/" ]; then 755 bomb "TOOLDIR '${TOOLDIR}' invalid" 756 fi 757 removedirs="${TOOLDIR}" 758 759 if [ -z "${DESTDIR}" ] || [ "${DESTDIR}" = "/" ]; then 760 if ${do_build} || ${do_distribution} || ${do_release}; then 761 if ! ${do_build} || \ 762 [ "${uname_s}" != "NetBSD" ] || \ 763 [ "${uname_m}" != "${MACHINE}" ]; then 764 bomb "DESTDIR must != / for cross builds, or ${progname} 'distribution' or 'release'." 765 fi 766 if ! ${do_expertmode}; then 767 bomb "DESTDIR must != / for non -E (expert) builds" 768 fi 769 statusmsg "WARNING: Building to /, in expert mode." 770 statusmsg " This may cause your system to break! Reasons include:" 771 statusmsg " - your kernel is not up to date" 772 statusmsg " - the libraries or toolchain have changed" 773 statusmsg " YOU HAVE BEEN WARNED!" 774 fi 775 else 776 removedirs="${removedirs} ${DESTDIR}" 777 fi 778 if ${do_build} || ${do_distribution} || ${do_release}; then 779 if ! ${do_expertmode} && \ 780 [ $(id -u 2>/dev/null) -ne 0 ] && \ 781 [ -z "${MKUNPRIVED}" ] ; then 782 bomb "-U or -E must be set for build as an unprivileged user." 783 fi 784 fi 785 if ${do_releasekernel} && [ -z "${RELEASEDIR}" ]; then 786 bomb "Must set RELEASEDIR with \`releasekernel=...'" 787 fi 788} 789 790 791createmakewrapper() 792{ 793 # Remove the target directories. 794 # 795 if ${do_removedirs}; then 796 for f in ${removedirs}; do 797 statusmsg "Removing ${f}" 798 ${runcmd} rm -r -f "${f}" 799 done 800 fi 801 802 # Recreate $TOOLDIR. 803 # 804 ${runcmd} mkdir -p "${TOOLDIR}/bin" || 805 bomb "mkdir of '${TOOLDIR}/bin' failed" 806 807 # Install ${toolprefix}make if it was built. 808 # 809 if ${do_rebuildmake}; then 810 ${runcmd} rm -f "${TOOLDIR}/bin/${toolprefix}make" 811 ${runcmd} cp "${make}" "${TOOLDIR}/bin/${toolprefix}make" || 812 bomb "Failed to install \$TOOLDIR/bin/${toolprefix}make" 813 make="${TOOLDIR}/bin/${toolprefix}make" 814 statusmsg "Created ${make}" 815 fi 816 817 # Build a ${toolprefix}make wrapper script, usable by hand as 818 # well as by build.sh. 819 # 820 if [ -z "${makewrapper}" ]; then 821 makewrapper="${TOOLDIR}/bin/${toolprefix}make-${makewrappermachine:-${MACHINE}}" 822 [ -z "${BUILDID}" ] || makewrapper="${makewrapper}-${BUILDID}" 823 fi 824 825 ${runcmd} rm -f "${makewrapper}" 826 if [ "${runcmd}" = "echo" ]; then 827 echo 'cat <<EOF >'${makewrapper} 828 makewrapout= 829 else 830 makewrapout=">>\${makewrapper}" 831 fi 832 833 eval cat <<EOF ${makewrapout} 834#! /bin/sh 835# Set proper variables to allow easy "make" building of a NetBSD subtree. 836# Generated from: \$NetBSD: build.sh,v 1.122 2003/10/26 03:12:21 lukem Exp $ 837# 838 839EOF 840 for f in ${makeenv}; do 841 if eval "[ -z \"\${$f}\" -a \"\${${f}-X}\" = \"X\" ]"; then 842 eval echo "unset ${f}" ${makewrapout} 843 else 844 eval echo "${f}=\'\$$(echo ${f})\'\;\ export\ ${f}" ${makewrapout} 845 fi 846 done 847 eval echo "USETOOLS=yes\; export USETOOLS" ${makewrapout} 848 849 eval cat <<EOF ${makewrapout} 850 851exec "\${TOOLDIR}/bin/${toolprefix}make" \${1+"\$@"} 852EOF 853 [ "${runcmd}" = "echo" ] && echo EOF 854 ${runcmd} chmod +x "${makewrapper}" 855 statusmsg "makewrapper: ${makewrapper}" 856 statusmsg "Updated ${makewrapper}" 857} 858 859buildtools() 860{ 861 if [ "${MKOBJDIRS}" != "no" ]; then 862 ${runcmd} "${makewrapper}" ${parallel} obj-tools || 863 bomb "Failed to make obj-tools" 864 fi 865 ${runcmd} cd tools 866 if [ -z "${MKUPDATE}" ]; then 867 cleandir=cleandir 868 else 869 cleandir= 870 fi 871 ${runcmd} "${makewrapper}" ${cleandir} dependall install || 872 bomb "Failed to make tools" 873 statusmsg "Tools built to ${TOOLDIR}" 874 ${runcmd} cd "${TOP}" 875} 876 877getkernelconf() 878{ 879 kernelconf="$1" 880 if [ "${MKOBJDIRS}" != "no" ]; then 881 # The correct value of KERNOBJDIR might 882 # depend on a prior "make obj" in 883 # ${KERNSRCDIR}/${KERNARCHDIR}/compile. 884 # 885 KERNSRCDIR="$(getmakevar KERNSRCDIR)" 886 KERNARCHDIR="$(getmakevar KERNARCHDIR)" 887 ${runcmd} cd "${KERNSRCDIR}/${KERNARCHDIR}/compile" 888 ${runcmd} "${makewrapper}" obj || 889 bomb "Failed to make obj in ${KERNSRCDIR}/${KERNARCHDIR}/compile" 890 ${runcmd} cd "${TOP}" 891 fi 892 KERNCONFDIR="$(getmakevar KERNCONFDIR)" 893 KERNOBJDIR="$(getmakevar KERNOBJDIR)" 894 case "${kernelconf}" in 895 */*) 896 kernelconfpath="${kernelconf}" 897 kernelconfname="${kernelconf##*/}" 898 ;; 899 *) 900 kernelconfpath="${KERNCONFDIR}/${kernelconf}" 901 kernelconfname="${kernelconf}" 902 ;; 903 esac 904 kernelbuildpath="${KERNOBJDIR}/${kernelconfname}" 905} 906 907buildkernel() 908{ 909 if ! ${do_tools} && ! ${buildkernelwarned:-false}; then 910 # Building tools every time we build a kernel is clearly 911 # unnecessary. We could try to figure out whether rebuilding 912 # the tools is necessary this time, but it doesn't seem worth 913 # the trouble. Instead, we say it's the user's responsibility 914 # to rebuild the tools if necessary. 915 # 916 statusmsg "Building kernel without building new tools" 917 buildkernelwarned=true 918 fi 919 getkernelconf $1 920 statusmsg "Building kernel: ${kernelconf}" 921 statusmsg "Build directory: ${kernelbuildpath}" 922 ${runcmd} mkdir -p "${kernelbuildpath}" || 923 bomb "Cannot mkdir: ${kernelbuildpath}" 924 if [ -z "${MKUPDATE}" ]; then 925 ${runcmd} cd "${kernelbuildpath}" 926 ${runcmd} "${makewrapper}" cleandir || 927 bomb "Failed to make cleandir in ${kernelbuildpath}" 928 ${runcmd} cd "${TOP}" 929 fi 930 ${runcmd} "${TOOLDIR}/bin/${toolprefix}config" -b "${kernelbuildpath}" \ 931 -s "${TOP}/sys" "${kernelconfpath}" || 932 bomb "${toolprefix}config failed for ${kernelconf}" 933 ${runcmd} cd "${kernelbuildpath}" 934 ${runcmd} "${makewrapper}" depend || 935 bomb "Failed to make depend in ${kernelbuildpath}" 936 ${runcmd} "${makewrapper}" ${parallel} all || 937 bomb "Failed to make all in ${kernelbuildpath}" 938 ${runcmd} cd "${TOP}" 939 940 if [ "${runcmd}" != "echo" ]; then 941 statusmsg "Kernels built from ${kernelconf}:" 942 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath}) 943 for kern in ${kernlist:-netbsd}; do 944 [ -f "${kernelbuildpath}/${kern}" ] && \ 945 echo " ${kernelbuildpath}/${kern}" 946 done | tee -a "${results}" 947 fi 948} 949 950releasekernel() 951{ 952 getkernelconf $1 953 kernelreldir="${RELEASEDIR}/${MACHINE}/binary/kernel" 954 ${runcmd} mkdir -p "${kernelreldir}" 955 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath}) 956 for kern in ${kernlist:-netbsd}; do 957 builtkern="${kernelbuildpath}/${kern}" 958 [ -f "${builtkern}" ] || continue 959 releasekern="${kernelreldir}/${kern}-${kernelconfname}.gz" 960 statusmsg "Kernel copy: ${releasekern}" 961 ${runcmd} gzip -c -9 < "${builtkern}" > "${releasekern}" 962 done 963} 964 965installworld() 966{ 967 dir="$1" 968 ${runcmd} "${makewrapper}" INSTALLWORLDDIR="${dir}" installworld || 969 bomb "Failed to make installworld to ${dir}" 970 statusmsg "Successful installworld to ${dir}" 971} 972 973 974main() 975{ 976 initdefaults 977 parseoptions "$@" 978 979 build_start=$(date) 980 statusmsg "${progname} command: $0 $@" 981 statusmsg "${progname} started: ${build_start}" 982 983 rebuildmake 984 validatemakeparams 985 createmakewrapper 986 987 # Perform the operations. 988 # 989 for op in ${operations}; do 990 case "${op}" in 991 992 makewrapper) 993 # no-op 994 ;; 995 996 tools) 997 buildtools 998 ;; 999 1000 obj|build|distribution|release|sets|sourcesets|params) 1001 ${runcmd} "${makewrapper}" ${parallel} ${op} || 1002 bomb "Failed to make ${op}" 1003 statusmsg "Successful make ${op}" 1004 ;; 1005 1006 kernel=*) 1007 arg=${op#*=} 1008 buildkernel "${arg}" 1009 ;; 1010 1011 releasekernel=*) 1012 arg=${op#*=} 1013 releasekernel "${arg}" 1014 ;; 1015 1016 install=*) 1017 arg=${op#*=} 1018 if [ "${arg}" = "/" ] && \ 1019 ( [ "${uname_s}" != "NetBSD" ] || \ 1020 [ "${uname_m}" != "${MACHINE}" ] ); then 1021 bomb "'${op}' must != / for cross builds." 1022 fi 1023 installworld "${arg}" 1024 ;; 1025 1026 *) 1027 bomb "Unknown operation \`${op}'" 1028 ;; 1029 1030 esac 1031 done 1032 1033 statusmsg "${progname} started: ${build_start}" 1034 statusmsg "${progname} ended: $(date)" 1035 if [ -s "${results}" ]; then 1036 echo "===> Summary of results:" 1037 sed -e 's/^===>//;s/^/ /' "${results}" 1038 echo "===> ." 1039 fi 1040} 1041 1042main "$@" 1043