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