build.sh revision 1.248 1 #! /usr/bin/env sh
2 # $NetBSD: build.sh,v 1.248 2011/09/09 13:29:23 apb Exp $
3 #
4 # Copyright (c) 2001-2011 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, for a system containing no tools.
33 #
34 # This script should run on any POSIX-compliant shell. If the
35 # first "sh" found in the PATH is a POSIX-compliant shell, then
36 # you should not need to take any special action. Otherwise, you
37 # should set the environment variable HOST_SH to a POSIX-compliant
38 # shell, and invoke build.sh with that shell. (Depending on your
39 # system, one of /bin/ksh, /usr/local/bin/bash, or /usr/xpg4/bin/sh
40 # might be a suitable shell.)
41 #
42
43 progname=${0##*/}
44 toppid=$$
45 results=/dev/null
46 tab=' '
47 trap "exit 1" 1 2 3 15
48
49 bomb()
50 {
51 cat >&2 <<ERRORMESSAGE
52
53 ERROR: $@
54 *** BUILD ABORTED ***
55 ERRORMESSAGE
56 kill ${toppid} # in case we were invoked from a subshell
57 exit 1
58 }
59
60
61 statusmsg()
62 {
63 ${runcmd} echo "===> $@" | tee -a "${results}"
64 }
65
66 statusmsg2()
67 {
68 local msg
69
70 msg="${1}"
71 shift
72 case "${msg}" in
73 ????????????????*) ;;
74 ??????????*) msg="${msg} ";;
75 ?????*) msg="${msg} ";;
76 *) msg="${msg} ";;
77 esac
78 case "${msg}" in
79 ?????????????????????*) ;;
80 ????????????????????) msg="${msg} ";;
81 ???????????????????) msg="${msg} ";;
82 ??????????????????) msg="${msg} ";;
83 ?????????????????) msg="${msg} ";;
84 ????????????????) msg="${msg} ";;
85 esac
86 statusmsg "${msg}$*"
87 }
88
89 warning()
90 {
91 statusmsg "Warning: $@"
92 }
93
94 # Find a program in the PATH, and print the result. If not found,
95 # print a default. If $2 is defined (even if it is an empty string),
96 # then that is the default; otherwise, $1 is used as the default.
97 find_in_PATH()
98 {
99 local prog="$1"
100 local result="${2-"$1"}"
101 local oldIFS="${IFS}"
102 local dir
103 IFS=":"
104 for dir in ${PATH}; do
105 if [ -x "${dir}/${prog}" ]; then
106 result="${dir}/${prog}"
107 break
108 fi
109 done
110 IFS="${oldIFS}"
111 echo "${result}"
112 }
113
114 # Try to find a working POSIX shell, and set HOST_SH to refer to it.
115 # Assumes that uname_s, uname_m, and PWD have been set.
116 set_HOST_SH()
117 {
118 # Even if ${HOST_SH} is already defined, we still do the
119 # sanity checks at the end.
120
121 # Solaris has /usr/xpg4/bin/sh.
122 #
123 [ -z "${HOST_SH}" ] && [ x"${uname_s}" = x"SunOS" ] && \
124 [ -x /usr/xpg4/bin/sh ] && HOST_SH="/usr/xpg4/bin/sh"
125
126 # Try to get the name of the shell that's running this script,
127 # by parsing the output from "ps". We assume that, if the host
128 # system's ps command supports -o comm at all, it will do so
129 # in the usual way: a one-line header followed by a one-line
130 # result, possibly including trailing white space. And if the
131 # host system's ps command doesn't support -o comm, we assume
132 # that we'll get an error message on stderr and nothing on
133 # stdout. (We don't try to use ps -o 'comm=' to suppress the
134 # header line, because that is less widely supported.)
135 #
136 # If we get the wrong result here, the user can override it by
137 # specifying HOST_SH in the environment.
138 #
139 [ -z "${HOST_SH}" ] && HOST_SH="$(
140 (ps -p $$ -o comm | sed -ne "2s/[ ${tab}]*\$//p") 2>/dev/null )"
141
142 # If nothing above worked, use "sh". We will later find the
143 # first directory in the PATH that has a "sh" program.
144 #
145 [ -z "${HOST_SH}" ] && HOST_SH="sh"
146
147 # If the result so far is not an absolute path, try to prepend
148 # PWD or search the PATH.
149 #
150 case "${HOST_SH}" in
151 /*) :
152 ;;
153 */*) HOST_SH="${PWD}/${HOST_SH}"
154 ;;
155 *) HOST_SH="$(find_in_PATH "${HOST_SH}")"
156 ;;
157 esac
158
159 # If we don't have an absolute path by now, bomb.
160 #
161 case "${HOST_SH}" in
162 /*) :
163 ;;
164 *) bomb "HOST_SH=\"${HOST_SH}\" is not an absolute path."
165 ;;
166 esac
167
168 # If HOST_SH is not executable, bomb.
169 #
170 [ -x "${HOST_SH}" ] ||
171 bomb "HOST_SH=\"${HOST_SH}\" is not executable."
172 }
173
174 # initdefaults --
175 # Set defaults before parsing command line options.
176 #
177 initdefaults()
178 {
179 makeenv=
180 makewrapper=
181 makewrappermachine=
182 runcmd=
183 operations=
184 removedirs=
185
186 [ -d usr.bin/make ] || cd "$(dirname $0)"
187 [ -d usr.bin/make ] ||
188 bomb "build.sh must be run from the top source level"
189 [ -f share/mk/bsd.own.mk ] ||
190 bomb "src/share/mk is missing; please re-fetch the source tree"
191
192 # Set various environment variables to known defaults,
193 # to minimize (cross-)build problems observed "in the field".
194 #
195 # LC_ALL=C must be set before we try to parse the output from
196 # any command. Other variables are set (or unset) here, before
197 # we parse command line arguments.
198 #
199 # These variables can be overridden via "-V var=value" if
200 # you know what you are doing.
201 #
202 unsetmakeenv INFODIR
203 unsetmakeenv LESSCHARSET
204 unsetmakeenv MAKEFLAGS
205 setmakeenv LC_ALL C
206
207 # Find information about the build platform. This should be
208 # kept in sync with _HOST_OSNAME, _HOST_OSREL, and _HOST_ARCH
209 # variables in share/mk/bsd.sys.mk.
210 #
211 # Note that "uname -p" is not part of POSIX, but we want uname_p
212 # to be set to the host MACHINE_ARCH, if possible. On systems
213 # where "uname -p" fails, prints "unknown", or prints a string
214 # that does not look like an identifier, fall back to using the
215 # output from "uname -m" instead.
216 #
217 uname_s=$(uname -s 2>/dev/null)
218 uname_r=$(uname -r 2>/dev/null)
219 uname_m=$(uname -m 2>/dev/null)
220 uname_p=$(uname -p 2>/dev/null || echo "unknown")
221 case "${uname_p}" in
222 ''|unknown|*[^-_A-Za-z0-9]*) uname_p="${uname_m}" ;;
223 esac
224
225 id_u=$(id -u 2>/dev/null || /usr/xpg4/bin/id -u 2>/dev/null)
226
227 # If $PWD is a valid name of the current directory, POSIX mandates
228 # that pwd return it by default which causes problems in the
229 # presence of symlinks. Unsetting PWD is simpler than changing
230 # every occurrence of pwd to use -P.
231 #
232 # XXX Except that doesn't work on Solaris. Or many Linuces.
233 #
234 unset PWD
235 TOP=$(/bin/pwd -P 2>/dev/null || /bin/pwd 2>/dev/null)
236
237 # The user can set HOST_SH in the environment, or we try to
238 # guess an appropriate value. Then we set several other
239 # variables from HOST_SH.
240 #
241 set_HOST_SH
242 setmakeenv HOST_SH "${HOST_SH}"
243 setmakeenv BSHELL "${HOST_SH}"
244 setmakeenv CONFIG_SHELL "${HOST_SH}"
245
246 # Set defaults.
247 #
248 toolprefix=nb
249
250 # Some systems have a small ARG_MAX. -X prevents make(1) from
251 # exporting variables in the environment redundantly.
252 #
253 case "${uname_s}" in
254 Darwin | FreeBSD | CYGWIN*)
255 MAKEFLAGS="-X ${MAKEFLAGS}"
256 ;;
257 esac
258
259 # do_{operation}=true if given operation is requested.
260 #
261 do_expertmode=false
262 do_rebuildmake=false
263 do_removedirs=false
264 do_tools=false
265 do_cleandir=false
266 do_obj=false
267 do_build=false
268 do_distribution=false
269 do_release=false
270 do_kernel=false
271 do_releasekernel=false
272 do_modules=false
273 do_installmodules=false
274 do_install=false
275 do_sets=false
276 do_sourcesets=false
277 do_syspkgs=false
278 do_iso_image=false
279 do_iso_image_source=false
280 do_params=false
281 do_rump=false
282
283 # done_{operation}=true if given operation has been done.
284 #
285 done_rebuildmake=false
286
287 # Create scratch directory
288 #
289 tmpdir="${TMPDIR-/tmp}/nbbuild$$"
290 mkdir "${tmpdir}" || bomb "Cannot mkdir: ${tmpdir}"
291 trap "cd /; rm -r -f \"${tmpdir}\"" 0
292 results="${tmpdir}/build.sh.results"
293
294 # Set source directories
295 #
296 setmakeenv NETBSDSRCDIR "${TOP}"
297
298 # Make sure KERNOBJDIR is an absolute path if defined
299 #
300 case "${KERNOBJDIR}" in
301 ''|/*) ;;
302 *) KERNOBJDIR="${TOP}/${KERNOBJDIR}"
303 setmakeenv KERNOBJDIR "${KERNOBJDIR}"
304 ;;
305 esac
306
307 # Find the version of NetBSD
308 #
309 DISTRIBVER="$(${HOST_SH} ${TOP}/sys/conf/osrelease.sh)"
310
311 # Set the BUILDSEED to NetBSD-"N"
312 #
313 setmakeenv BUILDSEED "NetBSD-$(${HOST_SH} ${TOP}/sys/conf/osrelease.sh -m)"
314
315 # Set MKARZERO to "yes"
316 #
317 setmakeenv MKARZERO "yes"
318
319 }
320
321 getarch()
322 {
323 # Translate some MACHINE name aliases (known only to build.sh)
324 # into proper MACHINE and MACHINE_ARCH names. Save the alias
325 # name in makewrappermachine.
326 #
327 case "${MACHINE}" in
328
329 evbarm-e[bl])
330 makewrappermachine=${MACHINE}
331 # MACHINE_ARCH is "arm" or "armeb", not "armel"
332 MACHINE_ARCH=arm${MACHINE##*-}
333 MACHINE_ARCH=${MACHINE_ARCH%el}
334 MACHINE=${MACHINE%-e[bl]}
335 ;;
336
337 evbmips-e[bl]|sbmips-e[bl])
338 makewrappermachine=${MACHINE}
339 MACHINE_ARCH=mips${MACHINE##*-}
340 MACHINE=${MACHINE%-e[bl]}
341 ;;
342
343 evbmips64-e[bl]|sbmips64-e[bl])
344 makewrappermachine=${MACHINE}
345 MACHINE_ARCH=mips64${MACHINE##*-}
346 MACHINE=${MACHINE%64-e[bl]}
347 ;;
348
349 evbsh3-e[bl])
350 makewrappermachine=${MACHINE}
351 MACHINE_ARCH=sh3${MACHINE##*-}
352 MACHINE=${MACHINE%-e[bl]}
353 ;;
354
355 esac
356
357 # Translate a MACHINE into a default MACHINE_ARCH.
358 #
359 case "${MACHINE}" in
360
361 acorn26|acorn32|cats|hpcarm|iyonix|netwinder|shark|zaurus)
362 MACHINE_ARCH=arm
363 ;;
364
365 evbarm) # unspecified MACHINE_ARCH gets LE
366 MACHINE_ARCH=${MACHINE_ARCH:=arm}
367 ;;
368
369 hp700)
370 MACHINE_ARCH=hppa
371 ;;
372
373 sun2)
374 MACHINE_ARCH=m68000
375 ;;
376
377 amiga|atari|cesfic|hp300|luna68k|mac68k|mvme68k|news68k|next68k|sun3|x68k)
378 MACHINE_ARCH=m68k
379 ;;
380
381 evbmips|sbmips) # no default MACHINE_ARCH
382 ;;
383
384 sgimips64)
385 makewrappermachine=${MACHINE}
386 MACHINE=${MACHINE%64}
387 MACHINE_ARCH=mips64eb
388 ;;
389
390 ews4800mips|mipsco|newsmips|sgimips|emips)
391 MACHINE_ARCH=mipseb
392 ;;
393
394 algor64|arc64|cobalt64|pmax64)
395 makewrappermachine=${MACHINE}
396 MACHINE=${MACHINE%64}
397 MACHINE_ARCH=mips64el
398 ;;
399
400 algor|arc|cobalt|hpcmips|pmax)
401 MACHINE_ARCH=mipsel
402 ;;
403
404 evbppc64|macppc64|ofppc64)
405 makewrappermachine=${MACHINE}
406 MACHINE=${MACHINE%64}
407 MACHINE_ARCH=powerpc64
408 ;;
409
410 amigappc|bebox|evbppc|ibmnws|macppc|mvmeppc|ofppc|prep|rs6000|sandpoint)
411 MACHINE_ARCH=powerpc
412 ;;
413
414 evbsh3) # no default MACHINE_ARCH
415 ;;
416
417 mmeye)
418 MACHINE_ARCH=sh3eb
419 ;;
420
421 dreamcast|hpcsh|landisk)
422 MACHINE_ARCH=sh3el
423 ;;
424
425 amd64)
426 MACHINE_ARCH=x86_64
427 ;;
428
429 alpha|i386|sparc|sparc64|vax|ia64)
430 MACHINE_ARCH=${MACHINE}
431 ;;
432
433 *)
434 bomb "Unknown target MACHINE: ${MACHINE}"
435 ;;
436
437 esac
438 }
439
440 validatearch()
441 {
442 # Ensure that the MACHINE_ARCH exists (and is supported by build.sh).
443 #
444 case "${MACHINE_ARCH}" in
445
446 alpha|arm|armeb|hppa|i386|m68000|m68k|mipse[bl]|mips64e[bl]|powerpc|powerpc64|sh3e[bl]|sparc|sparc64|vax|x86_64|ia64)
447 ;;
448
449 "")
450 bomb "No MACHINE_ARCH provided"
451 ;;
452
453 *)
454 bomb "Unknown target MACHINE_ARCH: ${MACHINE_ARCH}"
455 ;;
456
457 esac
458
459 # Determine valid MACHINE_ARCHs for MACHINE
460 #
461 case "${MACHINE}" in
462
463 evbarm)
464 arches="arm armeb"
465 ;;
466
467 algor|arc|cobalt|pmax)
468 arches="mipsel mips64el"
469 ;;
470
471 evbmips|sbmips)
472 arches="mipseb mipsel mips64eb mips64el"
473 ;;
474
475 sgimips)
476 arches="mipseb mips64eb"
477 ;;
478
479 evbsh3)
480 arches="sh3eb sh3el"
481 ;;
482
483 macppc|evbppc|ofppc)
484 arches="powerpc powerpc64"
485 ;;
486 *)
487 oma="${MACHINE_ARCH}"
488 getarch
489 arches="${MACHINE_ARCH}"
490 MACHINE_ARCH="${oma}"
491 ;;
492
493 esac
494
495 # Ensure that MACHINE_ARCH supports MACHINE
496 #
497 archok=false
498 for a in ${arches}; do
499 if [ "${a}" = "${MACHINE_ARCH}" ]; then
500 archok=true
501 break
502 fi
503 done
504 ${archok} ||
505 bomb "MACHINE_ARCH '${MACHINE_ARCH}' does not support MACHINE '${MACHINE}'"
506 }
507
508 # nobomb_getmakevar --
509 # Given the name of a make variable in $1, print make's idea of the
510 # value of that variable, or return 1 if there's an error.
511 #
512 nobomb_getmakevar()
513 {
514 [ -x "${make}" ] || return 1
515 "${make}" -m ${TOP}/share/mk -s -B -f- _x_ <<EOF || return 1
516 _x_:
517 echo \${$1}
518 .include <bsd.prog.mk>
519 .include <bsd.kernobj.mk>
520 EOF
521 }
522
523 # nobomb_getmakevar --
524 # Given the name of a make variable in $1, print make's idea of the
525 # value of that variable, or bomb if there's an error.
526 #
527 bomb_getmakevar()
528 {
529 [ -x "${make}" ] || bomb "bomb_getmakevar $1: ${make} is not executable"
530 nobomb_getmakevar "$1" || bomb "bomb_getmakevar $1: ${make} failed"
531 }
532
533 # nobomb_getmakevar --
534 # Given the name of a make variable in $1, print make's idea of the
535 # value of that variable, or print a literal '$' followed by the
536 # variable name if ${make} is not executable. This is intended for use in
537 # messages that need to be readable even if $make hasn't been built,
538 # such as when build.sh is run with the "-n" option.
539 #
540 getmakevar()
541 {
542 if [ -x "${make}" ]; then
543 bomb_getmakevar "$1"
544 else
545 echo "\$$1"
546 fi
547 }
548
549 setmakeenv()
550 {
551 eval "$1='$2'; export $1"
552 makeenv="${makeenv} $1"
553 }
554
555 unsetmakeenv()
556 {
557 eval "unset $1"
558 makeenv="${makeenv} $1"
559 }
560
561 # Given a variable name in $1, modify the variable in place as follows:
562 # For each space-separated word in the variable, call resolvepath.
563 resolvepaths()
564 {
565 local var="$1"
566 local val
567 eval val=\"\${${var}}\"
568 local newval=''
569 local word
570 for word in ${val}; do
571 resolvepath word
572 newval="${newval}${newval:+ }${word}"
573 done
574 eval ${var}=\"\${newval}\"
575 }
576
577 # Given a variable name in $1, modify the variable in place as follows:
578 # Convert possibly-relative path to absolute path by prepending
579 # ${TOP} if necessary. Also delete trailing "/", if any.
580 resolvepath()
581 {
582 local var="$1"
583 local val
584 eval val=\"\${${var}}\"
585 case "${val}" in
586 /)
587 ;;
588 /*)
589 val="${val%/}"
590 ;;
591 *)
592 val="${TOP}/${val%/}"
593 ;;
594 esac
595 eval ${var}=\"\${val}\"
596 }
597
598 usage()
599 {
600 if [ -n "$*" ]; then
601 echo ""
602 echo "${progname}: $*"
603 fi
604 cat <<_usage_
605
606 Usage: ${progname} [-EhnorUuxy] [-a arch] [-B buildid] [-C cdextras]
607 [-D dest] [-j njob] [-M obj] [-m mach] [-N noisy]
608 [-O obj] [-R release] [-S seed] [-T tools]
609 [-V var=[value]] [-w wrapper] [-X x11src] [-Y extsrcsrc]
610 [-Z var]
611 operation [...]
612
613 Build operations (all imply "obj" and "tools"):
614 build Run "make build".
615 distribution Run "make distribution" (includes DESTDIR/etc/ files).
616 release Run "make release" (includes kernels & distrib media).
617
618 Other operations:
619 help Show this message and exit.
620 makewrapper Create ${toolprefix}make-\${MACHINE} wrapper and ${toolprefix}make.
621 Always performed.
622 cleandir Run "make cleandir". [Default unless -u is used]
623 obj Run "make obj". [Default unless -o is used]
624 tools Build and install tools.
625 install=idir Run "make installworld" to \`idir' to install all sets
626 except \`etc'. Useful after "distribution" or "release"
627 kernel=conf Build kernel with config file \`conf'
628 releasekernel=conf Install kernel built by kernel=conf to RELEASEDIR.
629 installmodules=idir Run "make installmodules" to \`idir' to install all
630 kernel modules.
631 modules Build kernel modules.
632 rumptest Do a linktest for rump (for developers).
633 sets Create binary sets in
634 RELEASEDIR/RELEASEMACHINEDIR/binary/sets.
635 DESTDIR should be populated beforehand.
636 sourcesets Create source sets in RELEASEDIR/source/sets.
637 syspkgs Create syspkgs in
638 RELEASEDIR/RELEASEMACHINEDIR/binary/syspkgs.
639 iso-image Create CD-ROM image in RELEASEDIR/iso.
640 iso-image-source Create CD-ROM image with source in RELEASEDIR/iso.
641 params Display various make(1) parameters.
642
643 Options:
644 -a arch Set MACHINE_ARCH to arch. [Default: deduced from MACHINE]
645 -B buildid Set BUILDID to buildid.
646 -C cdextras Append cdextras to CDEXTRA variable for inclusion on CD-ROM.
647 -D dest Set DESTDIR to dest. [Default: destdir.MACHINE]
648 -E Set "expert" mode; disables various safety checks.
649 Should not be used without expert knowledge of the build system.
650 -h Print this help message.
651 -j njob Run up to njob jobs in parallel; see make(1) -j.
652 -M obj Set obj root directory to obj; sets MAKEOBJDIRPREFIX.
653 Unsets MAKEOBJDIR.
654 -m mach Set MACHINE to mach; not required if NetBSD native.
655 -N noisy Set the noisyness (MAKEVERBOSE) level of the build:
656 0 Minimal output ("quiet")
657 1 Describe what is occurring
658 2 Describe what is occurring and echo the actual command
659 3 Ignore the effect of the "@" prefix in make commands
660 4 Trace shell commands using the shell's -x flag
661 [Default: 2]
662 -n Show commands that would be executed, but do not execute them.
663 -O obj Set obj root directory to obj; sets a MAKEOBJDIR pattern.
664 Unsets MAKEOBJDIRPREFIX.
665 -o Set MKOBJDIRS=no; do not create objdirs at start of build.
666 -R release Set RELEASEDIR to release. [Default: releasedir]
667 -r Remove contents of TOOLDIR and DESTDIR before building.
668 -S seed Set BUILDSEED to seed. [Default: NetBSD-majorversion]
669 -T tools Set TOOLDIR to tools. If unset, and TOOLDIR is not set in
670 the environment, ${toolprefix}make will be (re)built
671 unconditionally.
672 -U Set MKUNPRIVED=yes; build without requiring root privileges,
673 install from an UNPRIVED build with proper file permissions.
674 -u Set MKUPDATE=yes; do not run "make cleandir" first.
675 Without this, everything is rebuilt, including the tools.
676 -V var=[value] Set variable \`var' to \`value'.
677 -w wrapper Create ${toolprefix}make script as wrapper.
678 [Default: \${TOOLDIR}/bin/${toolprefix}make-\${MACHINE}]
679 -X x11src Set X11SRCDIR to x11src. [Default: /usr/xsrc]
680 -x Set MKX11=yes; build X11 from X11SRCDIR
681 -Y extsrcsrc Set EXTSRCSRCDIR to extsrcsrc. [Default: /usr/extsrc]
682 -y Set MKEXTSRC=yes; build extsrc from EXTSRCSRCDIR
683 -Z var Unset ("zap") variable \`var'.
684
685 _usage_
686 exit 1
687 }
688
689 parseoptions()
690 {
691 opts='a:B:C:D:Ehj:M:m:N:nO:oR:rS:T:UuV:w:X:xY:yZ:'
692 opt_a=no
693
694 if type getopts >/dev/null 2>&1; then
695 # Use POSIX getopts.
696 #
697 getoptcmd='getopts ${opts} opt && opt=-${opt}'
698 optargcmd=':'
699 optremcmd='shift $((${OPTIND} -1))'
700 else
701 type getopt >/dev/null 2>&1 ||
702 bomb "/bin/sh shell is too old; try ksh or bash"
703
704 # Use old-style getopt(1) (doesn't handle whitespace in args).
705 #
706 args="$(getopt ${opts} $*)"
707 [ $? = 0 ] || usage
708 set -- ${args}
709
710 getoptcmd='[ $# -gt 0 ] && opt="$1" && shift'
711 optargcmd='OPTARG="$1"; shift'
712 optremcmd=':'
713 fi
714
715 # Parse command line options.
716 #
717 while eval ${getoptcmd}; do
718 case ${opt} in
719
720 -a)
721 eval ${optargcmd}
722 MACHINE_ARCH=${OPTARG}
723 opt_a=yes
724 ;;
725
726 -B)
727 eval ${optargcmd}
728 BUILDID=${OPTARG}
729 ;;
730
731 -C)
732 eval ${optargcmd}; resolvepaths OPTARG
733 CDEXTRA="${CDEXTRA}${CDEXTRA:+ }${OPTARG}"
734 ;;
735
736 -D)
737 eval ${optargcmd}; resolvepath OPTARG
738 setmakeenv DESTDIR "${OPTARG}"
739 ;;
740
741 -E)
742 do_expertmode=true
743 ;;
744
745 -j)
746 eval ${optargcmd}
747 parallel="-j ${OPTARG}"
748 ;;
749
750 -M)
751 eval ${optargcmd}; resolvepath OPTARG
752 case "${OPTARG}" in
753 \$*) usage "-M argument must not begin with '\$'"
754 ;;
755 *\$*) # can use resolvepath, but can't set TOP_objdir
756 resolvepath OPTARG
757 ;;
758 *) resolvepath OPTARG
759 TOP_objdir="${OPTARG}${TOP}"
760 ;;
761 esac
762 unsetmakeenv MAKEOBJDIR
763 setmakeenv MAKEOBJDIRPREFIX "${OPTARG}"
764 ;;
765
766 # -m overrides MACHINE_ARCH unless "-a" is specified
767 -m)
768 eval ${optargcmd}
769 MACHINE="${OPTARG}"
770 [ "${opt_a}" != "yes" ] && getarch
771 ;;
772
773 -N)
774 eval ${optargcmd}
775 case "${OPTARG}" in
776 0|1|2|3|4)
777 setmakeenv MAKEVERBOSE "${OPTARG}"
778 ;;
779 *)
780 usage "'${OPTARG}' is not a valid value for -N"
781 ;;
782 esac
783 ;;
784
785 -n)
786 runcmd=echo
787 ;;
788
789 -O)
790 eval ${optargcmd}
791 case "${OPTARG}" in
792 *\$*) usage "-O argument must not contain '\$'"
793 ;;
794 *) resolvepath OPTARG
795 TOP_objdir="${OPTARG}"
796 ;;
797 esac
798 unsetmakeenv MAKEOBJDIRPREFIX
799 setmakeenv MAKEOBJDIR "\${.CURDIR:C,^$TOP,$OPTARG,}"
800 ;;
801
802 -o)
803 MKOBJDIRS=no
804 ;;
805
806 -R)
807 eval ${optargcmd}; resolvepath OPTARG
808 setmakeenv RELEASEDIR "${OPTARG}"
809 ;;
810
811 -r)
812 do_removedirs=true
813 do_rebuildmake=true
814 ;;
815
816 -S)
817 eval ${optargcmd}
818 setmakeenv BUILDSEED "${OPTARG}"
819 ;;
820
821 -T)
822 eval ${optargcmd}; resolvepath OPTARG
823 TOOLDIR="${OPTARG}"
824 export TOOLDIR
825 ;;
826
827 -U)
828 setmakeenv MKUNPRIVED yes
829 ;;
830
831 -u)
832 setmakeenv MKUPDATE yes
833 ;;
834
835 -V)
836 eval ${optargcmd}
837 case "${OPTARG}" in
838 # XXX: consider restricting which variables can be changed?
839 [a-zA-Z_][a-zA-Z_0-9]*=*)
840 setmakeenv "${OPTARG%%=*}" "${OPTARG#*=}"
841 ;;
842 *)
843 usage "-V argument must be of the form 'var=[value]'"
844 ;;
845 esac
846 ;;
847
848 -w)
849 eval ${optargcmd}; resolvepath OPTARG
850 makewrapper="${OPTARG}"
851 ;;
852
853 -X)
854 eval ${optargcmd}; resolvepath OPTARG
855 setmakeenv X11SRCDIR "${OPTARG}"
856 ;;
857
858 -x)
859 setmakeenv MKX11 yes
860 ;;
861
862 -Y)
863 eval ${optargcmd}; resolvepath OPTARG
864 setmakeenv EXTSRCSRCDIR "${OPTARG}"
865 ;;
866
867 -y)
868 setmakeenv MKEXTSRC yes
869 ;;
870
871 -Z)
872 eval ${optargcmd}
873 # XXX: consider restricting which variables can be unset?
874 unsetmakeenv "${OPTARG}"
875 ;;
876
877 --)
878 break
879 ;;
880
881 -'?'|-h)
882 usage
883 ;;
884
885 esac
886 done
887
888 # Validate operations.
889 #
890 eval ${optremcmd}
891 while [ $# -gt 0 ]; do
892 op=$1; shift
893 operations="${operations} ${op}"
894
895 case "${op}" in
896
897 help)
898 usage
899 ;;
900
901 makewrapper|cleandir|obj|tools|build|distribution|release|sets|sourcesets|syspkgs|params)
902 ;;
903
904 iso-image)
905 op=iso_image # used as part of a variable name
906 ;;
907
908 iso-image-source)
909 op=iso_image_source # used as part of a variable name
910 ;;
911
912 kernel=*|releasekernel=*)
913 arg=${op#*=}
914 op=${op%%=*}
915 [ -n "${arg}" ] ||
916 bomb "Must supply a kernel name with \`${op}=...'"
917 ;;
918
919 modules)
920 op=modules
921 ;;
922
923 install=*|installmodules=*)
924 arg=${op#*=}
925 op=${op%%=*}
926 [ -n "${arg}" ] ||
927 bomb "Must supply a directory with \`install=...'"
928 ;;
929
930 rump|rumptest)
931 op=${op}
932 ;;
933
934 *)
935 usage "Unknown operation \`${op}'"
936 ;;
937
938 esac
939 eval do_${op}=true
940 done
941 [ -n "${operations}" ] || usage "Missing operation to perform."
942
943 # Set up MACHINE*. On a NetBSD host, these are allowed to be unset.
944 #
945 if [ -z "${MACHINE}" ]; then
946 [ "${uname_s}" = "NetBSD" ] ||
947 bomb "MACHINE must be set, or -m must be used, for cross builds."
948 MACHINE=${uname_m}
949 fi
950 [ -n "${MACHINE_ARCH}" ] || getarch
951 validatearch
952
953 # Set up default make(1) environment.
954 #
955 makeenv="${makeenv} TOOLDIR MACHINE MACHINE_ARCH MAKEFLAGS"
956 [ -z "${BUILDID}" ] || makeenv="${makeenv} BUILDID"
957 MAKEFLAGS="-de -m ${TOP}/share/mk ${MAKEFLAGS}"
958 MAKEFLAGS="${MAKEFLAGS} MKOBJDIRS=${MKOBJDIRS-yes}"
959 export MAKEFLAGS MACHINE MACHINE_ARCH
960 }
961
962 # sanitycheck --
963 # Sanity check after parsing command line options, before rebuildmake.
964 #
965 sanitycheck()
966 {
967 # If the PATH contains any non-absolute components (including,
968 # but not limited to, "." or ""), then complain. As an exception,
969 # allow "" or "." as the last component of the PATH. This is fatal
970 # if expert mode is not in effect.
971 #
972 local path="${PATH}"
973 path="${path%:}" # delete trailing ":"
974 path="${path%:.}" # delete trailing ":."
975 case ":${path}:/" in
976 *:[!/]*)
977 if ${do_expertmode}; then
978 warning "PATH contains non-absolute components"
979 else
980 bomb "PATH environment variable must not" \
981 "contain non-absolute components"
982 fi
983 ;;
984 esac
985 }
986
987 # print_tooldir_make --
988 # Try to find and print a path to an existing
989 # ${TOOLDIR}/bin/${toolprefix}make, for use by rebuildmake() before a
990 # new version of ${toolprefix}make has been built.
991 #
992 # * If TOOLDIR was set in the environment or on the command line, use
993 # that value.
994 # * Otherwise try to guess what TOOLDIR would be if not overridden by
995 # /etc/mk.conf, and check whether the resulting directory contains
996 # a copy of ${toolprefix}make (this should work for everybody who
997 # doesn't override TOOLDIR via /etc/mk.conf);
998 # * Failing that, search for ${toolprefix}make, nbmake, bmake, or make,
999 # in the PATH (this might accidentally find a non-NetBSD version of
1000 # make, which will lead to failure in the next step);
1001 # * If a copy of make was found above, try to use it with
1002 # nobomb_getmakevar to find the correct value for TOOLDIR, and believe the
1003 # result only if it's a directory that already exists;
1004 # * If a value of TOOLDIR was found above, and if
1005 # ${TOOLDIR}/bin/${toolprefix}make exists, print that value.
1006 #
1007 print_tooldir_make()
1008 {
1009 local possible_TOP_OBJ
1010 local possible_TOOLDIR
1011 local possible_make
1012 local tooldir_make
1013
1014 if [ -n "${TOOLDIR}" ]; then
1015 echo "${TOOLDIR}/bin/${toolprefix}make"
1016 return 0
1017 fi
1018
1019 # Set host_ostype to something like "NetBSD-4.5.6-i386". This
1020 # is intended to match the HOST_OSTYPE variable in <bsd.own.mk>.
1021 #
1022 local host_ostype="${uname_s}-$(
1023 echo "${uname_r}" | sed -e 's/([^)]*)//g' -e 's/ /_/g'
1024 )-$(
1025 echo "${uname_p}" | sed -e 's/([^)]*)//g' -e 's/ /_/g'
1026 )"
1027
1028 # Look in a few potential locations for
1029 # ${possible_TOOLDIR}/bin/${toolprefix}make.
1030 # If we find it, then set possible_make.
1031 #
1032 # In the usual case (without interference from environment
1033 # variables or /etc/mk.conf), <bsd.own.mk> should set TOOLDIR to
1034 # "${_SRC_TOP_OBJ_}/tooldir.${host_ostype}".
1035 #
1036 # In practice it's difficult to figure out the correct value
1037 # for _SRC_TOP_OBJ_. In the easiest case, when the -M or -O
1038 # options were passed to build.sh, then ${TOP_objdir} will be
1039 # the correct value. We also try a few other possibilities, but
1040 # we do not replicate all the logic of <bsd.obj.mk>.
1041 #
1042 for possible_TOP_OBJ in \
1043 "${TOP_objdir}" \
1044 "${MAKEOBJDIRPREFIX:+${MAKEOBJDIRPREFIX}${TOP}}" \
1045 "${TOP}" \
1046 "${TOP}/obj" \
1047 "${TOP}/obj.${MACHINE}"
1048 do
1049 [ -n "${possible_TOP_OBJ}" ] || continue
1050 possible_TOOLDIR="${possible_TOP_OBJ}/tooldir.${host_ostype}"
1051 possible_make="${possible_TOOLDIR}/bin/${toolprefix}make"
1052 if [ -x "${possible_make}" ]; then
1053 break
1054 else
1055 unset possible_make
1056 fi
1057 done
1058
1059 # If the above didn't work, search the PATH for a suitable
1060 # ${toolprefix}make, nbmake, bmake, or make.
1061 #
1062 : ${possible_make:=$(find_in_PATH ${toolprefix}make '')}
1063 : ${possible_make:=$(find_in_PATH nbmake '')}
1064 : ${possible_make:=$(find_in_PATH bmake '')}
1065 : ${possible_make:=$(find_in_PATH make '')}
1066
1067 # At this point, we don't care whether possible_make is in the
1068 # correct TOOLDIR or not; we simply want it to be usable by
1069 # getmakevar to help us find the correct TOOLDIR.
1070 #
1071 # Use ${possible_make} with nobomb_getmakevar to try to find
1072 # the value of TOOLDIR. Believe the result only if it's
1073 # a directory that already exists and contains bin/${toolprefix}make.
1074 #
1075 if [ -x "${possible_make}" ]; then
1076 possible_TOOLDIR="$(
1077 make="${possible_make}" nobomb_getmakevar TOOLDIR
1078 )"
1079 if [ $? = 0 ] && [ -n "${possible_TOOLDIR}" ] \
1080 && [ -d "${possible_TOOLDIR}" ];
1081 then
1082 tooldir_make="${possible_TOOLDIR}/bin/${toolprefix}make"
1083 if [ -x "${tooldir_make}" ]; then
1084 echo "${tooldir_make}"
1085 return 0
1086 fi
1087 fi
1088 fi
1089 return 1
1090 }
1091
1092 # rebuildmake --
1093 # Rebuild nbmake in a temporary directory if necessary. Sets $make
1094 # to a path to the nbmake executable. Sets done_rebuildmake=true
1095 # if nbmake was rebuilt.
1096 #
1097 # There is a cyclic dependency between building nbmake and choosing
1098 # TOOLDIR: TOOLDIR may be affected by settings in /etc/mk.conf, so we
1099 # would like to use getmakevar to get the value of TOOLDIR; but we can't
1100 # use getmakevar before we have an up to date version of nbmake; we
1101 # might already have an up to date version of nbmake in TOOLDIR, but we
1102 # don't yet know where TOOLDIR is.
1103 #
1104 # The default value of TOOLDIR also depends on the location of the top
1105 # level object directory, so $(getmakevar TOOLDIR) invoked before or
1106 # after making the top level object directory may produce different
1107 # results.
1108 #
1109 # Strictly speaking, we should do the following:
1110 #
1111 # 1. build a new version of nbmake in a temporary directory;
1112 # 2. use the temporary nbmake to create the top level obj directory;
1113 # 3. use $(getmakevar TOOLDIR) with the temporary nbmake to
1114 # get the corect value of TOOLDIR;
1115 # 4. move the temporary nbmake to ${TOOLDIR}/bin/nbmake.
1116 #
1117 # However, people don't like building nbmake unnecessarily if their
1118 # TOOLDIR has not changed since an earlier build. We try to avoid
1119 # rebuilding a temporary version of nbmake by taking some shortcuts to
1120 # guess a value for TOOLDIR, looking for an existing version of nbmake
1121 # in that TOOLDIR, and checking whether that nbmake is newer than the
1122 # sources used to build it.
1123 #
1124 rebuildmake()
1125 {
1126 make="$(print_tooldir_make)"
1127 if [ -n "${make}" ] && [ -x "${make}" ]; then
1128 for f in usr.bin/make/*.[ch] usr.bin/make/lst.lib/*.[ch]; do
1129 if [ "${f}" -nt "${make}" ]; then
1130 statusmsg "${make} outdated" \
1131 "(older than ${f}), needs building."
1132 do_rebuildmake=true
1133 break
1134 fi
1135 done
1136 else
1137 statusmsg "No \$TOOLDIR/bin/${toolprefix}make, needs building."
1138 do_rebuildmake=true
1139 fi
1140
1141 # Build bootstrap ${toolprefix}make if needed.
1142 if ${do_rebuildmake}; then
1143 statusmsg "Bootstrapping ${toolprefix}make"
1144 ${runcmd} cd "${tmpdir}"
1145 ${runcmd} env CC="${HOST_CC-cc}" CPPFLAGS="${HOST_CPPFLAGS}" \
1146 CFLAGS="${HOST_CFLAGS--O}" LDFLAGS="${HOST_LDFLAGS}" \
1147 ${HOST_SH} "${TOP}/tools/make/configure" ||
1148 bomb "Configure of ${toolprefix}make failed"
1149 ${runcmd} ${HOST_SH} buildmake.sh ||
1150 bomb "Build of ${toolprefix}make failed"
1151 make="${tmpdir}/${toolprefix}make"
1152 ${runcmd} cd "${TOP}"
1153 ${runcmd} rm -f usr.bin/make/*.o usr.bin/make/lst.lib/*.o
1154 done_rebuildmake=true
1155 fi
1156 }
1157
1158 # validatemakeparams --
1159 # Perform some late sanity checks, after rebuildmake,
1160 # but before createmakewrapper or any real work.
1161 #
1162 # Also create the top-level obj directory.
1163 #
1164 validatemakeparams()
1165 {
1166 if [ "${runcmd}" = "echo" ]; then
1167 TOOLCHAIN_MISSING=no
1168 EXTERNAL_TOOLCHAIN=""
1169 else
1170 TOOLCHAIN_MISSING=$(bomb_getmakevar TOOLCHAIN_MISSING)
1171 EXTERNAL_TOOLCHAIN=$(bomb_getmakevar EXTERNAL_TOOLCHAIN)
1172 fi
1173 if [ "${TOOLCHAIN_MISSING}" = "yes" ] && \
1174 [ -z "${EXTERNAL_TOOLCHAIN}" ]; then
1175 ${runcmd} echo "ERROR: build.sh (in-tree cross-toolchain) is not yet available for"
1176 ${runcmd} echo " MACHINE: ${MACHINE}"
1177 ${runcmd} echo " MACHINE_ARCH: ${MACHINE_ARCH}"
1178 ${runcmd} echo ""
1179 ${runcmd} echo "All builds for this platform should be done via a traditional make"
1180 ${runcmd} echo "If you wish to use an external cross-toolchain, set"
1181 ${runcmd} echo " EXTERNAL_TOOLCHAIN=<path to toolchain root>"
1182 ${runcmd} echo "in either the environment or mk.conf and rerun"
1183 ${runcmd} echo " ${progname} $*"
1184 exit 1
1185 fi
1186
1187 # Normalise MKOBJDIRS, MKUNPRIVED, and MKUPDATE
1188 # These may be set as build.sh options or in "mk.conf".
1189 # Don't export them as they're only used for tests in build.sh.
1190 #
1191 MKOBJDIRS=$(getmakevar MKOBJDIRS)
1192 MKUNPRIVED=$(getmakevar MKUNPRIVED)
1193 MKUPDATE=$(getmakevar MKUPDATE)
1194
1195 if [ "${MKOBJDIRS}" != "no" ]; then
1196 # Create the top-level object directory.
1197 #
1198 # "make obj NOSUBDIR=" can handle most cases, but it
1199 # can't handle the case where MAKEOBJDIRPREFIX is set
1200 # while the corresponding directory does not exist
1201 # (rules in <bsd.obj.mk> would abort the build). We
1202 # therefore have to handle the MAKEOBJDIRPREFIX case
1203 # without invoking "make obj". The MAKEOBJDIR case
1204 # could be handled either way, but we choose to handle
1205 # it similarly to MAKEOBJDIRPREFIX.
1206 #
1207 if [ -n "${TOP_obj}" ]; then
1208 # It must have been set by the "-M" or "-O"
1209 # command line options, so there's no need to
1210 # use getmakevar
1211 :
1212 elif [ -n "$MAKEOBJDIRPREFIX" ]; then
1213 TOP_obj="$(getmakevar MAKEOBJDIRPREFIX)${TOP}"
1214 elif [ -n "$MAKEOBJDIR" ]; then
1215 TOP_obj="$(getmakevar MAKEOBJDIR)"
1216 fi
1217 if [ -n "$TOP_obj" ]; then
1218 ${runcmd} mkdir -p "${TOP_obj}" ||
1219 bomb "Can't create top level object directory" \
1220 "${TOP_obj}"
1221 else
1222 ${runcmd} "${make}" -m ${TOP}/share/mk obj NOSUBDIR= ||
1223 bomb "Can't create top level object directory" \
1224 "using make obj"
1225 fi
1226
1227 # make obj in tools to ensure that the objdir for "tools"
1228 # is available.
1229 #
1230 ${runcmd} cd tools
1231 ${runcmd} "${make}" -m ${TOP}/share/mk obj NOSUBDIR= ||
1232 bomb "Failed to make obj in tools"
1233 ${runcmd} cd "${TOP}"
1234 fi
1235
1236 # Find TOOLDIR, DESTDIR, and RELEASEDIR, according to getmakevar,
1237 # and bomb if they have changed from the values we had from the
1238 # command line or environment.
1239 #
1240 # This must be done after creating the top-level object directory.
1241 #
1242 for var in TOOLDIR DESTDIR RELEASEDIR
1243 do
1244 eval oldval=\"\$${var}\"
1245 newval="$(getmakevar $var)"
1246 if ! $do_expertmode; then
1247 : ${_SRC_TOP_OBJ_:=$(getmakevar _SRC_TOP_OBJ_)}
1248 case "$var" in
1249 DESTDIR)
1250 : ${newval:=${_SRC_TOP_OBJ_}/destdir.${MACHINE}}
1251 makeenv="${makeenv} DESTDIR"
1252 ;;
1253 RELEASEDIR)
1254 : ${newval:=${_SRC_TOP_OBJ_}/releasedir}
1255 makeenv="${makeenv} RELEASEDIR"
1256 ;;
1257 esac
1258 fi
1259 if [ -n "$oldval" ] && [ "$oldval" != "$newval" ]; then
1260 bomb "Value of ${var} has changed" \
1261 "(was \"${oldval}\", now \"${newval}\")"
1262 fi
1263 eval ${var}=\"\${newval}\"
1264 eval export ${var}
1265 statusmsg2 "${var} path:" "${newval}"
1266 done
1267
1268 # RELEASEMACHINEDIR is just a subdir name, e.g. "i386".
1269 RELEASEMACHINEDIR=$(getmakevar RELEASEMACHINEDIR)
1270
1271 # Check validity of TOOLDIR and DESTDIR.
1272 #
1273 if [ -z "${TOOLDIR}" ] || [ "${TOOLDIR}" = "/" ]; then
1274 bomb "TOOLDIR '${TOOLDIR}' invalid"
1275 fi
1276 removedirs="${TOOLDIR}"
1277
1278 if [ -z "${DESTDIR}" ] || [ "${DESTDIR}" = "/" ]; then
1279 if ${do_build} || ${do_distribution} || ${do_release}; then
1280 if ! ${do_build} || \
1281 [ "${uname_s}" != "NetBSD" ] || \
1282 [ "${uname_m}" != "${MACHINE}" ]; then
1283 bomb "DESTDIR must != / for cross builds, or ${progname} 'distribution' or 'release'."
1284 fi
1285 if ! ${do_expertmode}; then
1286 bomb "DESTDIR must != / for non -E (expert) builds"
1287 fi
1288 statusmsg "WARNING: Building to /, in expert mode."
1289 statusmsg " This may cause your system to break! Reasons include:"
1290 statusmsg " - your kernel is not up to date"
1291 statusmsg " - the libraries or toolchain have changed"
1292 statusmsg " YOU HAVE BEEN WARNED!"
1293 fi
1294 else
1295 removedirs="${removedirs} ${DESTDIR}"
1296 fi
1297 if ${do_build} || ${do_distribution} || ${do_release}; then
1298 if ! ${do_expertmode} && \
1299 [ "$id_u" -ne 0 ] && \
1300 [ "${MKUNPRIVED}" = "no" ] ; then
1301 bomb "-U or -E must be set for build as an unprivileged user."
1302 fi
1303 fi
1304 if ${do_releasekernel} && [ -z "${RELEASEDIR}" ]; then
1305 bomb "Must set RELEASEDIR with \`releasekernel=...'"
1306 fi
1307
1308 # Install as non-root is a bad idea.
1309 #
1310 if ${do_install} && [ "$id_u" -ne 0 ] ; then
1311 if ${do_expertmode}; then
1312 warning "Will install as an unprivileged user."
1313 else
1314 bomb "-E must be set for install as an unprivileged user."
1315 fi
1316 fi
1317
1318 # If a previous build.sh run used -U (and therefore created a
1319 # METALOG file), then most subsequent build.sh runs must also
1320 # use -U. If DESTDIR is about to be removed, then don't perform
1321 # this check.
1322 #
1323 case "${do_removedirs} ${removedirs} " in
1324 true*" ${DESTDIR} "*)
1325 # DESTDIR is about to be removed
1326 ;;
1327 *)
1328 if ( ${do_build} || ${do_distribution} || ${do_release} || \
1329 ${do_install} ) && \
1330 [ -e "${DESTDIR}/METALOG" ] && \
1331 [ "${MKUNPRIVED}" = "no" ] ; then
1332 if $do_expertmode; then
1333 warning "A previous build.sh run specified -U."
1334 else
1335 bomb "A previous build.sh run specified -U; you must specify it again now."
1336 fi
1337 fi
1338 ;;
1339 esac
1340 }
1341
1342
1343 createmakewrapper()
1344 {
1345 # Remove the target directories.
1346 #
1347 if ${do_removedirs}; then
1348 for f in ${removedirs}; do
1349 statusmsg "Removing ${f}"
1350 ${runcmd} rm -r -f "${f}"
1351 done
1352 fi
1353
1354 # Recreate $TOOLDIR.
1355 #
1356 ${runcmd} mkdir -p "${TOOLDIR}/bin" ||
1357 bomb "mkdir of '${TOOLDIR}/bin' failed"
1358
1359 # If we did not previously rebuild ${toolprefix}make, then
1360 # check whether $make is still valid and the same as the output
1361 # from print_tooldir_make. If not, then rebuild make now. A
1362 # possible reason for this being necessary is that the actual
1363 # value of TOOLDIR might be different from the value guessed
1364 # before the top level obj dir was created.
1365 #
1366 if ! ${done_rebuildmake} && \
1367 ( [ ! -x "$make" ] || [ "$make" != "$(print_tooldir_make)" ] )
1368 then
1369 rebuildmake
1370 fi
1371
1372 # Install ${toolprefix}make if it was built.
1373 #
1374 if ${done_rebuildmake}; then
1375 ${runcmd} rm -f "${TOOLDIR}/bin/${toolprefix}make"
1376 ${runcmd} cp "${make}" "${TOOLDIR}/bin/${toolprefix}make" ||
1377 bomb "Failed to install \$TOOLDIR/bin/${toolprefix}make"
1378 make="${TOOLDIR}/bin/${toolprefix}make"
1379 statusmsg "Created ${make}"
1380 fi
1381
1382 # Build a ${toolprefix}make wrapper script, usable by hand as
1383 # well as by build.sh.
1384 #
1385 if [ -z "${makewrapper}" ]; then
1386 makewrapper="${TOOLDIR}/bin/${toolprefix}make-${makewrappermachine:-${MACHINE}}"
1387 [ -z "${BUILDID}" ] || makewrapper="${makewrapper}-${BUILDID}"
1388 fi
1389
1390 ${runcmd} rm -f "${makewrapper}"
1391 if [ "${runcmd}" = "echo" ]; then
1392 echo 'cat <<EOF >'${makewrapper}
1393 makewrapout=
1394 else
1395 makewrapout=">>\${makewrapper}"
1396 fi
1397
1398 case "${KSH_VERSION:-${SH_VERSION}}" in
1399 *PD\ KSH*|*MIRBSD\ KSH*)
1400 set +o braceexpand
1401 ;;
1402 esac
1403
1404 eval cat <<EOF ${makewrapout}
1405 #! ${HOST_SH}
1406 # Set proper variables to allow easy "make" building of a NetBSD subtree.
1407 # Generated from: \$NetBSD: build.sh,v 1.248 2011/09/09 13:29:23 apb Exp $
1408 # with these arguments: ${_args}
1409 #
1410
1411 EOF
1412 {
1413 for f in ${makeenv}; do
1414 if eval "[ -z \"\${$f}\" -a \"\${${f}-X}\" = \"X\" ]"; then
1415 eval echo "unset ${f}"
1416 else
1417 eval echo "${f}=\'\$$(echo ${f})\'\;\ export\ ${f}"
1418 fi
1419 done
1420
1421 eval cat <<EOF
1422 MAKEWRAPPERMACHINE=${makewrappermachine:-${MACHINE}}; export MAKEWRAPPERMACHINE
1423 USETOOLS=yes; export USETOOLS
1424 EOF
1425 } | eval sort -u "${makewrapout}"
1426 eval cat <<EOF "${makewrapout}"
1427
1428 exec "\${TOOLDIR}/bin/${toolprefix}make" \${1+"\$@"}
1429 EOF
1430 [ "${runcmd}" = "echo" ] && echo EOF
1431 ${runcmd} chmod +x "${makewrapper}"
1432 statusmsg2 "Updated makewrapper:" "${makewrapper}"
1433 }
1434
1435 make_in_dir()
1436 {
1437 dir="$1"
1438 op="$2"
1439 ${runcmd} cd "${dir}" ||
1440 bomb "Failed to cd to \"${dir}\""
1441 ${runcmd} "${makewrapper}" ${parallel} ${op} ||
1442 bomb "Failed to make ${op} in \"${dir}\""
1443 ${runcmd} cd "${TOP}" ||
1444 bomb "Failed to cd back to \"${TOP}\""
1445 }
1446
1447 buildtools()
1448 {
1449 if [ "${MKOBJDIRS}" != "no" ]; then
1450 ${runcmd} "${makewrapper}" ${parallel} obj-tools ||
1451 bomb "Failed to make obj-tools"
1452 fi
1453 if [ "${MKUPDATE}" = "no" ]; then
1454 make_in_dir tools cleandir
1455 fi
1456 make_in_dir tools dependall
1457 make_in_dir tools install
1458 statusmsg "Tools built to ${TOOLDIR}"
1459 }
1460
1461 getkernelconf()
1462 {
1463 kernelconf="$1"
1464 if [ "${MKOBJDIRS}" != "no" ]; then
1465 # The correct value of KERNOBJDIR might
1466 # depend on a prior "make obj" in
1467 # ${KERNSRCDIR}/${KERNARCHDIR}/compile.
1468 #
1469 KERNSRCDIR="$(getmakevar KERNSRCDIR)"
1470 KERNARCHDIR="$(getmakevar KERNARCHDIR)"
1471 make_in_dir "${KERNSRCDIR}/${KERNARCHDIR}/compile" obj
1472 fi
1473 KERNCONFDIR="$(getmakevar KERNCONFDIR)"
1474 KERNOBJDIR="$(getmakevar KERNOBJDIR)"
1475 case "${kernelconf}" in
1476 */*)
1477 kernelconfpath="${kernelconf}"
1478 kernelconfname="${kernelconf##*/}"
1479 ;;
1480 *)
1481 kernelconfpath="${KERNCONFDIR}/${kernelconf}"
1482 kernelconfname="${kernelconf}"
1483 ;;
1484 esac
1485 kernelbuildpath="${KERNOBJDIR}/${kernelconfname}"
1486 }
1487
1488 buildkernel()
1489 {
1490 if ! ${do_tools} && ! ${buildkernelwarned:-false}; then
1491 # Building tools every time we build a kernel is clearly
1492 # unnecessary. We could try to figure out whether rebuilding
1493 # the tools is necessary this time, but it doesn't seem worth
1494 # the trouble. Instead, we say it's the user's responsibility
1495 # to rebuild the tools if necessary.
1496 #
1497 statusmsg "Building kernel without building new tools"
1498 buildkernelwarned=true
1499 fi
1500 getkernelconf $1
1501 statusmsg2 "Building kernel:" "${kernelconf}"
1502 statusmsg2 "Build directory:" "${kernelbuildpath}"
1503 ${runcmd} mkdir -p "${kernelbuildpath}" ||
1504 bomb "Cannot mkdir: ${kernelbuildpath}"
1505 if [ "${MKUPDATE}" = "no" ]; then
1506 make_in_dir "${kernelbuildpath}" cleandir
1507 fi
1508 [ -x "${TOOLDIR}/bin/${toolprefix}config" ] \
1509 || bomb "${TOOLDIR}/bin/${toolprefix}config does not exist. You need to \"$0 tools\" first."
1510 ${runcmd} "${TOOLDIR}/bin/${toolprefix}config" -b "${kernelbuildpath}" \
1511 -s "${TOP}/sys" "${kernelconfpath}" ||
1512 bomb "${toolprefix}config failed for ${kernelconf}"
1513 make_in_dir "${kernelbuildpath}" depend
1514 make_in_dir "${kernelbuildpath}" all
1515
1516 if [ "${runcmd}" != "echo" ]; then
1517 statusmsg "Kernels built from ${kernelconf}:"
1518 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath})
1519 for kern in ${kernlist:-netbsd}; do
1520 [ -f "${kernelbuildpath}/${kern}" ] && \
1521 echo " ${kernelbuildpath}/${kern}"
1522 done | tee -a "${results}"
1523 fi
1524 }
1525
1526 releasekernel()
1527 {
1528 getkernelconf $1
1529 kernelreldir="${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/kernel"
1530 ${runcmd} mkdir -p "${kernelreldir}"
1531 kernlist=$(awk '$1 == "config" { print $2 }' ${kernelconfpath})
1532 for kern in ${kernlist:-netbsd}; do
1533 builtkern="${kernelbuildpath}/${kern}"
1534 [ -f "${builtkern}" ] || continue
1535 releasekern="${kernelreldir}/${kern}-${kernelconfname}.gz"
1536 statusmsg2 "Kernel copy:" "${releasekern}"
1537 if [ "${runcmd}" = "echo" ]; then
1538 echo "gzip -c -9 < ${builtkern} > ${releasekern}"
1539 else
1540 gzip -c -9 < "${builtkern}" > "${releasekern}"
1541 fi
1542 done
1543 }
1544
1545 buildmodules()
1546 {
1547 setmakeenv MKBINUTILS no
1548 if ! ${do_tools} && ! ${buildmoduleswarned:-false}; then
1549 # Building tools every time we build modules is clearly
1550 # unnecessary as well as a kernel.
1551 #
1552 statusmsg "Building modules without building new tools"
1553 buildmoduleswarned=true
1554 fi
1555
1556 statusmsg "Building kernel modules for NetBSD/${MACHINE} ${DISTRIBVER}"
1557 if [ "${MKOBJDIRS}" != "no" ]; then
1558 make_in_dir sys/modules obj ||
1559 bomb "Failed to make obj in sys/modules"
1560 fi
1561 if [ "${MKUPDATE}" = "no" ]; then
1562 make_in_dir sys/modules cleandir
1563 fi
1564 ${runcmd} "${makewrapper}" ${parallel} do-sys-modules ||
1565 bomb "Failed to make do-sys-modules"
1566
1567 statusmsg "Successful build of kernel modules for NetBSD/${MACHINE} ${DISTRIBVER}"
1568 }
1569
1570 installmodules()
1571 {
1572 dir="$1"
1573 ${runcmd} "${makewrapper}" INSTALLMODULESDIR="${dir}" installmodules ||
1574 bomb "Failed to make installmodules to ${dir}"
1575 statusmsg "Successful installmodules to ${dir}"
1576 }
1577
1578 installworld()
1579 {
1580 dir="$1"
1581 ${runcmd} "${makewrapper}" INSTALLWORLDDIR="${dir}" installworld ||
1582 bomb "Failed to make installworld to ${dir}"
1583 statusmsg "Successful installworld to ${dir}"
1584 }
1585
1586 # Run rump build&link tests.
1587 #
1588 # To make this feasible for running without having to install includes and
1589 # libraries into destdir (i.e. quick), we only run ld. This is possible
1590 # since the rump kernel is a closed namespace apart from calls to rumpuser.
1591 # Therefore, if ld complains only about rumpuser symbols, rump kernel
1592 # linking was successful.
1593 #
1594 # We test that rump links with a number of component configurations.
1595 # These attempt to mimic what is encountered in the full build.
1596 # See list below. The list should probably be either autogenerated
1597 # or managed elsewhere; keep it here until a better idea arises.
1598 #
1599 # Above all, note that THIS IS NOT A SUBSTITUTE FOR A FULL BUILD.
1600 #
1601
1602 RUMP_LIBSETS='
1603 -lrump,
1604 -lrumpvfs -lrump,
1605 -lrumpdev -lrump,
1606 -lrumpnet -lrump,
1607 -lrumpkern_tty -lrumpvfs -lrump,
1608 -lrumpfs_tmpfs -lrumpvfs -lrump,
1609 -lrumpfs_ffs -lrumpfs_msdos -lrumpvfs -lrumpdev_disk -lrumpdev -lrump,
1610 -lrumpnet_virtif -lrumpnet_netinet -lrumpnet_net -lrumpnet -lrump,
1611 -lrumpnet_sockin -lrumpfs_smbfs -lrumpdev_netsmb
1612 -lrumpkern_crypto -lrumpdev -lrumpnet -lrumpvfs -lrump,
1613 -lrumpnet_sockin -lrumpfs_nfs -lrumpnet -lrumpvfs -lrump,
1614 -lrumpdev_cgd -lrumpdev_raidframe -lrumpdev_disk -lrumpdev_rnd
1615 -lrumpdev_dm -lrumpdev -lrumpvfs -lrumpkern_crypto -lrump'
1616 dorump()
1617 {
1618 local doclean=""
1619 local doobjs=""
1620
1621 # we cannot link libs without building csu, and that leads to lossage
1622 [ "${1}" != "rumptest" ] && bomb 'build.sh rump not yet functional. ' \
1623 'did you mean "rumptest"?'
1624
1625 # create obj and distrib dirs
1626 if [ "${MKOBJDIRS}" != "no" ]; then
1627 make_in_dir "${NETBSDSRCDIR}/etc/mtree" obj
1628 make_in_dir "${NETBSDSRCDIR}/sys/rump" obj
1629 fi
1630 ${runcmd} "${makewrapper}" ${parallel} do-distrib-dirs \
1631 || bomb 'could not create distrib-dirs'
1632
1633 [ "${MKUPDATE}" = "no" ] && doclean="cleandir"
1634 targlist="${doclean} ${doobjs} dependall install"
1635 # optimize: for test we build only static libs (3x test speedup)
1636 if [ "${1}" = "rumptest" ] ; then
1637 setmakeenv NOPIC 1
1638 setmakeenv NOPROFILE 1
1639 fi
1640 for cmd in ${targlist} ; do
1641 make_in_dir "${NETBSDSRCDIR}/sys/rump" ${cmd}
1642 done
1643
1644 # if we just wanted to build & install rump, we're done
1645 [ "${1}" != "rumptest" ] && return
1646
1647 ${runcmd} cd "${NETBSDSRCDIR}/sys/rump/librump/rumpkern" \
1648 || bomb "cd to rumpkern failed"
1649 md_quirks=`${runcmd} "${makewrapper}" -V '${_SYMQUIRK}'`
1650 # one little, two little, three little backslashes ...
1651 md_quirks="$(echo ${md_quirks} | sed 's,\\,\\\\,g'";s/'//g" )"
1652 ${runcmd} cd "${TOP}" || bomb "cd to ${TOP} failed"
1653 tool_ld=`${runcmd} "${makewrapper}" -V '${LD}'`
1654
1655 local oIFS="${IFS}"
1656 IFS=","
1657 for set in ${RUMP_LIBSETS} ; do
1658 IFS="${oIFS}"
1659 ${runcmd} ${tool_ld} -nostdlib -L${DESTDIR}/usr/lib \
1660 -static --whole-archive ${set} 2>&1 -o /tmp/rumptest.$$ | \
1661 awk -v quirks="${md_quirks}" '
1662 /undefined reference/ &&
1663 !/more undefined references.*follow/{
1664 if (match($NF,
1665 "`(rumpuser_|__" quirks ")") == 0)
1666 fails[NR] = $0
1667 }
1668 /cannot find -l/{fails[NR] = $0}
1669 /cannot open output file/{fails[NR] = $0}
1670 END{
1671 for (x in fails)
1672 print fails[x]
1673 exit x!=0
1674 }'
1675 [ $? -ne 0 ] && bomb "Testlink of rump failed: ${set}"
1676 done
1677 statusmsg "Rump build&link tests successful"
1678 }
1679
1680 main()
1681 {
1682 initdefaults
1683 _args=$@
1684 parseoptions "$@"
1685
1686 sanitycheck
1687
1688 build_start=$(date)
1689 statusmsg2 "${progname} command:" "$0 $*"
1690 statusmsg2 "${progname} started:" "${build_start}"
1691 statusmsg2 "NetBSD version:" "${DISTRIBVER}"
1692 statusmsg2 "MACHINE:" "${MACHINE}"
1693 statusmsg2 "MACHINE_ARCH:" "${MACHINE_ARCH}"
1694 statusmsg2 "Build platform:" "${uname_s} ${uname_r} ${uname_m}"
1695 statusmsg2 "HOST_SH:" "${HOST_SH}"
1696
1697 rebuildmake
1698 validatemakeparams
1699 createmakewrapper
1700
1701 # Perform the operations.
1702 #
1703 for op in ${operations}; do
1704 case "${op}" in
1705
1706 makewrapper)
1707 # no-op
1708 ;;
1709
1710 tools)
1711 buildtools
1712 ;;
1713
1714 sets)
1715 statusmsg "Building sets from pre-populated ${DESTDIR}"
1716 ${runcmd} "${makewrapper}" ${parallel} ${op} ||
1717 bomb "Failed to make ${op}"
1718 setdir=${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/sets
1719 statusmsg "Built sets to ${setdir}"
1720 ;;
1721
1722 cleandir|obj|build|distribution|release|sourcesets|syspkgs|params)
1723 ${runcmd} "${makewrapper}" ${parallel} ${op} ||
1724 bomb "Failed to make ${op}"
1725 statusmsg "Successful make ${op}"
1726 ;;
1727
1728 iso-image|iso-image-source)
1729 ${runcmd} "${makewrapper}" ${parallel} \
1730 CDEXTRA="$CDEXTRA" ${op} ||
1731 bomb "Failed to make ${op}"
1732 statusmsg "Successful make ${op}"
1733 ;;
1734
1735 kernel=*)
1736 arg=${op#*=}
1737 buildkernel "${arg}"
1738 ;;
1739
1740 releasekernel=*)
1741 arg=${op#*=}
1742 releasekernel "${arg}"
1743 ;;
1744
1745 modules)
1746 buildmodules
1747 ;;
1748
1749 installmodules=*)
1750 arg=${op#*=}
1751 if [ "${arg}" = "/" ] && \
1752 ( [ "${uname_s}" != "NetBSD" ] || \
1753 [ "${uname_m}" != "${MACHINE}" ] ); then
1754 bomb "'${op}' must != / for cross builds."
1755 fi
1756 installmodules "${arg}"
1757 ;;
1758
1759 install=*)
1760 arg=${op#*=}
1761 if [ "${arg}" = "/" ] && \
1762 ( [ "${uname_s}" != "NetBSD" ] || \
1763 [ "${uname_m}" != "${MACHINE}" ] ); then
1764 bomb "'${op}' must != / for cross builds."
1765 fi
1766 installworld "${arg}"
1767 ;;
1768
1769 rump|rumptest)
1770 dorump "${op}"
1771 ;;
1772
1773 *)
1774 bomb "Unknown operation \`${op}'"
1775 ;;
1776
1777 esac
1778 done
1779
1780 statusmsg2 "${progname} ended:" "$(date)"
1781 if [ -s "${results}" ]; then
1782 echo "===> Summary of results:"
1783 sed -e 's/^===>//;s/^/ /' "${results}"
1784 echo "===> ."
1785 fi
1786 }
1787
1788 main "$@"
1789