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