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