xref: /titanic_51/usr/src/tools/scripts/nightly.sh (revision aed5247ff899ec457005d93dfbdb4ffd74574695)
1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
25# Copyright 2008, 2010, Richard Lowe
26# Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
27# Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
28#
29# Based on the nightly script from the integration folks,
30# Mostly modified and owned by mike_s.
31# Changes also by kjc, dmk.
32#
33# BRINGOVER_WS may be specified in the env file.
34# The default is the old behavior of CLONE_WS
35#
36# -i on the command line, means fast options, so when it's on the
37# command line (only), lint and check builds are skipped no matter what
38# the setting of their individual flags are in NIGHTLY_OPTIONS.
39#
40# LINTDIRS can be set in the env file, format is a list of:
41#
42#	/dirname-to-run-lint-on flag
43#
44#	Where flag is:	y - enable lint noise diff output
45#			n - disable lint noise diff output
46#
47#	For example: LINTDIRS="$SRC/uts n $SRC/stand y $SRC/psm y"
48#
49# OPTHOME and TEAMWARE may be set in the environment to override /opt
50# and /opt/teamware defaults.
51#
52
53#
54# The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
55# under certain circumstances, which can really screw things up; unset it.
56#
57unset CDPATH
58
59# Get the absolute path of the nightly script that the user invoked.  This
60# may be a relative path, and we need to do this before changing directory.
61nightly_path=`whence $0`
62
63#
64# Keep track of where we found nightly so we can invoke the matching
65# which_scm script.  If that doesn't work, don't go guessing, just rely
66# on the $PATH settings, which will generally give us either /opt/onbld
67# or the user's workspace.
68#
69WHICH_SCM=$(dirname $nightly_path)/which_scm
70if [[ ! -x $WHICH_SCM ]]; then
71	WHICH_SCM=which_scm
72fi
73
74function fatal_error
75{
76	print -u2 "nightly: $*"
77	exit 1
78}
79
80#
81# Function to do a DEBUG and non-DEBUG build. Needed because we might
82# need to do another for the source build, and since we only deliver DEBUG or
83# non-DEBUG packages.
84#
85# usage: normal_build
86#
87function normal_build {
88
89	typeset orig_p_FLAG="$p_FLAG"
90	typeset crypto_signer="$CODESIGN_USER"
91
92	suffix=""
93
94	# non-DEBUG build begins
95
96	if [ "$F_FLAG" = "n" ]; then
97		set_non_debug_build_flags
98		CODESIGN_USER="$crypto_signer" \
99		    build "non-DEBUG" "$suffix-nd" "-nd" "$MULTI_PROTO"
100		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a \
101		    "$p_FLAG" = "y" ]; then
102			copy_ihv_pkgs non-DEBUG -nd
103		fi
104	else
105		echo "\n==== No non-DEBUG $open_only build ====\n" >> "$LOGFILE"
106	fi
107
108	# non-DEBUG build ends
109
110	# DEBUG build begins
111
112	if [ "$D_FLAG" = "y" ]; then
113		set_debug_build_flags
114		CODESIGN_USER="$crypto_signer" \
115		    build "DEBUG" "$suffix" "" "$MULTI_PROTO"
116		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a \
117		    "$p_FLAG" = "y" ]; then
118			copy_ihv_pkgs DEBUG ""
119		fi
120	else
121		echo "\n==== No DEBUG $open_only build ====\n" >> "$LOGFILE"
122	fi
123
124	# DEBUG build ends
125
126	p_FLAG="$orig_p_FLAG"
127}
128
129#
130# usage: run_hook HOOKNAME ARGS...
131#
132# If variable "$HOOKNAME" is defined, insert a section header into
133# our logs and then run the command with ARGS
134#
135function run_hook {
136	HOOKNAME=$1
137    	eval HOOKCMD=\$$HOOKNAME
138	shift
139
140	if [ -n "$HOOKCMD" ]; then
141	    	(
142			echo "\n==== Running $HOOKNAME command: $HOOKCMD ====\n"
143		    	( $HOOKCMD "$@" 2>&1 )
144			if [ "$?" -ne 0 ]; then
145			    	# Let exit status propagate up
146			    	touch $TMPDIR/abort
147			fi
148		) | tee -a $mail_msg_file >> $LOGFILE
149
150		if [ -f $TMPDIR/abort ]; then
151			build_ok=n
152			echo "\nAborting at request of $HOOKNAME" |
153				tee -a $mail_msg_file >> $LOGFILE
154			exit 1
155		fi
156	fi
157}
158
159#
160# usage: filelist DESTDIR PATTERN
161#
162function filelist {
163	DEST=$1
164	PATTERN=$2
165	cd ${DEST}
166}
167
168# function to save off binaries after a full build for later
169# restoration
170function save_binaries {
171	# save off list of binaries
172	echo "\n==== Saving binaries from build at `date` ====\n" | \
173	    tee -a $mail_msg_file >> $LOGFILE
174	rm -f ${BINARCHIVE}
175	cd ${CODEMGR_WS}
176	filelist ${CODEMGR_WS} '^preserve:' >> $LOGFILE
177	filelist ${CODEMGR_WS} '^preserve:' | \
178	    cpio -ocB 2>/dev/null | compress \
179	    > ${BINARCHIVE}
180}
181
182# delete files
183# usage: hybridize_files DESTDIR MAKE_TARGET
184function hybridize_files {
185	DEST=$1
186	MAKETARG=$2
187
188	echo "\n==== Hybridizing files at `date` ====\n" | \
189	    tee -a $mail_msg_file >> $LOGFILE
190	for i in `filelist ${DEST} '^delete:'`
191	do
192		echo "removing ${i}." | tee -a $mail_msg_file >> $LOGFILE
193		rm -rf "${i}"
194	done
195	for i in `filelist ${DEST} '^hybridize:' `
196	do
197		echo "hybridizing ${i}." | tee -a $mail_msg_file >> $LOGFILE
198		rm -f ${i}+
199		sed -e "/^# HYBRID DELETE START/,/^# HYBRID DELETE END/d" \
200		    < ${i} > ${i}+
201		mv ${i}+ ${i}
202	done
203}
204
205# restore binaries into the proper source tree.
206# usage: restore_binaries DESTDIR MAKE_TARGET
207function restore_binaries {
208	DEST=$1
209	MAKETARG=$2
210
211	echo "\n==== Restoring binaries to ${MAKETARG} at `date` ====\n" | \
212	    tee -a $mail_msg_file >> $LOGFILE
213	cd ${DEST}
214	zcat ${BINARCHIVE} | \
215	    cpio -idmucvB 2>/dev/null | tee -a $mail_msg_file >> ${LOGFILE}
216}
217
218# rename files we save binaries of
219# usage: rename_files DESTDIR MAKE_TARGET
220function rename_files {
221	DEST=$1
222	MAKETARG=$2
223	echo "\n==== Renaming source files in ${MAKETARG} at `date` ====\n" | \
224	    tee -a $mail_msg_file >> $LOGFILE
225	for i in `filelist ${DEST} '^rename:'`
226	do
227		echo ${i} | tee -a $mail_msg_file >> ${LOGFILE}
228		rm -f ${i}.export
229		mv ${i} ${i}.export
230	done
231}
232
233#
234# Copy some or all of the source tree.
235#
236# Returns 0 for success, non-zero for failure.
237#
238# usage: copy_source CODEMGR_WS DESTDIR LABEL SRCROOT
239#
240function copy_source {
241	WS=$1
242	DEST=$2
243	label=$3
244	srcroot=$4
245
246	printf "\n==== Creating %s source from %s (%s) ====\n\n" \
247	    "$DEST" "$WS" "$label" | tee -a $mail_msg_file >> $LOGFILE
248
249	printf "cleaning out %s\n" "$DEST." >> $LOGFILE
250	rm -rf "$DEST" >> $LOGFILE 2>&1
251
252	printf "creating %s\n" "$DEST." >> $LOGFILE
253	mkdir -p "$DEST" 2>> $LOGFILE
254
255	if (( $? != 0 )) ; then
256		printf "failed to create %s\n" "$DEST" |
257		    tee -a $mail_msg_file >> $LOGFILE
258		build_ok=n
259		return 1
260	fi
261	cd "$WS"
262
263	printf "populating %s\n" "$DEST." >> $LOGFILE
264
265	case "$SCM_TYPE" in
266	teamware)
267		find $srcroot -name 's\.*' -a -type f -print | \
268		    sed -e 's,SCCS\/s.,,' | \
269		    grep -v '/\.del-*' | \
270		    cpio -pd $DEST >>$LOGFILE 2>&1
271		if (( $? != 0 )) ; then
272		    printf "cpio failed for %s\n" "$DEST" |
273			tee -a $mail_msg_file >> $LOGFILE
274		    build_ok=n
275		    return 1
276		fi
277		;;
278	mercurial)
279		copy_source_mercurial $DEST $srcroot
280		if (( $? != 0 )) ; then
281		    build_ok=n
282		    return 1
283		fi
284		;;
285	*)
286		build_ok=n
287		echo "Tree copy is not supported for workspace type" \
288		    "$SCM_TYPE" | tee -a $mail_msg_file >> $LOGFILE
289		return 1
290		;;
291	esac
292
293	return 0
294}
295
296#
297# Mercurial-specific copy code for copy_source().  Handles the
298# combined open and closed trees.
299#
300# Returns 0 for success, non-zero for failure.
301#
302# usage: copy_source_mercurial destdir srcroot
303#
304function copy_source_mercurial {
305	typeset dest=$1
306	typeset srcroot=$2
307	typeset open_top closed_top
308
309	case $srcroot in
310	usr)
311		open_top=usr
312		if [[ "$CLOSED_IS_PRESENT" = yes ]]; then
313			closed_top=usr/closed
314		fi
315		;;
316	usr/closed*)
317		if [[ "$CLOSED_IS_PRESENT" = no ]]; then
318			printf "can't copy %s: closed tree not present.\n" \
319			    "$srcroot" | tee -a $mail_msg_file >> $LOGFILE
320			return 1
321		fi
322		closed_top="$srcroot"
323		;;
324	*)
325		open_top="$srcroot"
326		;;
327	esac
328
329	if [[ -n "$open_top" ]]; then
330		hg locate -I "$open_top" | cpio -pd "$dest" >>$LOGFILE 2>&1
331		if (( $? != 0 )) ; then
332		    printf "cpio failed for %s\n" "$dest" |
333			tee -a $mail_msg_file >> $LOGFILE
334		    return 1
335		fi
336	fi
337
338	if [[ -n "$closed_top" ]]; then
339		mkdir -p "$dest/usr/closed" || return 1
340		if [[ "$closed_top" = usr/closed ]]; then
341			(cd usr/closed; hg locate |
342			    cpio -pd "$dest/usr/closed") >>$LOGFILE 2>&1
343			if (( $? != 0 )) ; then
344			    printf "cpio failed for %s/usr/closed\n" \
345				"$dest" | tee -a $mail_msg_file >> $LOGFILE
346			    return 1
347			fi
348		else
349			# copy subtree of usr/closed
350			closed_top=${closed_top#usr/closed/}
351			(cd usr/closed; hg locate -I "$closed_top" |
352			    cpio -pd "$dest/usr/closed") >>$LOGFILE 2>&1
353			if (( $? != 0 )) ; then
354			    printf "cpio failed for %s/usr/closed/%s\n" \
355				"$dest" "$closed_top" |
356				tee -a $mail_msg_file >> $LOGFILE
357			    return 1
358			fi
359		fi
360	fi
361
362	return 0
363}
364
365#
366# function to create (but not build) the export/crypt source tree.
367# usage: set_up_source_build CODEMGR_WS DESTDIR MAKE_TARGET
368# Sets SRC to the modified source tree, for use by the caller when it
369# builds the tree.
370#
371function set_up_source_build {
372	WS=$1
373	DEST=$2
374	MAKETARG=$3
375
376	copy_source $WS $DEST $MAKETARG usr
377	if (( $? != 0 )); then
378	    echo "\nCould not copy source tree for source build." |
379		tee -a $mail_msg_file >> $LOGFILE
380	    build_ok=n
381	    return
382	fi
383
384	SRC=${DEST}/usr/src
385
386	cd $SRC
387	rm -f ${MAKETARG}.out
388	echo "making ${MAKETARG} in ${SRC}." >> $LOGFILE
389	/bin/time $MAKE -e ${MAKETARG} 2>&1 | \
390	    tee -a $SRC/${MAKETARG}.out >> $LOGFILE
391	echo "\n==== ${MAKETARG} build errors ====\n" >> $mail_msg_file
392	egrep ":" $SRC/${MAKETARG}.out | \
393		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
394		egrep -v "Ignoring unknown host" | \
395		egrep -v "warning" >> $mail_msg_file
396
397	echo "clearing state files." >> $LOGFILE
398	find . -name '.make*' -exec rm -f {} \;
399}
400
401# Return library search directive as function of given root.
402function myldlibs {
403	echo "-L$1/lib -L$1/usr/lib"
404}
405
406# Return header search directive as function of given root.
407function myheaders {
408	echo "-I$1/usr/include"
409}
410
411#
412# Function to do the build, including package generation.
413# usage: build LABEL SUFFIX ND MULTIPROTO
414# - LABEL is used to tag build output.
415# - SUFFIX is used to distinguish files (e.g., DEBUG vs non-DEBUG,
416#   open-only vs full tree).
417# - ND is "-nd" (non-DEBUG builds) or "" (DEBUG builds).
418# - If MULTIPROTO is "yes", it means to name the proto area according to
419#   SUFFIX.  Otherwise ("no"), (re)use the standard proto area.
420#
421function build {
422	LABEL=$1
423	SUFFIX=$2
424	ND=$3
425	MULTIPROTO=$4
426	INSTALLOG=install${SUFFIX}-${MACH}
427	NOISE=noise${SUFFIX}-${MACH}
428	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
429
430	ORIGROOT=$ROOT
431	[ $MULTIPROTO = no ] || export ROOT=$ROOT$SUFFIX
432
433	if [[ "$O_FLAG" = y ]]; then
434		echo "\nSetting CLOSEDROOT= ${ROOT}-closed\n" >> $LOGFILE
435		export CLOSEDROOT=${ROOT}-closed
436	fi
437
438	export ENVLDLIBS1=`myldlibs $ROOT`
439	export ENVCPPFLAGS1=`myheaders $ROOT`
440
441	this_build_ok=y
442	#
443	#	Build OS-Networking source
444	#
445	echo "\n==== Building OS-Net source at `date` ($LABEL) ====\n" \
446		>> $LOGFILE
447
448	rm -f $SRC/${INSTALLOG}.out
449	cd $SRC
450	/bin/time $MAKE -e install 2>&1 | \
451	    tee -a $SRC/${INSTALLOG}.out >> $LOGFILE
452
453	if [[ "$SCM_TYPE" = teamware ]]; then
454		echo "\n==== SCCS Noise ($LABEL) ====\n" >> $mail_msg_file
455		egrep 'sccs(check:| *get)' $SRC/${INSTALLOG}.out >> \
456			$mail_msg_file
457	fi
458
459	echo "\n==== Build errors ($LABEL) ====\n" >> $mail_msg_file
460	egrep ":" $SRC/${INSTALLOG}.out |
461		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
462		egrep -v "Ignoring unknown host" | \
463		egrep -v "cc .* -o error " | \
464		egrep -v "warning" >> $mail_msg_file
465	if [ "$?" = "0" ]; then
466		build_ok=n
467		this_build_ok=n
468	fi
469	grep "bootblock image is .* bytes too big" $SRC/${INSTALLOG}.out \
470		>> $mail_msg_file
471	if [ "$?" = "0" ]; then
472		build_ok=n
473		this_build_ok=n
474	fi
475
476	if [ "$W_FLAG" = "n" ]; then
477		echo "\n==== Build warnings ($LABEL) ====\n" >>$mail_msg_file
478		egrep -i warning: $SRC/${INSTALLOG}.out \
479			| egrep -v '^tic:' \
480			| egrep -v "symbol (\`|')timezone' has differing types:" \
481		        | egrep -v "parameter <PSTAMP> set to" \
482			| egrep -v "Ignoring unknown host" \
483			| egrep -v "redefining segment flags attribute for" \
484			>> $mail_msg_file
485	fi
486
487	echo "\n==== Ended OS-Net source build at `date` ($LABEL) ====\n" \
488		>> $LOGFILE
489
490	echo "\n==== Elapsed build time ($LABEL) ====\n" >>$mail_msg_file
491	tail -3  $SRC/${INSTALLOG}.out >>$mail_msg_file
492
493	if [ "$i_FLAG" = "n" -a "$W_FLAG" = "n" ]; then
494		rm -f $SRC/${NOISE}.ref
495		if [ -f $SRC/${NOISE}.out ]; then
496			mv $SRC/${NOISE}.out $SRC/${NOISE}.ref
497		fi
498		grep : $SRC/${INSTALLOG}.out \
499			| egrep -v '^/' \
500			| egrep -v '^(Start|Finish|real|user|sys|./bld_awk)' \
501			| egrep -v '^tic:' \
502			| egrep -v '^mcs' \
503			| egrep -v '^LD_LIBRARY_PATH=' \
504			| egrep -v 'ar: creating' \
505			| egrep -v 'ar: writing' \
506			| egrep -v 'conflicts:' \
507			| egrep -v ':saved created' \
508			| egrep -v '^stty.*c:' \
509			| egrep -v '^mfgname.c:' \
510			| egrep -v '^uname-i.c:' \
511			| egrep -v '^volumes.c:' \
512			| egrep -v '^lint library construction:' \
513			| egrep -v 'tsort: INFORM:' \
514			| egrep -v 'stripalign:' \
515			| egrep -v 'chars, width' \
516			| egrep -v "symbol (\`|')timezone' has differing types:" \
517			| egrep -v 'PSTAMP' \
518			| egrep -v '|%WHOANDWHERE%|' \
519			| egrep -v '^Manifying' \
520			| egrep -v 'Ignoring unknown host' \
521			| egrep -v 'Processing method:' \
522			| egrep -v '^Writing' \
523			| egrep -v 'spellin1:' \
524			| egrep -v '^adding:' \
525			| egrep -v "^echo 'msgid" \
526			| egrep -v '^echo ' \
527			| egrep -v '\.c:$' \
528			| egrep -v '^Adding file:' \
529			| egrep -v 'CLASSPATH=' \
530			| egrep -v '\/var\/mail\/:saved' \
531			| egrep -v -- '-DUTS_VERSION=' \
532			| egrep -v '^Running Mkbootstrap' \
533			| egrep -v '^Applet length read:' \
534			| egrep -v 'bytes written:' \
535			| egrep -v '^File:SolarisAuthApplet.bin' \
536			| egrep -v -i 'jibversion' \
537			| egrep -v '^Output size:' \
538			| egrep -v '^Solo size statistics:' \
539			| egrep -v '^Using ROM API Version' \
540			| egrep -v '^Zero Signature length:' \
541			| egrep -v '^Note \(probably harmless\):' \
542			| egrep -v '::' \
543			| egrep -v -- '-xcache' \
544			| egrep -v '^\+' \
545			| egrep -v '^cc1: note: -fwritable-strings' \
546			| egrep -v 'svccfg-native -s svc:/' \
547			| sort | uniq >$SRC/${NOISE}.out
548		if [ ! -f $SRC/${NOISE}.ref ]; then
549			cp $SRC/${NOISE}.out $SRC/${NOISE}.ref
550		fi
551		echo "\n==== Build noise differences ($LABEL) ====\n" \
552			>>$mail_msg_file
553		diff $SRC/${NOISE}.ref $SRC/${NOISE}.out >>$mail_msg_file
554	fi
555
556	#
557	#	Re-sign selected binaries using signing server
558	#	(gatekeeper builds only)
559	#
560	if [ -n "$CODESIGN_USER" -a "$this_build_ok" = "y" ]; then
561		echo "\n==== Signing proto area at `date` ====\n" >> $LOGFILE
562		signing_file="${TMPDIR}/signing"
563		rm -f ${signing_file}
564		export CODESIGN_USER
565		signproto $SRC/tools/codesign/creds 2>&1 | \
566			tee -a ${signing_file} >> $LOGFILE
567		echo "\n==== Finished signing proto area at `date` ====\n" \
568		    >> $LOGFILE
569		echo "\n==== Crypto module signing errors ($LABEL) ====\n" \
570		    >> $mail_msg_file
571		egrep 'WARNING|ERROR' ${signing_file} >> $mail_msg_file
572		if (( $? == 0 )) ; then
573			build_ok=n
574			this_build_ok=n
575		fi
576	fi
577
578	#
579	#	Building Packages
580	#
581	if [ "$p_FLAG" = "y" -a "$this_build_ok" = "y" ]; then
582		if [ -d $SRC/pkg -o -d $SRC/pkgdefs ]; then
583			echo "\n==== Creating $LABEL packages at `date` ====\n" \
584				>> $LOGFILE
585			echo "Clearing out $PKGARCHIVE ..." >> $LOGFILE
586			rm -rf $PKGARCHIVE >> "$LOGFILE" 2>&1
587			mkdir -p $PKGARCHIVE >> "$LOGFILE" 2>&1
588
589			for d in pkg pkgdefs; do
590				if [ ! -f "$SRC/$d/Makefile" ]; then
591					continue
592				fi
593				rm -f $SRC/$d/${INSTALLOG}.out
594				cd $SRC/$d
595				/bin/time $MAKE -e install 2>&1 | \
596					tee -a $SRC/$d/${INSTALLOG}.out >> $LOGFILE
597			done
598
599			echo "\n==== package build errors ($LABEL) ====\n" \
600				>> $mail_msg_file
601
602			for d in pkg pkgdefs; do
603				if [ ! -f "$SRC/$d/Makefile" ]; then
604					continue
605				fi
606
607				egrep "${MAKE}|ERROR|WARNING" $SRC/$d/${INSTALLOG}.out | \
608					grep ':' | \
609					grep -v PSTAMP | \
610					egrep -v "Ignoring unknown host" \
611					>> $mail_msg_file
612			done
613		else
614			#
615			# Handle it gracefully if -p was set but there are
616			# neither pkg nor pkgdefs directories.
617			#
618			echo "\n==== No $LABEL packages to build ====\n" \
619				>> $LOGFILE
620		fi
621	else
622		echo "\n==== Not creating $LABEL packages ====\n" >> $LOGFILE
623	fi
624
625	ROOT=$ORIGROOT
626}
627
628# Usage: dolint /dir y|n
629# Arg. 2 is a flag to turn on/off the lint diff output
630function dolint {
631	if [ ! -d "$1" ]; then
632		echo "dolint error: $1 is not a directory"
633		exit 1
634	fi
635
636	if [ "$2" != "y" -a "$2" != "n" ]; then
637		echo "dolint internal error: $2 should be 'y' or 'n'"
638		exit 1
639	fi
640
641	lintdir=$1
642	dodiff=$2
643	base=`basename $lintdir`
644	LINTOUT=$lintdir/lint-${MACH}.out
645	LINTNOISE=$lintdir/lint-noise-${MACH}
646	export ENVLDLIBS1=`myldlibs $ROOT`
647	export ENVCPPFLAGS1=`myheaders $ROOT`
648
649	set_debug_build_flags
650
651	#
652	#	'$MAKE lint' in $lintdir
653	#
654	echo "\n==== Begin '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
655
656	# remove old lint.out
657	rm -f $lintdir/lint.out $lintdir/lint-noise.out
658	if [ -f $lintdir/lint-noise.ref ]; then
659		mv $lintdir/lint-noise.ref ${LINTNOISE}.ref
660	fi
661
662	rm -f $LINTOUT
663	cd $lintdir
664	#
665	# Remove all .ln files to ensure a full reference file
666	#
667	rm -f Nothing_to_remove \
668	    `find . \( -name SCCS -o -name .hg -o -name .svn -o -name .git \) \
669	    	-prune -o -type f -name '*.ln' -print `
670
671	/bin/time $MAKE -ek lint 2>&1 | \
672	    tee -a $LINTOUT >> $LOGFILE
673	echo "\n==== '$MAKE lint' of $base ERRORS ====\n" >> $mail_msg_file
674	grep "$MAKE:" $LINTOUT |
675		egrep -v "Ignoring unknown host" \
676		>> $mail_msg_file
677
678	echo "\n==== Ended '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
679
680	echo "\n==== Elapsed time of '$MAKE lint' of $base ====\n" \
681		>>$mail_msg_file
682	tail -3  $LINTOUT >>$mail_msg_file
683
684	rm -f ${LINTNOISE}.ref
685	if [ -f ${LINTNOISE}.out ]; then
686		mv ${LINTNOISE}.out ${LINTNOISE}.ref
687	fi
688        grep : $LINTOUT | \
689		egrep -v '^(real|user|sys)' |
690		egrep -v '(library construction)' | \
691		egrep -v ': global crosschecks' | \
692		egrep -v 'Ignoring unknown host' | \
693		egrep -v '\.c:$' | \
694		sort | uniq > ${LINTNOISE}.out
695	if [ ! -f ${LINTNOISE}.ref ]; then
696		cp ${LINTNOISE}.out ${LINTNOISE}.ref
697	fi
698	if [ "$dodiff" != "n" ]; then
699		echo "\n==== lint warnings $base ====\n" \
700			>>$mail_msg_file
701		# should be none, though there are a few that were filtered out
702		# above
703		egrep -i '(warning|lint):' ${LINTNOISE}.out \
704			| sort | uniq >> $mail_msg_file
705		echo "\n==== lint noise differences $base ====\n" \
706			>> $mail_msg_file
707		diff ${LINTNOISE}.ref ${LINTNOISE}.out \
708			>> $mail_msg_file
709	fi
710}
711
712# Install proto area from IHV build
713
714function copy_ihv_proto {
715
716	echo "\n==== Installing IHV proto area ====\n" \
717		>> $LOGFILE
718	if [ -d "$IA32_IHV_ROOT" ]; then
719		if [ ! -d "$ROOT" ]; then
720			echo "mkdir -p $ROOT" >> $LOGFILE
721			mkdir -p $ROOT
722		fi
723		echo "copying $IA32_IHV_ROOT to $ROOT\n" >> $LOGFILE
724		cd $IA32_IHV_ROOT
725		tar cf - . | (cd $ROOT; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
726	else
727		echo "$IA32_IHV_ROOT: not found" >> $LOGFILE
728	fi
729
730	if [ "$MULTI_PROTO" = yes ]; then
731		if [ ! -d "$ROOT-nd" ]; then
732			echo "mkdir -p $ROOT-nd" >> $LOGFILE
733			mkdir -p $ROOT-nd
734		fi
735		# If there's a non-DEBUG version of the IHV proto area,
736		# copy it, but copy something if there's not.
737		if [ -d "$IA32_IHV_ROOT-nd" ]; then
738			echo "copying $IA32_IHV_ROOT-nd to $ROOT-nd\n" >> $LOGFILE
739			cd $IA32_IHV_ROOT-nd
740		elif [ -d "$IA32_IHV_ROOT" ]; then
741			echo "copying $IA32_IHV_ROOT to $ROOT-nd\n" >> $LOGFILE
742			cd $IA32_IHV_ROOT
743		else
744			echo "$IA32_IHV_ROOT{-nd,}: not found" >> $LOGFILE
745			return
746		fi
747		tar cf - . | (cd $ROOT-nd; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
748	fi
749}
750
751# Install IHV packages in PKGARCHIVE
752# usage: copy_ihv_pkgs LABEL SUFFIX
753function copy_ihv_pkgs {
754	LABEL=$1
755	SUFFIX=$2
756	# always use non-DEBUG IHV packages
757	IA32_IHV_PKGS=${IA32_IHV_PKGS_ORIG}-nd
758	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
759
760	echo "\n==== Installing IHV packages from $IA32_IHV_PKGS ($LABEL) ====\n" \
761		>> $LOGFILE
762	if [ -d "$IA32_IHV_PKGS" ]; then
763		cd $IA32_IHV_PKGS
764		tar cf - * | \
765		   (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
766	else
767		echo "$IA32_IHV_PKGS: not found" >> $LOGFILE
768	fi
769
770	echo "\n==== Installing IHV packages from $IA32_IHV_BINARY_PKGS ($LABEL) ====\n" \
771		>> $LOGFILE
772	if [ -d "$IA32_IHV_BINARY_PKGS" ]; then
773		cd $IA32_IHV_BINARY_PKGS
774		tar cf - * | \
775		    (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
776	else
777		echo "$IA32_IHV_BINARY_PKGS: not found" >> $LOGFILE
778	fi
779}
780
781#
782# Build and install the onbld tools.
783#
784# usage: build_tools DESTROOT
785#
786# returns non-zero status if the build was successful.
787#
788function build_tools {
789	DESTROOT=$1
790
791	INSTALLOG=install-${MACH}
792
793	echo "\n==== Building tools at `date` ====\n" \
794		>> $LOGFILE
795
796	rm -f ${TOOLS}/${INSTALLOG}.out
797	cd ${TOOLS}
798	/bin/time $MAKE TOOLS_PROTO=${DESTROOT} -e install 2>&1 | \
799	    tee -a ${TOOLS}/${INSTALLOG}.out >> $LOGFILE
800
801	echo "\n==== Tools build errors ====\n" >> $mail_msg_file
802
803	egrep ":" ${TOOLS}/${INSTALLOG}.out |
804		egrep -e "(${MAKE}:|[ 	]error[: 	\n])" | \
805		egrep -v "Ignoring unknown host" | \
806		egrep -v warning >> $mail_msg_file
807	return $?
808}
809
810#
811# Set up to use locally installed tools.
812#
813# usage: use_tools TOOLSROOT
814#
815function use_tools {
816	TOOLSROOT=$1
817
818	#
819	# If we're not building ON workspace, then the TOOLSROOT
820	# settings here are clearly ignored by the workspace
821	# makefiles, prepending nonexistent directories to PATH is
822	# harmless, and we clearly do not wish to override
823	# ONBLD_TOOLS.
824	#
825	# If we're building an ON workspace, then the prepended PATH
826	# elements should supercede the preexisting ONBLD_TOOLS paths,
827	# and we want to override ONBLD_TOOLS to catch the tools that
828	# don't have specific path env vars here.
829	#
830	# So the only conditional behavior is overriding ONBLD_TOOLS,
831	# and we check for "an ON workspace" by looking for
832	# ${TOOLSROOT}/opt/onbld.
833	#
834
835	STABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/stabs
836	export STABS
837	CTFSTABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfstabs
838	export CTFSTABS
839	GENOFFSETS=${TOOLSROOT}/opt/onbld/bin/genoffsets
840	export GENOFFSETS
841
842	CTFCONVERT=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfconvert
843	export CTFCONVERT
844	CTFMERGE=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfmerge
845	export CTFMERGE
846
847	CTFCVTPTBL=${TOOLSROOT}/opt/onbld/bin/ctfcvtptbl
848	export CTFCVTPTBL
849	CTFFINDMOD=${TOOLSROOT}/opt/onbld/bin/ctffindmod
850	export CTFFINDMOD
851
852	if [ "$VERIFY_ELFSIGN" = "y" ]; then
853		ELFSIGN=${TOOLSROOT}/opt/onbld/bin/elfsigncmp
854	else
855		ELFSIGN=${TOOLSROOT}/opt/onbld/bin/${MACH}/elfsign
856	fi
857	export ELFSIGN
858
859	PATH="${TOOLSROOT}/opt/onbld/bin/${MACH}:${PATH}"
860	PATH="${TOOLSROOT}/opt/onbld/bin:${PATH}"
861	export PATH
862
863	if [ -d "${TOOLSROOT}/opt/onbld" ]; then
864		ONBLD_TOOLS=${TOOLSROOT}/opt/onbld
865		export ONBLD_TOOLS
866	fi
867
868	echo "\n==== New environment settings. ====\n" >> $LOGFILE
869	echo "STABS=${STABS}" >> $LOGFILE
870	echo "CTFSTABS=${CTFSTABS}" >> $LOGFILE
871	echo "CTFCONVERT=${CTFCONVERT}" >> $LOGFILE
872	echo "CTFMERGE=${CTFMERGE}" >> $LOGFILE
873	echo "CTFCVTPTBL=${CTFCVTPTBL}" >> $LOGFILE
874	echo "CTFFINDMOD=${CTFFINDMOD}" >> $LOGFILE
875	echo "ELFSIGN=${ELFSIGN}" >> $LOGFILE
876	echo "PATH=${PATH}" >> $LOGFILE
877	echo "ONBLD_TOOLS=${ONBLD_TOOLS}" >> $LOGFILE
878}
879
880function staffer {
881	if [ $ISUSER -ne 0 ]; then
882		"$@"
883	else
884		arg="\"$1\""
885		shift
886		for i
887		do
888			arg="$arg \"$i\""
889		done
890		eval su $STAFFER -c \'$arg\'
891	fi
892}
893
894#
895# Verify that the closed tree is present if it needs to be.
896# Sets CLOSED_IS_PRESENT for future use.
897#
898function check_closed_tree {
899	if [ -z "$CLOSED_IS_PRESENT" ]; then
900		if [ -d $CODEMGR_WS/usr/closed ]; then
901			CLOSED_IS_PRESENT="yes"
902		else
903			CLOSED_IS_PRESENT="no"
904		fi
905		export CLOSED_IS_PRESENT
906	fi
907	if [[ "$CLOSED_IS_PRESENT" = no && ! -d "$ON_CLOSED_BINS" ]]; then
908		#
909		# If it's an old (pre-split) tree or an empty
910		# workspace, don't complain.
911		#
912		if grep -s CLOSED_BUILD $SRC/Makefile.master > /dev/null; then
913			echo "If the closed sources are not present," \
914			    "ON_CLOSED_BINS"
915			echo "must point to the closed binaries tree."
916			build_ok=n
917			exit 1
918		fi
919	fi
920}
921
922function obsolete_build {
923    	echo "WARNING: Obsolete $1 build requested; request will be ignored"
924}
925
926#
927# wrapper over wsdiff.
928# usage: do_wsdiff LABEL OLDPROTO NEWPROTO
929#
930function do_wsdiff {
931	label=$1
932	oldproto=$2
933	newproto=$3
934
935	wsdiff="wsdiff"
936	[ "$t_FLAG" = y ] && wsdiff="wsdiff -t"
937
938	echo "\n==== Getting object changes since last build at `date`" \
939	    "($label) ====\n" | tee -a $LOGFILE >> $mail_msg_file
940	$wsdiff -s -r ${TMPDIR}/wsdiff.results $oldproto $newproto 2>&1 | \
941		    tee -a $LOGFILE >> $mail_msg_file
942	echo "\n==== Object changes determined at `date` ($label) ====\n" | \
943	    tee -a $LOGFILE >> $mail_msg_file
944}
945
946#
947# Functions for setting build flags (DEBUG/non-DEBUG).  Keep them
948# together.
949#
950
951function set_non_debug_build_flags {
952	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
953	export RELEASE_BUILD ; RELEASE_BUILD=
954	unset EXTRA_OPTIONS
955	unset EXTRA_CFLAGS
956}
957
958function set_debug_build_flags {
959	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
960	unset RELEASE_BUILD
961	unset EXTRA_OPTIONS
962	unset EXTRA_CFLAGS
963}
964
965
966MACH=`uname -p`
967
968if [ "$OPTHOME" = "" ]; then
969	OPTHOME=/opt
970	export OPTHOME
971fi
972if [ "$TEAMWARE" = "" ]; then
973	TEAMWARE=$OPTHOME/teamware
974	export TEAMWARE
975fi
976
977USAGE='Usage: nightly [-in] [+t] [-V VERS ] [ -S E|D|H|O ] <env_file>
978
979Where:
980	-i	Fast incremental options (no clobber, lint, check)
981	-n      Do not do a bringover
982	+t	Use the build tools in $ONBLD_TOOLS/bin
983	-V VERS set the build version string to VERS
984	-S	Build a variant of the source product
985		E - build exportable source
986		D - build domestic source (exportable + crypt)
987		H - build hybrid source (binaries + deleted source)
988		O - build (only) open source
989
990	<env_file>  file in Bourne shell syntax that sets and exports
991	variables that configure the operation of this script and many of
992	the scripts this one calls. If <env_file> does not exist,
993	it will be looked for in $OPTHOME/onbld/env.
994
995non-DEBUG is the default build type. Build options can be set in the
996NIGHTLY_OPTIONS variable in the <env_file> as follows:
997
998	-A	check for ABI differences in .so files
999	-C	check for cstyle/hdrchk errors
1000	-D	do a build with DEBUG on
1001	-F	do _not_ do a non-DEBUG build
1002	-G	gate keeper default group of options (-au)
1003	-I	integration engineer default group of options (-ampu)
1004	-M	do not run pmodes (safe file permission checker)
1005	-N	do not run protocmp
1006	-O	generate OpenSolaris deliverables
1007	-R	default group of options for building a release (-mp)
1008	-U	update proto area in the parent
1009	-V VERS set the build version string to VERS
1010	-X	copy x86 IHV proto area
1011	-f	find unreferenced files
1012	-i	do an incremental build (no "make clobber")
1013	-l	do "make lint" in $LINTDIRS (default: $SRC y)
1014	-m	send mail to $MAILTO at end of build
1015	-n      do not do a bringover
1016	-o	build using root privileges to set OWNER/GROUP (old style)
1017	-p	create packages
1018	-r	check ELF runtime attributes in the proto area
1019	-t	build and use the tools in $SRC/tools (default setting)
1020	+t	Use the build tools in $ONBLD_TOOLS/bin
1021	-u	update proto_list_$MACH and friends in the parent workspace;
1022		when used with -f, also build an unrefmaster.out in the parent
1023	-w	report on differences between previous and current proto areas
1024	-z	compress cpio archives with gzip
1025	-W	Do not report warnings (freeware gate ONLY)
1026	-S	Build a variant of the source product
1027		E - build exportable source
1028		D - build domestic source (exportable + crypt)
1029		H - build hybrid source (binaries + deleted source)
1030		O - build (only) open source
1031'
1032#
1033#	A log file will be generated under the name $LOGFILE
1034#	for partially completed build and log.`date '+%F'`
1035#	in the same directory for fully completed builds.
1036#
1037
1038# default values for low-level FLAGS; G I R are group FLAGS
1039A_FLAG=n
1040C_FLAG=n
1041D_FLAG=n
1042F_FLAG=n
1043f_FLAG=n
1044i_FLAG=n; i_CMD_LINE_FLAG=n
1045l_FLAG=n
1046M_FLAG=n
1047m_FLAG=n
1048N_FLAG=n
1049n_FLAG=n
1050O_FLAG=n
1051o_FLAG=n
1052P_FLAG=n
1053p_FLAG=n
1054r_FLAG=n
1055T_FLAG=n
1056t_FLAG=y
1057U_FLAG=n
1058u_FLAG=n
1059V_FLAG=n
1060W_FLAG=n
1061w_FLAG=n
1062X_FLAG=n
1063SD_FLAG=n
1064SE_FLAG=n
1065SH_FLAG=n
1066SO_FLAG=n
1067#
1068XMOD_OPT=
1069#
1070build_ok=y
1071
1072function is_source_build {
1073	[ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o \
1074	    "$SH_FLAG" = "y" -o "$SO_FLAG" = "y" ]
1075	return $?
1076}
1077
1078#
1079# examine arguments
1080#
1081
1082#
1083# single function for setting -S flag and doing error checking.
1084# usage: set_S_flag <type>
1085# where <type> is the source build type ("E", "D", ...).
1086#
1087function set_S_flag {
1088	if is_source_build; then
1089		echo "Can only build one source variant at a time."
1090		exit 1
1091	fi
1092	if [ "$1" = "E" ]; then
1093		SE_FLAG=y
1094	elif [ "$1" = "D" ]; then
1095		SD_FLAG=y
1096	elif [ "$1" = "H" ]; then
1097		SH_FLAG=y
1098	elif [ "$1" = "O" ]; then
1099		SO_FLAG=y
1100	else
1101		echo "$USAGE"
1102		exit 1
1103	fi
1104}
1105
1106OPTIND=1
1107while getopts +inS:tV: FLAG
1108do
1109	case $FLAG in
1110	  i )	i_FLAG=y; i_CMD_LINE_FLAG=y
1111		;;
1112	  n )	n_FLAG=y
1113		;;
1114	  S )
1115		set_S_flag $OPTARG
1116		;;
1117	 +t )	t_FLAG=n
1118		;;
1119	  V )	V_FLAG=y
1120		V_ARG="$OPTARG"
1121		;;
1122	 \? )	echo "$USAGE"
1123		exit 1
1124		;;
1125	esac
1126done
1127
1128# correct argument count after options
1129shift `expr $OPTIND - 1`
1130
1131# test that the path to the environment-setting file was given
1132if [ $# -ne 1 ]; then
1133	echo "$USAGE"
1134	exit 1
1135fi
1136
1137# check if user is running nightly as root
1138# ISUSER is set non-zero if an ordinary user runs nightly, or is zero
1139# when root invokes nightly.
1140/usr/bin/id | grep '^uid=0(' >/dev/null 2>&1
1141ISUSER=$?;	export ISUSER
1142
1143#
1144# force locale to C
1145LC_COLLATE=C;	export LC_COLLATE
1146LC_CTYPE=C;	export LC_CTYPE
1147LC_MESSAGES=C;	export LC_MESSAGES
1148LC_MONETARY=C;	export LC_MONETARY
1149LC_NUMERIC=C;	export LC_NUMERIC
1150LC_TIME=C;	export LC_TIME
1151
1152# clear environment variables we know to be bad for the build
1153unset LD_OPTIONS
1154unset LD_AUDIT		LD_AUDIT_32		LD_AUDIT_64
1155unset LD_BIND_NOW	LD_BIND_NOW_32		LD_BIND_NOW_64
1156unset LD_BREADTH	LD_BREADTH_32		LD_BREADTH_64
1157unset LD_CONFIG		LD_CONFIG_32		LD_CONFIG_64
1158unset LD_DEBUG		LD_DEBUG_32		LD_DEBUG_64
1159unset LD_DEMANGLE	LD_DEMANGLE_32		LD_DEMANGLE_64
1160unset LD_FLAGS		LD_FLAGS_32		LD_FLAGS_64
1161unset LD_LIBRARY_PATH	LD_LIBRARY_PATH_32	LD_LIBRARY_PATH_64
1162unset LD_LOADFLTR	LD_LOADFLTR_32		LD_LOADFLTR_64
1163unset LD_NOAUDIT	LD_NOAUDIT_32		LD_NOAUDIT_64
1164unset LD_NOAUXFLTR	LD_NOAUXFLTR_32		LD_NOAUXFLTR_64
1165unset LD_NOCONFIG	LD_NOCONFIG_32		LD_NOCONFIG_64
1166unset LD_NODIRCONFIG	LD_NODIRCONFIG_32	LD_NODIRCONFIG_64
1167unset LD_NODIRECT	LD_NODIRECT_32		LD_NODIRECT_64
1168unset LD_NOLAZYLOAD	LD_NOLAZYLOAD_32	LD_NOLAZYLOAD_64
1169unset LD_NOOBJALTER	LD_NOOBJALTER_32	LD_NOOBJALTER_64
1170unset LD_NOVERSION	LD_NOVERSION_32		LD_NOVERSION_64
1171unset LD_ORIGIN		LD_ORIGIN_32		LD_ORIGIN_64
1172unset LD_PRELOAD	LD_PRELOAD_32		LD_PRELOAD_64
1173unset LD_PROFILE	LD_PROFILE_32		LD_PROFILE_64
1174
1175unset CONFIG
1176unset GROUP
1177unset OWNER
1178unset REMOTE
1179unset ENV
1180unset ARCH
1181unset CLASSPATH
1182unset NAME
1183
1184#
1185# To get ONBLD_TOOLS from the environment, it must come from the env file.
1186# If it comes interactively, it is generally TOOLS_PROTO, which will be
1187# clobbered before the compiler version checks, which will therefore fail.
1188#
1189unset ONBLD_TOOLS
1190
1191#
1192#	Setup environmental variables
1193#
1194if [ -f /etc/nightly.conf ]; then
1195	. /etc/nightly.conf
1196fi
1197
1198if [ -f $1 ]; then
1199	if [[ $1 = */* ]]; then
1200		. $1
1201	else
1202		. ./$1
1203	fi
1204else
1205	if [ -f $OPTHOME/onbld/env/$1 ]; then
1206		. $OPTHOME/onbld/env/$1
1207	else
1208		echo "Cannot find env file as either $1 or $OPTHOME/onbld/env/$1"
1209		exit 1
1210	fi
1211fi
1212
1213# contents of stdenv.sh inserted after next line:
1214# STDENV_START
1215# STDENV_END
1216
1217# Check if we have sufficient data to continue...
1218[[ -v CODEMGR_WS ]] || fatal_error "Error: Variable CODEMGR_WS not set."
1219if  [[ "${NIGHTLY_OPTIONS}" == ~(F)n ]] ; then
1220	# Check if the gate data are valid if we don't do a "bringover" below
1221	[[ -d "${CODEMGR_WS}" ]] || \
1222		fatal_error "Error: ${CODEMGR_WS} is not a directory."
1223	[[ -f "${CODEMGR_WS}/usr/src/Makefile" ]] || \
1224		fatal_error "Error: ${CODEMGR_WS}/usr/src/Makefile not found."
1225fi
1226
1227#
1228# place ourselves in a new task, respecting BUILD_PROJECT if set.
1229#
1230if [ -z "$BUILD_PROJECT" ]; then
1231	/usr/bin/newtask -c $$
1232else
1233	/usr/bin/newtask -c $$ -p $BUILD_PROJECT
1234fi
1235
1236ps -o taskid= -p $$ | read build_taskid
1237ps -o project= -p $$ | read build_project
1238
1239#
1240# See if NIGHTLY_OPTIONS is set
1241#
1242if [ "$NIGHTLY_OPTIONS" = "" ]; then
1243	NIGHTLY_OPTIONS="-aBm"
1244fi
1245
1246#
1247# If BRINGOVER_WS was not specified, let it default to CLONE_WS
1248#
1249if [ "$BRINGOVER_WS" = "" ]; then
1250	BRINGOVER_WS=$CLONE_WS
1251fi
1252
1253#
1254# If CLOSED_BRINGOVER_WS was not specified, let it default to CLOSED_CLONE_WS
1255#
1256if [ "$CLOSED_BRINGOVER_WS" = "" ]; then
1257	CLOSED_BRINGOVER_WS=$CLOSED_CLONE_WS
1258fi
1259
1260#
1261# If BRINGOVER_FILES was not specified, default to usr
1262#
1263if [ "$BRINGOVER_FILES" = "" ]; then
1264	BRINGOVER_FILES="usr"
1265fi
1266
1267#
1268# If the closed sources are not present, the closed binaries must be
1269# present for the build to succeed.  If there's no pointer to the
1270# closed binaries, flag that now, rather than forcing the user to wait
1271# a couple hours (or more) to find out.
1272#
1273orig_closed_is_present="$CLOSED_IS_PRESENT"
1274check_closed_tree
1275
1276#
1277# Note: changes to the option letters here should also be applied to the
1278#	bldenv script.  `d' is listed for backward compatibility.
1279#
1280NIGHTLY_OPTIONS=-${NIGHTLY_OPTIONS#-}
1281OPTIND=1
1282while getopts +ABCDdFfGIilMmNnOoPpRrS:TtUuWwXxz FLAG $NIGHTLY_OPTIONS
1283do
1284	case $FLAG in
1285	  A )	A_FLAG=y
1286		#
1287		# If ELF_DATA_BASELINE_DIR is not defined, and we are on SWAN
1288		# (based on CLOSED_IS_PRESENT), then refuse to run. The value
1289		# of ELF version checking is greatly enhanced by including
1290		# the baseline gate comparison.
1291		if [ "$CLOSED_IS_PRESENT" = 'yes' -a \
1292		     "$ELF_DATA_BASELINE_DIR" = '' ]; then
1293			echo "ELF_DATA_BASELINE_DIR must be set if the A" \
1294			    "flag is present in\nNIGHTLY_OPTIONS and closed" \
1295			    "sources are present. Update environment file."
1296			exit 1;
1297		fi
1298		;;
1299	  B )	D_FLAG=y
1300		;; # old version of D
1301	  C )	C_FLAG=y
1302		;;
1303	  D )	D_FLAG=y
1304		;;
1305	  F )	F_FLAG=y
1306		;;
1307	  f )	f_FLAG=y
1308		;;
1309	  G )   u_FLAG=y
1310		;;
1311	  I )	m_FLAG=y
1312		p_FLAG=y
1313		u_FLAG=y
1314		;;
1315	  i )	i_FLAG=y
1316		;;
1317	  l )	l_FLAG=y
1318		;;
1319	  M )	M_FLAG=y
1320		;;
1321	  m )	m_FLAG=y
1322		;;
1323	  N )	N_FLAG=y
1324		;;
1325	  n )	n_FLAG=y
1326		;;
1327	  O )	O_FLAG=y
1328		;;
1329	  o )	o_FLAG=y
1330		;;
1331	  P )	P_FLAG=y
1332		;; # obsolete
1333	  p )	p_FLAG=y
1334		;;
1335	  R )	m_FLAG=y
1336		p_FLAG=y
1337		;;
1338	  r )	r_FLAG=y
1339		;;
1340	  S )
1341		set_S_flag $OPTARG
1342		;;
1343	  T )	T_FLAG=y
1344		;; # obsolete
1345	 +t )	t_FLAG=n
1346		;;
1347	  U )   if [ -z "${PARENT_ROOT}" ]; then
1348			echo "PARENT_ROOT must be set if the U flag is" \
1349			    "present in NIGHTLY_OPTIONS."
1350			exit 1
1351		fi
1352		NIGHTLY_PARENT_ROOT=$PARENT_ROOT
1353		if [ -n "${PARENT_TOOLS_ROOT}" ]; then
1354			NIGHTLY_PARENT_TOOLS_ROOT=$PARENT_TOOLS_ROOT
1355		fi
1356		U_FLAG=y
1357		;;
1358	  u )	u_FLAG=y
1359		;;
1360	  W )	W_FLAG=y
1361		;;
1362
1363	  w )	w_FLAG=y
1364		;;
1365	  X )	# now that we no longer need realmode builds, just
1366		# copy IHV packages.  only meaningful on x86.
1367		if [ "$MACH" = "i386" ]; then
1368			X_FLAG=y
1369		fi
1370		;;
1371	  x )	XMOD_OPT="-x"
1372		;;
1373	 \? )	echo "$USAGE"
1374		exit 1
1375		;;
1376	esac
1377done
1378
1379if [ $ISUSER -ne 0 ]; then
1380	if [ "$o_FLAG" = "y" ]; then
1381		echo "Old-style build requires root permission."
1382		exit 1
1383	fi
1384
1385	# Set default value for STAFFER, if needed.
1386	if [ -z "$STAFFER" -o "$STAFFER" = "nobody" ]; then
1387		STAFFER=`/usr/xpg4/bin/id -un`
1388		export STAFFER
1389	fi
1390fi
1391
1392if [ -z "$MAILTO" -o "$MAILTO" = "nobody" ]; then
1393	MAILTO=$STAFFER
1394	export MAILTO
1395fi
1396
1397PATH="$OPTHOME/onbld/bin:$OPTHOME/onbld/bin/${MACH}:/usr/ccs/bin"
1398PATH="$PATH:$OPTHOME/SUNWspro/bin:$TEAMWARE/bin:/usr/bin:/usr/sbin:/usr/ucb"
1399PATH="$PATH:/usr/openwin/bin:/usr/sfw/bin:/opt/sfw/bin:."
1400export PATH
1401
1402# roots of source trees, both relative to $SRC and absolute.
1403relsrcdirs="."
1404if [[ -d $CODEMGR_WS/usr/closed && "$CLOSED_IS_PRESENT" != no ]]; then
1405	relsrcdirs="$relsrcdirs ../closed"
1406fi
1407abssrcdirs=""
1408for d in $relsrcdirs; do
1409	abssrcdirs="$abssrcdirs $SRC/$d"
1410done
1411
1412unset CH
1413if [ "$o_FLAG" = "y" ]; then
1414# root invoked old-style build -- make sure it works as it always has
1415# by exporting 'CH'.  The current Makefile.master doesn't use this, but
1416# the old ones still do.
1417	PROTOCMPTERSE="protocmp.terse"
1418	CH=
1419	export CH
1420else
1421	PROTOCMPTERSE="protocmp.terse -gu"
1422fi
1423POUND_SIGN="#"
1424# have we set RELEASE_DATE in our env file?
1425if [ -z "$RELEASE_DATE" ]; then
1426	RELEASE_DATE=$(LC_ALL=C date +"%B %Y")
1427fi
1428BUILD_DATE=$(LC_ALL=C date +%Y-%b-%d)
1429BASEWSDIR=$(basename $CODEMGR_WS)
1430DEV_CM="\"@(#)SunOS Internal Development: $LOGNAME $BUILD_DATE [$BASEWSDIR]\""
1431
1432# we export POUND_SIGN, RELEASE_DATE and DEV_CM to speed up the build process
1433# by avoiding repeated shell invocations to evaluate Makefile.master definitions.
1434# we export o_FLAG and X_FLAG for use by makebfu, and by usr/src/pkg/Makefile
1435export o_FLAG X_FLAG POUND_SIGN RELEASE_DATE DEV_CM
1436
1437maketype="distributed"
1438MAKE=dmake
1439# get the dmake version string alone
1440DMAKE_VERSION=$( $MAKE -v )
1441DMAKE_VERSION=${DMAKE_VERSION#*: }
1442# focus in on just the dotted version number alone
1443DMAKE_MAJOR=$( echo $DMAKE_VERSION | \
1444	sed -e 's/.*\<\([^.]*\.[^   ]*\).*$/\1/' )
1445# extract the second (or final) integer
1446DMAKE_MINOR=${DMAKE_MAJOR#*.}
1447DMAKE_MINOR=${DMAKE_MINOR%%.*}
1448# extract the first integer
1449DMAKE_MAJOR=${DMAKE_MAJOR%%.*}
1450CHECK_DMAKE=${CHECK_DMAKE:-y}
1451# x86 was built on the 12th, sparc on the 13th.
1452if [ "$CHECK_DMAKE" = "y" -a \
1453     "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/12" -a \
1454     "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/13" -a \( \
1455     "$DMAKE_MAJOR" -lt 7 -o \
1456     "$DMAKE_MAJOR" -eq 7 -a "$DMAKE_MINOR" -lt 4 \) ]; then
1457	if [ -z "$DMAKE_VERSION" ]; then
1458		echo "$MAKE is missing."
1459		exit 1
1460	fi
1461	echo `whence $MAKE`" version is:"
1462	echo "  ${DMAKE_VERSION}"
1463	cat <<EOF
1464
1465This version may not be safe for use.  Either set TEAMWARE to a better
1466path or (if you really want to use this version of dmake anyway), add
1467the following to your environment to disable this check:
1468
1469  CHECK_DMAKE=n
1470EOF
1471	exit 1
1472fi
1473export PATH
1474export MAKE
1475
1476if [[ "$O_FLAG" = y ]]; then
1477	export TONICBUILD=""
1478else
1479	export TONICBUILD="#"
1480fi
1481
1482if [ "${SUNWSPRO}" != "" ]; then
1483	PATH="${SUNWSPRO}/bin:$PATH"
1484	export PATH
1485fi
1486
1487hostname=$(uname -n)
1488if [[ $DMAKE_MAX_JOBS != +([0-9]) || $DMAKE_MAX_JOBS -eq 0 ]]
1489then
1490	maxjobs=
1491	if [[ -f $HOME/.make.machines ]]
1492	then
1493		# Note: there is a hard tab and space character in the []s
1494		# below.
1495		egrep -i "^[ 	]*$hostname[ 	\.]" \
1496			$HOME/.make.machines | read host jobs
1497		maxjobs=${jobs##*=}
1498	fi
1499
1500	if [[ $maxjobs != +([0-9]) || $maxjobs -eq 0 ]]
1501	then
1502		# default
1503		maxjobs=4
1504	fi
1505
1506	export DMAKE_MAX_JOBS=$maxjobs
1507fi
1508
1509DMAKE_MODE=parallel;
1510export DMAKE_MODE
1511
1512if [ -z "${ROOT}" ]; then
1513	echo "ROOT must be set."
1514	exit 1
1515fi
1516
1517#
1518# if -V flag was given, reset VERSION to V_ARG
1519#
1520if [ "$V_FLAG" = "y" ]; then
1521	VERSION=$V_ARG
1522fi
1523
1524#
1525# Check for IHV root for copying ihv proto area
1526#
1527if [ "$X_FLAG" = "y" ]; then
1528        if [ "$IA32_IHV_ROOT" = "" ]; then
1529		echo "IA32_IHV_ROOT: must be set for copying ihv proto"
1530		args_ok=n
1531        fi
1532        if [ ! -d "$IA32_IHV_ROOT" ]; then
1533                echo "$IA32_IHV_ROOT: not found"
1534                args_ok=n
1535        fi
1536        if [ "$IA32_IHV_WS" = "" ]; then
1537		echo "IA32_IHV_WS: must be set for copying ihv proto"
1538		args_ok=n
1539        fi
1540        if [ ! -d "$IA32_IHV_WS" ]; then
1541                echo "$IA32_IHV_WS: not found"
1542                args_ok=n
1543        fi
1544fi
1545
1546# Append source version
1547if [ "$SE_FLAG" = "y" ]; then
1548	VERSION="${VERSION}:EXPORT"
1549fi
1550
1551if [ "$SD_FLAG" = "y" ]; then
1552	VERSION="${VERSION}:DOMESTIC"
1553fi
1554
1555if [ "$SH_FLAG" = "y" ]; then
1556	VERSION="${VERSION}:MODIFIED_SOURCE_PRODUCT"
1557fi
1558
1559if [ "$SO_FLAG" = "y" ]; then
1560	VERSION="${VERSION}:OPEN_ONLY"
1561fi
1562
1563TMPDIR="/tmp/nightly.tmpdir.$$"
1564export TMPDIR
1565rm -rf ${TMPDIR}
1566mkdir -p $TMPDIR || exit 1
1567chmod 777 $TMPDIR
1568
1569#
1570# Keep elfsign's use of pkcs11_softtoken from looking in the user home
1571# directory, which doesn't always work.   Needed until all build machines
1572# have the fix for 6271754
1573#
1574SOFTTOKEN_DIR=$TMPDIR
1575export SOFTTOKEN_DIR
1576
1577#
1578# Tools should only be built non-DEBUG.  Keep track of the tools proto
1579# area path relative to $TOOLS, because the latter changes in an
1580# export build.
1581#
1582# TOOLS_PROTO is included below for builds other than usr/src/tools
1583# that look for this location.  For usr/src/tools, this will be
1584# overridden on the $MAKE command line in build_tools().
1585#
1586TOOLS=${SRC}/tools
1587TOOLS_PROTO_REL=proto/root_${MACH}-nd
1588TOOLS_PROTO=${TOOLS}/${TOOLS_PROTO_REL};	export TOOLS_PROTO
1589
1590unset   CFLAGS LD_LIBRARY_PATH LDFLAGS
1591
1592# create directories that are automatically removed if the nightly script
1593# fails to start correctly
1594function newdir {
1595	dir=$1
1596	toadd=
1597	while [ ! -d $dir ]; do
1598		toadd="$dir $toadd"
1599		dir=`dirname $dir`
1600	done
1601	torm=
1602	newlist=
1603	for dir in $toadd; do
1604		if staffer mkdir $dir; then
1605			newlist="$ISUSER $dir $newlist"
1606			torm="$dir $torm"
1607		else
1608			[ -z "$torm" ] || staffer rmdir $torm
1609			return 1
1610		fi
1611	done
1612	newdirlist="$newlist $newdirlist"
1613	return 0
1614}
1615newdirlist=
1616
1617[ -d $CODEMGR_WS ] || newdir $CODEMGR_WS || exit 1
1618
1619# since this script assumes the build is from full source, it nullifies
1620# variables likely to have been set by a "ws" script; nullification
1621# confines the search space for headers and libraries to the proto area
1622# built from this immediate source.
1623ENVLDLIBS1=
1624ENVLDLIBS2=
1625ENVLDLIBS3=
1626ENVCPPFLAGS1=
1627ENVCPPFLAGS2=
1628ENVCPPFLAGS3=
1629ENVCPPFLAGS4=
1630PARENT_ROOT=
1631
1632export ENVLDLIBS3 ENVCPPFLAGS1 ENVCPPFLAGS2 ENVCPPFLAGS3 ENVCPPFLAGS4 \
1633	ENVLDLIBS1 ENVLDLIBS2 PARENT_ROOT
1634
1635PKGARCHIVE_ORIG=$PKGARCHIVE
1636IA32_IHV_PKGS_ORIG=$IA32_IHV_PKGS
1637
1638#
1639# Juggle the logs and optionally send mail on completion.
1640#
1641
1642function logshuffle {
1643    	LLOG="$ATLOG/log.`date '+%F.%H:%M'`"
1644	if [ -f $LLOG -o -d $LLOG ]; then
1645	    	LLOG=$LLOG.$$
1646	fi
1647	mkdir $LLOG
1648	export LLOG
1649
1650	if [ "$build_ok" = "y" ]; then
1651		mv $ATLOG/proto_list_${MACH} $LLOG
1652
1653		if [ -f $ATLOG/proto_list_tools_${MACH} ]; then
1654			mv $ATLOG/proto_list_tools_${MACH} $LLOG
1655	        fi
1656
1657		if [ -f $TMPDIR/wsdiff.results ]; then
1658		    	mv $TMPDIR/wsdiff.results $LLOG
1659		fi
1660
1661		if [ -f $TMPDIR/wsdiff-nd.results ]; then
1662			mv $TMPDIR/wsdiff-nd.results $LLOG
1663		fi
1664	fi
1665
1666	#
1667	# Now that we're about to send mail, it's time to check the noise
1668	# file.  In the event that an error occurs beyond this point, it will
1669	# be recorded in the nightly.log file, but nowhere else.  This would
1670	# include only errors that cause the copying of the noise log to fail
1671	# or the mail itself not to be sent.
1672	#
1673
1674	exec >>$LOGFILE 2>&1
1675	if [ -s $build_noise_file ]; then
1676	    	echo "\n==== Nightly build noise ====\n" |
1677		    tee -a $LOGFILE >>$mail_msg_file
1678		cat $build_noise_file >>$LOGFILE
1679		cat $build_noise_file >>$mail_msg_file
1680		echo | tee -a $LOGFILE >>$mail_msg_file
1681	fi
1682	rm -f $build_noise_file
1683
1684	case "$build_ok" in
1685		y)
1686			state=Completed
1687			;;
1688		i)
1689			state=Interrupted
1690			;;
1691		*)
1692	    		state=Failed
1693			;;
1694	esac
1695	NIGHTLY_STATUS=$state
1696	export NIGHTLY_STATUS
1697
1698	run_hook POST_NIGHTLY $state
1699	run_hook SYS_POST_NIGHTLY $state
1700
1701	#
1702	# mailx(1) sets From: based on the -r flag
1703	# if it is given.
1704	#
1705	mailx_r=
1706	if [[ -n "${MAILFROM}" ]]; then
1707		mailx_r="-r ${MAILFROM}"
1708	fi
1709
1710	cat $build_time_file $build_environ_file $mail_msg_file \
1711	    > ${LLOG}/mail_msg
1712	if [ "$m_FLAG" = "y" ]; then
1713	    	cat ${LLOG}/mail_msg | /usr/bin/mailx ${mailx_r} -s \
1714	"Nightly ${MACH} Build of `basename ${CODEMGR_WS}` ${state}." \
1715			${MAILTO}
1716	fi
1717
1718	if [ "$u_FLAG" = "y" -a "$build_ok" = "y" ]; then
1719	    	staffer cp ${LLOG}/mail_msg $PARENT_WS/usr/src/mail_msg-${MACH}
1720		staffer cp $LOGFILE $PARENT_WS/usr/src/nightly-${MACH}.log
1721	fi
1722
1723	mv $LOGFILE $LLOG
1724}
1725
1726#
1727#	Remove the locks and temporary files on any exit
1728#
1729function cleanup {
1730    	logshuffle
1731
1732	[ -z "$lockfile" ] || staffer rm -f $lockfile
1733	[ -z "$atloglockfile" ] || rm -f $atloglockfile
1734	[ -z "$ulockfile" ] || staffer rm -f $ulockfile
1735	[ -z "$Ulockfile" ] || rm -f $Ulockfile
1736
1737	set -- $newdirlist
1738	while [ $# -gt 0 ]; do
1739		ISUSER=$1 staffer rmdir $2
1740		shift; shift
1741	done
1742	rm -rf $TMPDIR
1743}
1744
1745function cleanup_signal {
1746    	build_ok=i
1747	# this will trigger cleanup(), above.
1748	exit 1
1749}
1750
1751trap cleanup 0
1752trap cleanup_signal 1 2 3 15
1753
1754#
1755# Generic lock file processing -- make sure that the lock file doesn't
1756# exist.  If it does, it should name the build host and PID.  If it
1757# doesn't, then make sure we can create it.  Clean up locks that are
1758# known to be stale (assumes host name is unique among build systems
1759# for the workspace).
1760#
1761function create_lock {
1762	lockf=$1
1763	lockvar=$2
1764
1765	ldir=`dirname $lockf`
1766	[ -d $ldir ] || newdir $ldir || exit 1
1767	eval $lockvar=$lockf
1768
1769	while ! staffer ln -s $hostname.$STAFFER.$$ $lockf 2> /dev/null; do
1770		basews=`basename $CODEMGR_WS`
1771		ls -l $lockf | nawk '{print $NF}' | IFS=. read host user pid
1772		if [ "$host" != "$hostname" ]; then
1773			echo "$MACH build of $basews apparently" \
1774			    "already started by $user on $host as $pid."
1775			exit 1
1776		elif kill -s 0 $pid 2>/dev/null; then
1777			echo "$MACH build of $basews already started" \
1778			    "by $user as $pid."
1779			exit 1
1780		else
1781			# stale lock; clear it out and try again
1782			rm -f $lockf
1783		fi
1784	done
1785}
1786
1787#
1788# Return the list of interesting proto areas, depending on the current
1789# options.
1790#
1791function allprotos {
1792	typeset roots="$ROOT"
1793
1794	if [[ "$F_FLAG" = n && "$MULTI_PROTO" = yes ]]; then
1795		roots="$roots $ROOT-nd"
1796	fi
1797
1798	if [[ $O_FLAG = y ]]; then
1799		roots="$roots $ROOT-closed"
1800		[ $MULTI_PROTO = yes ] && roots="$roots $ROOT-nd-closed"
1801	fi
1802
1803	echo $roots
1804}
1805
1806# Ensure no other instance of this script is running on this host.
1807# LOCKNAME can be set in <env_file>, and is by default, but is not
1808# required due to the use of $ATLOG below.
1809if [ -n "$LOCKNAME" ]; then
1810	create_lock /tmp/$LOCKNAME "lockfile"
1811fi
1812#
1813# Create from one, two, or three other locks:
1814#	$ATLOG/nightly.lock
1815#		- protects against multiple builds in same workspace
1816#	$PARENT_WS/usr/src/nightly.$MACH.lock
1817#		- protects against multiple 'u' copy-backs
1818#	$NIGHTLY_PARENT_ROOT/nightly.lock
1819#		- protects against multiple 'U' copy-backs
1820#
1821# Overriding ISUSER to 1 causes the lock to be created as root if the
1822# script is run as root.  The default is to create it as $STAFFER.
1823ISUSER=1 create_lock $ATLOG/nightly.lock "atloglockfile"
1824if [ "$u_FLAG" = "y" ]; then
1825	create_lock $PARENT_WS/usr/src/nightly.$MACH.lock "ulockfile"
1826fi
1827if [ "$U_FLAG" = "y" ]; then
1828	# NIGHTLY_PARENT_ROOT is written as root if script invoked as root.
1829	ISUSER=1 create_lock $NIGHTLY_PARENT_ROOT/nightly.lock "Ulockfile"
1830fi
1831
1832# Locks have been taken, so we're doing a build and we're committed to
1833# the directories we may have created so far.
1834newdirlist=
1835
1836#
1837# Create mail_msg_file
1838#
1839mail_msg_file="${TMPDIR}/mail_msg"
1840touch $mail_msg_file
1841build_time_file="${TMPDIR}/build_time"
1842build_environ_file="${TMPDIR}/build_environ"
1843touch $build_environ_file
1844#
1845#	Move old LOGFILE aside
1846#	ATLOG directory already made by 'create_lock' above
1847#
1848if [ -f $LOGFILE ]; then
1849	mv -f $LOGFILE ${LOGFILE}-
1850fi
1851#
1852#	Build OsNet source
1853#
1854START_DATE=`date`
1855SECONDS=0
1856echo "\n==== Nightly $maketype build started:   $START_DATE ====" \
1857    | tee -a $LOGFILE > $build_time_file
1858
1859echo "\nBuild project:  $build_project\nBuild taskid:   $build_taskid" | \
1860    tee -a $mail_msg_file >> $LOGFILE
1861
1862# make sure we log only to the nightly build file
1863build_noise_file="${TMPDIR}/build_noise"
1864exec </dev/null >$build_noise_file 2>&1
1865
1866run_hook SYS_PRE_NIGHTLY
1867run_hook PRE_NIGHTLY
1868
1869echo "\n==== list of environment variables ====\n" >> $LOGFILE
1870env >> $LOGFILE
1871
1872echo "\n==== Nightly argument issues ====\n" | tee -a $mail_msg_file >> $LOGFILE
1873
1874if [ "$P_FLAG" = "y" ]; then
1875	obsolete_build GPROF | tee -a $mail_msg_file >> $LOGFILE
1876fi
1877
1878if [ "$T_FLAG" = "y" ]; then
1879	obsolete_build TRACE | tee -a $mail_msg_file >> $LOGFILE
1880fi
1881
1882if is_source_build; then
1883	if [ "$i_FLAG" = "y" -o "$i_CMD_LINE_FLAG" = "y" ]; then
1884		echo "WARNING: the -S flags do not support incremental" \
1885		    "builds; forcing clobber\n" | tee -a $mail_msg_file >> $LOGFILE
1886		i_FLAG=n
1887		i_CMD_LINE_FLAG=n
1888	fi
1889	if [ "$N_FLAG" = "n" ]; then
1890		echo "WARNING: the -S flags do not support protocmp;" \
1891		    "protocmp disabled\n" | \
1892		    tee -a $mail_msg_file >> $LOGFILE
1893		N_FLAG=y
1894	fi
1895	if [ "$l_FLAG" = "y" ]; then
1896		echo "WARNING: the -S flags do not support lint;" \
1897		    "lint disabled\n" | tee -a $mail_msg_file >> $LOGFILE
1898		l_FLAG=n
1899	fi
1900	if [ "$C_FLAG" = "y" ]; then
1901		echo "WARNING: the -S flags do not support cstyle;" \
1902		    "cstyle check disabled\n" | tee -a $mail_msg_file >> $LOGFILE
1903		C_FLAG=n
1904	fi
1905else
1906	if [ "$N_FLAG" = "y" ]; then
1907		if [ "$p_FLAG" = "y" ]; then
1908			cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1909WARNING: the p option (create packages) is set, but so is the N option (do
1910         not run protocmp); this is dangerous; you should unset the N option
1911EOF
1912		else
1913			cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1914Warning: the N option (do not run protocmp) is set; it probably shouldn't be
1915EOF
1916		fi
1917		echo "" | tee -a $mail_msg_file >> $LOGFILE
1918	fi
1919fi
1920
1921if [ "$D_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
1922	#
1923	# In the past we just complained but went ahead with the lint
1924	# pass, even though the proto area was built non-DEBUG.  It's
1925	# unlikely that non-DEBUG headers will make a difference, but
1926	# rather than assuming it's a safe combination, force the user
1927	# to specify a DEBUG build.
1928	#
1929	echo "WARNING: DEBUG build not requested; disabling lint.\n" \
1930	    | tee -a $mail_msg_file >> $LOGFILE
1931	l_FLAG=n
1932fi
1933
1934if [ "$f_FLAG" = "y" ]; then
1935	if [ "$i_FLAG" = "y" ]; then
1936		echo "WARNING: the -f flag cannot be used during incremental" \
1937		    "builds; ignoring -f\n" | tee -a $mail_msg_file >> $LOGFILE
1938		f_FLAG=n
1939	fi
1940	if [ "${l_FLAG}${p_FLAG}" != "yy" ]; then
1941		echo "WARNING: the -f flag requires -l, and -p;" \
1942		    "ignoring -f\n" | tee -a $mail_msg_file >> $LOGFILE
1943		f_FLAG=n
1944	fi
1945fi
1946
1947if [ "$w_FLAG" = "y" -a ! -d $ROOT ]; then
1948	echo "WARNING: -w specified, but $ROOT does not exist;" \
1949	    "ignoring -w\n" | tee -a $mail_msg_file >> $LOGFILE
1950	w_FLAG=n
1951fi
1952
1953if [ "$t_FLAG" = "n" ]; then
1954	#
1955	# We're not doing a tools build, so make sure elfsign(1) is
1956	# new enough to safely sign non-crypto binaries.  We test
1957	# debugging output from elfsign to detect the old version.
1958	#
1959	newelfsigntest=`SUNW_CRYPTO_DEBUG=stderr /usr/bin/elfsign verify \
1960	    -e /usr/lib/security/pkcs11_softtoken.so.1 2>&1 \
1961	    | egrep algorithmOID`
1962	if [ -z "$newelfsigntest" ]; then
1963		echo "WARNING: /usr/bin/elfsign out of date;" \
1964		    "will only sign crypto modules\n" | \
1965		    tee -a $mail_msg_file >> $LOGFILE
1966		export ELFSIGN_OBJECT=true
1967	elif [ "$VERIFY_ELFSIGN" = "y" ]; then
1968		echo "WARNING: VERIFY_ELFSIGN=y requires" \
1969		    "the -t flag; ignoring VERIFY_ELFSIGN\n" | \
1970		    tee -a $mail_msg_file >> $LOGFILE
1971	fi
1972fi
1973
1974[ "$O_FLAG" = y ] && MULTI_PROTO=yes
1975
1976case $MULTI_PROTO in
1977yes|no)	;;
1978*)
1979	echo "WARNING: MULTI_PROTO is \"$MULTI_PROTO\"; " \
1980	    "should be \"yes\" or \"no\"." | tee -a $mail_msg_file >> $LOGFILE
1981	echo "Setting MULTI_PROTO to \"no\".\n" | \
1982	    tee -a $mail_msg_file >> $LOGFILE
1983	export MULTI_PROTO=no
1984	;;
1985esac
1986
1987echo "\n==== Build version ====\n" | tee -a $mail_msg_file >> $LOGFILE
1988echo $VERSION | tee -a $mail_msg_file >> $LOGFILE
1989
1990# Save the current proto area if we're comparing against the last build
1991if [ "$w_FLAG" = "y" -a -d "$ROOT" ]; then
1992    if [ -d "$ROOT.prev" ]; then
1993	rm -rf $ROOT.prev
1994    fi
1995    mv $ROOT $ROOT.prev
1996fi
1997
1998# Same for non-DEBUG proto area
1999if [ "$w_FLAG" = "y" -a "$MULTI_PROTO" = yes -a -d "$ROOT-nd" ]; then
2000	if [ -d "$ROOT-nd.prev" ]; then
2001		rm -rf $ROOT-nd.prev
2002	fi
2003	mv $ROOT-nd $ROOT-nd.prev
2004fi
2005
2006#
2007# Echo the SCM type of the parent workspace, this can't just be which_scm
2008# as that does not know how to identify various network repositories.
2009#
2010function parent_wstype {
2011	typeset scm_type junk
2012
2013	CODEMGR_WS="$BRINGOVER_WS" "$WHICH_SCM" 2>/dev/null \
2014	    | read scm_type junk
2015	if [[ -z "$scm_type" || "$scm_type" == unknown ]]; then
2016		# Probe BRINGOVER_WS to determine its type
2017		if [[ $BRINGOVER_WS == svn*://* ]]; then
2018			scm_type="subversion"
2019		elif [[ $BRINGOVER_WS == file://* ]] &&
2020		    egrep -s "This is a Subversion repository" \
2021		    ${BRINGOVER_WS#file://}/README.txt 2> /dev/null; then
2022			scm_type="subversion"
2023		elif [[ $BRINGOVER_WS == ssh://* ]]; then
2024			scm_type="mercurial"
2025		elif [[ $BRINGOVER_WS == http://* ]] && \
2026		    wget -q -O- --save-headers "$BRINGOVER_WS/?cmd=heads" | \
2027		    egrep -s "application/mercurial" 2> /dev/null; then
2028			scm_type="mercurial"
2029		elif svn info $BRINGOVER_WS > /dev/null 2>&1; then
2030			scm_type="subversion"
2031		else
2032			scm_type="none"
2033		fi
2034	fi
2035
2036	# fold both unsupported and unrecognized results into "none"
2037	case "$scm_type" in
2038	none|subversion|teamware|mercurial)
2039		;;
2040	*)	scm_type=none
2041		;;
2042	esac
2043
2044	echo $scm_type
2045}
2046
2047# Echo the SCM types of $CODEMGR_WS and $BRINGOVER_WS
2048function child_wstype {
2049	typeset scm_type junk
2050
2051	# Probe CODEMGR_WS to determine its type
2052	if [[ -d $CODEMGR_WS ]]; then
2053		$WHICH_SCM | read scm_type junk || exit 1
2054	fi
2055
2056	case "$scm_type" in
2057	none|subversion|git|teamware|mercurial)
2058		;;
2059	*)	scm_type=none
2060		;;
2061	esac
2062
2063	echo $scm_type
2064}
2065
2066SCM_TYPE=$(child_wstype)
2067
2068#
2069#	Decide whether to clobber
2070#
2071if [ "$i_FLAG" = "n" -a -d "$SRC" ]; then
2072	echo "\n==== Make clobber at `date` ====\n" >> $LOGFILE
2073
2074	cd $SRC
2075	# remove old clobber file
2076	rm -f $SRC/clobber.out
2077	rm -f $SRC/clobber-${MACH}.out
2078
2079	# Remove all .make.state* files, just in case we are restarting
2080	# the build after having interrupted a previous 'make clobber'.
2081	find . \( -name SCCS -o -name .hg -o -name .svn -o -name .git \
2082		-o -name 'interfaces.*' \) -prune \
2083		-o -name '.make.*' -print | xargs rm -f
2084
2085	$MAKE -ek clobber 2>&1 | tee -a $SRC/clobber-${MACH}.out >> $LOGFILE
2086	echo "\n==== Make clobber ERRORS ====\n" >> $mail_msg_file
2087	grep "$MAKE:" $SRC/clobber-${MACH}.out |
2088		egrep -v "Ignoring unknown host" \
2089		>> $mail_msg_file
2090
2091	if [[ "$t_FLAG" = "y" || "$O_FLAG" = "y" ]]; then
2092		echo "\n==== Make tools clobber at `date` ====\n" >> $LOGFILE
2093		cd ${TOOLS}
2094		rm -f ${TOOLS}/clobber-${MACH}.out
2095		$MAKE TOOLS_PROTO=$TOOLS_PROTO -ek clobber 2>&1 | \
2096			tee -a ${TOOLS}/clobber-${MACH}.out >> $LOGFILE
2097		echo "\n==== Make tools clobber ERRORS ====\n" \
2098			>> $mail_msg_file
2099		grep "$MAKE:" ${TOOLS}/clobber-${MACH}.out \
2100			>> $mail_msg_file
2101		rm -rf ${TOOLS_PROTO}
2102		mkdir -p ${TOOLS_PROTO}
2103	fi
2104
2105	typeset roots=$(allprotos)
2106	echo "\n\nClearing $roots" >> "$LOGFILE"
2107	rm -rf $roots
2108
2109	# Get back to a clean workspace as much as possible to catch
2110	# problems that only occur on fresh workspaces.
2111	# Remove all .make.state* files, libraries, and .o's that may
2112	# have been omitted from clobber.  A couple of libraries are
2113	# under source code control, so leave them alone.
2114	# We should probably blow away temporary directories too.
2115	cd $SRC
2116	find $relsrcdirs \( -name SCCS -o -name .hg -o -name .svn \
2117	    -o -name .git -o -name 'interfaces.*' \) -prune -o \
2118	    \( -name '.make.*' -o -name 'lib*.a' -o -name 'lib*.so*' -o \
2119	       -name '*.o' \) -print | \
2120	    grep -v 'tools/ctf/dwarf/.*/libdwarf' | xargs rm -f
2121else
2122	echo "\n==== No clobber at `date` ====\n" >> $LOGFILE
2123fi
2124
2125type bringover_teamware > /dev/null 2>&1 || function bringover_teamware {
2126	# sleep on the parent workspace's lock
2127	while egrep -s write $BRINGOVER_WS/Codemgr_wsdata/locks
2128	do
2129		sleep 120
2130	done
2131
2132	if [[ -z $BRINGOVER ]]; then
2133		BRINGOVER=$TEAMWARE/bin/bringover
2134	fi
2135
2136	staffer $BRINGOVER -c "nightly update" -p $BRINGOVER_WS \
2137	    -w $CODEMGR_WS $BRINGOVER_FILES < /dev/null 2>&1 ||
2138		touch $TMPDIR/bringover_failed
2139
2140        staffer bringovercheck $CODEMGR_WS >$TMPDIR/bringovercheck.out 2>&1
2141	if [ -s $TMPDIR/bringovercheck.out ]; then
2142		echo "\n==== POST-BRINGOVER CLEANUP NOISE ====\n"
2143		cat $TMPDIR/bringovercheck.out
2144	fi
2145}
2146
2147type bringover_mercurial > /dev/null 2>&1 || function bringover_mercurial {
2148	typeset -x PATH=$PATH
2149
2150	# If the repository doesn't exist yet, then we want to populate it.
2151	if [[ ! -d $CODEMGR_WS/.hg ]]; then
2152		staffer hg init $CODEMGR_WS
2153		staffer echo "[paths]" > $CODEMGR_WS/.hg/hgrc
2154		staffer echo "default=$BRINGOVER_WS" >> $CODEMGR_WS/.hg/hgrc
2155		touch $TMPDIR/new_repository
2156	fi
2157
2158	#
2159	# If the user set CLOSED_BRINGOVER_WS and didn't set CLOSED_IS_PRESENT
2160	# to "no," then we'll want to initialise the closed repository
2161	#
2162	# We use $orig_closed_is_present instead of $CLOSED_IS_PRESENT,
2163	# because for newly-created source trees, the latter will be "no"
2164	# until after the bringover completes.
2165	#
2166	if [[ "$orig_closed_is_present" != "no" && \
2167	    -n "$CLOSED_BRINGOVER_WS" && \
2168	    ! -d $CODEMGR_WS/usr/closed/.hg ]]; then
2169		staffer mkdir -p $CODEMGR_WS/usr/closed
2170		staffer hg init $CODEMGR_WS/usr/closed
2171		staffer echo "[paths]" > $CODEMGR_WS/usr/closed/.hg/hgrc
2172		staffer echo "default=$CLOSED_BRINGOVER_WS" >> $CODEMGR_WS/usr/closed/.hg/hgrc
2173		touch $TMPDIR/new_closed
2174		export CLOSED_IS_PRESENT=yes
2175	fi
2176
2177	typeset -x HGMERGE="/bin/false"
2178
2179	#
2180	# If the user has changes, regardless of whether those changes are
2181	# committed, and regardless of whether those changes conflict, then
2182	# we'll attempt to merge them either implicitly (uncommitted) or
2183	# explicitly (committed).
2184	#
2185	# These are the messages we'll use to help clarify mercurial output
2186	# in those cases.
2187	#
2188	typeset mergefailmsg="\
2189***\n\
2190*** nightly was unable to automatically merge your changes.  You should\n\
2191*** redo the full merge manually, following the steps outlined by mercurial\n\
2192*** above, then restart nightly.\n\
2193***\n"
2194	typeset mergepassmsg="\
2195***\n\
2196*** nightly successfully merged your changes.  This means that your working\n\
2197*** directory has been updated, but those changes are not yet committed.\n\
2198*** After nightly completes, you should validate the results of the merge,\n\
2199*** then use hg commit manually.\n\
2200***\n"
2201
2202	#
2203	# For each repository in turn:
2204	#
2205	# 1. Do the pull.  If this fails, dump the output and bail out.
2206	#
2207	# 2. If the pull resulted in an extra head, do an explicit merge.
2208	#    If this fails, dump the output and bail out.
2209	#
2210	# Because we can't rely on Mercurial to exit with a failure code
2211	# when a merge fails (Mercurial issue #186), we must grep the
2212	# output of pull/merge to check for attempted and/or failed merges.
2213	#
2214	# 3. If a merge failed, set the message and fail the bringover.
2215	#
2216	# 4. Otherwise, if a merge succeeded, set the message
2217	#
2218	# 5. Dump the output, and any message from step 3 or 4.
2219	#
2220
2221	typeset HG_SOURCE=$BRINGOVER_WS
2222	if [ ! -f $TMPDIR/new_repository ]; then
2223		HG_SOURCE=$TMPDIR/open_bundle.hg
2224		staffer hg --cwd $CODEMGR_WS incoming --bundle $HG_SOURCE \
2225		    -v $BRINGOVER_WS > $TMPDIR/incoming_open.out
2226
2227		#
2228		# If there are no incoming changesets, then incoming will
2229		# fail, and there will be no bundle file.  Reset the source,
2230		# to allow the remaining logic to complete with no false
2231		# negatives.  (Unlike incoming, pull will return success
2232		# for the no-change case.)
2233		#
2234		if (( $? != 0 )); then
2235			HG_SOURCE=$BRINGOVER_WS
2236		fi
2237	fi
2238
2239	staffer hg --cwd $CODEMGR_WS pull -u $HG_SOURCE \
2240	    > $TMPDIR/pull_open.out 2>&1
2241	if (( $? != 0 )); then
2242		printf "%s: pull failed as follows:\n\n" "$CODEMGR_WS"
2243		cat $TMPDIR/pull_open.out
2244		if grep "^merging.*failed" $TMPDIR/pull_open.out > /dev/null 2>&1; then
2245			printf "$mergefailmsg"
2246		fi
2247		touch $TMPDIR/bringover_failed
2248		return
2249	fi
2250
2251	if grep "not updating" $TMPDIR/pull_open.out > /dev/null 2>&1; then
2252		staffer hg --cwd $CODEMGR_WS merge \
2253		    >> $TMPDIR/pull_open.out 2>&1
2254		if (( $? != 0 )); then
2255			printf "%s: merge failed as follows:\n\n" \
2256			    "$CODEMGR_WS"
2257			cat $TMPDIR/pull_open.out
2258			if grep "^merging.*failed" $TMPDIR/pull_open.out \
2259			    > /dev/null 2>&1; then
2260				printf "$mergefailmsg"
2261			fi
2262			touch $TMPDIR/bringover_failed
2263			return
2264		fi
2265	fi
2266
2267	printf "updated %s with the following results:\n" "$CODEMGR_WS"
2268	cat $TMPDIR/pull_open.out
2269	if grep "^merging" $TMPDIR/pull_open.out >/dev/null 2>&1; then
2270		printf "$mergepassmsg"
2271	fi
2272	printf "\n"
2273
2274	#
2275	# We only want to update usr/closed if it exists, and we haven't been
2276	# told not to via $CLOSED_IS_PRESENT, and we actually know where to
2277	# pull from ($CLOSED_BRINGOVER_WS).
2278	#
2279	if [[ $CLOSED_IS_PRESENT = yes && \
2280	    -d $CODEMGR_WS/usr/closed/.hg && \
2281	    -n $CLOSED_BRINGOVER_WS ]]; then
2282
2283		HG_SOURCE=$CLOSED_BRINGOVER_WS
2284		if [ ! -f $TMPDIR/new_closed ]; then
2285			HG_SOURCE=$TMPDIR/closed_bundle.hg
2286			staffer hg --cwd $CODEMGR_WS/usr/closed incoming \
2287			    --bundle $HG_SOURCE -v $CLOSED_BRINGOVER_WS \
2288			    > $TMPDIR/incoming_closed.out
2289
2290			#
2291			# If there are no incoming changesets, then incoming will
2292			# fail, and there will be no bundle file.  Reset the source,
2293			# to allow the remaining logic to complete with no false
2294			# negatives.  (Unlike incoming, pull will return success
2295			# for the no-change case.)
2296			#
2297			if (( $? != 0 )); then
2298				HG_SOURCE=$CLOSED_BRINGOVER_WS
2299			fi
2300		fi
2301
2302		staffer hg --cwd $CODEMGR_WS/usr/closed pull -u \
2303			$HG_SOURCE > $TMPDIR/pull_closed.out 2>&1
2304		if (( $? != 0 )); then
2305			printf "closed pull failed as follows:\n\n"
2306			cat $TMPDIR/pull_closed.out
2307			if grep "^merging.*failed" $TMPDIR/pull_closed.out \
2308			    > /dev/null 2>&1; then
2309				printf "$mergefailmsg"
2310			fi
2311			touch $TMPDIR/bringover_failed
2312			return
2313		fi
2314
2315		if grep "not updating" $TMPDIR/pull_closed.out > /dev/null 2>&1; then
2316			staffer hg --cwd $CODEMGR_WS/usr/closed merge \
2317			    >> $TMPDIR/pull_closed.out 2>&1
2318			if (( $? != 0 )); then
2319				printf "closed merge failed as follows:\n\n"
2320				cat $TMPDIR/pull_closed.out
2321				if grep "^merging.*failed" $TMPDIR/pull_closed.out > /dev/null 2>&1; then
2322					printf "$mergefailmsg"
2323				fi
2324				touch $TMPDIR/bringover_failed
2325				return
2326			fi
2327		fi
2328
2329		printf "updated %s with the following results:\n" \
2330		    "$CODEMGR_WS/usr/closed"
2331		cat $TMPDIR/pull_closed.out
2332		if grep "^merging" $TMPDIR/pull_closed.out > /dev/null 2>&1; then
2333			printf "$mergepassmsg"
2334		fi
2335	fi
2336
2337	#
2338	# Per-changeset output is neither useful nor manageable for a
2339	# newly-created repository.
2340	#
2341	if [ -f $TMPDIR/new_repository ]; then
2342		return
2343	fi
2344
2345	printf "\nadded the following changesets to open repository:\n"
2346	cat $TMPDIR/incoming_open.out
2347
2348	#
2349	# The closed repository could have been newly created, even though
2350	# the open one previously existed...
2351	#
2352	if [ -f $TMPDIR/new_closed ]; then
2353		return
2354	fi
2355
2356	if [ -f $TMPDIR/incoming_closed.out ]; then
2357		printf "\nadded the following changesets to closed repository:\n"
2358		cat $TMPDIR/incoming_closed.out
2359	fi
2360}
2361
2362type bringover_subversion > /dev/null 2>&1 || function bringover_subversion {
2363	typeset -x PATH=$PATH
2364
2365	if [[ ! -d $CODEMGR_WS/.svn ]]; then
2366		staffer svn checkout $BRINGOVER_WS $CODEMGR_WS ||
2367			touch $TMPDIR/bringover_failed
2368	else
2369		typeset root
2370		root=$(staffer svn info $CODEMGR_WS |
2371			nawk '/^Repository Root:/ {print $NF}')
2372		if [[ $root != $BRINGOVER_WS ]]; then
2373			# We fail here because there's no way to update
2374			# from a named repo.
2375			cat <<-EOF
2376			\$BRINGOVER_WS doesn't match repository root:
2377			  \$BRINGOVER_WS:  $BRINGOVER_WS
2378			  Repository root: $root
2379			EOF
2380			touch $TMPDIR/bringover_failed
2381		else
2382			# If a conflict happens, svn still exits 0.
2383			staffer svn update $CODEMGR_WS | tee $TMPDIR/pull.out ||
2384				touch $TMPDIR/bringover_failed
2385			if grep "^C" $TMPDIR/pull.out > /dev/null 2>&1; then
2386				touch $TMPDIR/bringover_failed
2387			fi
2388		fi
2389	fi
2390}
2391
2392type bringover_none > /dev/null 2>&1 || function bringover_none {
2393	echo "Couldn't figure out what kind of SCM to use for $BRINGOVER_WS."
2394	touch $TMPDIR/bringover_failed
2395}
2396
2397#
2398#	Decide whether to bringover to the codemgr workspace
2399#
2400if [ "$n_FLAG" = "n" ]; then
2401	PARENT_SCM_TYPE=$(parent_wstype)
2402
2403	if [[ $SCM_TYPE != none && $SCM_TYPE != $PARENT_SCM_TYPE ]]; then
2404		echo "cannot bringover from $PARENT_SCM_TYPE to $SCM_TYPE, " \
2405		    "quitting at `date`." | tee -a $mail_msg_file >> $LOGFILE
2406		exit 1
2407	fi
2408
2409	run_hook PRE_BRINGOVER
2410
2411	echo "\n==== bringover to $CODEMGR_WS at `date` ====\n" >> $LOGFILE
2412	echo "\n==== BRINGOVER LOG ====\n" >> $mail_msg_file
2413
2414	eval "bringover_${PARENT_SCM_TYPE}" 2>&1 |
2415		tee -a $mail_msg_file >> $LOGFILE
2416
2417	if [ -f $TMPDIR/bringover_failed ]; then
2418		rm -f $TMPDIR/bringover_failed
2419		build_ok=n
2420		echo "trouble with bringover, quitting at `date`." |
2421			tee -a $mail_msg_file >> $LOGFILE
2422		exit 1
2423	fi
2424
2425	#
2426	# It's possible that we used the bringover above to create
2427	# $CODEMGR_WS.  If so, then SCM_TYPE was previously "none,"
2428	# but should now be the same as $BRINGOVER_WS.
2429	#
2430	[[ $SCM_TYPE = none ]] && SCM_TYPE=$PARENT_SCM_TYPE
2431
2432	run_hook POST_BRINGOVER
2433
2434	#
2435	# Possible transition from pre-split workspace to split
2436	# workspace.  See if the bringover changed anything.
2437	#
2438	CLOSED_IS_PRESENT="$orig_closed_is_present"
2439	check_closed_tree
2440
2441else
2442	echo "\n==== No bringover to $CODEMGR_WS ====\n" >> $LOGFILE
2443fi
2444
2445if [[ "$O_FLAG" = y && "$CLOSED_IS_PRESENT" != "yes" ]]; then
2446	build_ok=n
2447	echo "OpenSolaris binary deliverables need usr/closed." \
2448	    | tee -a "$mail_msg_file" >> $LOGFILE
2449	exit 1
2450fi
2451
2452# Safeguards
2453[[ -v CODEMGR_WS ]] || fatal_error "Error: Variable CODEMGR_WS not set."
2454[[ -d "${CODEMGR_WS}" ]] || fatal_error "Error: ${CODEMGR_WS} is not a directory."
2455[[ -f "${CODEMGR_WS}/usr/src/Makefile" ]] || fatal_error "Error: ${CODEMGR_WS}/usr/src/Makefile not found."
2456
2457echo "\n==== Build environment ====\n" | tee -a $build_environ_file >> $LOGFILE
2458
2459# System
2460whence uname | tee -a $build_environ_file >> $LOGFILE
2461uname -a 2>&1 | tee -a $build_environ_file >> $LOGFILE
2462echo | tee -a $build_environ_file >> $LOGFILE
2463
2464# make
2465whence $MAKE | tee -a $build_environ_file >> $LOGFILE
2466$MAKE -v | tee -a $build_environ_file >> $LOGFILE
2467echo "number of concurrent jobs = $DMAKE_MAX_JOBS" |
2468    tee -a $build_environ_file >> $LOGFILE
2469
2470#
2471# Report the compiler versions.
2472#
2473
2474if [[ ! -f $SRC/Makefile ]]; then
2475	build_ok=n
2476	echo "\nUnable to find \"Makefile\" in $SRC." | \
2477	    tee -a $build_environ_file >> $LOGFILE
2478	exit 1
2479fi
2480
2481( cd $SRC
2482  for target in cc-version cc64-version java-version; do
2483	echo
2484	#
2485	# Put statefile somewhere we know we can write to rather than trip
2486	# over a read-only $srcroot.
2487	#
2488	rm -f $TMPDIR/make-state
2489	export SRC
2490	if $MAKE -K $TMPDIR/make-state -e $target 2>/dev/null; then
2491		continue
2492	fi
2493	touch $TMPDIR/nocompiler
2494  done
2495  echo
2496) | tee -a $build_environ_file >> $LOGFILE
2497
2498if [ -f $TMPDIR/nocompiler ]; then
2499	rm -f $TMPDIR/nocompiler
2500	build_ok=n
2501	echo "Aborting due to missing compiler." |
2502		tee -a $build_environ_file >> $LOGFILE
2503	exit 1
2504fi
2505
2506# as
2507whence as | tee -a $build_environ_file >> $LOGFILE
2508as -V 2>&1 | head -1 | tee -a $build_environ_file >> $LOGFILE
2509echo | tee -a $build_environ_file >> $LOGFILE
2510
2511# Check that we're running a capable link-editor
2512whence ld | tee -a $build_environ_file >> $LOGFILE
2513LDVER=`ld -V 2>&1`
2514echo $LDVER | tee -a $build_environ_file >> $LOGFILE
2515LDVER=`echo $LDVER | sed -e "s/.*-1\.\([0-9]*\).*/\1/"`
2516if [ `expr $LDVER \< 422` -eq 1 ]; then
2517	echo "The link-editor needs to be at version 422 or higher to build" | \
2518	    tee -a $build_environ_file >> $LOGFILE
2519	echo "the latest stuff.  Hope your build works." | \
2520	    tee -a $build_environ_file >> $LOGFILE
2521fi
2522
2523#
2524# Build and use the workspace's tools if requested
2525#
2526if [[ "$t_FLAG" = "y" || "$O_FLAG" = y ]]; then
2527	set_non_debug_build_flags
2528
2529	build_tools ${TOOLS_PROTO}
2530	if [[ $? != 0  && "$t_FLAG" = y ]]; then
2531		use_tools $TOOLS_PROTO
2532	fi
2533fi
2534
2535#
2536# copy ihv proto area in addition to the build itself
2537#
2538if [ "$X_FLAG" = "y" ]; then
2539	copy_ihv_proto
2540fi
2541
2542if [ "$i_FLAG" = "y" -a "$SH_FLAG" = "y" ]; then
2543	echo "\n==== NOT Building base OS-Net source ====\n" | \
2544	    tee -a $LOGFILE >> $mail_msg_file
2545else
2546	# timestamp the start of the normal build; the findunref tool uses it.
2547	touch $SRC/.build.tstamp
2548
2549	normal_build
2550fi
2551
2552#
2553# Generate the THIRDPARTYLICENSE files if needed.  This is done after
2554# the build, so that dynamically-created license files are there.
2555# It's done before findunref to help identify license files that need
2556# to be added to tools/opensolaris/license-list.
2557#
2558if [ "$O_FLAG" = y -a "$build_ok" = y ]; then
2559	echo "\n==== Generating THIRDPARTYLICENSE files ====\n" |
2560	    tee -a "$mail_msg_file" >> "$LOGFILE"
2561
2562	if [ -d $ROOT/licenses/usr ]; then
2563		( cd $ROOT/licenses ; \
2564		    mktpl $SRC/pkg/license-list ) >> "$LOGFILE" 2>&1
2565		if (( $? != 0 )) ; then
2566			echo "Couldn't create THIRDPARTYLICENSE files" |
2567			    tee -a "$mail_msg_file" >> "$LOGFILE"
2568		fi
2569	else
2570		echo "No licenses found under $ROOT/licenses" |
2571		    tee -a "$mail_msg_file" >> "$LOGFILE"
2572	fi
2573fi
2574
2575ORIG_SRC=$SRC
2576BINARCHIVE=${CODEMGR_WS}/bin-${MACH}.cpio.Z
2577
2578if [ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o "$SH_FLAG" = "y" ]; then
2579	save_binaries
2580fi
2581
2582
2583# EXPORT_SRC comes after CRYPT_SRC since a domestic build will need
2584# $SRC pointing to the export_source usr/src.
2585
2586if [ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o "$SH_FLAG" = "y" ]; then
2587	if [ "$SD_FLAG" = "y" -a $build_ok = y ]; then
2588	    set_up_source_build ${CODEMGR_WS} ${CRYPT_SRC} CRYPT_SRC
2589	fi
2590
2591	if [ $build_ok = y ]; then
2592	    set_up_source_build ${CODEMGR_WS} ${EXPORT_SRC} EXPORT_SRC
2593	fi
2594fi
2595
2596if [ "$SD_FLAG" = "y" -a $build_ok = y ]; then
2597	# drop the crypt files in place.
2598	cd ${EXPORT_SRC}
2599	echo "\nextracting crypt_files.cpio.Z onto export_source.\n" \
2600	    >> ${LOGFILE}
2601	zcat ${CODEMGR_WS}/crypt_files.cpio.Z | \
2602	    cpio -idmucvB 2>/dev/null >> ${LOGFILE}
2603	if [ "$?" = "0" ]; then
2604		echo "\n==== DOMESTIC extraction succeeded ====\n" \
2605		    >> $mail_msg_file
2606	else
2607		echo "\n==== DOMESTIC extraction failed ====\n" \
2608		    >> $mail_msg_file
2609	fi
2610
2611fi
2612
2613if [ "$SO_FLAG" = "y" -a "$build_ok" = y ]; then
2614	#
2615	# Copy the open sources into their own tree.
2616	# If copy_source fails, it will have already generated an
2617	# error message and set build_ok=n, so we don't need to worry
2618	# about that here.
2619	#
2620	copy_source $CODEMGR_WS $OPEN_SRCDIR OPEN_SOURCE usr/src
2621fi
2622
2623if [ "$SO_FLAG" = "y" -a "$build_ok" = y ]; then
2624	SRC=$OPEN_SRCDIR/usr/src
2625	export CLOSED_IS_PRESENT=no
2626fi
2627
2628if is_source_build && [ $build_ok = y ] ; then
2629	# remove proto area(s) here, since we don't clobber
2630	rm -rf `allprotos`
2631	if [ "$t_FLAG" = "y" ]; then
2632		set_non_debug_build_flags
2633		ORIG_TOOLS=$TOOLS
2634		#
2635		# SRC was set earlier to point to the source build
2636		# source tree (e.g., $EXPORT_SRC).
2637		#
2638		TOOLS=${SRC}/tools
2639		TOOLS_PROTO=${TOOLS}/${TOOLS_PROTO_REL}; export TOOLS_PROTO
2640		build_tools ${TOOLS_PROTO}
2641		if [[ $? != 0 ]]; then
2642			use_tools ${TOOLS_PROTO}
2643		fi
2644	fi
2645
2646	normal_build
2647fi
2648
2649#
2650# There are several checks that need to look at the proto area, but
2651# they only need to look at one, and they don't care whether it's
2652# DEBUG or non-DEBUG.
2653#
2654if [[ "$MULTI_PROTO" = yes && "$D_FLAG" = n ]]; then
2655	checkroot=$ROOT-nd
2656else
2657	checkroot=$ROOT
2658fi
2659
2660if [ "$build_ok" = "y" ]; then
2661	echo "\n==== Creating protolist system file at `date` ====" \
2662		>> $LOGFILE
2663	protolist $checkroot > $ATLOG/proto_list_${MACH}
2664	echo "==== protolist system file created at `date` ====\n" \
2665		>> $LOGFILE
2666
2667	if [ "$N_FLAG" != "y" ]; then
2668
2669		E1=
2670		f1=
2671		if [ -d "$SRC/pkgdefs" ]; then
2672			f1="$SRC/pkgdefs/etc/exception_list_$MACH"
2673			if [ "$X_FLAG" = "y" ]; then
2674				f1="$f1 $IA32_IHV_WS/usr/src/pkgdefs/etc/exception_list_$MACH"
2675			fi
2676		fi
2677
2678		for f in $f1; do
2679			if [ -f "$f" ]; then
2680				E1="$E1 -e $f"
2681			fi
2682		done
2683
2684		E2=
2685		f2=
2686		if [ -d "$SRC/pkg" ]; then
2687			f2="$f2 exceptions/packaging"
2688		fi
2689
2690		for f in $f2; do
2691			if [ -f "$f" ]; then
2692				E2="$E2 -e $f"
2693			fi
2694		done
2695
2696		if [ -f "$REF_PROTO_LIST" ]; then
2697			#
2698			# For builds that copy the IHV proto area (-X), add the
2699			# IHV proto list to the reference list if the reference
2700			# was built without -X.
2701			#
2702			# For builds that don't copy the IHV proto area, add the
2703			# IHV proto list to the build's proto list if the
2704			# reference was built with -X.
2705			#
2706			# Use the presence of the first file entry of the cached
2707			# IHV proto list in the reference list to determine
2708			# whether it was built with -X or not.
2709			#
2710			IHV_REF_PROTO_LIST=$SRC/pkg/proto_list_ihv_$MACH
2711			grepfor=$(nawk '$1 == "f" { print $2; exit }' \
2712				$IHV_REF_PROTO_LIST 2> /dev/null)
2713			if [ $? = 0 -a -n "$grepfor" ]; then
2714				if [ "$X_FLAG" = "y" ]; then
2715					grep -w "$grepfor" \
2716						$REF_PROTO_LIST > /dev/null
2717					if [ ! "$?" = "0" ]; then
2718						REF_IHV_PROTO="-d $IHV_REF_PROTO_LIST"
2719					fi
2720				else
2721					grep -w "$grepfor" \
2722						$REF_PROTO_LIST > /dev/null
2723					if [ "$?" = "0" ]; then
2724						IHV_PROTO_LIST="$IHV_REF_PROTO_LIST"
2725					fi
2726				fi
2727			fi
2728		fi
2729	fi
2730
2731	if [ "$N_FLAG" != "y" -a -f $SRC/pkgdefs/Makefile ]; then
2732		echo "\n==== Impact on SVr4 packages ====\n" >> $mail_msg_file
2733		#
2734		# Compare the build's proto list with current package
2735		# definitions to audit the quality of package
2736		# definitions and makefile install targets. Use the
2737		# current exception list.
2738		#
2739		PKGDEFS_LIST=""
2740		for d in $abssrcdirs; do
2741			if [ -d $d/pkgdefs ]; then
2742				PKGDEFS_LIST="$PKGDEFS_LIST -d $d/pkgdefs"
2743			fi
2744		done
2745		if [ "$X_FLAG" = "y" -a \
2746		    -d $IA32_IHV_WS/usr/src/pkgdefs ]; then
2747			PKGDEFS_LIST="$PKGDEFS_LIST -d $IA32_IHV_WS/usr/src/pkgdefs"
2748		fi
2749		$PROTOCMPTERSE \
2750		    "Files missing from the proto area:" \
2751		    "Files missing from packages:" \
2752		    "Inconsistencies between pkgdefs and proto area:" \
2753		    ${E1} \
2754		    ${PKGDEFS_LIST} \
2755		    $ATLOG/proto_list_${MACH} \
2756		    >> $mail_msg_file
2757	fi
2758
2759	if [ "$N_FLAG" != "y" -a -d $SRC/pkg ]; then
2760		echo "\n==== Validating manifests against proto area ====\n" \
2761		    >> $mail_msg_file
2762		( cd $SRC/pkg ; $MAKE -e protocmp ROOT="$checkroot" ) \
2763		    >> $mail_msg_file
2764
2765	fi
2766
2767	if [ "$N_FLAG" != "y" -a -f "$REF_PROTO_LIST" ]; then
2768		echo "\n==== Impact on proto area ====\n" >> $mail_msg_file
2769		if [ -n "$E2" ]; then
2770			ELIST=$E2
2771		else
2772			ELIST=$E1
2773		fi
2774		$PROTOCMPTERSE \
2775			"Files in yesterday's proto area, but not today's:" \
2776			"Files in today's proto area, but not yesterday's:" \
2777			"Files that changed between yesterday and today:" \
2778			${ELIST} \
2779			-d $REF_PROTO_LIST \
2780			$REF_IHV_PROTO \
2781			$ATLOG/proto_list_${MACH} \
2782			$IHV_PROTO_LIST \
2783			>> $mail_msg_file
2784	fi
2785fi
2786
2787if [ "$u_FLAG" = "y"  -a "$build_ok" = "y" ]; then
2788	staffer cp $ATLOG/proto_list_${MACH} \
2789		$PARENT_WS/usr/src/proto_list_${MACH}
2790fi
2791
2792# Update parent proto area if necessary. This is done now
2793# so that the proto area has either DEBUG or non-DEBUG kernels.
2794# Note that this clears out the lock file, so we can dispense with
2795# the variable now.
2796if [ "$U_FLAG" = "y" -a "$build_ok" = "y" ]; then
2797	echo "\n==== Copying proto area to $NIGHTLY_PARENT_ROOT ====\n" | \
2798	    tee -a $LOGFILE >> $mail_msg_file
2799	rm -rf $NIGHTLY_PARENT_ROOT/*
2800	unset Ulockfile
2801	mkdir -p $NIGHTLY_PARENT_ROOT
2802	if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
2803		( cd $ROOT; tar cf - . |
2804		    ( cd $NIGHTLY_PARENT_ROOT;  umask 0; tar xpf - ) ) 2>&1 |
2805		    tee -a $mail_msg_file >> $LOGFILE
2806	fi
2807	if [[ "$MULTI_PROTO" = yes && "$F_FLAG" = n ]]; then
2808		rm -rf $NIGHTLY_PARENT_ROOT-nd/*
2809		mkdir -p $NIGHTLY_PARENT_ROOT-nd
2810		cd $ROOT-nd
2811		( tar cf - . |
2812		    ( cd $NIGHTLY_PARENT_ROOT-nd; umask 0; tar xpf - ) ) 2>&1 |
2813		    tee -a $mail_msg_file >> $LOGFILE
2814	fi
2815	if [ -n "${NIGHTLY_PARENT_TOOLS_ROOT}" ]; then
2816		echo "\n==== Copying tools proto area to $NIGHTLY_PARENT_TOOLS_ROOT ====\n" | \
2817		    tee -a $LOGFILE >> $mail_msg_file
2818		rm -rf $NIGHTLY_PARENT_TOOLS_ROOT/*
2819		mkdir -p $NIGHTLY_PARENT_TOOLS_ROOT
2820		if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
2821			( cd $TOOLS_PROTO; tar cf - . |
2822			    ( cd $NIGHTLY_PARENT_TOOLS_ROOT;
2823			    umask 0; tar xpf - ) ) 2>&1 |
2824			    tee -a $mail_msg_file >> $LOGFILE
2825		fi
2826	fi
2827fi
2828
2829#
2830# ELF verification: ABI (-A) and runtime (-r) checks
2831#
2832if [[ ($build_ok = y) && ( ($A_FLAG = y) || ($r_FLAG = y) ) ]]; then
2833	# Directory ELF-data.$MACH holds the files produced by these tests.
2834	elf_ddir=$SRC/ELF-data.$MACH
2835
2836	# If there is a previous ELF-data backup directory, remove it. Then,
2837	# rotate current ELF-data directory into its place and create a new
2838	# empty directory
2839	rm -rf $elf_ddir.ref
2840	if [[ -d $elf_ddir ]]; then
2841		mv $elf_ddir $elf_ddir.ref
2842	fi
2843	mkdir -p $elf_ddir
2844
2845	# Call find_elf to produce a list of the ELF objects in the proto area.
2846	# This list is passed to check_rtime and interface_check, preventing
2847	# them from separately calling find_elf to do the same work twice.
2848	find_elf -fr $checkroot > $elf_ddir/object_list
2849
2850	if [[ $A_FLAG = y ]]; then
2851	       	echo "\n==== Check versioning and ABI information ====\n"  | \
2852		    tee -a $LOGFILE >> $mail_msg_file
2853
2854		# Produce interface description for the proto. Report errors.
2855		interface_check -o -w $elf_ddir -f object_list \
2856			-i interface -E interface.err
2857		if [[ -s $elf_ddir/interface.err ]]; then
2858			tee -a $LOGFILE < $elf_ddir/interface.err \
2859				>> $mail_msg_file
2860		fi
2861
2862		# If ELF_DATA_BASELINE_DIR is defined, compare the new interface
2863		# description file to that from the baseline gate. Issue a
2864		# warning if the baseline is not present, and keep going.
2865		if [[ "$ELF_DATA_BASELINE_DIR" != '' ]]; then
2866			base_ifile="$ELF_DATA_BASELINE_DIR/interface"
2867
2868		       	echo "\n==== Compare versioning and ABI information" \
2869			    "to baseline ====\n"  | \
2870			    tee -a $LOGFILE >> $mail_msg_file
2871		       	echo "Baseline:  $base_ifile\n" >> $LOGFILE
2872
2873			if [[ -f $base_ifile ]]; then
2874				interface_cmp -d -o $base_ifile \
2875				    $elf_ddir/interface > $elf_ddir/interface.cmp
2876				if [[ -s $elf_ddir/interface.cmp ]]; then
2877					echo | tee -a $LOGFILE >> $mail_msg_file
2878					tee -a $LOGFILE < \
2879					    $elf_ddir/interface.cmp \
2880					    >> $mail_msg_file
2881				fi
2882			else
2883			       	echo "baseline not available. comparison" \
2884                                    "skipped" | \
2885				    tee -a $LOGFILE >> $mail_msg_file
2886			fi
2887
2888		fi
2889	fi
2890
2891	if [[ $r_FLAG = y ]]; then
2892		echo "\n==== Check ELF runtime attributes ====\n" | \
2893		    tee -a $LOGFILE >> $mail_msg_file
2894
2895		# If we're doing a DEBUG build the proto area will be left
2896		# with debuggable objects, thus don't assert -s.
2897		if [[ $D_FLAG = y ]]; then
2898			rtime_sflag=""
2899		else
2900			rtime_sflag="-s"
2901		fi
2902		check_rtime -i -m -v $rtime_sflag -o -w $elf_ddir \
2903			-D object_list  -f object_list -E runtime.err \
2904			-I runtime.attr.raw
2905
2906		# check_rtime -I output needs to be sorted in order to
2907		# compare it to that from previous builds.
2908		sort $elf_ddir/runtime.attr.raw > $elf_ddir/runtime.attr
2909		rm $elf_ddir/runtime.attr.raw
2910
2911		# Report errors
2912		if [[ -s $elf_ddir/runtime.err ]]; then
2913			tee -a $LOGFILE < $elf_ddir/runtime.err \
2914				>> $mail_msg_file
2915		fi
2916
2917		# If there is an ELF-data directory from a previous build,
2918		# then diff the attr files. These files contain information
2919		# about dependencies, versioning, and runpaths. There is some
2920		# overlap with the ABI checking done above, but this also
2921		# flushes out non-ABI interface differences along with the
2922		# other information.
2923		echo "\n==== Diff ELF runtime attributes" \
2924		    "(since last build) ====\n" | \
2925		    tee -a $LOGFILE >> $mail_msg_file >> $mail_msg_file
2926
2927		if [[ -f $elf_ddir.ref/runtime.attr ]]; then
2928			diff $elf_ddir.ref/runtime.attr \
2929				$elf_ddir/runtime.attr \
2930				>> $mail_msg_file
2931		fi
2932	fi
2933
2934	# If -u set, copy contents of ELF-data.$MACH to the parent workspace.
2935	if [[ "$u_FLAG" = "y" ]]; then
2936		p_elf_ddir=$PARENT_WS/usr/src/ELF-data.$MACH
2937
2938		# If parent lacks the ELF-data.$MACH directory, create it
2939		if [[ ! -d $p_elf_ddir ]]; then
2940			staffer mkdir -p $p_elf_ddir
2941		fi
2942
2943		# These files are used asynchronously by other builds for ABI
2944		# verification, as above for the -A option. As such, we require
2945		# the file replacement to be atomic. Copy the data to a temp
2946		# file in the same filesystem and then rename into place.
2947		(
2948			cd $elf_ddir
2949			for elf_dfile in *; do
2950				staffer cp $elf_dfile \
2951				    ${p_elf_ddir}/${elf_dfile}.new
2952				staffer mv -f ${p_elf_ddir}/${elf_dfile}.new \
2953				    ${p_elf_ddir}/${elf_dfile}
2954			done
2955		)
2956	fi
2957fi
2958
2959# DEBUG lint of kernel begins
2960
2961if [ "$i_CMD_LINE_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
2962	if [ "$LINTDIRS" = "" ]; then
2963		# LINTDIRS="$SRC/uts y $SRC/stand y $SRC/psm y"
2964		LINTDIRS="$SRC y"
2965	fi
2966	set $LINTDIRS
2967	while [ $# -gt 0 ]; do
2968		dolint $1 $2; shift; shift
2969	done
2970else
2971	echo "\n==== No '$MAKE lint' ====\n" >> $LOGFILE
2972fi
2973
2974# "make check" begins
2975
2976if [ "$i_CMD_LINE_FLAG" = "n" -a "$C_FLAG" = "y" ]; then
2977	# remove old check.out
2978	rm -f $SRC/check.out
2979
2980	rm -f $SRC/check-${MACH}.out
2981	cd $SRC
2982	$MAKE -ek check ROOT="$checkroot" 2>&1 | tee -a $SRC/check-${MACH}.out \
2983	    >> $LOGFILE
2984	echo "\n==== cstyle/hdrchk errors ====\n" >> $mail_msg_file
2985
2986	grep ":" $SRC/check-${MACH}.out |
2987		egrep -v "Ignoring unknown host" | \
2988		sort | uniq >> $mail_msg_file
2989else
2990	echo "\n==== No '$MAKE check' ====\n" >> $LOGFILE
2991fi
2992
2993echo "\n==== Find core files ====\n" | \
2994    tee -a $LOGFILE >> $mail_msg_file
2995
2996find $abssrcdirs -name core -a -type f -exec file {} \; | \
2997	tee -a $LOGFILE >> $mail_msg_file
2998
2999if [ "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
3000	echo "\n==== Diff unreferenced files (since last build) ====\n" \
3001	    | tee -a $LOGFILE >>$mail_msg_file
3002	rm -f $SRC/unref-${MACH}.ref
3003	if [ -f $SRC/unref-${MACH}.out ]; then
3004		mv $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
3005	fi
3006
3007	findunref -S $SCM_TYPE -t $SRC/.build.tstamp -s usr $CODEMGR_WS \
3008	    ${TOOLS}/findunref/exception_list 2>> $mail_msg_file | \
3009	    sort > $SRC/unref-${MACH}.out
3010
3011	if [ ! -f $SRC/unref-${MACH}.ref ]; then
3012		cp $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
3013	fi
3014
3015	diff $SRC/unref-${MACH}.ref $SRC/unref-${MACH}.out >>$mail_msg_file
3016fi
3017
3018#
3019# Generate the OpenSolaris deliverables if requested.  Some of these
3020# steps need to come after findunref and are commented below.
3021#
3022
3023# If we are doing an OpenSolaris _source_ build (-S O) then we do
3024# not have usr/closed available to us to generate closedbins from,
3025# so skip this part.
3026if [ "$SO_FLAG" = n -a "$O_FLAG" = y -a "$build_ok" = y ]; then
3027	echo "\n==== Generating OpenSolaris tarballs ====\n" | \
3028	    tee -a $mail_msg_file >> $LOGFILE
3029
3030	cd $CODEMGR_WS
3031
3032	#
3033	# This step grovels through the package manifests, so it
3034	# must come after findunref.
3035	#
3036	# We assume no DEBUG vs non-DEBUG package content variation
3037	# here; if that changes, then the "make all" in $SRC/pkg will
3038	# need to be moved into the conditionals and repeated for each
3039	# different build.
3040	#
3041	echo "Generating closed binaries tarball(s)..." >> $LOGFILE
3042	closed_basename=on-closed-bins
3043	if [ "$D_FLAG" = y ]; then
3044		bindrop "$closed_basename" >>"$LOGFILE" 2>&1
3045		if (( $? != 0 )) ; then
3046			echo "Couldn't create DEBUG closed binaries." |
3047			    tee -a $mail_msg_file >> $LOGFILE
3048			build_ok=n
3049		fi
3050	fi
3051	if [ "$F_FLAG" = n ]; then
3052		bindrop -n "$closed_basename-nd" >>"$LOGFILE" 2>&1
3053		if (( $? != 0 )) ; then
3054			echo "Couldn't create non-DEBUG closed binaries." |
3055			    tee -a $mail_msg_file >> $LOGFILE
3056			build_ok=n
3057		fi
3058	fi
3059
3060	echo "Generating README.opensolaris..." >> $LOGFILE
3061	cat $SRC/tools/opensolaris/README.opensolaris.tmpl | \
3062	    mkreadme_osol $CODEMGR_WS/README.opensolaris >> $LOGFILE 2>&1
3063	if (( $? != 0 )) ; then
3064		echo "Couldn't create README.opensolaris." |
3065		    tee -a $mail_msg_file >> $LOGFILE
3066		build_ok=n
3067	fi
3068fi
3069
3070# Verify that the usual lists of files, such as exception lists,
3071# contain only valid references to files.  If the build has failed,
3072# then don't check the proto area.
3073CHECK_PATHS=${CHECK_PATHS:-y}
3074if [ "$CHECK_PATHS" = y -a "$N_FLAG" != y ]; then
3075	echo "\n==== Check lists of files ====\n" | tee -a $LOGFILE \
3076		>>$mail_msg_file
3077	arg=-b
3078	[ "$build_ok" = y ] && arg=
3079	checkpaths $arg $checkroot 2>&1 | tee -a $LOGFILE >>$mail_msg_file
3080fi
3081
3082if [ "$M_FLAG" != "y" -a "$build_ok" = y ]; then
3083	echo "\n==== Impact on file permissions ====\n" \
3084		>> $mail_msg_file
3085
3086	abspkgdefs=
3087	abspkg=
3088	for d in $abssrcdirs; do
3089		if [ -d "$d/pkgdefs" ]; then
3090			abspkgdefs="$abspkgdefs $d"
3091		fi
3092		if [ -d "$d/pkg" ]; then
3093			abspkg="$abspkg $d"
3094		fi
3095	done
3096
3097	if [ -n "$abspkgdefs" ]; then
3098		pmodes -qvdP \
3099		    `find $abspkgdefs -name pkginfo.tmpl -print -o \
3100		    -name .del\* -prune | sed -e 's:/pkginfo.tmpl$::' | \
3101		    sort -u` >> $mail_msg_file
3102	fi
3103
3104	if [ -n "$abspkg" ]; then
3105		for d in "$abspkg"; do
3106			( cd $d/pkg ; $MAKE -e pmodes ) >> $mail_msg_file
3107		done
3108	fi
3109fi
3110
3111if [ "$w_FLAG" = "y" -a "$build_ok" = "y" ]; then
3112	if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
3113		do_wsdiff DEBUG $ROOT.prev $ROOT
3114	fi
3115
3116	if [[ "$MULTI_PROTO" = yes && "$F_FLAG" = n ]]; then
3117		do_wsdiff non-DEBUG $ROOT-nd.prev $ROOT-nd
3118	fi
3119fi
3120
3121END_DATE=`date`
3122echo "==== Nightly $maketype build completed: $END_DATE ====" | \
3123    tee -a $LOGFILE >> $build_time_file
3124
3125typeset -i10 hours
3126typeset -Z2 minutes
3127typeset -Z2 seconds
3128
3129elapsed_time=$SECONDS
3130((hours = elapsed_time / 3600 ))
3131((minutes = elapsed_time / 60  % 60))
3132((seconds = elapsed_time % 60))
3133
3134echo "\n==== Total build time ====" | \
3135    tee -a $LOGFILE >> $build_time_file
3136echo "\nreal    ${hours}:${minutes}:${seconds}" | \
3137    tee -a $LOGFILE >> $build_time_file
3138
3139if [ "$u_FLAG" = "y" -a "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
3140	staffer cp ${SRC}/unref-${MACH}.out $PARENT_WS/usr/src/
3141
3142	#
3143	# Produce a master list of unreferenced files -- ideally, we'd
3144	# generate the master just once after all of the nightlies
3145	# have finished, but there's no simple way to know when that
3146	# will be.  Instead, we assume that we're the last nightly to
3147	# finish and merge all of the unref-${MACH}.out files in
3148	# $PARENT_WS/usr/src/.  If we are in fact the final ${MACH} to
3149	# finish, then this file will be the authoritative master
3150	# list.  Otherwise, another ${MACH}'s nightly will eventually
3151	# overwrite ours with its own master, but in the meantime our
3152	# temporary "master" will be no worse than any older master
3153	# which was already on the parent.
3154	#
3155
3156	set -- $PARENT_WS/usr/src/unref-*.out
3157	cp "$1" ${TMPDIR}/unref.merge
3158	shift
3159
3160	for unreffile; do
3161		comm -12 ${TMPDIR}/unref.merge "$unreffile" > ${TMPDIR}/unref.$$
3162		mv ${TMPDIR}/unref.$$ ${TMPDIR}/unref.merge
3163	done
3164
3165	staffer cp ${TMPDIR}/unref.merge $PARENT_WS/usr/src/unrefmaster.out
3166fi
3167
3168#
3169# All done save for the sweeping up.
3170# (whichever exit we hit here will trigger the "cleanup" trap which
3171# optionally sends mail on completion).
3172#
3173if [ "$build_ok" = "y" ]; then
3174	exit 0
3175fi
3176exit 1
3177