1 #! /usr/bin/env sh 2 # $NetBSD: build.sh,v 1.400 2025/10/20 14:31:35 nat Exp $ 3 # 4 # Copyright (c) 2001-2023 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 # 19 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 # POSSIBILITY OF SUCH DAMAGE. 30 # 31 # 32 # Top level build wrapper, to build or cross-build NetBSD. 33 # 34 35 # 36 # {{{ Begin shell feature tests. 37 # 38 # We try to determine whether or not this script is being run under 39 # a shell that supports the features that we use. If not, we try to 40 # re-exec the script under another shell. If we can't find another 41 # suitable shell, then we show a message and exit. 42 # 43 44 errmsg= # error message, if not empty 45 shelltest=false # if true, exit after testing the shell 46 re_exec_allowed=true # if true, we may exec under another shell 47 48 # Parse special command line options in $1. These special options are 49 # for internal use only, are not documented, and are not valid anywhere 50 # other than $1. 51 case "$1" in 52 --shelltest) 53 shelltest=true 54 re_exec_allowed=false 55 shift 56 ;; 57 --no-re-exec) 58 re_exec_allowed=false 59 shift 60 ;; 61 esac 62 63 # Solaris /bin/sh, and other SVR4 shells, do not support "!". 64 # This is the first feature that we test, because subsequent 65 # tests use "!". 66 # 67 # Unfortunately, if the shell doesn't support ! most of the tests 68 # following which use '!' are likely to simply abort with a syntax error. 69 # Not executing the code containing ! does not avoid compiling it. 70 # 71 if test -z "$errmsg" 72 then 73 if ( eval '! false' ) >/dev/null 2>&1 74 then 75 : 76 else 77 errmsg='Shell does not support "!".' 78 fi 79 fi 80 81 # Does the shell support functions? 82 # 83 if test -z "$errmsg" 84 then 85 if ! ( 86 eval 'somefunction() { : ; }' 87 ) >/dev/null 2>&1 88 then 89 errmsg='Shell does not support functions.' 90 fi 91 fi 92 93 # Does the shell support the "local" keyword for variables in functions? 94 # 95 # Local variables are not required by SUSv3, but some scripts run during 96 # the NetBSD build use them. 97 # 98 # ksh93 fails this test; it uses an incompatible syntax involving the 99 # keywords 'function' and 'typeset'. 100 # 101 if test -z "$errmsg" 102 then 103 if ! ( 104 eval 'f() { local v=2; }; v=1; f && test x"$v" = x1' 105 ) >/dev/null 2>&1 106 then 107 errmsg='Shell does not support the "local" keyword in functions.' 108 fi 109 fi 110 111 # Does the shell support ${var%suffix}, ${var#prefix}, and their variants? 112 # 113 # We don't bother testing for ${var+value}, ${var-value}, or their variants, 114 # since shells without those (unlikely) are sure to fail other tests too. 115 # 116 if test -z "$errmsg" 117 then 118 if ! ( 119 eval 'var=a/b/c ; 120 test x"${var#*/};${var##*/};${var%/*};${var%%/*}" = \ 121 x"b/c;c;a/b;a" ;' 122 ) >/dev/null 2>&1 123 then 124 errmsg='Shell does not support "${var%suffix}" or "${var#prefix}".' 125 fi 126 fi 127 128 # Does the shell support IFS? 129 # 130 # zsh in normal mode (as opposed to "emulate sh" mode) fails this test. 131 # 132 if test -z "$errmsg" 133 then 134 if ! ( 135 eval 'IFS=: ; v=":a b::c" ; set -- $v ; IFS=+ ; 136 test x"$#;$1,$2,$3,$4;$*" = x"4;,a b,,c;+a b++c"' 137 ) >/dev/null 2>&1 138 then 139 errmsg='Shell does not support IFS word splitting.' 140 fi 141 fi 142 143 # Does the shell support ${1+"$@"}? 144 # 145 # Some versions of zsh fail this test, even in "emulate sh" mode. 146 # 147 if test -z "$errmsg" 148 then 149 if ! ( 150 eval 'set -- "a a a" "b b b" 151 set -- ${1+"$@"} 152 test x"$#;$1;$2" = x"2;a a a;b b b" ' 153 ) >/dev/null 2>&1 154 then 155 errmsg='Shell does not support ${1+"$@"}.' 156 fi 157 fi 158 159 # Does the shell support $(...) command substitution? 160 # 161 if test -z "$errmsg" 162 then 163 if ! ( 164 eval 'var=$(echo abc); test x"$var" = xabc' 165 ) >/dev/null 2>&1 166 then 167 errmsg='Shell does not support "$(...)" command substitution.' 168 fi 169 fi 170 171 # Does the shell support $(...) command substitution with 172 # unbalanced parentheses? 173 # 174 # Some shells known to fail this test are: NetBSD /bin/ksh (as of 2009-12), 175 # bash-3.1, pdksh-5.2.14, zsh-4.2.7 in "emulate sh" mode. 176 # 177 if test -z "$errmsg" 178 then 179 if ! ( 180 eval 'var=$(case x in x) echo abc;; esac); test x"$var" = x"abc"' 181 ) >/dev/null 2>&1 182 then 183 # XXX: This test is ignored because so many shells fail it; instead, 184 # the NetBSD build avoids using the problematic construct. 185 : ignore 'Shell does not support "$(...)" with unbalanced ")".' 186 fi 187 fi 188 189 # Does the shell support getopts or getopt? 190 # (XXX: Q: why the need for the eval here, looks unncessary) 191 # 192 if test -z "$errmsg" 193 then 194 if ! ( 195 eval 'type getopts || type getopt' 196 ) >/dev/null 2>&1 197 then 198 errmsg='Shell does not support getopts or getopt.' 199 fi 200 fi 201 202 # 203 # If shelltest is true, exit now, reporting whether or not the shell is good. 204 # 205 if "$shelltest" 206 then 207 if test -n "$errmsg" 208 then 209 echo >&2 "$0: $errmsg" 210 exit 1 211 else 212 exit 0 213 fi 214 fi 215 216 # 217 # If the shell was bad, try to exec a better shell, or report an error. 218 # 219 # Loops are broken by passing an extra "--no-re-exec" flag to the new 220 # instance of this script. 221 # 222 if test -n "$errmsg" 223 then 224 if "$re_exec_allowed" 225 then 226 for othershell in \ 227 "${HOST_SH}" /usr/xpg4/bin/sh ksh ksh88 mksh pdksh dash bash 228 # NOTE: some shells known not to work are: 229 # any shell using csh syntax; 230 # Solaris /bin/sh (missing many modern features); 231 # ksh93 (incompatible syntax for local variables); 232 # zsh (many differences, unless run in compatibility mode). 233 do 234 test -n "$othershell" || continue 235 if eval 'type "$othershell"' >/dev/null 2>&1 \ 236 && $othershell "$0" --shelltest >/dev/null 2>&1 237 then 238 cat <<EOF 239 $0: $errmsg 240 $0: Retrying under $othershell 241 EOF 242 HOST_SH="$othershell" 243 export HOST_SH 244 exec $othershell "$0" --no-re-exec "$@" # avoid ${1+"$@"} 245 fi 246 # If HOST_SH was set, but failed the test above, 247 # then give up without trying any other shells. 248 test x"${othershell}" = x"${HOST_SH}" && break 249 done 250 fi 251 252 # 253 # If we get here, then the shell is bad, and we either could not 254 # find a replacement, or were not allowed to try a replacement. 255 # 256 cat <<EOF 257 $0: $errmsg 258 259 The NetBSD build system requires a shell that supports modern POSIX 260 features, as well as the "local" keyword in functions (which is a 261 widely-implemented but non-standardised feature). 262 263 Please re-run this script under a suitable shell. For example: 264 265 /path/to/suitable/shell $0 ... 266 267 The above command will usually enable build.sh to automatically set 268 HOST_SH=/path/to/suitable/shell, but if that fails, then you may also 269 need to explicitly set the HOST_SH environment variable, as follows: 270 271 HOST_SH=/path/to/suitable/shell 272 export HOST_SH 273 \${HOST_SH} $0 ... 274 EOF 275 exit 1 276 fi 277 278 # 279 # }}} End shell feature tests. 280 # 281 282 progname=${0##*/} 283 toppid=$$ 284 results=/dev/null 285 tab=' ' 286 nl=' 287 ' 288 trap "exit 1" 1 2 3 15 289 290 bomb() 291 { 292 cat >&2 <<ERRORMESSAGE 293 294 ERROR: $* 295 296 *** BUILD ABORTED *** 297 ERRORMESSAGE 298 kill ${toppid} # in case we were invoked from a subshell 299 exit 1 300 } 301 302 # Quote args to make them safe in the shell. 303 # Usage: quotedlist="$(shell_quote args...)" 304 # 305 # After building up a quoted list, use it by evaling it inside 306 # double quotes, like this: 307 # eval "set -- $quotedlist" 308 # or like this: 309 # eval "\$command $quotedlist \$filename" 310 # 311 shell_quote() 312 ( 313 local result= 314 local arg qarg 315 LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII 316 for arg in "$@" 317 do 318 case "${arg}" in 319 '') 320 qarg="''" 321 ;; 322 *[!-./a-zA-Z0-9]*) 323 # Convert each embedded ' to '\'', 324 # then insert ' at the beginning of the first line, 325 # and append ' at the end of the last line. 326 # Finally, elide unnecessary '' pairs at the 327 # beginning and end of the result and as part of 328 # '\'''\'' sequences that result from multiple 329 # adjacent quotes in he input. 330 qarg=$(printf "%s\n" "$arg" | 331 ${SED:-sed} -e "s/'/'\\\\''/g" \ 332 -e "1s/^/'/" -e "\$s/\$/'/" \ 333 -e "1s/^''//" -e "\$s/''\$//" \ 334 -e "s/'''/'/g" 335 ) 336 ;; 337 *) 338 # Arg is not the empty string, and does not contain 339 # any unsafe characters. Leave it unchanged for 340 # readability. 341 qarg="${arg}" 342 ;; 343 esac 344 result="${result}${result:+ }${qarg}" 345 done 346 printf "%s\n" "$result" 347 ) 348 349 statusmsg() 350 { 351 ${runcmd} echo "===> $*" | tee -a "${results}" 352 } 353 354 statusmsg2() 355 { 356 local msg 357 358 msg=${1} 359 shift 360 361 case "${msg}" in 362 ????????????????*) ;; 363 ??????????*) msg="${msg} ";; 364 ?????*) msg="${msg} ";; 365 *) msg="${msg} ";; 366 esac 367 case "${msg}" in 368 ?????????????????????*) ;; 369 ????????????????????) msg="${msg} ";; 370 ???????????????????) msg="${msg} ";; 371 ??????????????????) msg="${msg} ";; 372 ?????????????????) msg="${msg} ";; 373 ????????????????) msg="${msg} ";; 374 esac 375 statusmsg "${msg}$*" 376 } 377 378 warning() 379 { 380 statusmsg "Warning: $*" 381 } 382 383 # Find a program in the PATH, and show the result. If not found, 384 # show a default. If $2 is defined (even if it is an empty string), 385 # then that is the default; otherwise, $1 is used as the default. 386 # 387 find_in_PATH() 388 { 389 local prog="$1" 390 local result="${2-$1}" 391 local dir 392 local IFS=: 393 394 for dir in ${PATH} 395 do 396 if [ -x "${dir}/${prog}" ] 397 then 398 result=${dir}/${prog} 399 break 400 fi 401 done 402 echo "${result}" 403 } 404 405 # Try to find a working POSIX shell, and set HOST_SH to refer to it. 406 # Assumes that uname_s, uname_m, and PWD have been set. 407 # 408 set_HOST_SH() 409 { 410 # Even if ${HOST_SH} is already defined, we still do the 411 # sanity checks at the end. 412 413 # Solaris has /usr/xpg4/bin/sh. 414 # 415 [ -z "${HOST_SH}" ] && 416 [ "${uname_s}" = SunOS ] && 417 [ -x /usr/xpg4/bin/sh ] && 418 HOST_SH=/usr/xpg4/bin/sh 419 420 # Try to get the name of the shell that's running this script, 421 # by parsing the output from "ps". We assume that, if the host 422 # system's ps command supports -o comm at all, it will do so 423 # in the usual way: a one-line header followed by a one-line 424 # result, possibly including trailing white space. And if the 425 # host system's ps command doesn't support -o comm, we assume 426 # that we'll get an error message on stderr and nothing on 427 # stdout. (We don't try to use ps -o 'comm=' to suppress the 428 # header line, because that is less widely supported.) 429 # 430 # If we get the wrong result here, the user can override it by 431 # specifying HOST_SH in the environment. 432 # 433 [ -z "${HOST_SH}" ] && HOST_SH=$( 434 ( 435 ps -p $$ -o comm | 436 sed -ne "2s/[ ${tab}]*\$//p" 437 ) 2>/dev/null 438 ) 439 440 # If nothing above worked, use "sh". We will later find the 441 # first directory in the PATH that has a "sh" program. 442 # 443 [ -z "${HOST_SH}" ] && HOST_SH="sh" 444 445 # If the result so far is not an absolute path, try to prepend 446 # PWD or search the PATH. 447 # 448 case "${HOST_SH}" in 449 /*) : 450 ;; 451 */*) HOST_SH="${PWD}/${HOST_SH}" 452 ;; 453 *) HOST_SH="$(find_in_PATH "${HOST_SH}")" 454 ;; 455 esac 456 457 # If we don't have an absolute path by now, bomb. 458 # 459 case "${HOST_SH}" in 460 /*) : 461 ;; 462 *) bomb "HOST_SH=\"${HOST_SH}\" is not an absolute path" 463 ;; 464 esac 465 466 # If HOST_SH is not executable, bomb. 467 # 468 [ -x "${HOST_SH}" ] || 469 bomb "HOST_SH=\"${HOST_SH}\" is not executable" 470 471 # If HOST_SH fails tests, bomb. 472 # ("$0" may be a path that is no longer valid, because we have 473 # performed "cd $(dirname $0)", so don't use $0 here.) 474 # 475 "${HOST_SH}" build.sh --shelltest || 476 bomb "HOST_SH=\"${HOST_SH}\" failed functionality tests" 477 } 478 479 # initdefaults -- 480 # Set defaults before parsing command line options. 481 # 482 initdefaults() 483 { 484 makeenv= 485 makewrapper= 486 makewrappermachine= 487 runcmd= 488 operations= 489 removedirs= 490 491 [ -d usr.bin/make ] || cd "$(dirname $0)" 492 [ -d usr.bin/make ] || 493 bomb "usr.bin/make not found; build.sh must be run from" \ 494 "the top level of source directory" 495 [ -f share/mk/bsd.own.mk ] || 496 bomb "src/share/mk is missing; please re-fetch the source tree" 497 498 # Set various environment variables to known defaults, 499 # to minimize (cross-)build problems observed "in the field". 500 # 501 # LC_ALL=C must be set before we try to parse the output from 502 # any command. Other variables are set (or unset) here, before 503 # we parse command line arguments. 504 # 505 # These variables can be overridden via "-V var=value" if 506 # you know what you are doing. 507 # 508 unsetmakeenv C_INCLUDE_PATH 509 unsetmakeenv CPLUS_INCLUDE_PATH 510 unsetmakeenv INFODIR 511 unsetmakeenv LESSCHARSET 512 unsetmakeenv MAKEFLAGS 513 unsetmakeenv TERMINFO 514 setmakeenv LC_ALL C 515 516 # Find information about the build platform. This should be 517 # kept in sync with _HOST_OSNAME, _HOST_OSREL, and _HOST_ARCH 518 # variables in share/mk/bsd.sys.mk. 519 # 520 # Note that "uname -p" is not part of POSIX, but we want uname_p 521 # to be set to the host MACHINE_ARCH, if possible. On systems 522 # where "uname -p" fails, shows "unknown", or shows a string 523 # that does not look like an identifier, fall back to using the 524 # output from "uname -m" instead. 525 # 526 uname_s=$(uname -s 2>/dev/null) 527 uname_r=$(uname -r 2>/dev/null) 528 uname_m=$(uname -m 2>/dev/null) 529 uname_p=$(uname -p 2>/dev/null || echo "unknown") 530 case "${uname_p}" in 531 ''|unknown|*[!-_A-Za-z0-9]*) uname_p="${uname_m}" ;; 532 esac 533 534 id_u=$(id -u 2>/dev/null || /usr/xpg4/bin/id -u 2>/dev/null) 535 536 # If $PWD is a valid name of the current directory, POSIX mandates 537 # that pwd return it by default which causes problems in the 538 # presence of symlinks. Unsetting PWD is simpler than changing 539 # every occurrence of pwd to use -P. 540 # 541 # XXX Except that doesn't work on Solaris. Or many Linuces. 542 # And the standard says altering PWD produces unspecified results 543 # So instead just cd -P to $PWD which should make PWD be symlink free 544 # 545 cd -P "${PWD}" || bomb "Cannot cd to \$PWD ($PWD)" 546 # At this point TOP=$PWD should just work, but let's be ultra safe. 547 TOP=$( (exec pwd -P 2>/dev/null) || (exec pwd 2>/dev/null) ) 548 549 # The user can set HOST_SH in the environment, or we try to 550 # guess an appropriate value. Then we set several other 551 # variables from HOST_SH. 552 # 553 set_HOST_SH 554 setmakeenv HOST_SH "${HOST_SH}" 555 setmakeenv BSHELL "${HOST_SH}" 556 setmakeenv CONFIG_SHELL "${HOST_SH}" 557 558 # Set defaults. 559 # 560 toolprefix=nb 561 562 # Some systems have a small ARG_MAX. -X prevents make(1) from 563 # exporting variables in the environment redundantly. 564 # 565 case "${uname_s}" in 566 Darwin | FreeBSD | CYGWIN*) 567 MAKEFLAGS="-X ${MAKEFLAGS}" 568 ;; 569 esac 570 571 # do_{operation}=true if given operation is requested. 572 # 573 do_expertmode=false 574 do_rebuildmake=false 575 do_removedirs=false 576 do_tools=false 577 do_libs=false 578 do_cleandir=false 579 do_obj=false 580 do_build=false 581 do_distribution=false 582 do_release=false 583 do_kernel=false 584 do_releasekernel=false 585 do_kernels=false 586 do_modules=false 587 do_installmodules=false 588 do_install=false 589 do_sets=false 590 do_sourcesets=false 591 do_syspkgs=false 592 do_pkg=false 593 do_iso_image=false 594 do_iso_image_source=false 595 do_live_image=false 596 do_install_image=false 597 do_disk_image=false 598 do_params=false 599 do_show_params=false 600 do_rump=false 601 do_dtb=false 602 603 # done_{operation}=true if given operation has been done. 604 # 605 done_rebuildmake=false 606 607 # Create scratch directory 608 # 609 tmpdir="${TMPDIR-/tmp}/nbbuild$$" 610 mkdir "${tmpdir}" || bomb "Cannot mkdir: ${tmpdir}" 611 trap "cd /; rm -r -f \"${tmpdir}\"" 0 612 results="${tmpdir}/build.sh.results" 613 614 # Set source directories 615 # 616 setmakeenv NETBSDSRCDIR "${TOP}" 617 618 # Make sure KERNOBJDIR is an absolute path if defined 619 # 620 case "${KERNOBJDIR}" in 621 ''|/*) ;; 622 *) KERNOBJDIR="${TOP}/${KERNOBJDIR}" 623 setmakeenv KERNOBJDIR "${KERNOBJDIR}" 624 ;; 625 esac 626 627 # Find the version of NetBSD 628 # 629 DISTRIBVER="$(${HOST_SH} ${TOP}/sys/conf/osrelease.sh)" 630 631 # Set the BUILDSEED to NetBSD-"N" 632 # 633 setmakeenv BUILDSEED \ 634 "NetBSD-$(${HOST_SH} ${TOP}/sys/conf/osrelease.sh -m)" 635 636 # Set MKARZERO to "yes" 637 # 638 setmakeenv MKARZERO yes 639 640 } 641 642 # valid_MACHINE_ARCH -- A multi-line string, listing all valid 643 # MACHINE/MACHINE_ARCH pairs. 644 # 645 # Each line contains a MACHINE and MACHINE_ARCH value, an optional ALIAS 646 # which may be used to refer to the MACHINE/MACHINE_ARCH pair, and an 647 # optional DEFAULT or NO_DEFAULT keyword. 648 # 649 # When a MACHINE corresponds to multiple possible values of 650 # MACHINE_ARCH, then this table should list all allowed combinations. 651 # If the MACHINE is associated with a default MACHINE_ARCH (to be 652 # used when the user specifies the MACHINE but fails to specify the 653 # MACHINE_ARCH), then one of the lines should have the "DEFAULT" 654 # keyword. If there is no default MACHINE_ARCH for a particular 655 # MACHINE, then there should be a line with the "NO_DEFAULT" keyword, 656 # and with a blank MACHINE_ARCH. 657 # 658 valid_MACHINE_ARCH=' 659 MACHINE=acorn32 MACHINE_ARCH=earmv4 ALIAS=eacorn32 DEFAULT 660 MACHINE=algor MACHINE_ARCH=mips64el ALIAS=algor64 661 MACHINE=algor MACHINE_ARCH=mipsel DEFAULT 662 MACHINE=alpha MACHINE_ARCH=alpha 663 MACHINE=amd64 MACHINE_ARCH=x86_64 664 MACHINE=amiga MACHINE_ARCH=m68k 665 MACHINE=amigappc MACHINE_ARCH=powerpc 666 MACHINE=arc MACHINE_ARCH=mips64el ALIAS=arc64 667 MACHINE=arc MACHINE_ARCH=mipsel DEFAULT 668 MACHINE=atari MACHINE_ARCH=m68k 669 MACHINE=bebox MACHINE_ARCH=powerpc 670 MACHINE=cats MACHINE_ARCH=earmv4 ALIAS=ecats DEFAULT 671 MACHINE=cesfic MACHINE_ARCH=m68k 672 MACHINE=cobalt MACHINE_ARCH=mips64el ALIAS=cobalt64 673 MACHINE=cobalt MACHINE_ARCH=mipsel DEFAULT 674 MACHINE=dreamcast MACHINE_ARCH=sh3el 675 MACHINE=emips MACHINE_ARCH=mipseb 676 MACHINE=epoc32 MACHINE_ARCH=earmv4 ALIAS=eepoc32 DEFAULT 677 MACHINE=evbarm MACHINE_ARCH= NO_DEFAULT 678 MACHINE=evbarm MACHINE_ARCH=earmv4 ALIAS=evbearmv4-el ALIAS=evbarmv4-el 679 MACHINE=evbarm MACHINE_ARCH=earmv4eb ALIAS=evbearmv4-eb ALIAS=evbarmv4-eb 680 MACHINE=evbarm MACHINE_ARCH=earmv5 ALIAS=evbearmv5-el ALIAS=evbarmv5-el 681 MACHINE=evbarm MACHINE_ARCH=earmv5hf ALIAS=evbearmv5hf-el ALIAS=evbarmv5hf-el 682 MACHINE=evbarm MACHINE_ARCH=earmv5eb ALIAS=evbearmv5-eb ALIAS=evbarmv5-eb 683 MACHINE=evbarm MACHINE_ARCH=earmv5hfeb ALIAS=evbearmv5hf-eb ALIAS=evbarmv5hf-eb 684 MACHINE=evbarm MACHINE_ARCH=earmv6 ALIAS=evbearmv6-el ALIAS=evbarmv6-el 685 MACHINE=evbarm MACHINE_ARCH=earmv6hf ALIAS=evbearmv6hf-el ALIAS=evbarmv6hf-el 686 MACHINE=evbarm MACHINE_ARCH=earmv6eb ALIAS=evbearmv6-eb ALIAS=evbarmv6-eb 687 MACHINE=evbarm MACHINE_ARCH=earmv6hfeb ALIAS=evbearmv6hf-eb ALIAS=evbarmv6hf-eb 688 MACHINE=evbarm MACHINE_ARCH=earmv7 ALIAS=evbearmv7-el ALIAS=evbarmv7-el 689 MACHINE=evbarm MACHINE_ARCH=earmv7eb ALIAS=evbearmv7-eb ALIAS=evbarmv7-eb 690 MACHINE=evbarm MACHINE_ARCH=earmv7hf ALIAS=evbearmv7hf-el ALIAS=evbarmv7hf-el 691 MACHINE=evbarm MACHINE_ARCH=earmv7hfeb ALIAS=evbearmv7hf-eb ALIAS=evbarmv7hf-eb 692 MACHINE=evbarm MACHINE_ARCH=aarch64 ALIAS=evbarm64-el ALIAS=evbarm64 693 MACHINE=evbarm MACHINE_ARCH=aarch64eb ALIAS=evbarm64-eb 694 MACHINE=evbcf MACHINE_ARCH=coldfire 695 MACHINE=evbmips MACHINE_ARCH= NO_DEFAULT 696 MACHINE=evbmips MACHINE_ARCH=mips64eb ALIAS=evbmips64-eb 697 MACHINE=evbmips MACHINE_ARCH=mips64el ALIAS=evbmips64-el 698 MACHINE=evbmips MACHINE_ARCH=mipseb ALIAS=evbmips-eb 699 MACHINE=evbmips MACHINE_ARCH=mipsel ALIAS=evbmips-el 700 MACHINE=evbmips MACHINE_ARCH=mipsn64eb ALIAS=evbmipsn64-eb 701 MACHINE=evbmips MACHINE_ARCH=mipsn64el ALIAS=evbmipsn64-el 702 MACHINE=evbppc MACHINE_ARCH=powerpc DEFAULT 703 MACHINE=evbppc MACHINE_ARCH=powerpc64 ALIAS=evbppc64 704 MACHINE=evbsh3 MACHINE_ARCH= NO_DEFAULT 705 MACHINE=evbsh3 MACHINE_ARCH=sh3eb ALIAS=evbsh3-eb 706 MACHINE=evbsh3 MACHINE_ARCH=sh3el ALIAS=evbsh3-el 707 MACHINE=ews4800mips MACHINE_ARCH=mipseb 708 MACHINE=hp300 MACHINE_ARCH=m68k 709 MACHINE=hppa MACHINE_ARCH=hppa 710 MACHINE=hpcarm MACHINE_ARCH=earmv4 ALIAS=hpcearm DEFAULT 711 MACHINE=hpcmips MACHINE_ARCH=mipsel 712 MACHINE=hpcsh MACHINE_ARCH=sh3el 713 MACHINE=i386 MACHINE_ARCH=i386 714 MACHINE=ia64 MACHINE_ARCH=ia64 715 MACHINE=ibmnws MACHINE_ARCH=powerpc 716 MACHINE=iyonix MACHINE_ARCH=earm ALIAS=eiyonix DEFAULT 717 MACHINE=landisk MACHINE_ARCH=sh3el 718 MACHINE=luna68k MACHINE_ARCH=m68k 719 MACHINE=mac68k MACHINE_ARCH=m68ksf ALIAS=mac68ksf 720 MACHINE=mac68k MACHINE_ARCH=m68k DEFAULT 721 MACHINE=macppc MACHINE_ARCH=powerpc DEFAULT 722 MACHINE=macppc MACHINE_ARCH=powerpc64 ALIAS=macppc64 723 MACHINE=mipsco MACHINE_ARCH=mipseb 724 MACHINE=mmeye MACHINE_ARCH=sh3eb 725 MACHINE=mvme68k MACHINE_ARCH=m68k 726 MACHINE=mvmeppc MACHINE_ARCH=powerpc 727 MACHINE=netwinder MACHINE_ARCH=earmv4 ALIAS=enetwinder DEFAULT 728 MACHINE=news68k MACHINE_ARCH=m68k 729 MACHINE=newsmips MACHINE_ARCH=mipseb 730 MACHINE=next68k MACHINE_ARCH=m68k 731 MACHINE=ofppc MACHINE_ARCH=powerpc DEFAULT 732 MACHINE=ofppc MACHINE_ARCH=powerpc64 ALIAS=ofppc64 733 MACHINE=or1k MACHINE_ARCH=or1k 734 MACHINE=playstation2 MACHINE_ARCH=mipsel 735 MACHINE=pmax MACHINE_ARCH=mips64el ALIAS=pmax64 736 MACHINE=pmax MACHINE_ARCH=mipsel DEFAULT 737 MACHINE=prep MACHINE_ARCH=powerpc 738 MACHINE=riscv MACHINE_ARCH=riscv64 ALIAS=riscv64 DEFAULT 739 MACHINE=riscv MACHINE_ARCH=riscv32 ALIAS=riscv32 740 MACHINE=rs6000 MACHINE_ARCH=powerpc 741 MACHINE=sandpoint MACHINE_ARCH=powerpc 742 MACHINE=sbmips MACHINE_ARCH= NO_DEFAULT 743 MACHINE=sbmips MACHINE_ARCH=mips64eb ALIAS=sbmips64-eb 744 MACHINE=sbmips MACHINE_ARCH=mips64el ALIAS=sbmips64-el 745 MACHINE=sbmips MACHINE_ARCH=mipseb ALIAS=sbmips-eb 746 MACHINE=sbmips MACHINE_ARCH=mipsel ALIAS=sbmips-el 747 MACHINE=sgimips MACHINE_ARCH=mips64eb ALIAS=sgimips64 748 MACHINE=sgimips MACHINE_ARCH=mipseb DEFAULT 749 MACHINE=shark MACHINE_ARCH=earmv4 ALIAS=eshark DEFAULT 750 MACHINE=sparc MACHINE_ARCH=sparc 751 MACHINE=sparc64 MACHINE_ARCH=sparc64 752 MACHINE=sun2 MACHINE_ARCH=m68000 753 MACHINE=sun3 MACHINE_ARCH=m68k 754 MACHINE=vax MACHINE_ARCH=vax 755 MACHINE=virt68k MACHINE_ARCH=m68k 756 MACHINE=x68k MACHINE_ARCH=m68k 757 MACHINE=zaurus MACHINE_ARCH=earm ALIAS=ezaurus DEFAULT 758 ' 759 760 # getarch -- find the default MACHINE_ARCH for a MACHINE, 761 # or convert an alias to a MACHINE/MACHINE_ARCH pair. 762 # 763 # Saves the original value of MACHINE in makewrappermachine before 764 # alias processing. 765 # 766 # Sets MACHINE and MACHINE_ARCH if the input MACHINE value is 767 # recognised as an alias, or recognised as a machine that has a default 768 # MACHINE_ARCH (or that has only one possible MACHINE_ARCH). 769 # 770 # Leaves MACHINE and MACHINE_ARCH unchanged if MACHINE is recognised 771 # as being associated with multiple MACHINE_ARCH values with no default. 772 # 773 # Bombs if MACHINE is not recognised. 774 # 775 getarch() 776 { 777 local IFS 778 local found= 779 local line 780 781 IFS="${nl}" 782 makewrappermachine="${MACHINE}" 783 for line in ${valid_MACHINE_ARCH} 784 do 785 line="${line%%#*}" # ignore comments 786 line="$( IFS=" ${tab}" ; echo $line )" # normalise white space 787 case "${line} " in 788 ' ') 789 # skip blank lines or comment lines 790 continue 791 ;; 792 *" ALIAS=${MACHINE} "*) 793 # Found a line with a matching ALIAS=<alias>. 794 found="$line" 795 break 796 ;; 797 "MACHINE=${MACHINE} "*" NO_DEFAULT"*) 798 # Found an explicit "NO_DEFAULT" for this MACHINE. 799 found="$line" 800 break 801 ;; 802 "MACHINE=${MACHINE} "*" DEFAULT"*) 803 # Found an explicit "DEFAULT" for this MACHINE. 804 found="$line" 805 break 806 ;; 807 "MACHINE=${MACHINE} "*) 808 # Found a line for this MACHINE. If it's the 809 # first such line, then tentatively accept it. 810 # If it's not the first matching line, then 811 # remember that there was more than one match. 812 case "$found" in 813 '') found="$line" ;; 814 *) found="MULTIPLE_MATCHES" ;; 815 esac 816 ;; 817 esac 818 done 819 820 case "$found" in 821 *NO_DEFAULT*|*MULTIPLE_MATCHES*) 822 # MACHINE is OK, but MACHINE_ARCH is still unknown 823 return 824 ;; 825 "MACHINE="*" MACHINE_ARCH="*) 826 # Obey the MACHINE= and MACHINE_ARCH= parts of the line. 827 IFS=' ' 828 for frag in ${found} 829 do 830 case "$frag" in 831 MACHINE=*|MACHINE_ARCH=*) 832 eval "$frag" 833 ;; 834 esac 835 done 836 ;; 837 *) 838 bomb "Unknown target MACHINE: ${MACHINE}" 839 ;; 840 esac 841 } 842 843 # validatearch -- check that the MACHINE/MACHINE_ARCH pair is supported. 844 # 845 # Bombs if the pair is not supported. 846 # 847 validatearch() 848 { 849 local IFS 850 local line 851 local foundpair=false foundmachine=false foundarch=false 852 853 case "${MACHINE_ARCH}" in 854 "") 855 bomb "No MACHINE_ARCH provided." \ 856 "Use 'build.sh -m ${MACHINE} list-arch' to show options" 857 ;; 858 esac 859 860 IFS="${nl}" 861 for line in ${valid_MACHINE_ARCH} 862 do 863 line="${line%%#*}" # ignore comments 864 line="$( IFS=" ${tab}" ; echo $line )" # normalise white space 865 case "${line} " in 866 ' ') 867 # skip blank lines or comment lines 868 continue 869 ;; 870 "MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} "*) 871 foundpair=true 872 ;; 873 "MACHINE=${MACHINE} "*) 874 foundmachine=true 875 ;; 876 *"MACHINE_ARCH=${MACHINE_ARCH} "*) 877 foundarch=true 878 ;; 879 esac 880 done 881 882 case "${foundpair}:${foundmachine}:${foundarch}" in 883 true:*) 884 : OK 885 ;; 886 *:false:*) 887 bomb "Unknown target MACHINE: ${MACHINE}" 888 ;; 889 *:*:false) 890 bomb "Unknown target MACHINE_ARCH: ${MACHINE_ARCH}" 891 ;; 892 *) 893 bomb "MACHINE_ARCH '${MACHINE_ARCH}' does not support MACHINE '${MACHINE}'" 894 ;; 895 esac 896 } 897 898 # listarch -- list valid MACHINE/MACHINE_ARCH/ALIAS values, 899 # optionally restricted to those where the MACHINE and/or MACHINE_ARCH 900 # match specified glob patterns. 901 # 902 listarch() 903 { 904 local machglob="$1" archglob="$2" 905 local IFS 906 local wildcard='*' 907 local line xline frag 908 local line_matches_machine line_matches_arch 909 local found=false 910 911 # Empty machglob or archglob should match anything 912 : "${machglob:=${wildcard}}" 913 : "${archglob:=${wildcard}}" 914 915 IFS="${nl}" 916 for line in ${valid_MACHINE_ARCH} 917 do 918 line="${line%%#*}" # ignore comments 919 xline="$( IFS=" ${tab}" ; echo $line )" # normalise white space 920 [ -z "${xline}" ] && continue # skip blank or comment lines 921 922 line_matches_machine=false 923 line_matches_arch=false 924 925 IFS=' ' 926 for frag in ${xline} 927 do 928 case "${frag}" in 929 MACHINE=${machglob}) 930 line_matches_machine=true ;; 931 ALIAS=${machglob}) 932 line_matches_machine=true ;; 933 MACHINE_ARCH=${archglob}) 934 line_matches_arch=true ;; 935 esac 936 done 937 938 if $line_matches_machine && $line_matches_arch 939 then 940 found=true 941 echo "$line" 942 fi 943 done 944 if ! $found 945 then 946 echo >&2 "No match for" \ 947 "MACHINE=${machglob} MACHINE_ARCH=${archglob}" 948 return 1 949 fi 950 return 0 951 } 952 953 # nobomb_getmakevar -- 954 # Given the name of a make variable in $1, show make's idea of the 955 # value of that variable, or return 1 if there's an error. 956 # 957 nobomb_getmakevar() 958 { 959 [ -x "${make}" ] || return 1 960 "${make}" -m ${TOP}/share/mk -s -B -f- _x_ <<EOF || return 1 961 _x_: 962 echo \${$1} 963 .include <bsd.prog.mk> 964 .include <bsd.kernobj.mk> 965 EOF 966 } 967 968 # bomb_getmakevar -- 969 # Given the name of a make variable in $1, show make's idea of the 970 # value of that variable, or bomb if there's an error. 971 # 972 bomb_getmakevar() 973 { 974 [ -x "${make}" ] || bomb "bomb_getmakevar $1: ${make} is not executable" 975 nobomb_getmakevar "$1" || bomb "bomb_getmakevar $1: ${make} failed" 976 } 977 978 # getmakevar -- 979 # Given the name of a make variable in $1, show make's idea of the 980 # value of that variable, or show a literal '$' followed by the 981 # variable name if ${make} is not executable. This is intended for use in 982 # messages that need to be readable even if $make hasn't been built, 983 # such as when build.sh is run with the "-n" option. 984 # 985 getmakevar() 986 { 987 if [ -x "${make}" ] 988 then 989 bomb_getmakevar "$1" 990 else 991 echo "\$$1" 992 fi 993 } 994 995 setmakeenv() 996 { 997 eval "$1='$2'; export $1" 998 makeenv="${makeenv} $1" 999 } 1000 1001 safe_setmakeenv() 1002 { 1003 case "$1" in 1004 1005 # Look for any vars we want to prohibit here, like: 1006 # Bad | Dangerous) usage "Cannot override $1 with -V";; 1007 1008 # That first char is OK has already been verified. 1009 *[!A-Za-z0-9_]*) usage "Bad variable name (-V): '$1'";; 1010 esac 1011 setmakeenv "$@" 1012 } 1013 1014 unsetmakeenv() 1015 { 1016 eval "unset $1" 1017 makeenv="${makeenv} $1" 1018 } 1019 1020 safe_unsetmakeenv() 1021 { 1022 case "$1" in 1023 1024 # Look for any vars user should not be able to unset 1025 # Needed | Must_Have) usage "Variable $1 cannot be unset";; 1026 1027 [!A-Za-z_]* | *[!A-Za-z0-9_]*) usage "Bad variable name (-Z): '$1'";; 1028 esac 1029 unsetmakeenv "$1" 1030 } 1031 1032 # Clear all variables defined in makeenv. Used to run a subprocess 1033 # outside the usual NetBSD build's make environment. 1034 # 1035 clearmakeenv() 1036 { 1037 local var 1038 1039 for var in ${makeenv} 1040 do 1041 unset ${var} 1042 done 1043 } 1044 1045 # Given a variable name in $1, modify the variable in place as follows: 1046 # For each space-separated word in the variable, call resolvepath. 1047 # 1048 resolvepaths() 1049 { 1050 local var="$1" 1051 local val 1052 eval val=\"\${${var}}\" 1053 local newval= 1054 local word 1055 1056 for word in ${val} 1057 do 1058 resolvepath word 1059 newval="${newval}${newval:+ }${word}" 1060 done 1061 eval ${var}=\"\${newval}\" 1062 } 1063 1064 # Given a variable name in $1, modify the variable in place as follows: 1065 # Convert possibly-relative path to absolute path by prepending 1066 # ${TOP} if necessary. Also delete trailing "/", if any. 1067 # 1068 resolvepath() 1069 { 1070 local var="$1" 1071 local val 1072 eval val=\"\${${var}}\" 1073 case "${val}" in 1074 /) 1075 ;; 1076 /*) 1077 val="${val%/}" 1078 ;; 1079 *) 1080 val="${TOP}/${val%/}" 1081 ;; 1082 esac 1083 eval ${var}=\"\${val}\" 1084 } 1085 1086 # Show synopsis to stdout. 1087 # 1088 synopsis() 1089 { 1090 cat <<_usage_ 1091 1092 Usage: ${progname} [-EnoPRrUux] [-a ARCH] [-B BID] [-C EXTRAS] 1093 [-c COMPILER] [-D DEST] [-j NJOB] [-M MOBJ] [-m MACH] 1094 [-N NOISY] [-O OOBJ] [-R RELEASE] [-S SEED] [-T TOOLS] 1095 [-V VAR=[VALUE]] [-w WRAPPER] [-X X11SRC] 1096 [-Z VAR] 1097 OPERATION ... 1098 ${progname} ( -h | -? ) 1099 1100 _usage_ 1101 } 1102 1103 # Show help to stdout. 1104 # 1105 help() 1106 { 1107 synopsis 1108 cat <<_usage_ 1109 Build OPERATIONs (all imply "obj" and "tools"): 1110 build Run "make build". 1111 distribution Run "make distribution" (includes DESTDIR/etc/ files). 1112 release Run "make release" (includes kernels & distrib media). 1113 1114 Other OPERATIONs: 1115 help Show this help message, and exit. 1116 makewrapper Create ${toolprefix}make-\${MACHINE} wrapper 1117 and ${toolprefix}make. 1118 Always performed. 1119 cleandir Run "make cleandir". [Default unless -u is used] 1120 dtb Build devicetree blobs. 1121 obj Run "make obj". [Default unless -o is used] 1122 tools Build and install tools. 1123 install=IDIR Run "make installworld" to IDIR to install all sets 1124 except 'etc'. Useful after "distribution" or "release". 1125 kernel=CONF Build kernel with config file CONF. 1126 kernel.gdb=CONF Build kernel (including netbsd.gdb) with config 1127 file CONF. 1128 releasekernel=CONF Install kernel built by kernel=CONF to RELEASEDIR. 1129 kernels Build all kernels. 1130 installmodules=IDIR Run "make installmodules" to IDIR to install all 1131 kernel modules. 1132 modules Build kernel modules. 1133 rumptest Do a linktest for rump (for developers). 1134 sets Create binary sets in 1135 RELEASEDIR/RELEASEMACHINEDIR/binary/sets. 1136 DESTDIR should be populated beforehand. 1137 distsets Same as "distribution sets". 1138 sourcesets Create source sets in RELEASEDIR/source/sets. 1139 syspkgs Create syspkgs in 1140 RELEASEDIR/RELEASEMACHINEDIR/binary/syspkgs. 1141 pkg=CATEGORY/PKG (EXPERIMENT) Build a package CATEGORY/PKG from pkgsrc. 1142 iso-image Create CD-ROM image in RELEASEDIR/images. 1143 iso-image-source Create CD-ROM image with source in RELEASEDIR/images. 1144 live-image Create bootable live image in 1145 RELEASEDIR/RELEASEMACHINEDIR/installation/liveimage. 1146 install-image Create bootable installation image in 1147 RELEASEDIR/RELEASEMACHINEDIR/installation/installimage. 1148 disk-image=TARGET Create bootable disk image in 1149 RELEASEDIR/RELEASEMACHINEDIR/binary/gzimg/TARGET.img.gz. 1150 params Create params file with various make(1) parameters. 1151 show-params Show various make(1) parameters. 1152 list-arch Show a list of valid MACHINE/MACHINE_ARCH values, 1153 and exit. The list may be narrowed by passing glob 1154 patterns or exact values in MACHINE or MACHINE_ARCH. 1155 mkrepro-timestamp Show the latest source timestamp used for reproducible 1156 builds and exit. Requires -P or -V MKREPRO=yes. 1157 show-revisionid Show the revision ID of the current directory 1158 (in SCM-dependent format) and exit. 1159 Requires -P or -V MKREPRO=yes. 1160 1161 Options: 1162 -a ARCH Set MACHINE_ARCH=ARCH. [Default: deduced from MACHINE] 1163 -B BID Set BUILDID=BID. 1164 -C EXTRAS Append EXTRAS to CDEXTRA for inclusion on CD-ROM. 1165 -c COMPILER Select compiler from COMPILER: 1166 clang 1167 gcc 1168 [Default: gcc] 1169 -D DEST Set DESTDIR=DEST. [Default: destdir.\${MACHINE}] 1170 -E Set "expert" mode; disables various safety checks. 1171 Should not be used without expert knowledge of the build 1172 system. 1173 -h Show this help message, and exit. 1174 -j NJOB Run up to NJOB jobs in parallel; see make(1) -j. 1175 -M MOBJ Set obj root directory to MOBJ; sets MAKEOBJDIRPREFIX=MOBJ, 1176 unsets MAKEOBJDIR. 1177 -m MACH Set MACHINE=MACH. Some MACH values are actually 1178 aliases that set MACHINE/MACHINE_ARCH pairs. 1179 [Default: deduced from the host system if the host 1180 OS is NetBSD] 1181 -N NOISY Set the noisiness (MAKEVERBOSE) level of the build to NOISY: 1182 0 Minimal output ("quiet"). 1183 1 Describe what is occurring. 1184 2 Describe what is occurring and echo the actual 1185 command. 1186 3 Ignore the effect of the "@" prefix in make 1187 commands. 1188 4 Trace shell commands using the shell's -x flag. 1189 [Default: 2] 1190 -n Show commands that would be executed, but do not execute 1191 them. 1192 -O OOBJ Set obj root directory to OOBJ; sets a MAKEOBJDIR pattern 1193 using OOBJ, unsets MAKEOBJDIRPREFIX. 1194 -o Set MKOBJDIRS=no; do not create objdirs at start of build. 1195 -P Set MKREPRO and MKREPRO_TIMESTAMP to the latest source 1196 CVS timestamp for reproducible builds. 1197 -R RELEASE Set RELEASEDIR=RELEASE. [Default: releasedir] 1198 -r Remove contents of TOOLDIR and DESTDIR before building. 1199 -S SEED Set BUILDSEED=SEED. [Default: NetBSD-majorversion] 1200 -T TOOLS Set TOOLDIR=TOOLS. If unset, and TOOLDIR is not set 1201 in the environment, ${toolprefix}make will be (re)built 1202 unconditionally. 1203 -U Set MKUNPRIVED=yes; build without requiring root privileges, 1204 install from an unprivileged build with proper file 1205 permissions. 1206 -u Set MKUPDATE=yes; do not run "make cleandir" first. 1207 Without this, everything is rebuilt, including the tools. 1208 -V VAR=[VALUE] Set variable VAR=VALUE. 1209 -w WRAPPER Create ${toolprefix}make script as WRAPPER. 1210 [Default: \${TOOLDIR}/bin/${toolprefix}make-\${MACHINE}] 1211 -X X11SRC Set X11SRCDIR=X11SRC. [Default: /usr/xsrc] 1212 -x Set MKX11=yes; build X11 from X11SRCDIR. 1213 -Z VAR Unset ("zap") variable VAR. 1214 -? Show this help message, and exit. 1215 1216 _usage_ 1217 } 1218 1219 # Show optional error message, help to stderr, and exit 1. 1220 # 1221 usage() 1222 { 1223 if [ -n "$*" ] 1224 then 1225 echo 1>&2 "" 1226 echo 1>&2 "${progname}: $*" 1227 fi 1228 synopsis 1>&2 1229 exit 1 1230 } 1231 1232 parseoptions() 1233 { 1234 opts=a:B:C:c:D:Ehj:M:m:N:nO:oPR:rS:T:UuV:w:X:xZ: 1235 opt_a=false 1236 opt_m=false 1237 local did_show_info=false 1238 1239 if type getopts >/dev/null 2>&1 1240 then 1241 # Use POSIX getopts. 1242 # 1243 getoptcmd='getopts :${opts} opt && opt=-${opt}' 1244 optargcmd=':' 1245 optremcmd='shift $((${OPTIND} -1))' 1246 else 1247 type getopt >/dev/null 2>&1 || 1248 bomb "Shell does not support getopts or getopt" 1249 1250 # Use old-style getopt(1) (doesn't handle whitespace in args). 1251 # 1252 args="$(getopt ${opts} $*)" 1253 [ $? = 0 ] || usage 1254 set -- ${args} 1255 1256 getoptcmd='[ $# -gt 0 ] && opt="$1" && shift' 1257 optargcmd='OPTARG="$1"; shift' 1258 optremcmd=':' 1259 fi 1260 1261 # Parse command line options. 1262 # 1263 while eval ${getoptcmd} 1264 do 1265 case ${opt} in 1266 1267 -a) 1268 eval ${optargcmd} 1269 MACHINE_ARCH=${OPTARG} 1270 opt_a=true 1271 ;; 1272 1273 -B) 1274 eval ${optargcmd} 1275 BUILDID=${OPTARG} 1276 ;; 1277 1278 -C) 1279 eval ${optargcmd} 1280 resolvepaths OPTARG 1281 CDEXTRA="${CDEXTRA}${CDEXTRA:+ }${OPTARG}" 1282 ;; 1283 1284 -c) 1285 eval ${optargcmd} 1286 case "${OPTARG}" in 1287 gcc) # default, no variables needed 1288 ;; 1289 clang) setmakeenv HAVE_LLVM yes 1290 setmakeenv MKLLVM yes 1291 setmakeenv MKGCC no 1292 ;; 1293 #pcc) ... 1294 # ;; 1295 *) bomb "Unknown compiler: ${OPTARG}" 1296 esac 1297 ;; 1298 1299 -D) 1300 eval ${optargcmd} 1301 resolvepath OPTARG 1302 setmakeenv DESTDIR "${OPTARG}" 1303 ;; 1304 1305 -E) 1306 do_expertmode=true 1307 ;; 1308 1309 -j) 1310 eval ${optargcmd} 1311 parallel="-j ${OPTARG}" 1312 ;; 1313 1314 -M) 1315 eval ${optargcmd} 1316 resolvepath OPTARG 1317 case "${OPTARG}" in 1318 \$*) usage "-M argument must not begin with '\$'" 1319 ;; 1320 *\$*) # can use resolvepath, but can't set TOP_objdir 1321 resolvepath OPTARG 1322 ;; 1323 *) resolvepath OPTARG 1324 TOP_objdir="${OPTARG}${TOP}" 1325 ;; 1326 esac 1327 unsetmakeenv MAKEOBJDIR 1328 setmakeenv MAKEOBJDIRPREFIX "${OPTARG}" 1329 ;; 1330 1331 # -m overrides MACHINE_ARCH unless "-a" is specified 1332 -m) 1333 eval ${optargcmd} 1334 MACHINE="${OPTARG}" 1335 opt_m=true 1336 ;; 1337 1338 -N) 1339 eval ${optargcmd} 1340 case "${OPTARG}" in 1341 0|1|2|3|4) 1342 setmakeenv MAKEVERBOSE "${OPTARG}" 1343 ;; 1344 *) 1345 usage "'${OPTARG}' is not a valid value for -N" 1346 ;; 1347 esac 1348 ;; 1349 1350 -n) 1351 runcmd=echo 1352 ;; 1353 1354 -O) 1355 eval ${optargcmd} 1356 case "${OPTARG}" in 1357 *\$*) usage "-O argument must not contain '\$'" 1358 ;; 1359 *) resolvepath OPTARG 1360 TOP_objdir="${OPTARG}" 1361 ;; 1362 esac 1363 unsetmakeenv MAKEOBJDIRPREFIX 1364 setmakeenv MAKEOBJDIR "\${.CURDIR:C,^$TOP,$OPTARG,}" 1365 ;; 1366 1367 -o) 1368 MKOBJDIRS=no 1369 ;; 1370 1371 -P) 1372 MKREPRO=yes 1373 export MKREPRO 1374 ;; 1375 1376 -R) 1377 eval ${optargcmd} 1378 resolvepath OPTARG 1379 setmakeenv RELEASEDIR "${OPTARG}" 1380 ;; 1381 1382 -r) 1383 do_removedirs=true 1384 do_rebuildmake=true 1385 ;; 1386 1387 -S) 1388 eval ${optargcmd} 1389 setmakeenv BUILDSEED "${OPTARG}" 1390 ;; 1391 1392 -T) 1393 eval ${optargcmd} 1394 resolvepath OPTARG 1395 TOOLDIR="${OPTARG}" 1396 export TOOLDIR 1397 ;; 1398 1399 -U) 1400 setmakeenv MKUNPRIVED yes 1401 ;; 1402 1403 -u) 1404 setmakeenv MKUPDATE yes 1405 ;; 1406 1407 -V) 1408 eval ${optargcmd} 1409 case "${OPTARG}" in 1410 # XXX: consider restricting which variables can be changed? 1411 [a-zA-Z_]*=*) 1412 safe_setmakeenv "${OPTARG%%=*}" "${OPTARG#*=}" 1413 ;; 1414 [a-zA-Z_]*) 1415 safe_setmakeenv "${OPTARG}" "" 1416 ;; 1417 *) 1418 usage "-V argument must be of the form 'VAR[=VALUE]'" 1419 ;; 1420 esac 1421 ;; 1422 1423 -w) 1424 eval ${optargcmd} 1425 resolvepath OPTARG 1426 makewrapper="${OPTARG}" 1427 ;; 1428 1429 -X) 1430 eval ${optargcmd} 1431 resolvepath OPTARG 1432 setmakeenv X11SRCDIR "${OPTARG}" 1433 ;; 1434 1435 -x) 1436 setmakeenv MKX11 yes 1437 ;; 1438 1439 -Z) 1440 eval ${optargcmd} 1441 # XXX: consider restricting which variables can be unset? 1442 safe_unsetmakeenv "${OPTARG}" 1443 ;; 1444 1445 --) 1446 break 1447 ;; 1448 1449 -h) 1450 help 1451 exit 0 1452 ;; 1453 1454 '-?') 1455 if [ "${OPTARG}" = '?' ] 1456 then 1457 help 1458 exit 0 1459 fi 1460 usage "Unknown option -${OPTARG}" 1461 ;; 1462 1463 -:) 1464 usage "Missing argument for option -${OPTARG}" 1465 ;; 1466 1467 *) 1468 usage "Unimplemented option ${opt}" 1469 ;; 1470 1471 esac 1472 done 1473 1474 # Validate operations. 1475 # 1476 eval ${optremcmd} 1477 while [ $# -gt 0 ] 1478 do 1479 op=$1; shift 1480 operations="${operations} ${op}" 1481 1482 case "${op}" in 1483 1484 help) 1485 help 1486 exit 0 1487 ;; 1488 1489 list-arch) 1490 listarch "${MACHINE}" "${MACHINE_ARCH}" 1491 exit 1492 ;; 1493 mkrepro-timestamp) 1494 setup_mkrepro quiet 1495 echo "${MKREPRO_TIMESTAMP:-0}" 1496 did_show_info=true 1497 ;; 1498 1499 show-revisionid) 1500 setup_mkrepro quiet 1501 echo "${NETBSD_REVISIONID}" 1502 did_show_info=true 1503 ;; 1504 1505 kernel=*|releasekernel=*|kernel.gdb=*) 1506 arg=${op#*=} 1507 op=${op%%=*} 1508 [ -n "${arg}" ] || 1509 bomb "Must supply a kernel name with '${op}=...'" 1510 ;; 1511 1512 disk-image=*) 1513 arg=${op#*=} 1514 op=disk_image 1515 [ -n "${arg}" ] || 1516 bomb "Must supply a target name with '${op}=...'" 1517 1518 ;; 1519 1520 pkg=*) 1521 arg=${op#*=} 1522 op=${op%%=*} 1523 [ -n "${arg}" ] || 1524 bomb "Must supply category/package with 'pkg=...'" 1525 ;; 1526 1527 install=*|installmodules=*) 1528 arg=${op#*=} 1529 op=${op%%=*} 1530 [ -n "${arg}" ] || 1531 bomb "Must supply a directory with 'install=...'" 1532 ;; 1533 1534 distsets) 1535 operations="$(echo "$operations" | sed 's/distsets/distribution sets/')" 1536 do_sets=true 1537 op=distribution 1538 ;; 1539 1540 build|\ 1541 cleandir|\ 1542 distribution|\ 1543 dtb|\ 1544 install-image|\ 1545 iso-image-source|\ 1546 iso-image|\ 1547 kernels|\ 1548 libs|\ 1549 live-image|\ 1550 makewrapper|\ 1551 modules|\ 1552 obj|\ 1553 params|\ 1554 release|\ 1555 rump|\ 1556 rumptest|\ 1557 sets|\ 1558 show-params|\ 1559 sourcesets|\ 1560 syspkgs|\ 1561 tools) 1562 ;; 1563 1564 *) 1565 usage "Unknown OPERATION '${op}'" 1566 ;; 1567 1568 esac 1569 # ${op} may contain chars that are not allowed in variable 1570 # names. Replace them with '_' before setting do_${op}. 1571 op="$( echo "$op" | tr -s '.-' '__')" 1572 eval do_${op}=true 1573 done 1574 1575 "$did_show_info" && [ "${MKREPRO_TIMESTAMP:-0}" -ne 0 ] && exit 1576 1577 [ -n "${operations}" ] || usage "Missing OPERATION to perform" 1578 1579 # Set up MACHINE*. On a NetBSD host, these are allowed to be unset. 1580 # 1581 if [ -z "${MACHINE}" ] 1582 then 1583 [ "${uname_s}" = NetBSD ] || { 1584 bomb "MACHINE must be set, or -m must be used," \ 1585 "for cross builds" 1586 } 1587 MACHINE=${uname_m} 1588 MACHINE_ARCH=${uname_p} 1589 fi 1590 if $opt_m && ! $opt_a 1591 then 1592 # Settings implied by the command line -m option 1593 # override MACHINE_ARCH from the environment (if any). 1594 getarch 1595 fi 1596 [ -n "${MACHINE_ARCH}" ] || getarch 1597 validatearch 1598 1599 # Set up default make(1) environment. 1600 # 1601 makeenv="${makeenv} TOOLDIR MACHINE MACHINE_ARCH MAKEFLAGS" 1602 [ -z "${BUILDID}" ] || makeenv="${makeenv} BUILDID" 1603 [ -z "${BUILDINFO}" ] || makeenv="${makeenv} BUILDINFO" 1604 MAKEFLAGS="-de -m ${TOP}/share/mk ${MAKEFLAGS}" 1605 MAKEFLAGS="${MAKEFLAGS} MKOBJDIRS=${MKOBJDIRS-yes}" 1606 export MAKEFLAGS MACHINE MACHINE_ARCH 1607 if [ -z "${USETOOLS}" ]; then 1608 setmakeenv USETOOLS yes 1609 else 1610 setmakeenv USETOOLS "${USETOOLS}" 1611 fi 1612 setmakeenv MAKEWRAPPERMACHINE "${makewrappermachine:-${MACHINE}}" 1613 setmakeenv MAKE_OBJDIR_CHECK_WRITABLE no 1614 } 1615 1616 # sanitycheck -- 1617 # Sanity check after parsing command line options, before rebuildmake. 1618 # 1619 sanitycheck() 1620 { 1621 # Install as non-root is a bad idea. 1622 # 1623 if ${do_install} && [ "$id_u" -ne 0 ] 1624 then 1625 if ${do_expertmode} 1626 then 1627 warning "Will install as an unprivileged user" 1628 else 1629 bomb "-E must be set for install as an unprivileged user" 1630 fi 1631 fi 1632 1633 # If the PATH contains any non-absolute components (including, 1634 # but not limited to, "." or ""), then complain. As an exception, 1635 # allow "" or "." as the last component of the PATH. This is fatal 1636 # if expert mode is not in effect. 1637 # 1638 local path="${PATH}" 1639 path="${path%:}" # delete trailing ":" 1640 path="${path%:.}" # delete trailing ":." 1641 case ":${path}:/" in 1642 *:[!/~]*) 1643 if ${do_expertmode} 1644 then 1645 warning "PATH contains non-absolute components" 1646 else 1647 bomb "PATH environment variable must not" \ 1648 "contain non-absolute components" 1649 fi 1650 ;; 1651 esac 1652 1653 while [ "${MKX11-no}" = yes ] # not really a loop 1654 do 1655 test -n "${X11SRCDIR}" && { 1656 test -d "${X11SRCDIR}/external" || 1657 bomb "X11SRCDIR (${X11SRCDIR}) does not exist (with -x)" 1658 break 1659 } 1660 for _xd in \ 1661 "${NETBSDSRCDIR%/*}/xsrc" \ 1662 "${NETBSDSRCDIR}/xsrc" \ 1663 /usr/xsrc 1664 do 1665 test -f "${_xd}/Makefile" && 1666 setmakeenv X11SRCDIR "${_xd}" && 1667 break 2 1668 done 1669 bomb "Asked to build X11 but no xsrc" 1670 done 1671 1672 while $do_pkg # not really a loop 1673 do 1674 test -n "${PKGSRCDIR}" && { 1675 test -f "${PKGSRCDIR}/mk/bsd.pkg.mk" || 1676 bomb "PKGSRCDIR (${PKGSRCDIR}) does not exist" 1677 break 1678 } 1679 for _pd in \ 1680 "${NETBSDSRCDIR%/*}/pkgsrc" \ 1681 "${NETBSDSRCDIR}/pkgsrc" \ 1682 /usr/pkgsrc 1683 do 1684 test -f "${_pd}/mk/bsd.pkg.mk" && 1685 setmakeenv PKGSRCDIR "${_pd}" && 1686 break 2 1687 done 1688 bomb "Asked to build package but no pkgsrc" 1689 done 1690 if $do_pkg && [ "${MKX11-no}" = yes ] 1691 then 1692 # See comment below about X11_TYPE in pkgsrc mk.conf. 1693 # (Feel free to remove this, and set X11_TYPE to 1694 # native/modular according to MKX11=yes/no, if you want 1695 # to do the work to make X11_TYPE=native cross-builds 1696 # work.) 1697 bomb "Experimental \`build.sh pkg=...'" \ 1698 "does not support -x/MKX11=yes" 1699 fi 1700 } 1701 1702 # find a command in PATH and print the full filename 1703 print_path_of() 1704 { 1705 set -- $( type "$1" ) 1706 printf "${3}\n" 1707 } 1708 1709 1710 # print_tooldir_program -- 1711 # Try to find and show a path to an existing 1712 # ${TOOLDIR}/bin/${toolprefix}program 1713 # 1714 print_tooldir_program() 1715 { 1716 local possible_TOP_OBJ 1717 local possible_TOOLDIR 1718 local possible_program 1719 local tooldir_program 1720 local program="${1}" 1721 1722 if [ "${USETOOLS-yes}" != "yes" ]; then 1723 print_path_of "${program}" 1724 return 1725 fi 1726 1727 if [ -n "${TOOLDIR}" ] 1728 then 1729 echo "${TOOLDIR}/bin/${toolprefix}${program}" 1730 return 1731 fi 1732 1733 # Set host_ostype to something like "NetBSD-4.5.6-i386". This 1734 # is intended to match the HOST_OSTYPE variable in <bsd.own.mk>. 1735 # 1736 local host_ostype="${uname_s}-$( 1737 echo "${uname_r}" | sed -e 's/([^)]*)//g' -e 's/ /_/g' 1738 )-$( 1739 echo "${uname_p}" | sed -e 's/([^)]*)//g' -e 's/ /_/g' 1740 )" 1741 1742 # Look in a few potential locations for 1743 # ${possible_TOOLDIR}/bin/${toolprefix}${program}. 1744 # If we find it, then set possible_program. 1745 # 1746 # In the usual case (without interference from environment 1747 # variables or /etc/mk.conf), <bsd.own.mk> should set TOOLDIR to 1748 # "${_SRC_TOP_OBJ_}/tooldir.${host_ostype}". 1749 # 1750 # In practice it's difficult to figure out the correct value 1751 # for _SRC_TOP_OBJ_. In the easiest case, when the -M or -O 1752 # options were passed to build.sh, then ${TOP_objdir} will be 1753 # the correct value. We also try a few other possibilities, but 1754 # we do not replicate all the logic of <bsd.obj.mk>. 1755 # 1756 for possible_TOP_OBJ in \ 1757 "${TOP_objdir}" \ 1758 "${MAKEOBJDIRPREFIX:+${MAKEOBJDIRPREFIX}${TOP}}" \ 1759 "${TOP}" \ 1760 "${TOP}/obj" \ 1761 "${TOP}/obj.${MACHINE}" 1762 do 1763 [ -n "${possible_TOP_OBJ}" ] || continue 1764 possible_TOOLDIR="${possible_TOP_OBJ}/tooldir.${host_ostype}" 1765 possible_program="${possible_TOOLDIR}/bin/${toolprefix}${program}" 1766 if [ -x "${possible_program}" ] 1767 then 1768 echo ${possible_program} 1769 return 1770 fi 1771 done 1772 echo '' 1773 } 1774 1775 # print_tooldir_make -- 1776 # Try to find and show a path to an existing 1777 # ${TOOLDIR}/bin/${toolprefix}make, for use by rebuildmake() before a 1778 # new version of ${toolprefix}make has been built. 1779 # 1780 # * If TOOLDIR was set in the environment or on the command line, use 1781 # that value. 1782 # * Otherwise try to guess what TOOLDIR would be if not overridden by 1783 # /etc/mk.conf, and check whether the resulting directory contains 1784 # a copy of ${toolprefix}make (this should work for everybody who 1785 # doesn't override TOOLDIR via /etc/mk.conf); 1786 # * Failing that, search for ${toolprefix}make, nbmake, bmake, or make, 1787 # in the PATH (this might accidentally find a version of make that 1788 # does not understand the syntax used by NetBSD make, and that will 1789 # lead to failure in the next step); 1790 # * If a copy of make was found above, try to use it with 1791 # nobomb_getmakevar to find the correct value for TOOLDIR, and believe the 1792 # result only if it's a directory that already exists; 1793 # * If a value of TOOLDIR was found above, and if 1794 # ${TOOLDIR}/bin/${toolprefix}make exists, show that value. 1795 # 1796 print_tooldir_make() 1797 { 1798 local possible_make 1799 local possible_TOOLDIR 1800 local tooldir_make 1801 1802 possible_make=$(print_tooldir_program make) 1803 # If the above didn't work, search the PATH for a suitable 1804 # ${toolprefix}make, nbmake, bmake, or make. 1805 # 1806 : ${possible_make:=$(find_in_PATH ${toolprefix}make '')} 1807 : ${possible_make:=$(find_in_PATH nbmake '')} 1808 : ${possible_make:=$(find_in_PATH bmake '')} 1809 : ${possible_make:=$(find_in_PATH make '')} 1810 1811 # At this point, we don't care whether possible_make is in the 1812 # correct TOOLDIR or not; we simply want it to be usable by 1813 # getmakevar to help us find the correct TOOLDIR. 1814 # 1815 # Use ${possible_make} with nobomb_getmakevar to try to find 1816 # the value of TOOLDIR. Believe the result only if it's 1817 # a directory that already exists and contains bin/${toolprefix}make. 1818 # 1819 if [ -x "${possible_make}" ] 1820 then 1821 possible_TOOLDIR=$( 1822 make="${possible_make}" \ 1823 nobomb_getmakevar TOOLDIR 2>/dev/null 1824 ) 1825 if [ $? = 0 ] && 1826 [ -n "${possible_TOOLDIR}" ] && 1827 [ -d "${possible_TOOLDIR}" ] 1828 then 1829 tooldir_make="${possible_TOOLDIR}/bin/${toolprefix}make" 1830 if [ -x "${tooldir_make}" ] 1831 then 1832 echo "${tooldir_make}" 1833 return 0 1834 fi 1835 fi 1836 fi 1837 return 1 1838 } 1839 1840 # rebuildmake -- 1841 # Rebuild nbmake in a temporary directory if necessary. Sets $make 1842 # to a path to the nbmake executable. Sets done_rebuildmake=true 1843 # if nbmake was rebuilt. 1844 # 1845 # There is a cyclic dependency between building nbmake and choosing 1846 # TOOLDIR: TOOLDIR may be affected by settings in /etc/mk.conf, so we 1847 # would like to use getmakevar to get the value of TOOLDIR; but we can't 1848 # use getmakevar before we have an up to date version of nbmake; we 1849 # might already have an up to date version of nbmake in TOOLDIR, but we 1850 # don't yet know where TOOLDIR is. 1851 # 1852 # The default value of TOOLDIR also depends on the location of the top 1853 # level object directory, so $(getmakevar TOOLDIR) invoked before or 1854 # after making the top level object directory may produce different 1855 # results. 1856 # 1857 # Strictly speaking, we should do the following: 1858 # 1859 # 1. build a new version of nbmake in a temporary directory; 1860 # 2. use the temporary nbmake to create the top level obj directory; 1861 # 3. use $(getmakevar TOOLDIR) with the temporary nbmake to 1862 # get the correct value of TOOLDIR; 1863 # 4. move the temporary nbmake to ${TOOLDIR}/bin/nbmake. 1864 # 1865 # However, people don't like building nbmake unnecessarily if their 1866 # TOOLDIR has not changed since an earlier build. We try to avoid 1867 # rebuilding a temporary version of nbmake by taking some shortcuts to 1868 # guess a value for TOOLDIR, looking for an existing version of nbmake 1869 # in that TOOLDIR, and checking whether that nbmake is newer than the 1870 # sources used to build it. 1871 # 1872 rebuildmake() 1873 { 1874 make="$(print_tooldir_make)" 1875 if [ -n "${make}" ] && [ -x "${make}" ] 1876 then 1877 for f in usr.bin/make/*.[ch] 1878 do 1879 if [ "${f}" -nt "${make}" ] 1880 then 1881 statusmsg "${make} outdated" \ 1882 "(older than ${f}), needs building." 1883 do_rebuildmake=true 1884 break 1885 fi 1886 done 1887 else 1888 statusmsg "No \$TOOLDIR/bin/${toolprefix}make, needs building." 1889 do_rebuildmake=true 1890 fi 1891 1892 # Build bootstrap ${toolprefix}make if needed. 1893 if ! ${do_rebuildmake} 1894 then 1895 return 1896 fi 1897 1898 # Silent configure with MAKEVERBOSE==0 1899 if [ ${MAKEVERBOSE:-2} -eq 0 ] 1900 then 1901 configure_args=--silent 1902 fi 1903 1904 statusmsg "Bootstrapping ${toolprefix}make" 1905 ${runcmd} cd "${tmpdir}" 1906 ${runcmd} env CC="${HOST_CC-cc}" CPPFLAGS="${HOST_CPPFLAGS}" \ 1907 CFLAGS="${HOST_CFLAGS--O}" LDFLAGS="${HOST_LDFLAGS}" \ 1908 ${HOST_SH} "${TOP}/tools/make/configure" ${configure_args} || 1909 ( cp ${tmpdir}/config.log ${tmpdir}-config.log 1910 bomb "Configure of ${toolprefix}make failed," \ 1911 "see ${tmpdir}-config.log for details" ) 1912 ${runcmd} ${HOST_SH} buildmake.sh || 1913 bomb "Build of ${toolprefix}make failed" 1914 make="${tmpdir}/${toolprefix}make" 1915 ${runcmd} cd "${TOP}" 1916 ${runcmd} rm -f usr.bin/make/*.o 1917 done_rebuildmake=true 1918 } 1919 1920 # validatemakeparams -- 1921 # Perform some late sanity checks, after rebuildmake, 1922 # but before createmakewrapper or any real work. 1923 # 1924 # Creates the top-level obj directory, because that 1925 # is needed by some of the sanity checks. 1926 # 1927 # Shows status messages reporting the values of several variables. 1928 # 1929 validatemakeparams() 1930 { 1931 # Determine MAKECONF first, and set in the makewrapper. 1932 # If set in the environment, then use that. 1933 # else if ./mk.conf exists, then set MAKECONF to that, 1934 # else use the default from share/mk/bsd.own.mk (/etc/mk.conf). 1935 # 1936 if [ -n "${MAKECONF+1}" ] 1937 then 1938 setmakeenv MAKECONF "${MAKECONF}" 1939 statusmsg2 "getenv MAKECONF:" "${MAKECONF}" 1940 elif [ -f "${TOP}/mk.conf" ] 1941 then 1942 setmakeenv MAKECONF "${TOP}/mk.conf" 1943 statusmsg2 "mk.conf MAKECONF:" "${MAKECONF}" 1944 else 1945 MAKECONF=$(getmakevar MAKECONF) 1946 setmakeenv MAKECONF "${MAKECONF}" 1947 statusmsg2 "share/mk MAKECONF:" "${MAKECONF}" 1948 fi 1949 if [ -z "${MAKECONF}" ] 1950 then 1951 bomb "MAKECONF must not be empty" 1952 elif [ -e "${MAKECONF}" ] 1953 then 1954 statusmsg2 "MAKECONF file:" "${MAKECONF}" 1955 else 1956 statusmsg2 "MAKECONF file:" "${MAKECONF} (File not found)" 1957 fi 1958 1959 # Normalise MKOBJDIRS, MKUNPRIVED, and MKUPDATE. 1960 # These may be set as build.sh options or in "mk.conf". 1961 # Don't export them as they're only used for tests in build.sh. 1962 # 1963 MKOBJDIRS=$(getmakevar MKOBJDIRS) 1964 MKUNPRIVED=$(getmakevar MKUNPRIVED) 1965 MKUPDATE=$(getmakevar MKUPDATE) 1966 1967 # Non-root should always use either the -U or -E flag. 1968 # 1969 if ! ${do_expertmode} && [ "$id_u" -ne 0 ] && [ "${MKUNPRIVED}" = no ] 1970 then 1971 bomb "-U or -E must be set for build as an unprivileged user" 1972 fi 1973 1974 if [ "${runcmd}" = echo ] 1975 then 1976 TOOLCHAIN_MISSING=no 1977 EXTERNAL_TOOLCHAIN= 1978 else 1979 TOOLCHAIN_MISSING=$(bomb_getmakevar TOOLCHAIN_MISSING) 1980 EXTERNAL_TOOLCHAIN=$(bomb_getmakevar EXTERNAL_TOOLCHAIN) 1981 fi 1982 if [ "${TOOLCHAIN_MISSING}" = yes ] && [ -z "${EXTERNAL_TOOLCHAIN}" ] 1983 then 1984 ${runcmd} echo "ERROR: build.sh (in-tree cross-toolchain)" \ 1985 "is not yet available for" 1986 ${runcmd} echo " MACHINE: ${MACHINE}" 1987 ${runcmd} echo " MACHINE_ARCH: ${MACHINE_ARCH}" 1988 ${runcmd} echo "" 1989 ${runcmd} echo "All builds for this platform should be done" \ 1990 "via a traditional make" 1991 ${runcmd} echo "If you wish to use an external" \ 1992 "cross-toolchain, set" 1993 ${runcmd} echo " EXTERNAL_TOOLCHAIN=<path to" \ 1994 "toolchain root>" 1995 ${runcmd} echo "in either the environment or mk.conf and rerun" 1996 ${runcmd} echo " ${progname} $*" 1997 exit 1 1998 fi 1999 2000 if [ "${MKOBJDIRS}" != no ] 2001 then 2002 # Create the top-level object directory. 2003 # 2004 # "make obj NOSUBDIR=" can handle most cases, but it 2005 # can't handle the case where MAKEOBJDIRPREFIX is set 2006 # while the corresponding directory does not exist 2007 # (rules in <bsd.obj.mk> would abort the build). We 2008 # therefore have to handle the MAKEOBJDIRPREFIX case 2009 # without invoking "make obj". The MAKEOBJDIR case 2010 # could be handled either way, but we choose to handle 2011 # it similarly to MAKEOBJDIRPREFIX. 2012 # 2013 if [ -n "${TOP_obj}" ] 2014 then 2015 # It must have been set by the "-M" or "-O" 2016 # command line options, so there's no need to 2017 # use getmakevar 2018 : 2019 elif [ -n "$MAKEOBJDIRPREFIX" ] 2020 then 2021 TOP_obj="$(getmakevar MAKEOBJDIRPREFIX)${TOP}" 2022 elif [ -n "$MAKEOBJDIR" ] 2023 then 2024 TOP_obj="$(getmakevar MAKEOBJDIR)" 2025 fi 2026 if [ -n "$TOP_obj" ] 2027 then 2028 ${runcmd} mkdir -p "${TOP_obj}" || 2029 bomb "Can't create top level object directory" \ 2030 "${TOP_obj}" 2031 else 2032 ${runcmd} "${make}" -m "${TOP}/share/mk" obj NOSUBDIR= || 2033 bomb "Can't create top level object directory" \ 2034 "using make obj" 2035 fi 2036 2037 # make obj in tools to ensure that the objdir for "tools" 2038 # is available. 2039 # 2040 ${runcmd} cd tools 2041 ${runcmd} "${make}" -m "${TOP}/share/mk" obj NOSUBDIR= || 2042 bomb "Failed to make obj in tools" 2043 ${runcmd} cd "${TOP}" 2044 fi 2045 2046 # Find TOOLDIR, DESTDIR, and RELEASEDIR, according to getmakevar, 2047 # and bomb if they have changed from the values we had from the 2048 # command line or environment. 2049 # 2050 # This must be done after creating the top-level object directory. 2051 # 2052 for var in TOOLDIR DESTDIR RELEASEDIR 2053 do 2054 eval oldval=\"\$${var}\" 2055 newval="$(getmakevar $var)" 2056 if ! $do_expertmode 2057 then 2058 : ${_SRC_TOP_OBJ_:=$(getmakevar _SRC_TOP_OBJ_)} 2059 case "$var" in 2060 DESTDIR) 2061 : ${newval:=${_SRC_TOP_OBJ_}/destdir.${MACHINE}} 2062 makeenv="${makeenv} DESTDIR" 2063 ;; 2064 RELEASEDIR) 2065 : ${newval:=${_SRC_TOP_OBJ_}/releasedir} 2066 makeenv="${makeenv} RELEASEDIR" 2067 ;; 2068 esac 2069 fi 2070 if [ -n "$oldval" ] && [ "$oldval" != "$newval" ] 2071 then 2072 bomb "Value of ${var} has changed" \ 2073 "(was \"${oldval}\", now \"${newval}\")" 2074 fi 2075 eval ${var}=\"\${newval}\" 2076 eval export ${var} 2077 statusmsg2 "${var} path:" "${newval}" 2078 done 2079 2080 # RELEASEMACHINEDIR is just a subdir name, e.g. "i386". 2081 RELEASEMACHINEDIR=$(getmakevar RELEASEMACHINEDIR) 2082 2083 # Check validity of TOOLDIR and DESTDIR. 2084 # 2085 if [ -z "${TOOLDIR}" ] || [ "${TOOLDIR}" = / ] 2086 then 2087 bomb "TOOLDIR '${TOOLDIR}' invalid" 2088 fi 2089 removedirs="${TOOLDIR}" 2090 2091 if [ -z "${DESTDIR}" ] || [ "${DESTDIR}" = / ] 2092 then 2093 if ${do_distribution} || ${do_release} || 2094 [ "${uname_s}" != NetBSD ] || 2095 [ "${uname_m}" != "${MACHINE}" ] 2096 then 2097 bomb "DESTDIR must != / for cross builds," \ 2098 "or ${progname} 'distribution' or 'release'" 2099 fi 2100 if ! ${do_expertmode} 2101 then 2102 bomb "DESTDIR must != / for non -E (expert) builds" 2103 fi 2104 statusmsg "WARNING: Building to /, in expert mode." 2105 statusmsg " This may cause your system to break!" 2106 statusmsg " Reasons include:" 2107 statusmsg " - your kernel is not up to date" 2108 statusmsg " - the libraries or toolchain have changed" 2109 statusmsg " YOU HAVE BEEN WARNED!" 2110 else 2111 removedirs="${removedirs} ${DESTDIR}" 2112 fi 2113 if ${do_releasekernel} && [ -z "${RELEASEDIR}" ] 2114 then 2115 bomb "Must set RELEASEDIR with 'releasekernel=...'" 2116 fi 2117 2118 # If a previous build.sh run used -U (and therefore created a 2119 # METALOG file), then most subsequent build.sh runs must also 2120 # use -U. If DESTDIR is about to be removed, then don't perform 2121 # this check. 2122 # 2123 case "${do_removedirs} ${removedirs} " in 2124 true*" ${DESTDIR} "*) 2125 # DESTDIR is about to be removed 2126 ;; 2127 *) 2128 if [ -e "${DESTDIR}/METALOG" ] && 2129 [ "${MKUNPRIVED}" = no ] 2130 then 2131 if $do_expertmode 2132 then 2133 warning "A previous build.sh run specified -U" 2134 else 2135 bomb "A previous build.sh run specified -U;" \ 2136 "you must specify it again now" 2137 fi 2138 fi 2139 ;; 2140 esac 2141 2142 # live-image and install-image targets require binary sets 2143 # (actually DESTDIR/etc/mtree/set.* files) built with MKUNPRIVED. 2144 # If release operation is specified with live-image or install-image, 2145 # the release op should be performed with -U for later image ops. 2146 # 2147 if ${do_release} && 2148 { ${do_live_image} || ${do_install_image} ; } && 2149 [ "${MKUNPRIVED}" = no ] 2150 then 2151 bomb "-U must be specified on building release" \ 2152 "to create images later" 2153 fi 2154 } 2155 2156 2157 createmakewrapper() 2158 { 2159 # Remove the target directories. 2160 # 2161 if ${do_removedirs} 2162 then 2163 for f in ${removedirs} 2164 do 2165 statusmsg "Removing ${f}" 2166 ${runcmd} rm -r -f "${f}" 2167 done 2168 fi 2169 2170 # Recreate $TOOLDIR. 2171 # 2172 ${runcmd} mkdir -p "${TOOLDIR}/bin" || 2173 bomb "mkdir of '${TOOLDIR}/bin' failed" 2174 2175 # If we did not previously rebuild ${toolprefix}make, then 2176 # check whether $make is still valid and the same as the output 2177 # from print_tooldir_make. If not, then rebuild make now. A 2178 # possible reason for this being necessary is that the actual 2179 # value of TOOLDIR might be different from the value guessed 2180 # before the top level obj dir was created. 2181 # 2182 if ! ${done_rebuildmake} && 2183 { ! [ -x "$make" ] || [ "$make" != "$(print_tooldir_make)" ] ; } 2184 then 2185 rebuildmake 2186 fi 2187 2188 # Install ${toolprefix}make if it was built. 2189 # 2190 if ${done_rebuildmake} 2191 then 2192 ${runcmd} rm -f "${TOOLDIR}/bin/${toolprefix}make" 2193 ${runcmd} cp "${make}" "${TOOLDIR}/bin/${toolprefix}make" || 2194 bomb "Failed to install \$TOOLDIR/bin/${toolprefix}make" 2195 make="${TOOLDIR}/bin/${toolprefix}make" 2196 statusmsg "Created ${make}" 2197 fi 2198 2199 # Build a ${toolprefix}make wrapper script, usable by hand as 2200 # well as by build.sh. 2201 # 2202 if [ -z "${makewrapper}" ] 2203 then 2204 makewrapper="${TOOLDIR}/bin/${toolprefix}make" 2205 makewrapper="${makewrapper}-${makewrappermachine:-${MACHINE}}" 2206 [ -z "${BUILDID}" ] || makewrapper="${makewrapper}-${BUILDID}" 2207 fi 2208 2209 ${runcmd} rm -f "${makewrapper}" 2210 if [ "${runcmd}" = echo ] 2211 then 2212 echo 'cat <<EOF >'${makewrapper} 2213 makewrapout= 2214 else 2215 makewrapout=">>\${makewrapper}" 2216 fi 2217 2218 case "${KSH_VERSION:-${SH_VERSION}}" in 2219 *PD\ KSH*|*MIRBSD\ KSH*) 2220 set +o braceexpand 2221 ;; 2222 esac 2223 2224 eval cat <<EOF ${makewrapout} 2225 #! ${HOST_SH} 2226 # Set proper variables to allow easy "make" building of a NetBSD subtree. 2227 # Generated from: \$NetBSD: build.sh,v 1.400 2025/10/20 14:31:35 nat Exp $ 2228 # with these arguments: ${_args} 2229 # 2230 2231 EOF 2232 { 2233 sorted_vars=$( 2234 for var in ${makeenv} 2235 do 2236 echo "${var}" 2237 done | 2238 sort -u 2239 ) 2240 for var in ${sorted_vars} 2241 do 2242 eval val=\"\${${var}}\" 2243 eval is_set=\"\${${var}+set}\" 2244 if [ -z "${is_set}" ] 2245 then 2246 echo "unset ${var}" 2247 else 2248 qval="$(shell_quote "${val}")" 2249 echo "${var}=${qval}; export ${var}" 2250 fi 2251 done 2252 2253 cat <<-EOF 2254 2255 exec "\${TOOLDIR}/bin/${toolprefix}make" \${1+"\$@"} 2256 EOF 2257 } | eval cat "${makewrapout}" 2258 [ "${runcmd}" = echo ] && echo EOF 2259 ${runcmd} chmod +x "${makewrapper}" 2260 statusmsg2 "Updated makewrapper:" "${makewrapper}" 2261 } 2262 2263 make_in_dir() 2264 { 2265 local dir="$1" 2266 local op="$2" 2267 ${runcmd} cd "${dir}" || 2268 bomb "Failed to cd to \"${dir}\"" 2269 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2270 bomb "Failed to make ${op} in \"${dir}\"" 2271 ${runcmd} cd "${TOP}" || 2272 bomb "Failed to cd back to \"${TOP}\"" 2273 } 2274 2275 buildtools() 2276 { 2277 if [ "${MKOBJDIRS}" != no ] 2278 then 2279 ${runcmd} "${makewrapper}" ${parallel} obj-tools || 2280 bomb "Failed to make obj-tools" 2281 fi 2282 if [ "${MKUPDATE}" = no ] 2283 then 2284 make_in_dir tools cleandir 2285 fi 2286 make_in_dir tools build_install 2287 statusmsg "Tools built to ${TOOLDIR}" 2288 } 2289 2290 buildlibs() 2291 { 2292 if [ "${MKOBJDIRS}" != no ] 2293 then 2294 ${runcmd} "${makewrapper}" ${parallel} obj || 2295 bomb "Failed to make obj" 2296 fi 2297 if [ "${MKUPDATE}" = no ] 2298 then 2299 make_in_dir lib cleandir 2300 fi 2301 make_in_dir . do-distrib-dirs 2302 make_in_dir . includes 2303 make_in_dir . do-lib 2304 statusmsg "libs built" 2305 } 2306 2307 getkernelconf() 2308 { 2309 kernelconf=$1 2310 if [ "${MKOBJDIRS}" != no ] 2311 then 2312 # The correct value of KERNOBJDIR might 2313 # depend on a prior "make obj" in 2314 # ${KERNSRCDIR}/${KERNARCHDIR}/compile. 2315 # 2316 KERNSRCDIR="$(getmakevar KERNSRCDIR)" 2317 KERNARCHDIR="$(getmakevar KERNARCHDIR)" 2318 make_in_dir "${KERNSRCDIR}/${KERNARCHDIR}/compile" obj 2319 fi 2320 KERNCONFDIR=$(getmakevar KERNCONFDIR) 2321 KERNOBJDIR=$(getmakevar KERNOBJDIR) 2322 case "${kernelconf}" in 2323 */*) 2324 kernelconfpath=${kernelconf} 2325 kernelconfname=${kernelconf##*/} 2326 ;; 2327 *) 2328 kernelconfpath=${KERNCONFDIR}/${kernelconf} 2329 kernelconfname=${kernelconf} 2330 ;; 2331 esac 2332 kernelbuildpath=${KERNOBJDIR}/${kernelconfname} 2333 } 2334 2335 diskimage() 2336 { 2337 ARG="$(echo "$1" | tr '[:lower:]' '[:upper:]')" 2338 [ -f "${DESTDIR}/etc/mtree/set.base" ] || 2339 bomb "The release binaries must be built first" 2340 kerneldir="${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/kernel" 2341 kernel="${kerneldir}/netbsd-${ARG}.gz" 2342 [ -f "${kernel}" ] || 2343 bomb "The kernel ${kernel} must be built first" 2344 make_in_dir "${NETBSDSRCDIR}/etc" "smp_${1}" 2345 } 2346 2347 buildkernel() 2348 { 2349 if ! ${do_tools} && ! ${buildkernelwarned:-false} 2350 then 2351 # Building tools every time we build a kernel is clearly 2352 # unnecessary. We could try to figure out whether rebuilding 2353 # the tools is necessary this time, but it doesn't seem worth 2354 # the trouble. Instead, we say it's the user's responsibility 2355 # to rebuild the tools if necessary. 2356 # 2357 statusmsg "Building kernel without building new tools" 2358 buildkernelwarned=true 2359 fi 2360 getkernelconf $1 2361 statusmsg2 "Building kernel:" "${kernelconf}" 2362 statusmsg2 "Build directory:" "${kernelbuildpath}" 2363 ${runcmd} mkdir -p "${kernelbuildpath}" || 2364 bomb "Cannot mkdir: ${kernelbuildpath}" 2365 if [ "${MKUPDATE}" = no ] 2366 then 2367 make_in_dir "${kernelbuildpath}" cleandir 2368 fi 2369 [ -x "${TOOLDIR}/bin/${toolprefix}config" ] || 2370 bomb "${TOOLDIR}/bin/${toolprefix}config does not exist." \ 2371 "You need to \"$0 tools\" first" 2372 CONFIGOPTS=$(getmakevar CONFIGOPTS) 2373 ${runcmd} "${TOOLDIR}/bin/${toolprefix}config" ${CONFIGOPTS} \ 2374 -b "${kernelbuildpath}" -s "${TOP}/sys" ${configopts} \ 2375 "${kernelconfpath}" || 2376 bomb "${toolprefix}config failed for ${kernelconf}" 2377 make_in_dir "${kernelbuildpath}" depend 2378 make_in_dir "${kernelbuildpath}" all 2379 2380 if [ "${runcmd}" != echo ] 2381 then 2382 statusmsg "Kernels built from ${kernelconf}:" 2383 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath}) 2384 for kern in ${kernlist:-netbsd} 2385 do 2386 [ -f "${kernelbuildpath}/${kern}" ] && 2387 echo " ${kernelbuildpath}/${kern}" 2388 done | tee -a "${results}" 2389 fi 2390 } 2391 2392 releasekernel() 2393 { 2394 getkernelconf $1 2395 kernelreldir="${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/kernel" 2396 ${runcmd} mkdir -p "${kernelreldir}" 2397 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath}) 2398 for kern in ${kernlist:-netbsd} 2399 do 2400 builtkern="${kernelbuildpath}/${kern}" 2401 [ -f "${builtkern}" ] || continue 2402 releasekern="${kernelreldir}/${kern}-${kernelconfname}.gz" 2403 statusmsg2 "Kernel copy:" "${releasekern}" 2404 if [ "${runcmd}" = echo ] 2405 then 2406 echo "gzip -c -9 < ${builtkern} > ${releasekern}" 2407 else 2408 gzip -c -9 < "${builtkern}" > "${releasekern}" 2409 fi 2410 done 2411 } 2412 2413 buildkernels() 2414 { 2415 allkernels=$( runcmd= make_in_dir etc '-V ${ALL_KERNELS}' ) 2416 for k in $allkernels 2417 do 2418 buildkernel "${k}" 2419 done 2420 } 2421 2422 buildmodules() 2423 { 2424 setmakeenv MKBINUTILS no 2425 if ! ${do_tools} && ! ${buildmoduleswarned:-false} 2426 then 2427 # Building tools every time we build modules is clearly 2428 # unnecessary as well as a kernel. 2429 # 2430 statusmsg "Building modules without building new tools" 2431 buildmoduleswarned=true 2432 fi 2433 2434 statusmsg "Building kernel modules for NetBSD/${MACHINE} ${DISTRIBVER}" 2435 if [ "${MKOBJDIRS}" != no ] 2436 then 2437 make_in_dir sys/modules obj 2438 fi 2439 if [ "${MKUPDATE}" = no ] 2440 then 2441 make_in_dir sys/modules cleandir 2442 fi 2443 make_in_dir sys/modules dependall 2444 make_in_dir sys/modules install 2445 2446 statusmsg "Successful build of kernel modules for" \ 2447 "NetBSD/${MACHINE} ${DISTRIBVER}" 2448 } 2449 2450 builddtb() 2451 { 2452 statusmsg "Building devicetree blobs for" \ 2453 "NetBSD/${MACHINE} ${DISTRIBVER}" 2454 if [ "${MKOBJDIRS}" != no ] 2455 then 2456 make_in_dir sys/dtb obj 2457 fi 2458 if [ "${MKUPDATE}" = no ] 2459 then 2460 make_in_dir sys/dtb cleandir 2461 fi 2462 make_in_dir sys/dtb dependall 2463 make_in_dir sys/dtb install 2464 2465 statusmsg "Successful build of devicetree blobs for" \ 2466 "NetBSD/${MACHINE} ${DISTRIBVER}" 2467 } 2468 2469 buildpkg() 2470 { 2471 local catpkg 2472 local pkgroot 2473 local makejobsarg 2474 local makejobsvar 2475 local quiet 2476 local opsys_version 2477 2478 catpkg="$1" 2479 2480 pkgroot="${TOP_objdir:-${TOP}}/pkgroot" 2481 ${runcmd} mkdir -p "${pkgroot}" || 2482 bomb "Can't create package root" "${pkgroot}" 2483 2484 # Get a symlink-free absolute path to pkg -- pkgsrc wants this. 2485 # 2486 # XXX See TOP= above regarding pwd -P. 2487 pkgroot=$(unset PWD; cd "${pkgroot}" && 2488 ((exec pwd -P 2>/dev/null) || (exec pwd 2>/dev/null))) 2489 2490 case $parallel in 2491 "-j "*) 2492 makejobsarg="--make-jobs ${parallel#-j }" 2493 makejobsvar="MAKE_JOBS=${parallel#-j }" 2494 ;; 2495 *) makejobsarg= 2496 makejobsvar= 2497 ;; 2498 esac 2499 2500 if [ "${MAKEVERBOSE}" -eq 0 ] 2501 then 2502 quiet="--quiet" 2503 else 2504 quiet= 2505 fi 2506 2507 # Derived from pkgsrc/mk/bsd.prefs.mk rev. 1.451. 2508 opsys_version=$(echo "${DISTRIBVER}" | 2509 awk -F. '{ 2510 major=int($1) 2511 minor=int($2) 2512 if (minor>=100) minor=99 2513 patch=int($3) 2514 if (patch>=100) patch=99 2515 printf "%02d%02d%02d", major, minor, patch 2516 }' 2517 ) 2518 2519 # Bootstrap pkgsrc if needed. 2520 # 2521 # XXX Redo this if it's out-of-date, not just if it's missing. 2522 if ! [ -x "${pkgroot}/pkg/bin/bmake" ] 2523 then 2524 statusmsg "Bootstrapping pkgsrc" 2525 2526 cat >"${pkgroot}/mk.conf-fragment" <<EOF 2527 USE_CROSS_COMPILE?= no 2528 TOOLDIR= ${TOOLDIR} 2529 CROSS_DESTDIR= ${DESTDIR} 2530 CROSS_MACHINE_ARCH= ${MACHINE_ARCH} 2531 CROSS_OPSYS= NetBSD 2532 CROSS_OS_VERSION= ${DISTRIBVER} 2533 CROSS_OPSYS_VERSION= ${opsys_version} 2534 CROSS_LOWER_OPSYS= netbsd 2535 CROSS_LOWER_OPSYS_VERSUFFIX= # empty 2536 CROSS_LOWER_OS_VARIANT= # empty 2537 CROSS_LOWER_VARIANT_VERSION= # empty 2538 CROSS_LOWER_VENDOR= # empty 2539 CROSS_OBJECT_FMT= ELF 2540 2541 ALLOW_VULNERABLE_PACKAGES= yes 2542 BINPKG_SITES= # empty 2543 FAILOVER_FETCH= yes 2544 FETCH_TIMEOUT= 1800 2545 PASSIVE_FETCH= yes 2546 2547 DISTDIR= ${pkgroot}/distfiles 2548 PACKAGES= ${pkgroot}/packages 2549 WRKOBJDIR= ${pkgroot}/work 2550 2551 # pkgsrc cross-builds are not set up to support native X, but also part 2552 # of the point of pkgsrc cross-build infrastructure is to not need 2553 # native X any more. 2554 # 2555 # (If you fix this, remove the bomb in build.sh pkg=... on MKX11=yes.) 2556 X11_TYPE= modular 2557 2558 .-include "${MAKECONF}" 2559 2560 MKDEBUG= no # interferes with pkgsrc builds 2561 EOF 2562 2563 # XXX Set --abi for mips and whatever else needs it? 2564 # XXX Unprivileged native tools, privileged cross. 2565 ( 2566 cd "${PKGSRCDIR}" && 2567 clearmakeenv && 2568 ./bootstrap/bootstrap \ 2569 ${makejobsarg} \ 2570 --mk-fragment "${pkgroot}/mk.conf-fragment" \ 2571 --prefix "${pkgroot}/pkg" \ 2572 ${quiet} \ 2573 --unprivileged \ 2574 --workdir "${pkgroot}/bootwork" 2575 ) || 2576 bomb "Failed to bootstrap pkgsrc" 2577 fi 2578 2579 # Build the package. 2580 ( 2581 cd "${PKGSRCDIR}/${catpkg}" && 2582 clearmakeenv && 2583 "${pkgroot}/pkg/bin/bmake" package \ 2584 USE_CROSS_COMPILE=yes \ 2585 ${makejobsvar} 2586 ) || 2587 bomb "Failed to build ${catpkg}" 2588 } 2589 2590 installmodules() 2591 { 2592 dir="$1" 2593 ${runcmd} "${makewrapper}" INSTALLMODULESDIR="${dir}" installmodules || 2594 bomb "Failed to make installmodules to ${dir}" 2595 statusmsg "Successful installmodules to ${dir}" 2596 } 2597 2598 installworld() 2599 { 2600 dir="$1" 2601 ${runcmd} "${makewrapper}" INSTALLWORLDDIR="${dir}" installworld || 2602 bomb "Failed to make installworld to ${dir}" 2603 statusmsg "Successful installworld to ${dir}" 2604 } 2605 2606 # Run rump build&link tests. 2607 # 2608 # To make this feasible for running without having to install includes and 2609 # libraries into destdir (i.e. quick), we only run ld. This is possible 2610 # since the rump kernel is a closed namespace apart from calls to rumpuser. 2611 # Therefore, if ld complains only about rumpuser symbols, rump kernel 2612 # linking was successful. 2613 # 2614 # We test that rump links with a number of component configurations. 2615 # These attempt to mimic what is encountered in the full build. 2616 # See list below. The list should probably be either autogenerated 2617 # or managed elsewhere; keep it here until a better idea arises. 2618 # 2619 # Above all, note that THIS IS NOT A SUBSTITUTE FOR A FULL BUILD. 2620 # 2621 2622 # XXX: uwe: kern/56599 - while riastradh addressed librump problems, 2623 # there are still unwanted dependencies: 2624 # net -> net_net 2625 # vfs -> fifo 2626 2627 # -lrumpvfs -> $LRUMPVFS for now 2628 LRUMPVFS="-lrumpvfs -lrumpvfs_nofifofs" 2629 2630 RUMP_LIBSETS=" 2631 -lrump, 2632 -lrumpvfs 2633 --no-whole-archive -lrumpvfs_nofifofs -lrump, 2634 -lrumpkern_tty 2635 --no-whole-archive $LRUMPVFS -lrump, 2636 -lrumpfs_tmpfs 2637 --no-whole-archive $LRUMPVFS -lrump, 2638 -lrumpfs_ffs -lrumpfs_msdos 2639 --no-whole-archive $LRUMPVFS -lrumpdev_disk -lrumpdev -lrump, 2640 -lrumpnet_virtif -lrumpnet_netinet -lrumpnet_net -lrumpnet 2641 --no-whole-archive -lrump, 2642 -lrumpfs_nfs 2643 --no-whole-archive $LRUMPVFS 2644 -lrumpnet_sockin -lrumpnet_virtif -lrumpnet_netinet 2645 --start-group -lrumpnet_net -lrumpnet --end-group -lrump, 2646 -lrumpdev_cgd -lrumpdev_raidframe -lrumpdev_rnd -lrumpdev_dm 2647 --no-whole-archive $LRUMPVFS -lrumpdev_disk -lrumpdev -lrumpkern_crypto -lrump 2648 " 2649 2650 dorump() 2651 { 2652 local doclean= 2653 local doobjs= 2654 2655 export RUMPKERN_ONLY=1 2656 # create obj and distrib dirs 2657 if [ "${MKOBJDIRS}" != no ] 2658 then 2659 make_in_dir "${NETBSDSRCDIR}/etc/mtree" obj 2660 make_in_dir "${NETBSDSRCDIR}/sys/rump" obj 2661 fi 2662 ${runcmd} "${makewrapper}" ${parallel} do-distrib-dirs \ 2663 || bomb "Could not create distrib-dirs" 2664 2665 [ "${MKUPDATE}" = no ] && doclean="cleandir" 2666 targlist="${doclean} ${doobjs} dependall install" 2667 2668 # optimize: for test we build only static libs (3x test speedup) 2669 if [ "${1}" = rumptest ] 2670 then 2671 setmakeenv NOPIC 1 2672 setmakeenv NOPROFILE 1 2673 fi 2674 2675 for cmd in ${targlist} 2676 do 2677 make_in_dir "${NETBSDSRCDIR}/sys/rump" ${cmd} 2678 done 2679 2680 # if we just wanted to build & install rump, we're done 2681 [ "${1}" != rumptest ] && return 2682 2683 ${runcmd} cd "${NETBSDSRCDIR}/sys/rump/librump/rumpkern" || 2684 bomb "cd to rumpkern failed" 2685 2686 md_quirks=`${runcmd} "${makewrapper}" -V '${_SYMQUIRK}'` 2687 # one little, two little, three little backslashes ... 2688 md_quirks="$(echo ${md_quirks} | sed 's,\\,\\\\,g'";s/'//g" )" 2689 ${runcmd} cd "${TOP}" || bomb "cd to ${TOP} failed" 2690 tool_ld=`${runcmd} "${makewrapper}" -V '${LD}'` 2691 2692 local oIFS="${IFS-UnSeTT}" 2693 IFS="," 2694 for set in ${RUMP_LIBSETS} 2695 do 2696 case "${oIFS}" in 2697 UnSeTT) unset IFS;; 2698 *) IFS="${oIFS}";; 2699 esac 2700 ${runcmd} ${tool_ld} -nostdlib -L${DESTDIR}/usr/lib \ 2701 -static --whole-archive ${set} --no-whole-archive \ 2702 -lpthread -lc 2>&1 -o /tmp/rumptest.$$ | 2703 awk -v quirks="${md_quirks}" ' 2704 /undefined reference/ && 2705 !/more undefined references.*follow/{ 2706 if (match($NF, 2707 "`(rumpuser_|rumpcomp_|__" quirks ")") == 0) 2708 fails[NR] = $0 2709 } 2710 /cannot find -l/{fails[NR] = $0} 2711 /cannot open output file/{fails[NR] = $0} 2712 END{ 2713 for (x in fails) 2714 print fails[x] 2715 exit x!=0 2716 }' 2717 [ $? -ne 0 ] && bomb "Testlink of rump failed: ${set}" 2718 done 2719 statusmsg "Rump build&link tests successful" 2720 } 2721 2722 repro_date() { 2723 # try the bsd date fail back the linux one 2724 date -u -r "$1" 2> /dev/null || date -u -d "@$1" 2725 } 2726 2727 setup_mkrepro() 2728 { 2729 local quiet="$1" 2730 2731 if [ "${MKREPRO-no}" != yes ] 2732 then 2733 return 2734 fi 2735 if [ "${MKREPRO_TIMESTAMP-0}" -ne 0 ] 2736 then 2737 return 2738 fi 2739 2740 MKREPRO_TIMESTAMP=0 2741 NETBSD_REVISIONID= 2742 local base 2743 local d 2744 local t 2745 local rid 2746 local tag 2747 local vcs 2748 for base in src xsrc 2749 do 2750 case $base in 2751 src) d=${NETBSDSRCDIR-/usr/src}/ 2752 ;; 2753 xsrc) [ "${MKX11-no}" = yes ] || continue 2754 d=${X11SRCDIR-/usr/xsrc}/ 2755 ;; 2756 esac 2757 if [ -d "${d}CVS" ] 2758 then 2759 local cvslatest="$(print_tooldir_program cvslatest)" 2760 if ! [ -x "${cvslatest}" ] 2761 then 2762 buildtools 2763 fi 2764 local nbdate="$(print_tooldir_program date)" 2765 2766 local cvslatestflags= 2767 if "${do_expertmode}" 2768 then 2769 cvslatestflags=-i 2770 fi 2771 2772 if [ -f "${d}CVS/Tag" ] 2773 then 2774 tag=$(sed -e 's/^T//' <${d}CVS/Tag) 2775 else 2776 tag=HEAD 2777 fi 2778 t=$("${cvslatest}" ${cvslatestflags} "${d}") || 2779 bomb "${cvslatest} failed" 2780 rid="${tag}:$(${nbdate} -u -r ${t} '+%Y%m%d%H%M%S')" 2781 vcs=cvs 2782 elif [ -d "${d}.git" ] || [ -f "${d}.git" ] 2783 then 2784 t=$(cd "${d}" && git log -1 --format=%ct) || 2785 bomb "git log %ct failed" 2786 rid="$( 2787 cd "${d}" && git log -1 --format=%H)" || 2788 bomb "git log %H failed" 2789 vcs=git 2790 elif [ -d "${d}.hg" ] 2791 then 2792 t=$(hg --repo "$d" \ 2793 log -r . --template '{date.unixtime}\n') || 2794 bomb "hg log failed" 2795 rid=$(hg --repo "$d" \ 2796 identify --template '{id}\n') || 2797 bomb "hg identify failed" 2798 vcs=hg 2799 elif [ -f "${d}.hg_archival.txt" ] 2800 then 2801 local stat 2802 stat=$(print_tooldir_program stat) || 2803 bomb "print_tooldir_program stat failed" 2804 if ! [ -x "${stat}" ] 2805 then 2806 buildtools 2807 fi 2808 2809 t=$("${stat}" -t '%s' -f '%m' "${d}.hg_archival.txt") || 2810 bomb "stat failed on ${d}.hg_archival.txt" 2811 rid=$( 2812 awk '/^node:/ { print $2 }' <"${d}.hg_archival.txt" 2813 ) || bomb \ 2814 "awk failed to find node: in ${d}.hg_archival.txt" 2815 vcs=hg 2816 else 2817 bomb "Cannot determine VCS for '$d'" 2818 fi 2819 NETBSD_REVISIONID="${NETBSD_REVISIONID}${NETBSD_REVISIONID:+-}${base}@${vcs}:${rid}" 2820 2821 if [ -z "$t" ] 2822 then 2823 bomb "Failed to get timestamp for vcs=$vcs in '$d'" 2824 fi 2825 2826 #echo "latest $d $vcs $t" 2827 if [ "$t" -gt "$MKREPRO_TIMESTAMP" ] 2828 then 2829 MKREPRO_TIMESTAMP="$t" 2830 fi 2831 done 2832 2833 [ "${MKREPRO_TIMESTAMP}" -ne 0 ] || bomb "Failed to compute timestamp" 2834 if [ -z "${quiet}" ] 2835 then 2836 statusmsg2 "MKREPRO_TIMESTAMP" \ 2837 "$(repro_date "${MKREPRO_TIMESTAMP}")" 2838 fi 2839 export MKREPRO MKREPRO_TIMESTAMP NETBSD_REVISIONID 2840 } 2841 2842 main() 2843 { 2844 initdefaults 2845 _args=$* 2846 parseoptions "$@" 2847 2848 sanitycheck 2849 2850 build_start=$(date) 2851 statusmsg2 "${progname} command:" "$0 $*" 2852 statusmsg2 "${progname} started:" "${build_start}" 2853 statusmsg2 "NetBSD version:" "${DISTRIBVER}" 2854 statusmsg2 "MACHINE:" "${MACHINE}" 2855 statusmsg2 "MACHINE_ARCH:" "${MACHINE_ARCH}" 2856 statusmsg2 "Build platform:" "${uname_s} ${uname_r} ${uname_m}" 2857 statusmsg2 "HOST_SH:" "${HOST_SH}" 2858 if [ -n "${BUILDID}" ] 2859 then 2860 statusmsg2 BUILDID: "${BUILDID}" 2861 fi 2862 if [ -n "${BUILDINFO}" ] 2863 then 2864 printf "%b\n" "${BUILDINFO}" | 2865 while read -r line 2866 do 2867 [ -s "${line}" ] && continue 2868 statusmsg2 BUILDINFO: "${line}" 2869 done 2870 fi 2871 2872 if [ -n "${MAKECONF+1}" ] && [ -z "${MAKECONF}" ] 2873 then 2874 bomb "MAKECONF must not be empty" 2875 fi 2876 2877 rebuildmake 2878 validatemakeparams "$@" 2879 createmakewrapper 2880 setup_mkrepro 2881 2882 # Perform the operations. 2883 # 2884 for op in ${operations} 2885 do 2886 case "${op}" in 2887 2888 makewrapper) 2889 # no-op 2890 ;; 2891 2892 tools) 2893 buildtools 2894 ;; 2895 libs) 2896 buildlibs 2897 ;; 2898 2899 sets) 2900 statusmsg "Building sets from pre-populated ${DESTDIR}" 2901 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2902 bomb "Failed to make ${op}" 2903 setdir=${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/sets 2904 statusmsg "Built sets to ${setdir}" 2905 ;; 2906 2907 build|distribution|release) 2908 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2909 bomb "Failed to make ${op}" 2910 statusmsg "Successful make ${op}" 2911 ;; 2912 2913 cleandir|obj|sourcesets|syspkgs|params|show-params) 2914 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2915 bomb "Failed to make ${op}" 2916 statusmsg "Successful make ${op}" 2917 ;; 2918 2919 iso-image|iso-image-source) 2920 ${runcmd} "${makewrapper}" ${parallel} \ 2921 CDEXTRA="$CDEXTRA" ${op} || 2922 bomb "Failed to make ${op}" 2923 statusmsg "Successful make ${op}" 2924 ;; 2925 2926 live-image|install-image) 2927 # install-image and live-image require mtree spec files 2928 # built with MKUNPRIVED. Assume MKUNPRIVED build has 2929 # been performed if METALOG file is created in DESTDIR. 2930 if [ ! -e "${DESTDIR}/METALOG" ] 2931 then 2932 bomb "The release binaries must have been" \ 2933 "built with -U to create images" 2934 fi 2935 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2936 bomb "Failed to make ${op}" 2937 statusmsg "Successful make ${op}" 2938 ;; 2939 kernel=*) 2940 arg=${op#*=} 2941 buildkernel "${arg}" 2942 ;; 2943 kernel.gdb=*) 2944 arg=${op#*=} 2945 configopts="-D DEBUG=-g" 2946 buildkernel "${arg}" 2947 ;; 2948 releasekernel=*) 2949 arg=${op#*=} 2950 releasekernel "${arg}" 2951 ;; 2952 2953 kernels) 2954 buildkernels 2955 ;; 2956 2957 disk-image=*) 2958 arg=${op#*=} 2959 diskimage "${arg}" 2960 ;; 2961 2962 dtb) 2963 builddtb 2964 ;; 2965 2966 modules) 2967 buildmodules 2968 ;; 2969 2970 pkg=*) 2971 arg=${op#*=} 2972 if ! [ -d "${PKGSRCDIR}/${arg}" ] 2973 then 2974 bomb "no such package ${arg}" 2975 fi 2976 buildpkg "${arg}" 2977 ;; 2978 2979 installmodules=*) 2980 arg=${op#*=} 2981 if [ "${arg}" = / ] && { 2982 [ "${uname_s}" != NetBSD ] || 2983 [ "${uname_m}" != "${MACHINE}" ] 2984 } 2985 then 2986 bomb "'${op}' must != / for cross builds" 2987 fi 2988 installmodules "${arg}" 2989 ;; 2990 2991 install=*) 2992 arg=${op#*=} 2993 if [ "${arg}" = / ] && { 2994 [ "${uname_s}" != NetBSD ] || 2995 [ "${uname_m}" != "${MACHINE}" ] 2996 } 2997 then 2998 bomb "'${op}' must != / for cross builds" 2999 fi 3000 installworld "${arg}" 3001 ;; 3002 3003 rump) 3004 make_in_dir . do-distrib-dirs 3005 make_in_dir . includes 3006 make_in_dir lib/csu dependall 3007 make_in_dir lib/csu install 3008 make_in_dir external/gpl3/gcc/lib/libgcc dependall 3009 make_in_dir external/gpl3/gcc/lib/libgcc install 3010 dorump "${op}" 3011 ;; 3012 3013 rumptest) 3014 dorump "${op}" 3015 ;; 3016 3017 *) 3018 bomb "Unknown OPERATION '${op}'" 3019 ;; 3020 3021 esac 3022 done 3023 3024 statusmsg2 "${progname} ended:" "$(date)" 3025 if [ -s "${results}" ] 3026 then 3027 echo "===> Summary of results:" 3028 sed -e 's/^===>//;s/^/ /' "${results}" 3029 echo "===> ." 3030 fi 3031 } 3032 3033 main "$@" 3034