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