build.sh revision 1.399 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