Home | History | Annotate | Download | only in scripts
      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 2008 Sun Microsystems, Inc.  All rights reserved.
     25 # Use is subject to license terms.
     26 #
     27 # ident	"%Z%%M%	%I%	%E% SMI"
     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 # -A flag in NIGHTLY_OPTIONS checks ABI diffs in .so files
     50 # This option requires a couple of scripts.
     51 #
     52 # OPTHOME and TEAMWARE may be set in the environment to override /opt
     53 # and /opt/teamware defaults.
     54 #
     55 
     56 #
     57 # The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
     58 # under certain circumstances, which can really screw things up; unset it.
     59 #
     60 unset CDPATH
     61 
     62 # Get the absolute path of the nightly script that the user invoked.  This
     63 # may be a relative path, and we need to do this before changing directory.
     64 nightly_path=`whence $0`
     65 
     66 #
     67 # Keep track of where we found nightly so we can invoke the matching
     68 # which_scm script.  If that doesn't work, don't go guessing, just rely
     69 # on the $PATH settings, which will generally give us either /opt/onbld
     70 # or the user's workspace.
     71 #
     72 WHICH_SCM=$(dirname $nightly_path)/which_scm
     73 if [[ ! -x $WHICH_SCM ]]; then
     74 	WHICH_SCM=which_scm
     75 fi
     76 
     77 #
     78 # Print the tag string used to identify a build (e.g., "DEBUG
     79 # open-only")
     80 # usage: tagstring debug-part open-part
     81 #
     82 tagstring() {
     83 	debug_part=$1
     84 	open_part=$2
     85 
     86 	if [ -n "$open_part" ]; then
     87 		echo "$debug_part $open_part"
     88 	else
     89 		echo "$debug_part"
     90 	fi
     91 }
     92 
     93 #
     94 # Function to do a DEBUG and non-DEBUG build. Needed because we might
     95 # need to do another for the source build, and since we only deliver DEBUG or
     96 # non-DEBUG packages.
     97 #
     98 # usage: normal_build [-O]
     99 # -O	OpenSolaris delivery build.  Put the proto area and
    100 #	(eventually) packages in -open directories.  Use skeleton
    101 #	closed binaries.  Don't generate archives--that needs to be
    102 #	done later, after we've generated the closed binaries.  Also
    103 #	skip the package build (until 6414822 is fixed).
    104 #
    105 
    106 normal_build() {
    107 
    108 	typeset orig_p_FLAG="$p_FLAG"
    109 	typeset orig_a_FLAG="$a_FLAG"
    110 
    111 	suffix=""
    112 	open_only=""
    113 	while getopts O FLAG $*; do
    114 		case $FLAG in
    115 		O)
    116 			suffix="-open"
    117 			open_only="open-only"
    118 			p_FLAG=n
    119 			a_FLAG=n
    120 			;;
    121 		esac
    122 	done
    123 
    124 	# non-DEBUG build begins
    125 
    126 	if [ "$F_FLAG" = "n" ]; then
    127 		set_non_debug_build_flags
    128 		mytag=`tagstring "non-DEBUG" "$open_only"`
    129 		build "$mytag" "$suffix-nd" "$MULTI_PROTO"
    130 		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a \
    131 		    "$p_FLAG" = "y" ]; then
    132 			copy_ihv_pkgs non-DEBUG -nd
    133 		fi
    134 	else
    135 		echo "\n==== No non-DEBUG $open_only build ====\n" >> "$LOGFILE"
    136 	fi
    137 
    138 	# non-DEBUG build ends
    139 
    140 	# DEBUG build begins
    141 
    142 	if [ "$D_FLAG" = "y" ]; then
    143 		set_debug_build_flags
    144 		mytag=`tagstring "DEBUG" "$open_only"`
    145 		build "$mytag" "$suffix" "$MULTI_PROTO"
    146 		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a \
    147 		    "$p_FLAG" = "y" ]; then
    148 			copy_ihv_pkgs DEBUG ""
    149 		fi
    150 
    151 	else
    152 		echo "\n==== No DEBUG $open_only build ====\n" >> "$LOGFILE"
    153 	fi
    154 
    155 	# DEBUG build ends
    156 
    157 	p_FLAG="$orig_p_FLAG"
    158 	a_FLAG="$orig_a_FLAG"
    159 }
    160 
    161 #
    162 # usage: run_hook HOOKNAME ARGS...
    163 #
    164 # If variable "$HOOKNAME" is defined, insert a section header into 
    165 # our logs and then run the command with ARGS
    166 #
    167 run_hook() {
    168 	HOOKNAME=$1
    169     	eval HOOKCMD=\$$HOOKNAME
    170 	shift
    171 
    172 	if [ -n "$HOOKCMD" ]; then 
    173 	    	(
    174 			echo "\n==== Running $HOOKNAME command: $HOOKCMD ====\n"
    175 		    	( $HOOKCMD "$@" 2>&1 )
    176 			if [ "$?" -ne 0 ]; then
    177 			    	# Let exit status propagate up
    178 			    	touch $TMPDIR/abort
    179 			fi
    180 		) | tee -a $mail_msg_file >> $LOGFILE
    181 
    182 		if [ -f $TMPDIR/abort ]; then
    183 			build_ok=n
    184 			echo "\nAborting at request of $HOOKNAME" |
    185 				tee -a $mail_msg_file >> $LOGFILE
    186 			exit 1
    187 		fi
    188 	fi
    189 }
    190 
    191 #
    192 # usage: filelist DESTDIR PATTERN
    193 #
    194 filelist() {
    195 	DEST=$1
    196 	PATTERN=$2
    197 	cd ${DEST}
    198 
    199 	OBJFILES=${ORIG_SRC}/xmod/obj_files
    200 	if [ ! -f ${OBJFILES} ]; then
    201 		return;
    202 	fi
    203 	for i in `grep -v '^#' ${OBJFILES} | \
    204 	    grep ${PATTERN} | cut -d: -f2 | tr -d ' \t'`
    205 	do
    206 		# wildcard expansion
    207 		for j in $i
    208 		do
    209 			if [ -f "$j" ]; then
    210 				echo $j
    211 			fi
    212 			if [ -d "$j" ]; then
    213 				echo $j
    214 			fi
    215 		done
    216 	done | sort | uniq
    217 }
    218 
    219 # function to save off binaries after a full build for later
    220 # restoration
    221 save_binaries() {
    222 	# save off list of binaries
    223 	echo "\n==== Saving binaries from build at `date` ====\n" | \
    224 	    tee -a $mail_msg_file >> $LOGFILE
    225 	rm -f ${BINARCHIVE}
    226 	cd ${CODEMGR_WS}
    227 	filelist ${CODEMGR_WS} '^preserve:' >> $LOGFILE
    228 	filelist ${CODEMGR_WS} '^preserve:' | \
    229 	    cpio -ocB 2>/dev/null | compress \
    230 	    > ${BINARCHIVE}
    231 }
    232 
    233 # delete files
    234 # usage: hybridize_files DESTDIR MAKE_TARGET
    235 hybridize_files() {
    236 	DEST=$1
    237 	MAKETARG=$2
    238 
    239 	echo "\n==== Hybridizing files at `date` ====\n" | \
    240 	    tee -a $mail_msg_file >> $LOGFILE
    241 	for i in `filelist ${DEST} '^delete:'`
    242 	do
    243 		echo "removing ${i}." | tee -a $mail_msg_file >> $LOGFILE
    244 		rm -rf "${i}"
    245 	done
    246 	for i in `filelist ${DEST} '^hybridize:' `
    247 	do
    248 		echo "hybridizing ${i}." | tee -a $mail_msg_file >> $LOGFILE
    249 		rm -f ${i}+
    250 		sed -e "/^# HYBRID DELETE START/,/^# HYBRID DELETE END/d" \
    251 		    < ${i} > ${i}+
    252 		mv ${i}+ ${i}
    253 	done
    254 }
    255 
    256 # restore binaries into the proper source tree.
    257 # usage: restore_binaries DESTDIR MAKE_TARGET
    258 restore_binaries() {
    259 	DEST=$1
    260 	MAKETARG=$2
    261 
    262 	echo "\n==== Restoring binaries to ${MAKETARG} at `date` ====\n" | \
    263 	    tee -a $mail_msg_file >> $LOGFILE
    264 	cd ${DEST}
    265 	zcat ${BINARCHIVE} | \
    266 	    cpio -idmucvB 2>/dev/null | tee -a $mail_msg_file >> ${LOGFILE}
    267 }
    268 
    269 # rename files we save binaries of
    270 # usage: rename_files DESTDIR MAKE_TARGET
    271 rename_files() {
    272 	DEST=$1
    273 	MAKETARG=$2
    274 	echo "\n==== Renaming source files in ${MAKETARG} at `date` ====\n" | \
    275 	    tee -a $mail_msg_file >> $LOGFILE
    276 	for i in `filelist ${DEST} '^rename:'`
    277 	do
    278 		echo ${i} | tee -a $mail_msg_file >> ${LOGFILE}
    279 		rm -f ${i}.export
    280 		mv ${i} ${i}.export
    281 	done
    282 }
    283 
    284 #
    285 # Copy some or all of the source tree.
    286 #
    287 # Returns 0 for success, non-zero for failure.
    288 #
    289 # usage: copy_source CODEMGR_WS DESTDIR LABEL SRCROOT
    290 #
    291 copy_source() {
    292 	WS=$1
    293 	DEST=$2
    294 	label=$3
    295 	srcroot=$4
    296 
    297 	printf "\n==== Creating %s source from %s (%s) ====\n\n" \
    298 	    "$DEST" "$WS" "$label" | tee -a $mail_msg_file >> $LOGFILE
    299 
    300 	printf "cleaning out %s\n" "$DEST." >> $LOGFILE
    301 	rm -rf "$DEST" >> $LOGFILE 2>&1
    302 
    303 	printf "creating %s\n" "$DEST." >> $LOGFILE
    304 	mkdir -p "$DEST" 2>> $LOGFILE
    305 
    306 	if (( $? != 0 )) ; then
    307 		printf "failed to create %s\n" "$DEST" |
    308 		    tee -a $mail_msg_file >> $LOGFILE
    309 		build_ok=n
    310 		return 1
    311 	fi
    312 	cd "$WS"
    313 
    314 	printf "populating %s\n" "$DEST." >> $LOGFILE
    315 
    316 	case "$SCM_TYPE" in
    317 	teamware)
    318 		find $srcroot -name 's\.*' -a -type f -print | \
    319 		    sed -e 's,SCCS\/s.,,' | \
    320 		    grep -v '/\.del-*' | \
    321 		    cpio -pd $DEST >>$LOGFILE 2>&1
    322 		if (( $? != 0 )) ; then
    323 		    printf "cpio failed for %s\n" "$DEST" |
    324 			tee -a $mail_msg_file >> $LOGFILE
    325 		    build_ok=n
    326 		    return 1
    327 		fi
    328 		;;
    329 	mercurial)
    330 		copy_source_mercurial $DEST $srcroot
    331 		if (( $? != 0 )) ; then
    332 		    build_ok=n
    333 		    return 1
    334 		fi
    335 		;;
    336 	*)
    337 		build_ok=n
    338 		echo "Tree copy is not supported for workspace type" \
    339 		    "$SCM_TYPE" | tee -a $mail_msg_file >> $LOGFILE
    340 		return 1
    341 		;;
    342 	esac
    343 
    344 	return 0
    345 }
    346 
    347 #
    348 # Mercurial-specific copy code for copy_source().  Handles the
    349 # combined open and closed trees.
    350 #
    351 # Returns 0 for success, non-zero for failure.
    352 #
    353 # usage: copy_source_mercurial destdir srcroot
    354 #
    355 function copy_source_mercurial {
    356 	typeset dest=$1
    357 	typeset srcroot=$2
    358 	typeset open_top closed_top
    359 
    360 	case $srcroot in
    361 	usr)
    362 		open_top=usr
    363 		if [[ "$CLOSED_IS_PRESENT" = yes ]]; then
    364 			closed_top=usr/closed
    365 		fi
    366 		;;
    367 	usr/closed*)
    368 		if [[ "$CLOSED_IS_PRESENT" = no ]]; then
    369 			printf "can't copy %s: closed tree not present.\n" \
    370 			    "$srcroot" | tee -a $mail_msg_file >> $LOGFILE
    371 			return 1
    372 		fi
    373 		closed_top="$srcroot"
    374 		;;
    375 	*)
    376 		open_top="$srcroot"
    377 		;;
    378 	esac		
    379 
    380 	if [[ -n "$open_top" ]]; then
    381 		hg locate -I "$open_top" | cpio -pd "$dest" >>$LOGFILE 2>&1
    382 		if (( $? != 0 )) ; then
    383 		    printf "cpio failed for %s\n" "$dest" |
    384 			tee -a $mail_msg_file >> $LOGFILE
    385 		    return 1
    386 		fi
    387 	fi
    388 
    389 	if [[ -n "$closed_top" ]]; then
    390 		mkdir -p "$dest/usr/closed" || return 1
    391 		if [[ "$closed_top" = usr/closed ]]; then
    392 			(cd usr/closed; hg locate |
    393 			    cpio -pd "$dest/usr/closed") >>$LOGFILE 2>&1
    394 			if (( $? != 0 )) ; then
    395 			    printf "cpio failed for %s/usr/closed\n" \
    396 				"$dest" | tee -a $mail_msg_file >> $LOGFILE
    397 			    return 1
    398 			fi
    399 		else
    400 			# copy subtree of usr/closed
    401 			closed_top=${closed_top#usr/closed/}
    402 			(cd usr/closed; hg locate -I "$closed_top" |
    403 			    cpio -pd "$dest/usr/closed") >>$LOGFILE 2>&1
    404 			if (( $? != 0 )) ; then
    405 			    printf "cpio failed for %s/usr/closed/%s\n" \
    406 				"$dest" "$closed_top" |
    407 				tee -a $mail_msg_file >> $LOGFILE
    408 			    return 1
    409 			fi
    410 		fi
    411 	fi
    412 
    413 	return 0
    414 }
    415 
    416 #
    417 # function to create (but not build) the export/crypt source tree.
    418 # usage: set_up_source_build CODEMGR_WS DESTDIR MAKE_TARGET
    419 # Sets SRC to the modified source tree, for use by the caller when it
    420 # builds the tree.
    421 #
    422 set_up_source_build() {
    423 	WS=$1
    424 	DEST=$2
    425 	MAKETARG=$3
    426 
    427 	copy_source $WS $DEST $MAKETARG usr
    428 	if (( $? != 0 )); then
    429 	    echo "\nCould not copy source tree for source build." |
    430 		tee -a $mail_msg_file >> $LOGFILE
    431 	    build_ok=n
    432 	    return
    433 	fi
    434 
    435 	SRC=${DEST}/usr/src
    436 
    437 	cd $SRC
    438 	rm -f ${MAKETARG}.out
    439 	echo "making ${MAKETARG} in ${SRC}." >> $LOGFILE
    440 	/bin/time $MAKE -e ${MAKETARG} 2>&1 | \
    441 	    tee -a $SRC/${MAKETARG}.out >> $LOGFILE
    442 	echo "\n==== ${MAKETARG} build errors ====\n" >> $mail_msg_file
    443 	egrep ":" $SRC/${MAKETARG}.out | \
    444 		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
    445 		egrep -v "Ignoring unknown host" | \
    446 		egrep -v "warning" >> $mail_msg_file
    447 
    448 	echo "clearing state files." >> $LOGFILE
    449 	find . -name '.make*' -exec rm -f {} \;
    450 
    451 	cd ${DEST}
    452 	if [ "${MAKETARG}" = "CRYPT_SRC" ]; then
    453 		rm -f ${CODEMGR_WS}/crypt_files.cpio.Z
    454 		echo "\n==== xmod/cry_files that don't exist ====\n" | \
    455 		    tee -a $mail_msg_file >> $LOGFILE
    456 		CRYPT_FILES=${WS}/usr/src/xmod/cry_files
    457 		for i in `cat ${CRYPT_FILES}`
    458 		do
    459 			# make sure the files exist
    460 			if [ -f "$i" ]; then
    461 				continue
    462 			fi
    463 			if [ -d "$i" ]; then
    464 				continue
    465 			fi
    466 			echo "$i" | tee -a $mail_msg_file >> $LOGFILE
    467 		done
    468 		find `cat ${CRYPT_FILES}` -print 2>/dev/null | \
    469 		    cpio -ocB 2>/dev/null | \
    470 		    compress > ${CODEMGR_WS}/crypt_files.cpio.Z
    471 	fi
    472 
    473 	if [ "${MAKETARG}" = "EXPORT_SRC" ]; then
    474 		# rename first, since we might restore a file
    475 		# of the same name (mapfiles)
    476 		rename_files ${EXPORT_SRC} EXPORT_SRC
    477 		if [ "$SH_FLAG" = "y" ]; then
    478 			hybridize_files ${EXPORT_SRC} EXPORT_SRC
    479 		fi
    480 	fi
    481 
    482 	# save the cleartext
    483 	echo "\n==== Creating ${MAKETARG}.cpio.Z ====\n" | \
    484 	    tee -a $mail_msg_file >> $LOGFILE
    485 	cd ${DEST}
    486 	rm -f ${MAKETARG}.cpio.Z
    487 	find usr -depth -print | \
    488 	    grep -v usr/src/${MAKETARG}.out | \
    489 	    cpio -ocB 2>/dev/null | \
    490 	    compress > ${CODEMGR_WS}/${MAKETARG}.cpio.Z
    491 	if [ "${MAKETARG}" = "EXPORT_SRC" ]; then
    492 		restore_binaries ${EXPORT_SRC} EXPORT_SRC
    493 	fi
    494 
    495 	if [ "${MAKETARG}" = "CRYPT_SRC" ]; then
    496 		restore_binaries ${CRYPT_SRC} CRYPT_SRC
    497 	fi
    498 
    499 }
    500 
    501 # Return library search directive as function of given root.
    502 myldlibs() {
    503 	echo "-L$1/lib -L$1/usr/lib"
    504 }
    505 
    506 # Return header search directive as function of given root.
    507 myheaders() {
    508 	echo "-I$1/usr/include"
    509 }
    510 
    511 #
    512 # Wrapper over commands that generate BFU archives.  The entire
    513 # command output gets written to LOGFILE, and any unexpected messages
    514 # are written to the mail message.  Returns with the status of the
    515 # original command.
    516 #
    517 makebfu_filt() {
    518 	typeset tmplog
    519 	typeset errors
    520 	typeset cmd
    521 	integer cmd_stat
    522 
    523 	cmd="$1"
    524 	shift
    525 	tmplog="$TMPDIR/$cmd.out"
    526 	errors="$TMPDIR/$cmd-errors"
    527 	$cmd $* > "$tmplog" 2>&1
    528 	cmd_stat=$?
    529 	cat "$tmplog" >> "$LOGFILE"
    530 	grep -v "^Creating .* archive:" "$tmplog" | grep -v "^Making" | \
    531 	    grep -v "^$" | sort -u > "$errors"
    532 	if [[ -s "$errors" ]]; then
    533 		echo "\n==== cpio archives build errors ($LABEL) ====\n" \
    534 		    >> "$mail_msg_file"
    535 		cat "$errors" >> "$mail_msg_file"
    536 	fi
    537 	rm -f "$tmplog" "$errors"
    538 	return $cmd_stat
    539 }
    540 
    541 #
    542 # Function to do the build, including cpio archive and package generation.
    543 # usage: build LABEL SUFFIX MULTIPROTO
    544 # - LABEL is used to tag build output.
    545 # - SUFFIX is used to distinguish files (e.g., debug vs non-debug).
    546 # - If MULTIPROTO is "yes", it means to name the proto area according to
    547 #   SUFFIX.  Otherwise ("no"), (re)use the standard proto area.
    548 #
    549 build() {
    550 	LABEL=$1
    551 	SUFFIX=$2
    552 	MULTIPROTO=$3
    553 	INSTALLOG=install${SUFFIX}-${MACH}
    554 	NOISE=noise${SUFFIX}-${MACH}
    555 	CPIODIR=${CPIODIR_ORIG}${SUFFIX}
    556 	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
    557 	if [ "$SPARC_RM_PKGARCHIVE_ORIG" ]; then
    558 		SPARC_RM_PKGARCHIVE=${SPARC_RM_PKGARCHIVE_ORIG}${SUFFIX}
    559 	fi
    560 
    561 	ORIGROOT=$ROOT
    562 	[ $MULTIPROTO = no ] || export ROOT=$ROOT$SUFFIX
    563 
    564 	export ENVLDLIBS1=`myldlibs $ROOT`
    565 	export ENVCPPFLAGS1=`myheaders $ROOT`
    566 
    567 	this_build_ok=y
    568 	#
    569 	#	Build OS-Networking source
    570 	#
    571 	echo "\n==== Building OS-Net source at `date` ($LABEL) ====\n" \
    572 		>> $LOGFILE
    573 
    574 	rm -f $SRC/${INSTALLOG}.out
    575 	cd $SRC
    576 	/bin/time $MAKE -e install 2>&1 | \
    577 	    tee -a $SRC/${INSTALLOG}.out >> $LOGFILE
    578 
    579 	if [[ "$SCM_TYPE" = teamware ]]; then
    580 		echo "\n==== SCCS Noise ($LABEL) ====\n" >> $mail_msg_file
    581 		egrep 'sccs(check:| *get)' $SRC/${INSTALLOG}.out >> \
    582 			$mail_msg_file
    583 	fi
    584 
    585 	echo "\n==== Build errors ($LABEL) ====\n" >> $mail_msg_file
    586 	egrep ":" $SRC/${INSTALLOG}.out |
    587 		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
    588 		egrep -v "Ignoring unknown host" | \
    589 		egrep -v "cc .* -o error " | \
    590 		egrep -v "warning" >> $mail_msg_file
    591 	if [ "$?" = "0" ]; then
    592 		build_ok=n
    593 		this_build_ok=n
    594 	fi
    595 	grep "bootblock image is .* bytes too big" $SRC/${INSTALLOG}.out \
    596 		>> $mail_msg_file
    597 	if [ "$?" = "0" ]; then
    598 		build_ok=n
    599 		this_build_ok=n
    600 	fi
    601 
    602 	if [ "$W_FLAG" = "n" ]; then
    603 		echo "\n==== Build warnings ($LABEL) ====\n" >>$mail_msg_file
    604 		egrep -i warning: $SRC/${INSTALLOG}.out \
    605 			| egrep -v '^tic:' \
    606 			| egrep -v "symbol \`timezone' has differing types:" \
    607 		        | egrep -v "parameter <PSTAMP> set to" \
    608 			| egrep -v "Ignoring unknown host" \
    609 			| egrep -v "redefining segment flags attribute for" \
    610 			>> $mail_msg_file
    611 	fi
    612 
    613 	echo "\n==== Ended OS-Net source build at `date` ($LABEL) ====\n" \
    614 		>> $LOGFILE
    615 
    616 	echo "\n==== Elapsed build time ($LABEL) ====\n" >>$mail_msg_file
    617 	tail -3  $SRC/${INSTALLOG}.out >>$mail_msg_file
    618 
    619 	if [ "$i_FLAG" = "n" -a "$W_FLAG" = "n" ]; then
    620 		rm -f $SRC/${NOISE}.ref
    621 		if [ -f $SRC/${NOISE}.out ]; then
    622 			mv $SRC/${NOISE}.out $SRC/${NOISE}.ref
    623 		fi
    624 		grep : $SRC/${INSTALLOG}.out \
    625 			| egrep -v '^/' \
    626 			| egrep -v '^(Start|Finish|real|user|sys|./bld_awk)' \
    627 			| egrep -v '^tic:' \
    628 			| egrep -v '^mcs' \
    629 			| egrep -v '^LD_LIBRARY_PATH=' \
    630 			| egrep -v 'ar: creating' \
    631 			| egrep -v 'ar: writing' \
    632 			| egrep -v 'conflicts:' \
    633 			| egrep -v ':saved created' \
    634 			| egrep -v '^stty.*c:' \
    635 			| egrep -v '^mfgname.c:' \
    636 			| egrep -v '^uname-i.c:' \
    637 			| egrep -v '^volumes.c:' \
    638 			| egrep -v '^lint library construction:' \
    639 			| egrep -v 'tsort: INFORM:' \
    640 			| egrep -v 'stripalign:' \
    641 			| egrep -v 'chars, width' \
    642 			| egrep -v "symbol \`timezone' has differing types:" \
    643 			| egrep -v 'PSTAMP' \
    644 			| egrep -v '|%WHOANDWHERE%|' \
    645 			| egrep -v '^Manifying' \
    646 			| egrep -v 'Ignoring unknown host' \
    647 			| egrep -v 'Processing method:' \
    648 			| egrep -v '^Writing' \
    649 			| egrep -v 'spellin1:' \
    650 			| egrep -v '^adding:' \
    651 			| egrep -v "^echo 'msgid" \
    652 			| egrep -v '^echo ' \
    653 			| egrep -v '\.c:$' \
    654 			| egrep -v '^Adding file:' \
    655 			| egrep -v 'CLASSPATH=' \
    656 			| egrep -v '\/var\/mail\/:saved' \
    657 			| egrep -v -- '-DUTS_VERSION=' \
    658 			| egrep -v '^Running Mkbootstrap' \
    659 			| egrep -v '^Applet length read:' \
    660 			| egrep -v 'bytes written:' \
    661 			| egrep -v '^File:SolarisAuthApplet.bin' \
    662 			| egrep -v -i 'jibversion' \
    663 			| egrep -v '^Output size:' \
    664 			| egrep -v '^Solo size statistics:' \
    665 			| egrep -v '^Using ROM API Version' \
    666 			| egrep -v '^Zero Signature length:' \
    667 			| egrep -v '^Note \(probably harmless\):' \
    668 			| egrep -v '::' \
    669 			| egrep -v -- '-xcache' \
    670 			| egrep -v '^\+' \
    671 			| egrep -v '^cc1: note: -fwritable-strings' \
    672 			| egrep -v 'svccfg-native -s svc:/' \
    673 			| sort | uniq >$SRC/${NOISE}.out
    674 		if [ ! -f $SRC/${NOISE}.ref ]; then
    675 			cp $SRC/${NOISE}.out $SRC/${NOISE}.ref
    676 		fi
    677 		echo "\n==== Build noise differences ($LABEL) ====\n" \
    678 			>>$mail_msg_file
    679 		diff $SRC/${NOISE}.ref $SRC/${NOISE}.out >>$mail_msg_file
    680 	fi
    681 
    682 	#
    683 	#	Re-sign selected binaries using signing server
    684 	#	(gatekeeper builds only)
    685 	#
    686 	if [ -n "$CODESIGN_USER" -a "$this_build_ok" = "y" ]; then
    687 		echo "\n==== Signing proto area at `date` ====\n" >> $LOGFILE
    688 		signing_file="${TMPDIR}/signing"
    689 		rm -f ${signing_file}
    690 		export CODESIGN_USER
    691 		signproto $SRC/tools/codesign/creds 2>&1 | \
    692 			tee -a ${signing_file} >> $LOGFILE
    693 		echo "\n==== Finished signing proto area at `date` ====\n" \
    694 		    >> $LOGFILE
    695 		echo "\n==== Crypto module signing errors ($LABEL) ====\n" \
    696 		    >> $mail_msg_file
    697 		egrep 'WARNING|ERROR' ${signing_file} >> $mail_msg_file
    698 		if (( $? == 0 )) ; then
    699 			build_ok=n
    700 			this_build_ok=n
    701 		fi
    702 	fi
    703 
    704 	#
    705 	#	Create cpio archives for preintegration testing (PIT)
    706 	#
    707 	if [ "$a_FLAG" = "y" -a "$this_build_ok" = "y" ]; then
    708 		echo "\n==== Creating $LABEL cpio archives at `date` ====\n" \
    709 			>> $LOGFILE
    710 		makebfu_filt makebfu
    711 		# hack for test folks
    712 		if [ -z "`echo $PARENT_WS|egrep '^\/ws\/'`" ]; then
    713 			X=/net/`uname -n`${CPIODIR}
    714 		else
    715 			X=${CPIODIR}
    716 		fi
    717 		echo "Archive_directory: ${X}" >${TMPDIR}/f
    718 		cp ${TMPDIR}/f $(dirname $(dirname ${CPIODIR}))/.${MACH}_wgtrun
    719 		rm -f ${TMPDIR}/f
    720 
    721 	else
    722 		echo "\n==== Not creating $LABEL cpio archives ====\n" \
    723 			>> $LOGFILE
    724 	fi
    725 
    726 	#
    727 	#	Building Packages
    728 	#
    729 	if [ "$p_FLAG" = "y" -a "$this_build_ok" = "y" ]; then
    730 		echo "\n==== Creating $LABEL packages at `date` ====\n" \
    731 			>> $LOGFILE
    732 		rm -f $SRC/pkgdefs/${INSTALLOG}.out
    733 		echo "Clearing out $PKGARCHIVE ..." >> $LOGFILE
    734 		rm -rf $PKGARCHIVE
    735 		mkdir -p $PKGARCHIVE
    736 
    737 		#
    738 		# Optional build of sparc realmode on i386
    739 		#
    740 		if [ "$MACH" = "i386" ] && [ "${SPARC_RM_PKGARCHIVE}" ]; then
    741 			echo "Clearing out ${SPARC_RM_PKGARCHIVE} ..." \
    742 				>> $LOGFILE
    743 			rm -rf ${SPARC_RM_PKGARCHIVE}
    744 			mkdir -p ${SPARC_RM_PKGARCHIVE}
    745 		fi
    746 
    747 		cd $SRC/pkgdefs
    748 		$MAKE -e install 2>&1 | \
    749 			tee -a $SRC/pkgdefs/${INSTALLOG}.out >> $LOGFILE
    750 		echo "\n==== Package build errors ($LABEL) ====\n" \
    751 			>> $mail_msg_file
    752 		egrep "${MAKE}|ERROR|WARNING" $SRC/pkgdefs/${INSTALLOG}.out | \
    753 			grep ':' | \
    754 			grep -v PSTAMP | \
    755 			egrep -v "Ignoring unknown host" \
    756 			>> $mail_msg_file
    757 	else
    758 		echo "\n==== Not creating $LABEL packages ====\n" >> $LOGFILE
    759 	fi
    760 
    761 	ROOT=$ORIGROOT
    762 }
    763 
    764 # Usage: dolint /dir y|n
    765 # Arg. 2 is a flag to turn on/off the lint diff output
    766 dolint() {
    767 	if [ ! -d "$1" ]; then
    768 		echo "dolint error: $1 is not a directory"
    769 		exit 1
    770 	fi
    771 
    772 	if [ "$2" != "y" -a "$2" != "n" ]; then
    773 		echo "dolint internal error: $2 should be 'y' or 'n'"
    774 		exit 1
    775 	fi
    776 
    777 	lintdir=$1
    778 	dodiff=$2
    779 	base=`basename $lintdir`
    780 	LINTOUT=$lintdir/lint-${MACH}.out
    781 	LINTNOISE=$lintdir/lint-noise-${MACH}
    782 	export ENVLDLIBS1=`myldlibs $ROOT`
    783 	export ENVCPPFLAGS1=`myheaders $ROOT`
    784 
    785 	set_debug_build_flags
    786 
    787 	#
    788 	#	'$MAKE lint' in $lintdir
    789 	#
    790 	echo "\n==== Begin '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
    791 
    792 	# remove old lint.out
    793 	rm -f $lintdir/lint.out $lintdir/lint-noise.out
    794 	if [ -f $lintdir/lint-noise.ref ]; then
    795 		mv $lintdir/lint-noise.ref ${LINTNOISE}.ref
    796 	fi
    797 
    798 	rm -f $LINTOUT
    799 	cd $lintdir
    800 	#
    801 	# Remove all .ln files to ensure a full reference file
    802 	#
    803 	rm -f Nothing_to_remove \
    804 	    `find . \( -name SCCS -o -name .hg -o -name .svn \) \
    805 	    	-prune -o -type f -name '*.ln' -print `
    806 
    807 	/bin/time $MAKE -ek lint 2>&1 | \
    808 	    tee -a $LINTOUT >> $LOGFILE
    809 	echo "\n==== '$MAKE lint' of $base ERRORS ====\n" >> $mail_msg_file
    810 	grep "$MAKE:" $LINTOUT |
    811 		egrep -v "Ignoring unknown host" \
    812 		>> $mail_msg_file
    813 
    814 	echo "\n==== Ended '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
    815 
    816 	echo "\n==== Elapsed time of '$MAKE lint' of $base ====\n" \
    817 		>>$mail_msg_file
    818 	tail -3  $LINTOUT >>$mail_msg_file
    819 
    820 	rm -f ${LINTNOISE}.ref
    821 	if [ -f ${LINTNOISE}.out ]; then
    822 		mv ${LINTNOISE}.out ${LINTNOISE}.ref
    823 	fi
    824         grep : $LINTOUT | \
    825 		egrep -v '^(real|user|sys)' |
    826 		egrep -v '(library construction)' | \
    827 		egrep -v ': global crosschecks' | \
    828 		egrep -v 'Ignoring unknown host' | \
    829 		egrep -v '\.c:$' | \
    830 		sort | uniq > ${LINTNOISE}.out
    831 	if [ ! -f ${LINTNOISE}.ref ]; then
    832 		cp ${LINTNOISE}.out ${LINTNOISE}.ref
    833 	fi
    834 	if [ "$dodiff" != "n" ]; then
    835 		echo "\n==== lint warnings $base ====\n" \
    836 			>>$mail_msg_file
    837 		# should be none, though there are a few that were filtered out
    838 		# above
    839 		egrep -i '(warning|lint):' ${LINTNOISE}.out \
    840 			| sort | uniq >> $mail_msg_file
    841 		echo "\n==== lint noise differences $base ====\n" \
    842 			>> $mail_msg_file
    843 		diff ${LINTNOISE}.ref ${LINTNOISE}.out \
    844 			>> $mail_msg_file
    845 	fi
    846 }
    847 
    848 # Install proto area from IHV build
    849 
    850 copy_ihv_proto() {
    851 
    852 	echo "\n==== Installing IHV proto area ====\n" \
    853 		>> $LOGFILE
    854 	if [ -d "$IA32_IHV_ROOT" ]; then
    855 		if [ ! -d "$ROOT" ]; then
    856 			echo "mkdir -p $ROOT" >> $LOGFILE
    857 			mkdir -p $ROOT
    858 		fi
    859 		echo "copying $IA32_IHV_ROOT to $ROOT\n" >> $LOGFILE
    860 		cd $IA32_IHV_ROOT
    861 		tar -cf - . | (cd $ROOT; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
    862 	else
    863 		echo "$IA32_IHV_ROOT: not found" >> $LOGFILE
    864 	fi
    865 
    866 	if [ "$MULTI_PROTO" = yes ]; then
    867 		if [ ! -d "$ROOT-nd" ]; then
    868 			echo "mkdir -p $ROOT-nd" >> $LOGFILE
    869 			mkdir -p $ROOT-nd
    870 		fi
    871 		# If there's a non-debug version of the IHV proto area,
    872 		# copy it, but copy something if there's not.
    873 		if [ -d "$IA32_IHV_ROOT-nd" ]; then
    874 			echo "copying $IA32_IHV_ROOT-nd to $ROOT-nd\n" >> $LOGFILE
    875 			cd $IA32_IHV_ROOT-nd
    876 		elif [ -d "$IA32_IHV_ROOT" ]; then
    877 			echo "copying $IA32_IHV_ROOT to $ROOT-nd\n" >> $LOGFILE
    878 			cd $IA32_IHV_ROOT
    879 		else
    880 			echo "$IA32_IHV_ROOT{-nd,}: not found" >> $LOGFILE
    881 			return
    882 		fi
    883 		tar -cf - . | (cd $ROOT-nd; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
    884 	fi
    885 }
    886 
    887 # Install IHV packages in PKGARCHIVE
    888 # usage: copy_ihv_pkgs LABEL SUFFIX
    889 copy_ihv_pkgs() {
    890 	LABEL=$1
    891 	SUFFIX=$2
    892 	# always use non-DEBUG IHV packages
    893 	IA32_IHV_PKGS=${IA32_IHV_PKGS_ORIG}-nd
    894 	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
    895 
    896 	echo "\n==== Installing IHV packages from $IA32_IHV_PKGS ($LABEL) ====\n" \
    897 		>> $LOGFILE
    898 	if [ -d "$IA32_IHV_PKGS" ]; then
    899 		cd $IA32_IHV_PKGS
    900 		tar -cf - * | \
    901 		   (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
    902 	else
    903 		echo "$IA32_IHV_PKGS: not found" >> $LOGFILE
    904 	fi
    905 
    906 	echo "\n==== Installing IHV packages from $IA32_IHV_BINARY_PKGS ($LABEL) ====\n" \
    907 		>> $LOGFILE
    908 	if [ -d "$IA32_IHV_BINARY_PKGS" ]; then
    909 		cd $IA32_IHV_BINARY_PKGS
    910 		tar -cf - * | \
    911 		    (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
    912 	else
    913 		echo "$IA32_IHV_BINARY_PKGS: not found" >> $LOGFILE
    914 	fi
    915 }
    916 
    917 #
    918 # Build and install the onbld tools.
    919 #
    920 # usage: build_tools DESTROOT
    921 #
    922 # returns non-zero status if the build was successful.
    923 #
    924 build_tools() {
    925 	DESTROOT=$1
    926 
    927 	INSTALLOG=install-${MACH}
    928 
    929 	echo "\n==== Building tools at `date` ====\n" \
    930 		>> $LOGFILE
    931 
    932 	rm -f ${TOOLS}/${INSTALLOG}.out
    933 	cd ${TOOLS}
    934 	/bin/time $MAKE ROOT=${DESTROOT} -e install 2>&1 | \
    935 	    tee -a ${TOOLS}/${INSTALLOG}.out >> $LOGFILE
    936 
    937 	echo "\n==== Tools build errors ====\n" >> $mail_msg_file
    938 
    939 	egrep ":" ${TOOLS}/${INSTALLOG}.out |
    940 		egrep -e "(${MAKE}:|[ 	]error[: 	\n])" | \
    941 		egrep -v "Ignoring unknown host" | \
    942 		egrep -v warning >> $mail_msg_file
    943 	return $?
    944 }
    945 
    946 #
    947 # Set up to use locally installed tools.
    948 #
    949 # usage: use_tools TOOLSROOT
    950 #
    951 use_tools() {
    952 	TOOLSROOT=$1
    953 
    954 	STABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/stabs
    955 	export STABS
    956 	CTFSTABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfstabs
    957 	export CTFSTABS
    958 	GENOFFSETS=${TOOLSROOT}/opt/onbld/bin/genoffsets
    959 	export GENOFFSETS
    960 
    961 	CTFCONVERT=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfconvert
    962 	export CTFCONVERT
    963 	CTFMERGE=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfmerge
    964 	export CTFMERGE
    965 
    966 	CTFCVTPTBL=${TOOLSROOT}/opt/onbld/bin/ctfcvtptbl
    967 	export CTFCVTPTBL
    968 	CTFFINDMOD=${TOOLSROOT}/opt/onbld/bin/ctffindmod
    969 	export CTFFINDMOD
    970 
    971 	if [ "$VERIFY_ELFSIGN" = "y" ]; then
    972 		ELFSIGN=${TOOLSROOT}/opt/onbld/bin/elfsigncmp
    973 	else
    974 		ELFSIGN=${TOOLSROOT}/opt/onbld/bin/${MACH}/elfsign
    975 	fi
    976 	export ELFSIGN
    977 
    978 	PATH="${TOOLSROOT}/opt/onbld/bin/${MACH}:${PATH}"
    979 	PATH="${TOOLSROOT}/opt/onbld/bin:${PATH}"
    980 	export PATH
    981 
    982 	echo "\n==== New environment settings. ====\n" >> $LOGFILE
    983 	echo "STABS=${STABS}" >> $LOGFILE
    984 	echo "CTFSTABS=${CTFSTABS}" >> $LOGFILE
    985 	echo "CTFCONVERT=${CTFCONVERT}" >> $LOGFILE
    986 	echo "CTFMERGE=${CTFMERGE}" >> $LOGFILE
    987 	echo "CTFCVTPTBL=${CTFCVTPTBL}" >> $LOGFILE
    988 	echo "CTFFINDMOD=${CTFFINDMOD}" >> $LOGFILE
    989 	echo "ELFSIGN=${ELFSIGN}" >> $LOGFILE
    990 	echo "PATH=${PATH}" >> $LOGFILE
    991 }
    992 
    993 staffer() {
    994 	if [ $ISUSER -ne 0 ]; then
    995 		"$@"
    996 	else
    997 		arg="\"$1\""
    998 		shift
    999 		for i
   1000 		do
   1001 			arg="$arg \"$i\""
   1002 		done
   1003 		eval su $STAFFER -c \'$arg\'
   1004 	fi
   1005 }
   1006 
   1007 #
   1008 # Verify that the closed tree is present if it needs to be.
   1009 # Sets CLOSED_IS_PRESENT for future use.
   1010 #
   1011 check_closed_tree() {
   1012 	if [ -z "$CLOSED_IS_PRESENT" ]; then
   1013 		if [ -d $CODEMGR_WS/usr/closed ]; then
   1014 			CLOSED_IS_PRESENT="yes"
   1015 		else
   1016 			CLOSED_IS_PRESENT="no"
   1017 		fi
   1018 		export CLOSED_IS_PRESENT
   1019 	fi
   1020 	if [[ "$CLOSED_IS_PRESENT" = no && ! -d "$ON_CLOSED_BINS" ]]; then
   1021 		#
   1022 		# If it's an old (pre-split) tree or an empty
   1023 		# workspace, don't complain.
   1024 		#
   1025 		if grep -s CLOSED_BUILD $SRC/Makefile.master > /dev/null; then
   1026 			echo "If the closed sources are not present," \
   1027 			    "ON_CLOSED_BINS"
   1028 			echo "must point to the closed binaries tree."
   1029 			build_ok=n
   1030 			exit 1
   1031 		fi
   1032 	fi
   1033 }
   1034 
   1035 obsolete_build() {
   1036     	echo "WARNING: Obsolete $1 build requested; request will be ignored"
   1037 }
   1038 
   1039 #
   1040 # wrapper over wsdiff.
   1041 # usage: do_wsdiff LABEL OLDPROTO NEWPROTO
   1042 #
   1043 do_wsdiff() {
   1044 	label=$1
   1045 	oldproto=$2
   1046 	newproto=$3
   1047 
   1048 	echo "\n==== Objects that differ since last build ($label) ====\n" | \
   1049 	    tee -a $LOGFILE >> $mail_msg_file
   1050 
   1051 	wsdiff="wsdiff"
   1052 	[ "$t_FLAG" = y ] && wsdiff="wsdiff -t"
   1053 
   1054 	$wsdiff -r ${TMPDIR}/wsdiff.results $oldproto $newproto 2>&1 | \
   1055 		    tee -a $LOGFILE >> $mail_msg_file
   1056 }
   1057 
   1058 #
   1059 # Functions for setting build flags (debug/non-debug).  Keep them
   1060 # together.
   1061 #
   1062 
   1063 set_non_debug_build_flags() {
   1064 	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
   1065 	export RELEASE_BUILD ; RELEASE_BUILD=
   1066 	unset EXTRA_OPTIONS
   1067 	unset EXTRA_CFLAGS
   1068 }
   1069 
   1070 set_debug_build_flags() {
   1071 	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
   1072 	unset RELEASE_BUILD
   1073 	unset EXTRA_OPTIONS
   1074 	unset EXTRA_CFLAGS
   1075 }
   1076 
   1077 
   1078 MACH=`uname -p`
   1079 
   1080 if [ "$OPTHOME" = "" ]; then
   1081 	OPTHOME=/opt
   1082 	export OPTHOME
   1083 fi
   1084 if [