1 #! /usr/bin/env sh 2 # $NetBSD: build.sh,v 1.399 2025/07/08 12:29:40 hgutch 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=m68k 720 MACHINE=macppc MACHINE_ARCH=powerpc DEFAULT 721 MACHINE=macppc MACHINE_ARCH=powerpc64 ALIAS=macppc64 722 MACHINE=mipsco MACHINE_ARCH=mipseb 723 MACHINE=mmeye MACHINE_ARCH=sh3eb 724 MACHINE=mvme68k MACHINE_ARCH=m68k 725 MACHINE=mvmeppc MACHINE_ARCH=powerpc 726 MACHINE=netwinder MACHINE_ARCH=earmv4 ALIAS=enetwinder DEFAULT 727 MACHINE=news68k MACHINE_ARCH=m68k 728 MACHINE=newsmips MACHINE_ARCH=mipseb 729 MACHINE=next68k MACHINE_ARCH=m68k 730 MACHINE=ofppc MACHINE_ARCH=powerpc DEFAULT 731 MACHINE=ofppc MACHINE_ARCH=powerpc64 ALIAS=ofppc64 732 MACHINE=or1k MACHINE_ARCH=or1k 733 MACHINE=playstation2 MACHINE_ARCH=mipsel 734 MACHINE=pmax MACHINE_ARCH=mips64el ALIAS=pmax64 735 MACHINE=pmax MACHINE_ARCH=mipsel DEFAULT 736 MACHINE=prep MACHINE_ARCH=powerpc 737 MACHINE=riscv MACHINE_ARCH=riscv64 ALIAS=riscv64 DEFAULT 738 MACHINE=riscv MACHINE_ARCH=riscv32 ALIAS=riscv32 739 MACHINE=rs6000 MACHINE_ARCH=powerpc 740 MACHINE=sandpoint MACHINE_ARCH=powerpc 741 MACHINE=sbmips MACHINE_ARCH= NO_DEFAULT 742 MACHINE=sbmips MACHINE_ARCH=mips64eb ALIAS=sbmips64-eb 743 MACHINE=sbmips MACHINE_ARCH=mips64el ALIAS=sbmips64-el 744 MACHINE=sbmips MACHINE_ARCH=mipseb ALIAS=sbmips-eb 745 MACHINE=sbmips MACHINE_ARCH=mipsel ALIAS=sbmips-el 746 MACHINE=sgimips MACHINE_ARCH=mips64eb ALIAS=sgimips64 747 MACHINE=sgimips MACHINE_ARCH=mipseb DEFAULT 748 MACHINE=shark MACHINE_ARCH=earmv4 ALIAS=eshark DEFAULT 749 MACHINE=sparc MACHINE_ARCH=sparc 750 MACHINE=sparc64 MACHINE_ARCH=sparc64 751 MACHINE=sun2 MACHINE_ARCH=m68000 752 MACHINE=sun3 MACHINE_ARCH=m68k 753 MACHINE=vax MACHINE_ARCH=vax 754 MACHINE=virt68k MACHINE_ARCH=m68k 755 MACHINE=x68k MACHINE_ARCH=m68k 756 MACHINE=zaurus MACHINE_ARCH=earm ALIAS=ezaurus DEFAULT 757 ' 758 759 # getarch -- find the default MACHINE_ARCH for a MACHINE, 760 # or convert an alias to a MACHINE/MACHINE_ARCH pair. 761 # 762 # Saves the original value of MACHINE in makewrappermachine before 763 # alias processing. 764 # 765 # Sets MACHINE and MACHINE_ARCH if the input MACHINE value is 766 # recognised as an alias, or recognised as a machine that has a default 767 # MACHINE_ARCH (or that has only one possible MACHINE_ARCH). 768 # 769 # Leaves MACHINE and MACHINE_ARCH unchanged if MACHINE is recognised 770 # as being associated with multiple MACHINE_ARCH values with no default. 771 # 772 # Bombs if MACHINE is not recognised. 773 # 774 getarch() 775 { 776 local IFS 777 local found= 778 local line 779 780 IFS="${nl}" 781 makewrappermachine="${MACHINE}" 782 for line in ${valid_MACHINE_ARCH} 783 do 784 line="${line%%#*}" # ignore comments 785 line="$( IFS=" ${tab}" ; echo $line )" # normalise white space 786 case "${line} " in 787 ' ') 788 # skip blank lines or comment lines 789 continue 790 ;; 791 *" ALIAS=${MACHINE} "*) 792 # Found a line with a matching ALIAS=<alias>. 793 found="$line" 794 break 795 ;; 796 "MACHINE=${MACHINE} "*" NO_DEFAULT"*) 797 # Found an explicit "NO_DEFAULT" for this MACHINE. 798 found="$line" 799 break 800 ;; 801 "MACHINE=${MACHINE} "*" DEFAULT"*) 802 # Found an explicit "DEFAULT" for this MACHINE. 803 found="$line" 804 break 805 ;; 806 "MACHINE=${MACHINE} "*) 807 # Found a line for this MACHINE. If it's the 808 # first such line, then tentatively accept it. 809 # If it's not the first matching line, then 810 # remember that there was more than one match. 811 case "$found" in 812 '') found="$line" ;; 813 *) found="MULTIPLE_MATCHES" ;; 814 esac 815 ;; 816 esac 817 done 818 819 case "$found" in 820 *NO_DEFAULT*|*MULTIPLE_MATCHES*) 821 # MACHINE is OK, but MACHINE_ARCH is still unknown 822 return 823 ;; 824 "MACHINE="*" MACHINE_ARCH="*) 825 # Obey the MACHINE= and MACHINE_ARCH= parts of the line. 826 IFS=' ' 827 for frag in ${found} 828 do 829 case "$frag" in 830 MACHINE=*|MACHINE_ARCH=*) 831 eval "$frag" 832 ;; 833 esac 834 done 835 ;; 836 *) 837 bomb "Unknown target MACHINE: ${MACHINE}" 838 ;; 839 esac 840 } 841 842 # validatearch -- check that the MACHINE/MACHINE_ARCH pair is supported. 843 # 844 # Bombs if the pair is not supported. 845 # 846 validatearch() 847 { 848 local IFS 849 local line 850 local foundpair=false foundmachine=false foundarch=false 851 852 case "${MACHINE_ARCH}" in 853 "") 854 bomb "No MACHINE_ARCH provided." \ 855 "Use 'build.sh -m ${MACHINE} list-arch' to show options" 856 ;; 857 esac 858 859 IFS="${nl}" 860 for line in ${valid_MACHINE_ARCH} 861 do 862 line="${line%%#*}" # ignore comments 863 line="$( IFS=" ${tab}" ; echo $line )" # normalise white space 864 case "${line} " in 865 ' ') 866 # skip blank lines or comment lines 867 continue 868 ;; 869 "MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} "*) 870 foundpair=true 871 ;; 872 "MACHINE=${MACHINE} "*) 873 foundmachine=true 874 ;; 875 *"MACHINE_ARCH=${MACHINE_ARCH} "*) 876 foundarch=true 877 ;; 878 esac 879 done 880 881 case "${foundpair}:${foundmachine}:${foundarch}" in 882 true:*) 883 : OK 884 ;; 885 *:false:*) 886 bomb "Unknown target MACHINE: ${MACHINE}" 887 ;; 888 *:*:false) 889 bomb "Unknown target MACHINE_ARCH: ${MACHINE_ARCH}" 890 ;; 891 *) 892 bomb "MACHINE_ARCH '${MACHINE_ARCH}' does not support MACHINE '${MACHINE}'" 893 ;; 894 esac 895 } 896 897 # listarch -- list valid MACHINE/MACHINE_ARCH/ALIAS values, 898 # optionally restricted to those where the MACHINE and/or MACHINE_ARCH 899 # match specified glob patterns. 900 # 901 listarch() 902 { 903 local machglob="$1" archglob="$2" 904 local IFS 905 local wildcard='*' 906 local line xline frag 907 local line_matches_machine line_matches_arch 908 local found=false 909 910 # Empty machglob or archglob should match anything 911 : "${machglob:=${wildcard}}" 912 : "${archglob:=${wildcard}}" 913 914 IFS="${nl}" 915 for line in ${valid_MACHINE_ARCH} 916 do 917 line="${line%%#*}" # ignore comments 918 xline="$( IFS=" ${tab}" ; echo $line )" # normalise white space 919 [ -z "${xline}" ] && continue # skip blank or comment lines 920 921 line_matches_machine=false 922 line_matches_arch=false 923 924 IFS=' ' 925 for frag in ${xline} 926 do 927 case "${frag}" in 928 MACHINE=${machglob}) 929 line_matches_machine=true ;; 930 ALIAS=${machglob}) 931 line_matches_machine=true ;; 932 MACHINE_ARCH=${archglob}) 933 line_matches_arch=true ;; 934 esac 935 done 936 937 if $line_matches_machine && $line_matches_arch 938 then 939 found=true 940 echo "$line" 941 fi 942 done 943 if ! $found 944 then 945 echo >&2 "No match for" \ 946 "MACHINE=${machglob} MACHINE_ARCH=${archglob}" 947 return 1 948 fi 949 return 0 950 } 951 952 # nobomb_getmakevar -- 953 # Given the name of a make variable in $1, show make's idea of the 954 # value of that variable, or return 1 if there's an error. 955 # 956 nobomb_getmakevar() 957 { 958 [ -x "${make}" ] || return 1 959 "${make}" -m ${TOP}/share/mk -s -B -f- _x_ <<EOF || return 1 960 _x_: 961 echo \${$1} 962 .include <bsd.prog.mk> 963 .include <bsd.kernobj.mk> 964 EOF 965 } 966 967 # bomb_getmakevar -- 968 # Given the name of a make variable in $1, show make's idea of the 969 # value of that variable, or bomb if there's an error. 970 # 971 bomb_getmakevar() 972 { 973 [ -x "${make}" ] || bomb "bomb_getmakevar $1: ${make} is not executable" 974 nobomb_getmakevar "$1" || bomb "bomb_getmakevar $1: ${make} failed" 975 } 976 977 # getmakevar -- 978 # Given the name of a make variable in $1, show make's idea of the 979 # value of that variable, or show a literal '$' followed by the 980 # variable name if ${make} is not executable. This is intended for use in 981 # messages that need to be readable even if $make hasn't been built, 982 # such as when build.sh is run with the "-n" option. 983 # 984 getmakevar() 985 { 986 if [ -x "${make}" ] 987 then 988 bomb_getmakevar "$1" 989 else 990 echo "\$$1" 991 fi 992 } 993 994 setmakeenv() 995 { 996 eval "$1='$2'; export $1" 997 makeenv="${makeenv} $1" 998 } 999 1000 safe_setmakeenv() 1001 { 1002 case "$1" in 1003 1004 # Look for any vars we want to prohibit here, like: 1005 # Bad | Dangerous) usage "Cannot override $1 with -V";; 1006 1007 # That first char is OK has already been verified. 1008 *[!A-Za-z0-9_]*) usage "Bad variable name (-V): '$1'";; 1009 esac 1010 setmakeenv "$@" 1011 } 1012 1013 unsetmakeenv() 1014 { 1015 eval "unset $1" 1016 makeenv="${makeenv} $1" 1017 } 1018 1019 safe_unsetmakeenv() 1020 { 1021 case "$1" in 1022 1023 # Look for any vars user should not be able to unset 1024 # Needed | Must_Have) usage "Variable $1 cannot be unset";; 1025 1026 [!A-Za-z_]* | *[!A-Za-z0-9_]*) usage "Bad variable name (-Z): '$1'";; 1027 esac 1028 unsetmakeenv "$1" 1029 } 1030 1031 # Clear all variables defined in makeenv. Used to run a subprocess 1032 # outside the usual NetBSD build's make environment. 1033 # 1034 clearmakeenv() 1035 { 1036 local var 1037 1038 for var in ${makeenv} 1039 do 1040 unset ${var} 1041 done 1042 } 1043 1044 # Given a variable name in $1, modify the variable in place as follows: 1045 # For each space-separated word in the variable, call resolvepath. 1046 # 1047 resolvepaths() 1048 { 1049 local var="$1" 1050 local val 1051 eval val=\"\${${var}}\" 1052 local newval= 1053 local word 1054 1055 for word in ${val} 1056 do 1057 resolvepath word 1058 newval="${newval}${newval:+ }${word}" 1059 done 1060 eval ${var}=\"\${newval}\" 1061 } 1062 1063 # Given a variable name in $1, modify the variable in place as follows: 1064 # Convert possibly-relative path to absolute path by prepending 1065 # ${TOP} if necessary. Also delete trailing "/", if any. 1066 # 1067 resolvepath() 1068 { 1069 local var="$1" 1070 local val 1071 eval val=\"\${${var}}\" 1072 case "${val}" in 1073 /) 1074 ;; 1075 /*) 1076 val="${val%/}" 1077 ;; 1078 *) 1079 val="${TOP}/${val%/}" 1080 ;; 1081 esac 1082 eval ${var}=\"\${val}\" 1083 } 1084 1085 # Show synopsis to stdout. 1086 # 1087 synopsis() 1088 { 1089 cat <<_usage_ 1090 1091 Usage: ${progname} [-EnoPRrUux] [-a ARCH] [-B BID] [-C EXTRAS] 1092 [-c COMPILER] [-D DEST] [-j NJOB] [-M MOBJ] [-m MACH] 1093 [-N NOISY] [-O OOBJ] [-R RELEASE] [-S SEED] [-T TOOLS] 1094 [-V VAR=[VALUE]] [-w WRAPPER] [-X X11SRC] 1095 [-Z VAR] 1096 OPERATION ... 1097 ${progname} ( -h | -? ) 1098 1099 _usage_ 1100 } 1101 1102 # Show help to stdout. 1103 # 1104 help() 1105 { 1106 synopsis 1107 cat <<_usage_ 1108 Build OPERATIONs (all imply "obj" and "tools"): 1109 build Run "make build". 1110 distribution Run "make distribution" (includes DESTDIR/etc/ files). 1111 release Run "make release" (includes kernels & distrib media). 1112 1113 Other OPERATIONs: 1114 help Show this help message, and exit. 1115 makewrapper Create ${toolprefix}make-\${MACHINE} wrapper 1116 and ${toolprefix}make. 1117 Always performed. 1118 cleandir Run "make cleandir". [Default unless -u is used] 1119 dtb Build devicetree blobs. 1120 obj Run "make obj". [Default unless -o is used] 1121 tools Build and install tools. 1122 install=IDIR Run "make installworld" to IDIR to install all sets 1123 except 'etc'. Useful after "distribution" or "release". 1124 kernel=CONF Build kernel with config file CONF. 1125 kernel.gdb=CONF Build kernel (including netbsd.gdb) with config 1126 file CONF. 1127 releasekernel=CONF Install kernel built by kernel=CONF to RELEASEDIR. 1128 kernels Build all kernels. 1129 installmodules=IDIR Run "make installmodules" to IDIR to install all 1130 kernel modules. 1131 modules Build kernel modules. 1132 rumptest Do a linktest for rump (for developers). 1133 sets Create binary sets in 1134 RELEASEDIR/RELEASEMACHINEDIR/binary/sets. 1135 DESTDIR should be populated beforehand. 1136 distsets Same as "distribution sets". 1137 sourcesets Create source sets in RELEASEDIR/source/sets. 1138 syspkgs Create syspkgs in 1139 RELEASEDIR/RELEASEMACHINEDIR/binary/syspkgs. 1140 pkg=CATEGORY/PKG (EXPERIMENT) Build a package CATEGORY/PKG from pkgsrc. 1141 iso-image Create CD-ROM image in RELEASEDIR/images. 1142 iso-image-source Create CD-ROM image with source in RELEASEDIR/images. 1143 live-image Create bootable live image in 1144 RELEASEDIR/RELEASEMACHINEDIR/installation/liveimage. 1145 install-image Create bootable installation image in 1146 RELEASEDIR/RELEASEMACHINEDIR/installation/installimage. 1147 disk-image=TARGET Create bootable disk image in 1148 RELEASEDIR/RELEASEMACHINEDIR/binary/gzimg/TARGET.img.gz. 1149 params Create params file with various make(1) parameters. 1150 show-params Show various make(1) parameters. 1151 list-arch Show a list of valid MACHINE/MACHINE_ARCH values, 1152 and exit. The list may be narrowed by passing glob 1153 patterns or exact values in MACHINE or MACHINE_ARCH. 1154 mkrepro-timestamp Show the latest source timestamp used for reproducible 1155 builds and exit. Requires -P or -V MKREPRO=yes. 1156 show-revisionid Show the revision ID of the current directory 1157 (in SCM-dependent format) and exit. 1158 Requires -P or -V MKREPRO=yes. 1159 1160 Options: 1161 -a ARCH Set MACHINE_ARCH=ARCH. [Default: deduced from MACHINE] 1162 -B BID Set BUILDID=BID. 1163 -C EXTRAS Append EXTRAS to CDEXTRA for inclusion on CD-ROM. 1164 -c COMPILER Select compiler from COMPILER: 1165 clang 1166 gcc 1167 [Default: gcc] 1168 -D DEST Set DESTDIR=DEST. [Default: destdir.\${MACHINE}] 1169 -E Set "expert" mode; disables various safety checks. 1170 Should not be used without expert knowledge of the build 1171 system. 1172 -h Show this help message, and exit. 1173 -j NJOB Run up to NJOB jobs in parallel; see make(1) -j. 1174 -M MOBJ Set obj root directory to MOBJ; sets MAKEOBJDIRPREFIX=MOBJ, 1175 unsets MAKEOBJDIR. 1176 -m MACH Set MACHINE=MACH. Some MACH values are actually 1177 aliases that set MACHINE/MACHINE_ARCH pairs. 1178 [Default: deduced from the host system if the host 1179 OS is NetBSD] 1180 -N NOISY Set the noisiness (MAKEVERBOSE) level of the build to NOISY: 1181 0 Minimal output ("quiet"). 1182 1 Describe what is occurring. 1183 2 Describe what is occurring and echo the actual 1184 command. 1185 3 Ignore the effect of the "@" prefix in make 1186 commands. 1187 4 Trace shell commands using the shell's -x flag. 1188 [Default: 2] 1189 -n Show commands that would be executed, but do not execute 1190 them. 1191 -O OOBJ Set obj root directory to OOBJ; sets a MAKEOBJDIR pattern 1192 using OOBJ, unsets MAKEOBJDIRPREFIX. 1193 -o Set MKOBJDIRS=no; do not create objdirs at start of build. 1194 -P Set MKREPRO and MKREPRO_TIMESTAMP to the latest source 1195 CVS timestamp for reproducible builds. 1196 -R RELEASE Set RELEASEDIR=RELEASE. [Default: releasedir] 1197 -r Remove contents of TOOLDIR and DESTDIR before building. 1198 -S SEED Set BUILDSEED=SEED. [Default: NetBSD-majorversion] 1199 -T TOOLS Set TOOLDIR=TOOLS. If unset, and TOOLDIR is not set 1200 in the environment, ${toolprefix}make will be (re)built 1201 unconditionally. 1202 -U Set MKUNPRIVED=yes; build without requiring root privileges, 1203 install from an unprivileged build with proper file 1204 permissions. 1205 -u Set MKUPDATE=yes; do not run "make cleandir" first. 1206 Without this, everything is rebuilt, including the tools. 1207 -V VAR=[VALUE] Set variable VAR=VALUE. 1208 -w WRAPPER Create ${toolprefix}make script as WRAPPER. 1209 [Default: \${TOOLDIR}/bin/${toolprefix}make-\${MACHINE}] 1210 -X X11SRC Set X11SRCDIR=X11SRC. [Default: /usr/xsrc] 1211 -x Set MKX11=yes; build X11 from X11SRCDIR. 1212 -Z VAR Unset ("zap") variable VAR. 1213 -? Show this help message, and exit. 1214 1215 _usage_ 1216 } 1217 1218 # Show optional error message, help to stderr, and exit 1. 1219 # 1220 usage() 1221 { 1222 if [ -n "$*" ] 1223 then 1224 echo 1>&2 "" 1225 echo 1>&2 "${progname}: $*" 1226 fi 1227 synopsis 1>&2 1228 exit 1 1229 } 1230 1231 parseoptions() 1232 { 1233 opts=a:B:C:c:D:Ehj:M:m:N:nO:oPR:rS:T:UuV:w:X:xZ: 1234 opt_a=false 1235 opt_m=false 1236 local did_show_info=false 1237 1238 if type getopts >/dev/null 2>&1 1239 then 1240 # Use POSIX getopts. 1241 # 1242 getoptcmd='getopts :${opts} opt && opt=-${opt}' 1243 optargcmd=':' 1244 optremcmd='shift $((${OPTIND} -1))' 1245 else 1246 type getopt >/dev/null 2>&1 || 1247 bomb "Shell does not support getopts or getopt" 1248 1249 # Use old-style getopt(1) (doesn't handle whitespace in args). 1250 # 1251 args="$(getopt ${opts} $*)" 1252 [ $? = 0 ] || usage 1253 set -- ${args} 1254 1255 getoptcmd='[ $# -gt 0 ] && opt="$1" && shift' 1256 optargcmd='OPTARG="$1"; shift' 1257 optremcmd=':' 1258 fi 1259 1260 # Parse command line options. 1261 # 1262 while eval ${getoptcmd} 1263 do 1264 case ${opt} in 1265 1266 -a) 1267 eval ${optargcmd} 1268 MACHINE_ARCH=${OPTARG} 1269 opt_a=true 1270 ;; 1271 1272 -B) 1273 eval ${optargcmd} 1274 BUILDID=${OPTARG} 1275 ;; 1276 1277 -C) 1278 eval ${optargcmd} 1279 resolvepaths OPTARG 1280 CDEXTRA="${CDEXTRA}${CDEXTRA:+ }${OPTARG}" 1281 ;; 1282 1283 -c) 1284 eval ${optargcmd} 1285 case "${OPTARG}" in 1286 gcc) # default, no variables needed 1287 ;; 1288 clang) setmakeenv HAVE_LLVM yes 1289 setmakeenv MKLLVM yes 1290 setmakeenv MKGCC no 1291 ;; 1292 #pcc) ... 1293 # ;; 1294 *) bomb "Unknown compiler: ${OPTARG}" 1295 esac 1296 ;; 1297 1298 -D) 1299 eval ${optargcmd} 1300 resolvepath OPTARG 1301 setmakeenv DESTDIR "${OPTARG}" 1302 ;; 1303 1304 -E) 1305 do_expertmode=true 1306 ;; 1307 1308 -j) 1309 eval ${optargcmd} 1310 parallel="-j ${OPTARG}" 1311 ;; 1312 1313 -M) 1314 eval ${optargcmd} 1315 resolvepath OPTARG 1316 case "${OPTARG}" in 1317 \$*) usage "-M argument must not begin with '\$'" 1318 ;; 1319 *\$*) # can use resolvepath, but can't set TOP_objdir 1320 resolvepath OPTARG 1321 ;; 1322 *) resolvepath OPTARG 1323 TOP_objdir="${OPTARG}${TOP}" 1324 ;; 1325 esac 1326 unsetmakeenv MAKEOBJDIR 1327 setmakeenv MAKEOBJDIRPREFIX "${OPTARG}" 1328 ;; 1329 1330 # -m overrides MACHINE_ARCH unless "-a" is specified 1331 -m) 1332 eval ${optargcmd} 1333 MACHINE="${OPTARG}" 1334 opt_m=true 1335 ;; 1336 1337 -N) 1338 eval ${optargcmd} 1339 case "${OPTARG}" in 1340 0|1|2|3|4) 1341 setmakeenv MAKEVERBOSE "${OPTARG}" 1342 ;; 1343 *) 1344 usage "'${OPTARG}' is not a valid value for -N" 1345 ;; 1346 esac 1347 ;; 1348 1349 -n) 1350 runcmd=echo 1351 ;; 1352 1353 -O) 1354 eval ${optargcmd} 1355 case "${OPTARG}" in 1356 *\$*) usage "-O argument must not contain '\$'" 1357 ;; 1358 *) resolvepath OPTARG 1359 TOP_objdir="${OPTARG}" 1360 ;; 1361 esac 1362 unsetmakeenv MAKEOBJDIRPREFIX 1363 setmakeenv MAKEOBJDIR "\${.CURDIR:C,^$TOP,$OPTARG,}" 1364 ;; 1365 1366 -o) 1367 MKOBJDIRS=no 1368 ;; 1369 1370 -P) 1371 MKREPRO=yes 1372 export MKREPRO 1373 ;; 1374 1375 -R) 1376 eval ${optargcmd} 1377 resolvepath OPTARG 1378 setmakeenv RELEASEDIR "${OPTARG}" 1379 ;; 1380 1381 -r) 1382 do_removedirs=true 1383 do_rebuildmake=true 1384 ;; 1385 1386 -S) 1387 eval ${optargcmd} 1388 setmakeenv BUILDSEED "${OPTARG}" 1389 ;; 1390 1391 -T) 1392 eval ${optargcmd} 1393 resolvepath OPTARG 1394 TOOLDIR="${OPTARG}" 1395 export TOOLDIR 1396 ;; 1397 1398 -U) 1399 setmakeenv MKUNPRIVED yes 1400 ;; 1401 1402 -u) 1403 setmakeenv MKUPDATE yes 1404 ;; 1405 1406 -V) 1407 eval ${optargcmd} 1408 case "${OPTARG}" in 1409 # XXX: consider restricting which variables can be changed? 1410 [a-zA-Z_]*=*) 1411 safe_setmakeenv "${OPTARG%%=*}" "${OPTARG#*=}" 1412 ;; 1413 [a-zA-Z_]*) 1414 safe_setmakeenv "${OPTARG}" "" 1415 ;; 1416 *) 1417 usage "-V argument must be of the form 'VAR[=VALUE]'" 1418 ;; 1419 esac 1420 ;; 1421 1422 -w) 1423 eval ${optargcmd} 1424 resolvepath OPTARG 1425 makewrapper="${OPTARG}" 1426 ;; 1427 1428 -X) 1429 eval ${optargcmd} 1430 resolvepath OPTARG 1431 setmakeenv X11SRCDIR "${OPTARG}" 1432 ;; 1433 1434 -x) 1435 setmakeenv MKX11 yes 1436 ;; 1437 1438 -Z) 1439 eval ${optargcmd} 1440 # XXX: consider restricting which variables can be unset? 1441 safe_unsetmakeenv "${OPTARG}" 1442 ;; 1443 1444 --) 1445 break 1446 ;; 1447 1448 -h) 1449 help 1450 exit 0 1451 ;; 1452 1453 '-?') 1454 if [ "${OPTARG}" = '?' ] 1455 then 1456 help 1457 exit 0 1458 fi 1459 usage "Unknown option -${OPTARG}" 1460 ;; 1461 1462 -:) 1463 usage "Missing argument for option -${OPTARG}" 1464 ;; 1465 1466 *) 1467 usage "Unimplemented option ${opt}" 1468 ;; 1469 1470 esac 1471 done 1472 1473 # Validate operations. 1474 # 1475 eval ${optremcmd} 1476 while [ $# -gt 0 ] 1477 do 1478 op=$1; shift 1479 operations="${operations} ${op}" 1480 1481 case "${op}" in 1482 1483 help) 1484 help 1485 exit 0 1486 ;; 1487 1488 list-arch) 1489 listarch "${MACHINE}" "${MACHINE_ARCH}" 1490 exit 1491 ;; 1492 mkrepro-timestamp) 1493 setup_mkrepro quiet 1494 echo "${MKREPRO_TIMESTAMP:-0}" 1495 did_show_info=true 1496 ;; 1497 1498 show-revisionid) 1499 setup_mkrepro quiet 1500 echo "${NETBSD_REVISIONID}" 1501 did_show_info=true 1502 ;; 1503 1504 kernel=*|releasekernel=*|kernel.gdb=*) 1505 arg=${op#*=} 1506 op=${op%%=*} 1507 [ -n "${arg}" ] || 1508 bomb "Must supply a kernel name with '${op}=...'" 1509 ;; 1510 1511 disk-image=*) 1512 arg=${op#*=} 1513 op=disk_image 1514 [ -n "${arg}" ] || 1515 bomb "Must supply a target name with '${op}=...'" 1516 1517 ;; 1518 1519 pkg=*) 1520 arg=${op#*=} 1521 op=${op%%=*} 1522 [ -n "${arg}" ] || 1523 bomb "Must supply category/package with 'pkg=...'" 1524 ;; 1525 1526 install=*|installmodules=*) 1527 arg=${op#*=} 1528 op=${op%%=*} 1529 [ -n "${arg}" ] || 1530 bomb "Must supply a directory with 'install=...'" 1531 ;; 1532 1533 distsets) 1534 operations="$(echo "$operations" | sed 's/distsets/distribution sets/')" 1535 do_sets=true 1536 op=distribution 1537 ;; 1538 1539 build|\ 1540 cleandir|\ 1541 distribution|\ 1542 dtb|\ 1543 install-image|\ 1544 iso-image-source|\ 1545 iso-image|\ 1546 kernels|\ 1547 libs|\ 1548 live-image|\ 1549 makewrapper|\ 1550 modules|\ 1551 obj|\ 1552 params|\ 1553 release|\ 1554 rump|\ 1555 rumptest|\ 1556 sets|\ 1557 show-params|\ 1558 sourcesets|\ 1559 syspkgs|\ 1560 tools) 1561 ;; 1562 1563 *) 1564 usage "Unknown OPERATION '${op}'" 1565 ;; 1566 1567 esac 1568 # ${op} may contain chars that are not allowed in variable 1569 # names. Replace them with '_' before setting do_${op}. 1570 op="$( echo "$op" | tr -s '.-' '__')" 1571 eval do_${op}=true 1572 done 1573 1574 "$did_show_info" && [ "${MKREPRO_TIMESTAMP:-0}" -ne 0 ] && exit 1575 1576 [ -n "${operations}" ] || usage "Missing OPERATION to perform" 1577 1578 # Set up MACHINE*. On a NetBSD host, these are allowed to be unset. 1579 # 1580 if [ -z "${MACHINE}" ] 1581 then 1582 [ "${uname_s}" = NetBSD ] || { 1583 bomb "MACHINE must be set, or -m must be used," \ 1584 "for cross builds" 1585 } 1586 MACHINE=${uname_m} 1587 MACHINE_ARCH=${uname_p} 1588 fi 1589 if $opt_m && ! $opt_a 1590 then 1591 # Settings implied by the command line -m option 1592 # override MACHINE_ARCH from the environment (if any). 1593 getarch 1594 fi 1595 [ -n "${MACHINE_ARCH}" ] || getarch 1596 validatearch 1597 1598 # Set up default make(1) environment. 1599 # 1600 makeenv="${makeenv} TOOLDIR MACHINE MACHINE_ARCH MAKEFLAGS" 1601 [ -z "${BUILDID}" ] || makeenv="${makeenv} BUILDID" 1602 [ -z "${BUILDINFO}" ] || makeenv="${makeenv} BUILDINFO" 1603 MAKEFLAGS="-de -m ${TOP}/share/mk ${MAKEFLAGS}" 1604 MAKEFLAGS="${MAKEFLAGS} MKOBJDIRS=${MKOBJDIRS-yes}" 1605 export MAKEFLAGS MACHINE MACHINE_ARCH 1606 if [ -z "${USETOOLS}" ]; then 1607 setmakeenv USETOOLS yes 1608 else 1609 setmakeenv USETOOLS "${USETOOLS}" 1610 fi 1611 setmakeenv MAKEWRAPPERMACHINE "${makewrappermachine:-${MACHINE}}" 1612 setmakeenv MAKE_OBJDIR_CHECK_WRITABLE no 1613 } 1614 1615 # sanitycheck -- 1616 # Sanity check after parsing command line options, before rebuildmake. 1617 # 1618 sanitycheck() 1619 { 1620 # Install as non-root is a bad idea. 1621 # 1622 if ${do_install} && [ "$id_u" -ne 0 ] 1623 then 1624 if ${do_expertmode} 1625 then 1626 warning "Will install as an unprivileged user" 1627 else 1628 bomb "-E must be set for install as an unprivileged user" 1629 fi 1630 fi 1631 1632 # If the PATH contains any non-absolute components (including, 1633 # but not limited to, "." or ""), then complain. As an exception, 1634 # allow "" or "." as the last component of the PATH. This is fatal 1635 # if expert mode is not in effect. 1636 # 1637 local path="${PATH}" 1638 path="${path%:}" # delete trailing ":" 1639 path="${path%:.}" # delete trailing ":." 1640 case ":${path}:/" in 1641 *:[!/~]*) 1642 if ${do_expertmode} 1643 then 1644 warning "PATH contains non-absolute components" 1645 else 1646 bomb "PATH environment variable must not" \ 1647 "contain non-absolute components" 1648 fi 1649 ;; 1650 esac 1651 1652 while [ "${MKX11-no}" = yes ] # not really a loop 1653 do 1654 test -n "${X11SRCDIR}" && { 1655 test -d "${X11SRCDIR}/external" || 1656 bomb "X11SRCDIR (${X11SRCDIR}) does not exist (with -x)" 1657 break 1658 } 1659 for _xd in \ 1660 "${NETBSDSRCDIR%/*}/xsrc" \ 1661 "${NETBSDSRCDIR}/xsrc" \ 1662 /usr/xsrc 1663 do 1664 test -f "${_xd}/Makefile" && 1665 setmakeenv X11SRCDIR "${_xd}" && 1666 break 2 1667 done 1668 bomb "Asked to build X11 but no xsrc" 1669 done 1670 1671 while $do_pkg # not really a loop 1672 do 1673 test -n "${PKGSRCDIR}" && { 1674 test -f "${PKGSRCDIR}/mk/bsd.pkg.mk" || 1675 bomb "PKGSRCDIR (${PKGSRCDIR}) does not exist" 1676 break 1677 } 1678 for _pd in \ 1679 "${NETBSDSRCDIR%/*}/pkgsrc" \ 1680 "${NETBSDSRCDIR}/pkgsrc" \ 1681 /usr/pkgsrc 1682 do 1683 test -f "${_pd}/mk/bsd.pkg.mk" && 1684 setmakeenv PKGSRCDIR "${_pd}" && 1685 break 2 1686 done 1687 bomb "Asked to build package but no pkgsrc" 1688 done 1689 if $do_pkg && [ "${MKX11-no}" = yes ] 1690 then 1691 # See comment below about X11_TYPE in pkgsrc mk.conf. 1692 # (Feel free to remove this, and set X11_TYPE to 1693 # native/modular according to MKX11=yes/no, if you want 1694 # to do the work to make X11_TYPE=native cross-builds 1695 # work.) 1696 bomb "Experimental \`build.sh pkg=...'" \ 1697 "does not support -x/MKX11=yes" 1698 fi 1699 } 1700 1701 # find a command in PATH and print the full filename 1702 print_path_of() 1703 { 1704 set -- $( type "$1" ) 1705 printf "${3}\n" 1706 } 1707 1708 1709 # print_tooldir_program -- 1710 # Try to find and show a path to an existing 1711 # ${TOOLDIR}/bin/${toolprefix}program 1712 # 1713 print_tooldir_program() 1714 { 1715 local possible_TOP_OBJ 1716 local possible_TOOLDIR 1717 local possible_program 1718 local tooldir_program 1719 local program="${1}" 1720 1721 if [ "${USETOOLS-yes}" != "yes" ]; then 1722 print_path_of "${program}" 1723 return 1724 fi 1725 1726 if [ -n "${TOOLDIR}" ] 1727 then 1728 echo "${TOOLDIR}/bin/${toolprefix}${program}" 1729 return 1730 fi 1731 1732 # Set host_ostype to something like "NetBSD-4.5.6-i386". This 1733 # is intended to match the HOST_OSTYPE variable in <bsd.own.mk>. 1734 # 1735 local host_ostype="${uname_s}-$( 1736 echo "${uname_r}" | sed -e 's/([^)]*)//g' -e 's/ /_/g' 1737 )-$( 1738 echo "${uname_p}" | sed -e 's/([^)]*)//g' -e 's/ /_/g' 1739 )" 1740 1741 # Look in a few potential locations for 1742 # ${possible_TOOLDIR}/bin/${toolprefix}${program}. 1743 # If we find it, then set possible_program. 1744 # 1745 # In the usual case (without interference from environment 1746 # variables or /etc/mk.conf), <bsd.own.mk> should set TOOLDIR to 1747 # "${_SRC_TOP_OBJ_}/tooldir.${host_ostype}". 1748 # 1749 # In practice it's difficult to figure out the correct value 1750 # for _SRC_TOP_OBJ_. In the easiest case, when the -M or -O 1751 # options were passed to build.sh, then ${TOP_objdir} will be 1752 # the correct value. We also try a few other possibilities, but 1753 # we do not replicate all the logic of <bsd.obj.mk>. 1754 # 1755 for possible_TOP_OBJ in \ 1756 "${TOP_objdir}" \ 1757 "${MAKEOBJDIRPREFIX:+${MAKEOBJDIRPREFIX}${TOP}}" \ 1758 "${TOP}" \ 1759 "${TOP}/obj" \ 1760 "${TOP}/obj.${MACHINE}" 1761 do 1762 [ -n "${possible_TOP_OBJ}" ] || continue 1763 possible_TOOLDIR="${possible_TOP_OBJ}/tooldir.${host_ostype}" 1764 possible_program="${possible_TOOLDIR}/bin/${toolprefix}${program}" 1765 if [ -x "${possible_program}" ] 1766 then 1767 echo ${possible_program} 1768 return 1769 fi 1770 done 1771 echo '' 1772 } 1773 1774 # print_tooldir_make -- 1775 # Try to find and show a path to an existing 1776 # ${TOOLDIR}/bin/${toolprefix}make, for use by rebuildmake() before a 1777 # new version of ${toolprefix}make has been built. 1778 # 1779 # * If TOOLDIR was set in the environment or on the command line, use 1780 # that value. 1781 # * Otherwise try to guess what TOOLDIR would be if not overridden by 1782 # /etc/mk.conf, and check whether the resulting directory contains 1783 # a copy of ${toolprefix}make (this should work for everybody who 1784 # doesn't override TOOLDIR via /etc/mk.conf); 1785 # * Failing that, search for ${toolprefix}make, nbmake, bmake, or make, 1786 # in the PATH (this might accidentally find a version of make that 1787 # does not understand the syntax used by NetBSD make, and that will 1788 # lead to failure in the next step); 1789 # * If a copy of make was found above, try to use it with 1790 # nobomb_getmakevar to find the correct value for TOOLDIR, and believe the 1791 # result only if it's a directory that already exists; 1792 # * If a value of TOOLDIR was found above, and if 1793 # ${TOOLDIR}/bin/${toolprefix}make exists, show that value. 1794 # 1795 print_tooldir_make() 1796 { 1797 local possible_make 1798 local possible_TOOLDIR 1799 local tooldir_make 1800 1801 possible_make=$(print_tooldir_program make) 1802 # If the above didn't work, search the PATH for a suitable 1803 # ${toolprefix}make, nbmake, bmake, or make. 1804 # 1805 : ${possible_make:=$(find_in_PATH ${toolprefix}make '')} 1806 : ${possible_make:=$(find_in_PATH nbmake '')} 1807 : ${possible_make:=$(find_in_PATH bmake '')} 1808 : ${possible_make:=$(find_in_PATH make '')} 1809 1810 # At this point, we don't care whether possible_make is in the 1811 # correct TOOLDIR or not; we simply want it to be usable by 1812 # getmakevar to help us find the correct TOOLDIR. 1813 # 1814 # Use ${possible_make} with nobomb_getmakevar to try to find 1815 # the value of TOOLDIR. Believe the result only if it's 1816 # a directory that already exists and contains bin/${toolprefix}make. 1817 # 1818 if [ -x "${possible_make}" ] 1819 then 1820 possible_TOOLDIR=$( 1821 make="${possible_make}" \ 1822 nobomb_getmakevar TOOLDIR 2>/dev/null 1823 ) 1824 if [ $? = 0 ] && 1825 [ -n "${possible_TOOLDIR}" ] && 1826 [ -d "${possible_TOOLDIR}" ] 1827 then 1828 tooldir_make="${possible_TOOLDIR}/bin/${toolprefix}make" 1829 if [ -x "${tooldir_make}" ] 1830 then 1831 echo "${tooldir_make}" 1832 return 0 1833 fi 1834 fi 1835 fi 1836 return 1 1837 } 1838 1839 # rebuildmake -- 1840 # Rebuild nbmake in a temporary directory if necessary. Sets $make 1841 # to a path to the nbmake executable. Sets done_rebuildmake=true 1842 # if nbmake was rebuilt. 1843 # 1844 # There is a cyclic dependency between building nbmake and choosing 1845 # TOOLDIR: TOOLDIR may be affected by settings in /etc/mk.conf, so we 1846 # would like to use getmakevar to get the value of TOOLDIR; but we can't 1847 # use getmakevar before we have an up to date version of nbmake; we 1848 # might already have an up to date version of nbmake in TOOLDIR, but we 1849 # don't yet know where TOOLDIR is. 1850 # 1851 # The default value of TOOLDIR also depends on the location of the top 1852 # level object directory, so $(getmakevar TOOLDIR) invoked before or 1853 # after making the top level object directory may produce different 1854 # results. 1855 # 1856 # Strictly speaking, we should do the following: 1857 # 1858 # 1. build a new version of nbmake in a temporary directory; 1859 # 2. use the temporary nbmake to create the top level obj directory; 1860 # 3. use $(getmakevar TOOLDIR) with the temporary nbmake to 1861 # get the correct value of TOOLDIR; 1862 # 4. move the temporary nbmake to ${TOOLDIR}/bin/nbmake. 1863 # 1864 # However, people don't like building nbmake unnecessarily if their 1865 # TOOLDIR has not changed since an earlier build. We try to avoid 1866 # rebuilding a temporary version of nbmake by taking some shortcuts to 1867 # guess a value for TOOLDIR, looking for an existing version of nbmake 1868 # in that TOOLDIR, and checking whether that nbmake is newer than the 1869 # sources used to build it. 1870 # 1871 rebuildmake() 1872 { 1873 make="$(print_tooldir_make)" 1874 if [ -n "${make}" ] && [ -x "${make}" ] 1875 then 1876 for f in usr.bin/make/*.[ch] 1877 do 1878 if [ "${f}" -nt "${make}" ] 1879 then 1880 statusmsg "${make} outdated" \ 1881 "(older than ${f}), needs building." 1882 do_rebuildmake=true 1883 break 1884 fi 1885 done 1886 else 1887 statusmsg "No \$TOOLDIR/bin/${toolprefix}make, needs building." 1888 do_rebuildmake=true 1889 fi 1890 1891 # Build bootstrap ${toolprefix}make if needed. 1892 if ! ${do_rebuildmake} 1893 then 1894 return 1895 fi 1896 1897 # Silent configure with MAKEVERBOSE==0 1898 if [ ${MAKEVERBOSE:-2} -eq 0 ] 1899 then 1900 configure_args=--silent 1901 fi 1902 1903 statusmsg "Bootstrapping ${toolprefix}make" 1904 ${runcmd} cd "${tmpdir}" 1905 ${runcmd} env CC="${HOST_CC-cc}" CPPFLAGS="${HOST_CPPFLAGS}" \ 1906 CFLAGS="${HOST_CFLAGS--O}" LDFLAGS="${HOST_LDFLAGS}" \ 1907 ${HOST_SH} "${TOP}/tools/make/configure" ${configure_args} || 1908 ( cp ${tmpdir}/config.log ${tmpdir}-config.log 1909 bomb "Configure of ${toolprefix}make failed," \ 1910 "see ${tmpdir}-config.log for details" ) 1911 ${runcmd} ${HOST_SH} buildmake.sh || 1912 bomb "Build of ${toolprefix}make failed" 1913 make="${tmpdir}/${toolprefix}make" 1914 ${runcmd} cd "${TOP}" 1915 ${runcmd} rm -f usr.bin/make/*.o 1916 done_rebuildmake=true 1917 } 1918 1919 # validatemakeparams -- 1920 # Perform some late sanity checks, after rebuildmake, 1921 # but before createmakewrapper or any real work. 1922 # 1923 # Creates the top-level obj directory, because that 1924 # is needed by some of the sanity checks. 1925 # 1926 # Shows status messages reporting the values of several variables. 1927 # 1928 validatemakeparams() 1929 { 1930 # Determine MAKECONF first, and set in the makewrapper. 1931 # If set in the environment, then use that. 1932 # else if ./mk.conf exists, then set MAKECONF to that, 1933 # else use the default from share/mk/bsd.own.mk (/etc/mk.conf). 1934 # 1935 if [ -n "${MAKECONF+1}" ] 1936 then 1937 setmakeenv MAKECONF "${MAKECONF}" 1938 statusmsg2 "getenv MAKECONF:" "${MAKECONF}" 1939 elif [ -f "${TOP}/mk.conf" ] 1940 then 1941 setmakeenv MAKECONF "${TOP}/mk.conf" 1942 statusmsg2 "mk.conf MAKECONF:" "${MAKECONF}" 1943 else 1944 MAKECONF=$(getmakevar MAKECONF) 1945 setmakeenv MAKECONF "${MAKECONF}" 1946 statusmsg2 "share/mk MAKECONF:" "${MAKECONF}" 1947 fi 1948 if [ -z "${MAKECONF}" ] 1949 then 1950 bomb "MAKECONF must not be empty" 1951 elif [ -e "${MAKECONF}" ] 1952 then 1953 statusmsg2 "MAKECONF file:" "${MAKECONF}" 1954 else 1955 statusmsg2 "MAKECONF file:" "${MAKECONF} (File not found)" 1956 fi 1957 1958 # Normalise MKOBJDIRS, MKUNPRIVED, and MKUPDATE. 1959 # These may be set as build.sh options or in "mk.conf". 1960 # Don't export them as they're only used for tests in build.sh. 1961 # 1962 MKOBJDIRS=$(getmakevar MKOBJDIRS) 1963 MKUNPRIVED=$(getmakevar MKUNPRIVED) 1964 MKUPDATE=$(getmakevar MKUPDATE) 1965 1966 # Non-root should always use either the -U or -E flag. 1967 # 1968 if ! ${do_expertmode} && [ "$id_u" -ne 0 ] && [ "${MKUNPRIVED}" = no ] 1969 then 1970 bomb "-U or -E must be set for build as an unprivileged user" 1971 fi 1972 1973 if [ "${runcmd}" = echo ] 1974 then 1975 TOOLCHAIN_MISSING=no 1976 EXTERNAL_TOOLCHAIN= 1977 else 1978 TOOLCHAIN_MISSING=$(bomb_getmakevar TOOLCHAIN_MISSING) 1979 EXTERNAL_TOOLCHAIN=$(bomb_getmakevar EXTERNAL_TOOLCHAIN) 1980 fi 1981 if [ "${TOOLCHAIN_MISSING}" = yes ] && [ -z "${EXTERNAL_TOOLCHAIN}" ] 1982 then 1983 ${runcmd} echo "ERROR: build.sh (in-tree cross-toolchain)" \ 1984 "is not yet available for" 1985 ${runcmd} echo " MACHINE: ${MACHINE}" 1986 ${runcmd} echo " MACHINE_ARCH: ${MACHINE_ARCH}" 1987 ${runcmd} echo "" 1988 ${runcmd} echo "All builds for this platform should be done" \ 1989 "via a traditional make" 1990 ${runcmd} echo "If you wish to use an external" \ 1991 "cross-toolchain, set" 1992 ${runcmd} echo " EXTERNAL_TOOLCHAIN=<path to" \ 1993 "toolchain root>" 1994 ${runcmd} echo "in either the environment or mk.conf and rerun" 1995 ${runcmd} echo " ${progname} $*" 1996 exit 1 1997 fi 1998 1999 if [ "${MKOBJDIRS}" != no ] 2000 then 2001 # Create the top-level object directory. 2002 # 2003 # "make obj NOSUBDIR=" can handle most cases, but it 2004 # can't handle the case where MAKEOBJDIRPREFIX is set 2005 # while the corresponding directory does not exist 2006 # (rules in <bsd.obj.mk> would abort the build). We 2007 # therefore have to handle the MAKEOBJDIRPREFIX case 2008 # without invoking "make obj". The MAKEOBJDIR case 2009 # could be handled either way, but we choose to handle 2010 # it similarly to MAKEOBJDIRPREFIX. 2011 # 2012 if [ -n "${TOP_obj}" ] 2013 then 2014 # It must have been set by the "-M" or "-O" 2015 # command line options, so there's no need to 2016 # use getmakevar 2017 : 2018 elif [ -n "$MAKEOBJDIRPREFIX" ] 2019 then 2020 TOP_obj="$(getmakevar MAKEOBJDIRPREFIX)${TOP}" 2021 elif [ -n "$MAKEOBJDIR" ] 2022 then 2023 TOP_obj="$(getmakevar MAKEOBJDIR)" 2024 fi 2025 if [ -n "$TOP_obj" ] 2026 then 2027 ${runcmd} mkdir -p "${TOP_obj}" || 2028 bomb "Can't create top level object directory" \ 2029 "${TOP_obj}" 2030 else 2031 ${runcmd} "${make}" -m "${TOP}/share/mk" obj NOSUBDIR= || 2032 bomb "Can't create top level object directory" \ 2033 "using make obj" 2034 fi 2035 2036 # make obj in tools to ensure that the objdir for "tools" 2037 # is available. 2038 # 2039 ${runcmd} cd tools 2040 ${runcmd} "${make}" -m "${TOP}/share/mk" obj NOSUBDIR= || 2041 bomb "Failed to make obj in tools" 2042 ${runcmd} cd "${TOP}" 2043 fi 2044 2045 # Find TOOLDIR, DESTDIR, and RELEASEDIR, according to getmakevar, 2046 # and bomb if they have changed from the values we had from the 2047 # command line or environment. 2048 # 2049 # This must be done after creating the top-level object directory. 2050 # 2051 for var in TOOLDIR DESTDIR RELEASEDIR 2052 do 2053 eval oldval=\"\$${var}\" 2054 newval="$(getmakevar $var)" 2055 if ! $do_expertmode 2056 then 2057 : ${_SRC_TOP_OBJ_:=$(getmakevar _SRC_TOP_OBJ_)} 2058 case "$var" in 2059 DESTDIR) 2060 : ${newval:=${_SRC_TOP_OBJ_}/destdir.${MACHINE}} 2061 makeenv="${makeenv} DESTDIR" 2062 ;; 2063 RELEASEDIR) 2064 : ${newval:=${_SRC_TOP_OBJ_}/releasedir} 2065 makeenv="${makeenv} RELEASEDIR" 2066 ;; 2067 esac 2068 fi 2069 if [ -n "$oldval" ] && [ "$oldval" != "$newval" ] 2070 then 2071 bomb "Value of ${var} has changed" \ 2072 "(was \"${oldval}\", now \"${newval}\")" 2073 fi 2074 eval ${var}=\"\${newval}\" 2075 eval export ${var} 2076 statusmsg2 "${var} path:" "${newval}" 2077 done 2078 2079 # RELEASEMACHINEDIR is just a subdir name, e.g. "i386". 2080 RELEASEMACHINEDIR=$(getmakevar RELEASEMACHINEDIR) 2081 2082 # Check validity of TOOLDIR and DESTDIR. 2083 # 2084 if [ -z "${TOOLDIR}" ] || [ "${TOOLDIR}" = / ] 2085 then 2086 bomb "TOOLDIR '${TOOLDIR}' invalid" 2087 fi 2088 removedirs="${TOOLDIR}" 2089 2090 if [ -z "${DESTDIR}" ] || [ "${DESTDIR}" = / ] 2091 then 2092 if ${do_distribution} || ${do_release} || 2093 [ "${uname_s}" != NetBSD ] || 2094 [ "${uname_m}" != "${MACHINE}" ] 2095 then 2096 bomb "DESTDIR must != / for cross builds," \ 2097 "or ${progname} 'distribution' or 'release'" 2098 fi 2099 if ! ${do_expertmode} 2100 then 2101 bomb "DESTDIR must != / for non -E (expert) builds" 2102 fi 2103 statusmsg "WARNING: Building to /, in expert mode." 2104 statusmsg " This may cause your system to break!" 2105 statusmsg " Reasons include:" 2106 statusmsg " - your kernel is not up to date" 2107 statusmsg " - the libraries or toolchain have changed" 2108 statusmsg " YOU HAVE BEEN WARNED!" 2109 else 2110 removedirs="${removedirs} ${DESTDIR}" 2111 fi 2112 if ${do_releasekernel} && [ -z "${RELEASEDIR}" ] 2113 then 2114 bomb "Must set RELEASEDIR with 'releasekernel=...'" 2115 fi 2116 2117 # If a previous build.sh run used -U (and therefore created a 2118 # METALOG file), then most subsequent build.sh runs must also 2119 # use -U. If DESTDIR is about to be removed, then don't perform 2120 # this check. 2121 # 2122 case "${do_removedirs} ${removedirs} " in 2123 true*" ${DESTDIR} "*) 2124 # DESTDIR is about to be removed 2125 ;; 2126 *) 2127 if [ -e "${DESTDIR}/METALOG" ] && 2128 [ "${MKUNPRIVED}" = no ] 2129 then 2130 if $do_expertmode 2131 then 2132 warning "A previous build.sh run specified -U" 2133 else 2134 bomb "A previous build.sh run specified -U;" \ 2135 "you must specify it again now" 2136 fi 2137 fi 2138 ;; 2139 esac 2140 2141 # live-image and install-image targets require binary sets 2142 # (actually DESTDIR/etc/mtree/set.* files) built with MKUNPRIVED. 2143 # If release operation is specified with live-image or install-image, 2144 # the release op should be performed with -U for later image ops. 2145 # 2146 if ${do_release} && 2147 { ${do_live_image} || ${do_install_image} ; } && 2148 [ "${MKUNPRIVED}" = no ] 2149 then 2150 bomb "-U must be specified on building release" \ 2151 "to create images later" 2152 fi 2153 } 2154 2155 2156 createmakewrapper() 2157 { 2158 # Remove the target directories. 2159 # 2160 if ${do_removedirs} 2161 then 2162 for f in ${removedirs} 2163 do 2164 statusmsg "Removing ${f}" 2165 ${runcmd} rm -r -f "${f}" 2166 done 2167 fi 2168 2169 # Recreate $TOOLDIR. 2170 # 2171 ${runcmd} mkdir -p "${TOOLDIR}/bin" || 2172 bomb "mkdir of '${TOOLDIR}/bin' failed" 2173 2174 # If we did not previously rebuild ${toolprefix}make, then 2175 # check whether $make is still valid and the same as the output 2176 # from print_tooldir_make. If not, then rebuild make now. A 2177 # possible reason for this being necessary is that the actual 2178 # value of TOOLDIR might be different from the value guessed 2179 # before the top level obj dir was created. 2180 # 2181 if ! ${done_rebuildmake} && 2182 { ! [ -x "$make" ] || [ "$make" != "$(print_tooldir_make)" ] ; } 2183 then 2184 rebuildmake 2185 fi 2186 2187 # Install ${toolprefix}make if it was built. 2188 # 2189 if ${done_rebuildmake} 2190 then 2191 ${runcmd} rm -f "${TOOLDIR}/bin/${toolprefix}make" 2192 ${runcmd} cp "${make}" "${TOOLDIR}/bin/${toolprefix}make" || 2193 bomb "Failed to install \$TOOLDIR/bin/${toolprefix}make" 2194 make="${TOOLDIR}/bin/${toolprefix}make" 2195 statusmsg "Created ${make}" 2196 fi 2197 2198 # Build a ${toolprefix}make wrapper script, usable by hand as 2199 # well as by build.sh. 2200 # 2201 if [ -z "${makewrapper}" ] 2202 then 2203 makewrapper="${TOOLDIR}/bin/${toolprefix}make" 2204 makewrapper="${makewrapper}-${makewrappermachine:-${MACHINE}}" 2205 [ -z "${BUILDID}" ] || makewrapper="${makewrapper}-${BUILDID}" 2206 fi 2207 2208 ${runcmd} rm -f "${makewrapper}" 2209 if [ "${runcmd}" = echo ] 2210 then 2211 echo 'cat <<EOF >'${makewrapper} 2212 makewrapout= 2213 else 2214 makewrapout=">>\${makewrapper}" 2215 fi 2216 2217 case "${KSH_VERSION:-${SH_VERSION}}" in 2218 *PD\ KSH*|*MIRBSD\ KSH*) 2219 set +o braceexpand 2220 ;; 2221 esac 2222 2223 eval cat <<EOF ${makewrapout} 2224 #! ${HOST_SH} 2225 # Set proper variables to allow easy "make" building of a NetBSD subtree. 2226 # Generated from: \$NetBSD: build.sh,v 1.399 2025/07/08 12:29:40 hgutch Exp $ 2227 # with these arguments: ${_args} 2228 # 2229 2230 EOF 2231 { 2232 sorted_vars=$( 2233 for var in ${makeenv} 2234 do 2235 echo "${var}" 2236 done | 2237 sort -u 2238 ) 2239 for var in ${sorted_vars} 2240 do 2241 eval val=\"\${${var}}\" 2242 eval is_set=\"\${${var}+set}\" 2243 if [ -z "${is_set}" ] 2244 then 2245 echo "unset ${var}" 2246 else 2247 qval="$(shell_quote "${val}")" 2248 echo "${var}=${qval}; export ${var}" 2249 fi 2250 done 2251 2252 cat <<-EOF 2253 2254 exec "\${TOOLDIR}/bin/${toolprefix}make" \${1+"\$@"} 2255 EOF 2256 } | eval cat "${makewrapout}" 2257 [ "${runcmd}" = echo ] && echo EOF 2258 ${runcmd} chmod +x "${makewrapper}" 2259 statusmsg2 "Updated makewrapper:" "${makewrapper}" 2260 } 2261 2262 make_in_dir() 2263 { 2264 local dir="$1" 2265 local op="$2" 2266 ${runcmd} cd "${dir}" || 2267 bomb "Failed to cd to \"${dir}\"" 2268 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2269 bomb "Failed to make ${op} in \"${dir}\"" 2270 ${runcmd} cd "${TOP}" || 2271 bomb "Failed to cd back to \"${TOP}\"" 2272 } 2273 2274 buildtools() 2275 { 2276 if [ "${MKOBJDIRS}" != no ] 2277 then 2278 ${runcmd} "${makewrapper}" ${parallel} obj-tools || 2279 bomb "Failed to make obj-tools" 2280 fi 2281 if [ "${MKUPDATE}" = no ] 2282 then 2283 make_in_dir tools cleandir 2284 fi 2285 make_in_dir tools build_install 2286 statusmsg "Tools built to ${TOOLDIR}" 2287 } 2288 2289 buildlibs() 2290 { 2291 if [ "${MKOBJDIRS}" != no ] 2292 then 2293 ${runcmd} "${makewrapper}" ${parallel} obj || 2294 bomb "Failed to make obj" 2295 fi 2296 if [ "${MKUPDATE}" = no ] 2297 then 2298 make_in_dir lib cleandir 2299 fi 2300 make_in_dir . do-distrib-dirs 2301 make_in_dir . includes 2302 make_in_dir . do-lib 2303 statusmsg "libs built" 2304 } 2305 2306 getkernelconf() 2307 { 2308 kernelconf=$1 2309 if [ "${MKOBJDIRS}" != no ] 2310 then 2311 # The correct value of KERNOBJDIR might 2312 # depend on a prior "make obj" in 2313 # ${KERNSRCDIR}/${KERNARCHDIR}/compile. 2314 # 2315 KERNSRCDIR="$(getmakevar KERNSRCDIR)" 2316 KERNARCHDIR="$(getmakevar KERNARCHDIR)" 2317 make_in_dir "${KERNSRCDIR}/${KERNARCHDIR}/compile" obj 2318 fi 2319 KERNCONFDIR=$(getmakevar KERNCONFDIR) 2320 KERNOBJDIR=$(getmakevar KERNOBJDIR) 2321 case "${kernelconf}" in 2322 */*) 2323 kernelconfpath=${kernelconf} 2324 kernelconfname=${kernelconf##*/} 2325 ;; 2326 *) 2327 kernelconfpath=${KERNCONFDIR}/${kernelconf} 2328 kernelconfname=${kernelconf} 2329 ;; 2330 esac 2331 kernelbuildpath=${KERNOBJDIR}/${kernelconfname} 2332 } 2333 2334 diskimage() 2335 { 2336 ARG="$(echo "$1" | tr '[:lower:]' '[:upper:]')" 2337 [ -f "${DESTDIR}/etc/mtree/set.base" ] || 2338 bomb "The release binaries must be built first" 2339 kerneldir="${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/kernel" 2340 kernel="${kerneldir}/netbsd-${ARG}.gz" 2341 [ -f "${kernel}" ] || 2342 bomb "The kernel ${kernel} must be built first" 2343 make_in_dir "${NETBSDSRCDIR}/etc" "smp_${1}" 2344 } 2345 2346 buildkernel() 2347 { 2348 if ! ${do_tools} && ! ${buildkernelwarned:-false} 2349 then 2350 # Building tools every time we build a kernel is clearly 2351 # unnecessary. We could try to figure out whether rebuilding 2352 # the tools is necessary this time, but it doesn't seem worth 2353 # the trouble. Instead, we say it's the user's responsibility 2354 # to rebuild the tools if necessary. 2355 # 2356 statusmsg "Building kernel without building new tools" 2357 buildkernelwarned=true 2358 fi 2359 getkernelconf $1 2360 statusmsg2 "Building kernel:" "${kernelconf}" 2361 statusmsg2 "Build directory:" "${kernelbuildpath}" 2362 ${runcmd} mkdir -p "${kernelbuildpath}" || 2363 bomb "Cannot mkdir: ${kernelbuildpath}" 2364 if [ "${MKUPDATE}" = no ] 2365 then 2366 make_in_dir "${kernelbuildpath}" cleandir 2367 fi 2368 [ -x "${TOOLDIR}/bin/${toolprefix}config" ] || 2369 bomb "${TOOLDIR}/bin/${toolprefix}config does not exist." \ 2370 "You need to \"$0 tools\" first" 2371 CONFIGOPTS=$(getmakevar CONFIGOPTS) 2372 ${runcmd} "${TOOLDIR}/bin/${toolprefix}config" ${CONFIGOPTS} \ 2373 -b "${kernelbuildpath}" -s "${TOP}/sys" ${configopts} \ 2374 "${kernelconfpath}" || 2375 bomb "${toolprefix}config failed for ${kernelconf}" 2376 make_in_dir "${kernelbuildpath}" depend 2377 make_in_dir "${kernelbuildpath}" all 2378 2379 if [ "${runcmd}" != echo ] 2380 then 2381 statusmsg "Kernels built from ${kernelconf}:" 2382 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath}) 2383 for kern in ${kernlist:-netbsd} 2384 do 2385 [ -f "${kernelbuildpath}/${kern}" ] && 2386 echo " ${kernelbuildpath}/${kern}" 2387 done | tee -a "${results}" 2388 fi 2389 } 2390 2391 releasekernel() 2392 { 2393 getkernelconf $1 2394 kernelreldir="${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/kernel" 2395 ${runcmd} mkdir -p "${kernelreldir}" 2396 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath}) 2397 for kern in ${kernlist:-netbsd} 2398 do 2399 builtkern="${kernelbuildpath}/${kern}" 2400 [ -f "${builtkern}" ] || continue 2401 releasekern="${kernelreldir}/${kern}-${kernelconfname}.gz" 2402 statusmsg2 "Kernel copy:" "${releasekern}" 2403 if [ "${runcmd}" = echo ] 2404 then 2405 echo "gzip -c -9 < ${builtkern} > ${releasekern}" 2406 else 2407 gzip -c -9 < "${builtkern}" > "${releasekern}" 2408 fi 2409 done 2410 } 2411 2412 buildkernels() 2413 { 2414 allkernels=$( runcmd= make_in_dir etc '-V ${ALL_KERNELS}' ) 2415 for k in $allkernels 2416 do 2417 buildkernel "${k}" 2418 done 2419 } 2420 2421 buildmodules() 2422 { 2423 setmakeenv MKBINUTILS no 2424 if ! ${do_tools} && ! ${buildmoduleswarned:-false} 2425 then 2426 # Building tools every time we build modules is clearly 2427 # unnecessary as well as a kernel. 2428 # 2429 statusmsg "Building modules without building new tools" 2430 buildmoduleswarned=true 2431 fi 2432 2433 statusmsg "Building kernel modules for NetBSD/${MACHINE} ${DISTRIBVER}" 2434 if [ "${MKOBJDIRS}" != no ] 2435 then 2436 make_in_dir sys/modules obj 2437 fi 2438 if [ "${MKUPDATE}" = no ] 2439 then 2440 make_in_dir sys/modules cleandir 2441 fi 2442 make_in_dir sys/modules dependall 2443 make_in_dir sys/modules install 2444 2445 statusmsg "Successful build of kernel modules for" \ 2446 "NetBSD/${MACHINE} ${DISTRIBVER}" 2447 } 2448 2449 builddtb() 2450 { 2451 statusmsg "Building devicetree blobs for" \ 2452 "NetBSD/${MACHINE} ${DISTRIBVER}" 2453 if [ "${MKOBJDIRS}" != no ] 2454 then 2455 make_in_dir sys/dtb obj 2456 fi 2457 if [ "${MKUPDATE}" = no ] 2458 then 2459 make_in_dir sys/dtb cleandir 2460 fi 2461 make_in_dir sys/dtb dependall 2462 make_in_dir sys/dtb install 2463 2464 statusmsg "Successful build of devicetree blobs for" \ 2465 "NetBSD/${MACHINE} ${DISTRIBVER}" 2466 } 2467 2468 buildpkg() 2469 { 2470 local catpkg 2471 local pkgroot 2472 local makejobsarg 2473 local makejobsvar 2474 local quiet 2475 local opsys_version 2476 2477 catpkg="$1" 2478 2479 pkgroot="${TOP_objdir:-${TOP}}/pkgroot" 2480 ${runcmd} mkdir -p "${pkgroot}" || 2481 bomb "Can't create package root" "${pkgroot}" 2482 2483 # Get a symlink-free absolute path to pkg -- pkgsrc wants this. 2484 # 2485 # XXX See TOP= above regarding pwd -P. 2486 pkgroot=$(unset PWD; cd "${pkgroot}" && 2487 ((exec pwd -P 2>/dev/null) || (exec pwd 2>/dev/null))) 2488 2489 case $parallel in 2490 "-j "*) 2491 makejobsarg="--make-jobs ${parallel#-j }" 2492 makejobsvar="MAKE_JOBS=${parallel#-j }" 2493 ;; 2494 *) makejobsarg= 2495 makejobsvar= 2496 ;; 2497 esac 2498 2499 if [ "${MAKEVERBOSE}" -eq 0 ] 2500 then 2501 quiet="--quiet" 2502 else 2503 quiet= 2504 fi 2505 2506 # Derived from pkgsrc/mk/bsd.prefs.mk rev. 1.451. 2507 opsys_version=$(echo "${DISTRIBVER}" | 2508 awk -F. '{ 2509 major=int($1) 2510 minor=int($2) 2511 if (minor>=100) minor=99 2512 patch=int($3) 2513 if (patch>=100) patch=99 2514 printf "%02d%02d%02d", major, minor, patch 2515 }' 2516 ) 2517 2518 # Bootstrap pkgsrc if needed. 2519 # 2520 # XXX Redo this if it's out-of-date, not just if it's missing. 2521 if ! [ -x "${pkgroot}/pkg/bin/bmake" ] 2522 then 2523 statusmsg "Bootstrapping pkgsrc" 2524 2525 cat >"${pkgroot}/mk.conf-fragment" <<EOF 2526 USE_CROSS_COMPILE?= no 2527 TOOLDIR= ${TOOLDIR} 2528 CROSS_DESTDIR= ${DESTDIR} 2529 CROSS_MACHINE_ARCH= ${MACHINE_ARCH} 2530 CROSS_OPSYS= NetBSD 2531 CROSS_OS_VERSION= ${DISTRIBVER} 2532 CROSS_OPSYS_VERSION= ${opsys_version} 2533 CROSS_LOWER_OPSYS= netbsd 2534 CROSS_LOWER_OPSYS_VERSUFFIX= # empty 2535 CROSS_LOWER_OS_VARIANT= # empty 2536 CROSS_LOWER_VARIANT_VERSION= # empty 2537 CROSS_LOWER_VENDOR= # empty 2538 CROSS_OBJECT_FMT= ELF 2539 2540 ALLOW_VULNERABLE_PACKAGES= yes 2541 BINPKG_SITES= # empty 2542 FAILOVER_FETCH= yes 2543 FETCH_TIMEOUT= 1800 2544 PASSIVE_FETCH= yes 2545 2546 DISTDIR= ${pkgroot}/distfiles 2547 PACKAGES= ${pkgroot}/packages 2548 WRKOBJDIR= ${pkgroot}/work 2549 2550 # pkgsrc cross-builds are not set up to support native X, but also part 2551 # of the point of pkgsrc cross-build infrastructure is to not need 2552 # native X any more. 2553 # 2554 # (If you fix this, remove the bomb in build.sh pkg=... on MKX11=yes.) 2555 X11_TYPE= modular 2556 2557 .-include "${MAKECONF}" 2558 2559 MKDEBUG= no # interferes with pkgsrc builds 2560 EOF 2561 2562 # XXX Set --abi for mips and whatever else needs it? 2563 # XXX Unprivileged native tools, privileged cross. 2564 ( 2565 cd "${PKGSRCDIR}" && 2566 clearmakeenv && 2567 ./bootstrap/bootstrap \ 2568 ${makejobsarg} \ 2569 --mk-fragment "${pkgroot}/mk.conf-fragment" \ 2570 --prefix "${pkgroot}/pkg" \ 2571 ${quiet} \ 2572 --unprivileged \ 2573 --workdir "${pkgroot}/bootwork" 2574 ) || 2575 bomb "Failed to bootstrap pkgsrc" 2576 fi 2577 2578 # Build the package. 2579 ( 2580 cd "${PKGSRCDIR}/${catpkg}" && 2581 clearmakeenv && 2582 "${pkgroot}/pkg/bin/bmake" package \ 2583 USE_CROSS_COMPILE=yes \ 2584 ${makejobsvar} 2585 ) || 2586 bomb "Failed to build ${catpkg}" 2587 } 2588 2589 installmodules() 2590 { 2591 dir="$1" 2592 ${runcmd} "${makewrapper}" INSTALLMODULESDIR="${dir}" installmodules || 2593 bomb "Failed to make installmodules to ${dir}" 2594 statusmsg "Successful installmodules to ${dir}" 2595 } 2596 2597 installworld() 2598 { 2599 dir="$1" 2600 ${runcmd} "${makewrapper}" INSTALLWORLDDIR="${dir}" installworld || 2601 bomb "Failed to make installworld to ${dir}" 2602 statusmsg "Successful installworld to ${dir}" 2603 } 2604 2605 # Run rump build&link tests. 2606 # 2607 # To make this feasible for running without having to install includes and 2608 # libraries into destdir (i.e. quick), we only run ld. This is possible 2609 # since the rump kernel is a closed namespace apart from calls to rumpuser. 2610 # Therefore, if ld complains only about rumpuser symbols, rump kernel 2611 # linking was successful. 2612 # 2613 # We test that rump links with a number of component configurations. 2614 # These attempt to mimic what is encountered in the full build. 2615 # See list below. The list should probably be either autogenerated 2616 # or managed elsewhere; keep it here until a better idea arises. 2617 # 2618 # Above all, note that THIS IS NOT A SUBSTITUTE FOR A FULL BUILD. 2619 # 2620 2621 # XXX: uwe: kern/56599 - while riastradh addressed librump problems, 2622 # there are still unwanted dependencies: 2623 # net -> net_net 2624 # vfs -> fifo 2625 2626 # -lrumpvfs -> $LRUMPVFS for now 2627 LRUMPVFS="-lrumpvfs -lrumpvfs_nofifofs" 2628 2629 RUMP_LIBSETS=" 2630 -lrump, 2631 -lrumpvfs 2632 --no-whole-archive -lrumpvfs_nofifofs -lrump, 2633 -lrumpkern_tty 2634 --no-whole-archive $LRUMPVFS -lrump, 2635 -lrumpfs_tmpfs 2636 --no-whole-archive $LRUMPVFS -lrump, 2637 -lrumpfs_ffs -lrumpfs_msdos 2638 --no-whole-archive $LRUMPVFS -lrumpdev_disk -lrumpdev -lrump, 2639 -lrumpnet_virtif -lrumpnet_netinet -lrumpnet_net -lrumpnet 2640 --no-whole-archive -lrump, 2641 -lrumpfs_nfs 2642 --no-whole-archive $LRUMPVFS 2643 -lrumpnet_sockin -lrumpnet_virtif -lrumpnet_netinet 2644 --start-group -lrumpnet_net -lrumpnet --end-group -lrump, 2645 -lrumpdev_cgd -lrumpdev_raidframe -lrumpdev_rnd -lrumpdev_dm 2646 --no-whole-archive $LRUMPVFS -lrumpdev_disk -lrumpdev -lrumpkern_crypto -lrump 2647 " 2648 2649 dorump() 2650 { 2651 local doclean= 2652 local doobjs= 2653 2654 export RUMPKERN_ONLY=1 2655 # create obj and distrib dirs 2656 if [ "${MKOBJDIRS}" != no ] 2657 then 2658 make_in_dir "${NETBSDSRCDIR}/etc/mtree" obj 2659 make_in_dir "${NETBSDSRCDIR}/sys/rump" obj 2660 fi 2661 ${runcmd} "${makewrapper}" ${parallel} do-distrib-dirs \ 2662 || bomb "Could not create distrib-dirs" 2663 2664 [ "${MKUPDATE}" = no ] && doclean="cleandir" 2665 targlist="${doclean} ${doobjs} dependall install" 2666 2667 # optimize: for test we build only static libs (3x test speedup) 2668 if [ "${1}" = rumptest ] 2669 then 2670 setmakeenv NOPIC 1 2671 setmakeenv NOPROFILE 1 2672 fi 2673 2674 for cmd in ${targlist} 2675 do 2676 make_in_dir "${NETBSDSRCDIR}/sys/rump" ${cmd} 2677 done 2678 2679 # if we just wanted to build & install rump, we're done 2680 [ "${1}" != rumptest ] && return 2681 2682 ${runcmd} cd "${NETBSDSRCDIR}/sys/rump/librump/rumpkern" || 2683 bomb "cd to rumpkern failed" 2684 2685 md_quirks=`${runcmd} "${makewrapper}" -V '${_SYMQUIRK}'` 2686 # one little, two little, three little backslashes ... 2687 md_quirks="$(echo ${md_quirks} | sed 's,\\,\\\\,g'";s/'//g" )" 2688 ${runcmd} cd "${TOP}" || bomb "cd to ${TOP} failed" 2689 tool_ld=`${runcmd} "${makewrapper}" -V '${LD}'` 2690 2691 local oIFS="${IFS-UnSeTT}" 2692 IFS="," 2693 for set in ${RUMP_LIBSETS} 2694 do 2695 case "${oIFS}" in 2696 UnSeTT) unset IFS;; 2697 *) IFS="${oIFS}";; 2698 esac 2699 ${runcmd} ${tool_ld} -nostdlib -L${DESTDIR}/usr/lib \ 2700 -static --whole-archive ${set} --no-whole-archive \ 2701 -lpthread -lc 2>&1 -o /tmp/rumptest.$$ | 2702 awk -v quirks="${md_quirks}" ' 2703 /undefined reference/ && 2704 !/more undefined references.*follow/{ 2705 if (match($NF, 2706 "`(rumpuser_|rumpcomp_|__" quirks ")") == 0) 2707 fails[NR] = $0 2708 } 2709 /cannot find -l/{fails[NR] = $0} 2710 /cannot open output file/{fails[NR] = $0} 2711 END{ 2712 for (x in fails) 2713 print fails[x] 2714 exit x!=0 2715 }' 2716 [ $? -ne 0 ] && bomb "Testlink of rump failed: ${set}" 2717 done 2718 statusmsg "Rump build&link tests successful" 2719 } 2720 2721 repro_date() { 2722 # try the bsd date fail back the linux one 2723 date -u -r "$1" 2> /dev/null || date -u -d "@$1" 2724 } 2725 2726 setup_mkrepro() 2727 { 2728 local quiet="$1" 2729 2730 if [ "${MKREPRO-no}" != yes ] 2731 then 2732 return 2733 fi 2734 if [ "${MKREPRO_TIMESTAMP-0}" -ne 0 ] 2735 then 2736 return 2737 fi 2738 2739 MKREPRO_TIMESTAMP=0 2740 NETBSD_REVISIONID= 2741 local base 2742 local d 2743 local t 2744 local rid 2745 local tag 2746 local vcs 2747 for base in src xsrc 2748 do 2749 case $base in 2750 src) d=${NETBSDSRCDIR-/usr/src}/ 2751 ;; 2752 xsrc) [ "${MKX11-no}" = yes ] || continue 2753 d=${X11SRCDIR-/usr/xsrc}/ 2754 ;; 2755 esac 2756 if [ -d "${d}CVS" ] 2757 then 2758 local cvslatest="$(print_tooldir_program cvslatest)" 2759 if ! [ -x "${cvslatest}" ] 2760 then 2761 buildtools 2762 fi 2763 local nbdate="$(print_tooldir_program date)" 2764 2765 local cvslatestflags= 2766 if "${do_expertmode}" 2767 then 2768 cvslatestflags=-i 2769 fi 2770 2771 if [ -f "${d}CVS/Tag" ] 2772 then 2773 tag=$(sed -e 's/^T//' <${d}CVS/Tag) 2774 else 2775 tag=HEAD 2776 fi 2777 t=$("${cvslatest}" ${cvslatestflags} "${d}") || 2778 bomb "${cvslatest} failed" 2779 rid="${tag}:$(${nbdate} -u -r ${t} '+%Y%m%d%H%M%S')" 2780 vcs=cvs 2781 elif [ -d "${d}.git" ] || [ -f "${d}.git" ] 2782 then 2783 t=$(cd "${d}" && git log -1 --format=%ct) || 2784 bomb "git log %ct failed" 2785 rid="$( 2786 cd "${d}" && git log -1 --format=%H)" || 2787 bomb "git log %H failed" 2788 vcs=git 2789 elif [ -d "${d}.hg" ] 2790 then 2791 t=$(hg --repo "$d" \ 2792 log -r . --template '{date.unixtime}\n') || 2793 bomb "hg log failed" 2794 rid=$(hg --repo "$d" \ 2795 identify --template '{id}\n') || 2796 bomb "hg identify failed" 2797 vcs=hg 2798 elif [ -f "${d}.hg_archival.txt" ] 2799 then 2800 local stat 2801 stat=$(print_tooldir_program stat) || 2802 bomb "print_tooldir_program stat failed" 2803 if ! [ -x "${stat}" ] 2804 then 2805 buildtools 2806 fi 2807 2808 t=$("${stat}" -t '%s' -f '%m' "${d}.hg_archival.txt") || 2809 bomb "stat failed on ${d}.hg_archival.txt" 2810 rid=$( 2811 awk '/^node:/ { print $2 }' <"${d}.hg_archival.txt" 2812 ) || bomb \ 2813 "awk failed to find node: in ${d}.hg_archival.txt" 2814 vcs=hg 2815 else 2816 bomb "Cannot determine VCS for '$d'" 2817 fi 2818 NETBSD_REVISIONID="${NETBSD_REVISIONID}${NETBSD_REVISIONID:+-}${base}@${vcs}:${rid}" 2819 2820 if [ -z "$t" ] 2821 then 2822 bomb "Failed to get timestamp for vcs=$vcs in '$d'" 2823 fi 2824 2825 #echo "latest $d $vcs $t" 2826 if [ "$t" -gt "$MKREPRO_TIMESTAMP" ] 2827 then 2828 MKREPRO_TIMESTAMP="$t" 2829 fi 2830 done 2831 2832 [ "${MKREPRO_TIMESTAMP}" -ne 0 ] || bomb "Failed to compute timestamp" 2833 if [ -z "${quiet}" ] 2834 then 2835 statusmsg2 "MKREPRO_TIMESTAMP" \ 2836 "$(repro_date "${MKREPRO_TIMESTAMP}")" 2837 fi 2838 export MKREPRO MKREPRO_TIMESTAMP NETBSD_REVISIONID 2839 } 2840 2841 main() 2842 { 2843 initdefaults 2844 _args=$* 2845 parseoptions "$@" 2846 2847 sanitycheck 2848 2849 build_start=$(date) 2850 statusmsg2 "${progname} command:" "$0 $*" 2851 statusmsg2 "${progname} started:" "${build_start}" 2852 statusmsg2 "NetBSD version:" "${DISTRIBVER}" 2853 statusmsg2 "MACHINE:" "${MACHINE}" 2854 statusmsg2 "MACHINE_ARCH:" "${MACHINE_ARCH}" 2855 statusmsg2 "Build platform:" "${uname_s} ${uname_r} ${uname_m}" 2856 statusmsg2 "HOST_SH:" "${HOST_SH}" 2857 if [ -n "${BUILDID}" ] 2858 then 2859 statusmsg2 BUILDID: "${BUILDID}" 2860 fi 2861 if [ -n "${BUILDINFO}" ] 2862 then 2863 printf "%b\n" "${BUILDINFO}" | 2864 while read -r line 2865 do 2866 [ -s "${line}" ] && continue 2867 statusmsg2 BUILDINFO: "${line}" 2868 done 2869 fi 2870 2871 if [ -n "${MAKECONF+1}" ] && [ -z "${MAKECONF}" ] 2872 then 2873 bomb "MAKECONF must not be empty" 2874 fi 2875 2876 rebuildmake 2877 validatemakeparams "$@" 2878 createmakewrapper 2879 setup_mkrepro 2880 2881 # Perform the operations. 2882 # 2883 for op in ${operations} 2884 do 2885 case "${op}" in 2886 2887 makewrapper) 2888 # no-op 2889 ;; 2890 2891 tools) 2892 buildtools 2893 ;; 2894 libs) 2895 buildlibs 2896 ;; 2897 2898 sets) 2899 statusmsg "Building sets from pre-populated ${DESTDIR}" 2900 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2901 bomb "Failed to make ${op}" 2902 setdir=${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/sets 2903 statusmsg "Built sets to ${setdir}" 2904 ;; 2905 2906 build|distribution|release) 2907 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2908 bomb "Failed to make ${op}" 2909 statusmsg "Successful make ${op}" 2910 ;; 2911 2912 cleandir|obj|sourcesets|syspkgs|params|show-params) 2913 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2914 bomb "Failed to make ${op}" 2915 statusmsg "Successful make ${op}" 2916 ;; 2917 2918 iso-image|iso-image-source) 2919 ${runcmd} "${makewrapper}" ${parallel} \ 2920 CDEXTRA="$CDEXTRA" ${op} || 2921 bomb "Failed to make ${op}" 2922 statusmsg "Successful make ${op}" 2923 ;; 2924 2925 live-image|install-image) 2926 # install-image and live-image require mtree spec files 2927 # built with MKUNPRIVED. Assume MKUNPRIVED build has 2928 # been performed if METALOG file is created in DESTDIR. 2929 if [ ! -e "${DESTDIR}/METALOG" ] 2930 then 2931 bomb "The release binaries must have been" \ 2932 "built with -U to create images" 2933 fi 2934 ${runcmd} "${makewrapper}" ${parallel} ${op} || 2935 bomb "Failed to make ${op}" 2936 statusmsg "Successful make ${op}" 2937 ;; 2938 kernel=*) 2939 arg=${op#*=} 2940 buildkernel "${arg}" 2941 ;; 2942 kernel.gdb=*) 2943 arg=${op#*=} 2944 configopts="-D DEBUG=-g" 2945 buildkernel "${arg}" 2946 ;; 2947 releasekernel=*) 2948 arg=${op#*=} 2949 releasekernel "${arg}" 2950 ;; 2951 2952 kernels) 2953 buildkernels 2954 ;; 2955 2956 disk-image=*) 2957 arg=${op#*=} 2958 diskimage "${arg}" 2959 ;; 2960 2961 dtb) 2962 builddtb 2963 ;; 2964 2965 modules) 2966 buildmodules 2967 ;; 2968 2969 pkg=*) 2970 arg=${op#*=} 2971 if ! [ -d "${PKGSRCDIR}/${arg}" ] 2972 then 2973 bomb "no such package ${arg}" 2974 fi 2975 buildpkg "${arg}" 2976 ;; 2977 2978 installmodules=*) 2979 arg=${op#*=} 2980 if [ "${arg}" = / ] && { 2981 [ "${uname_s}" != NetBSD ] || 2982 [ "${uname_m}" != "${MACHINE}" ] 2983 } 2984 then 2985 bomb "'${op}' must != / for cross builds" 2986 fi 2987 installmodules "${arg}" 2988 ;; 2989 2990 install=*) 2991 arg=${op#*=} 2992 if [ "${arg}" = / ] && { 2993 [ "${uname_s}" != NetBSD ] || 2994 [ "${uname_m}" != "${MACHINE}" ] 2995 } 2996 then 2997 bomb "'${op}' must != / for cross builds" 2998 fi 2999 installworld "${arg}" 3000 ;; 3001 3002 rump) 3003 make_in_dir . do-distrib-dirs 3004 make_in_dir . includes 3005 make_in_dir lib/csu dependall 3006 make_in_dir lib/csu install 3007 make_in_dir external/gpl3/gcc/lib/libgcc dependall 3008 make_in_dir external/gpl3/gcc/lib/libgcc install 3009 dorump "${op}" 3010 ;; 3011 3012 rumptest) 3013 dorump "${op}" 3014 ;; 3015 3016 *) 3017 bomb "Unknown OPERATION '${op}'" 3018 ;; 3019 3020 esac 3021 done 3022 3023 statusmsg2 "${progname} ended:" "$(date)" 3024 if [ -s "${results}" ] 3025 then 3026 echo "===> Summary of results:" 3027 sed -e 's/^===>//;s/^/ /' "${results}" 3028 echo "===> ." 3029 fi 3030 } 3031 3032 main "$@" 3033