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