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