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