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 may be set in the environment to override /opt
50 #
51
52 #
53 # The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
54 # under certain circumstances, which can really screw things up; unset it.
55 #
56 unset CDPATH
57
58 # Get the absolute path of the nightly script that the user invoked. This
59 # may be a relative path, and we need to do this before changing directory.
60 nightly_path=`whence $0`
61
62 #
63 # Keep track of where we found nightly so we can invoke the matching
64 # which_scm script. If that doesn't work, don't go guessing, just rely
65 # on the $PATH settings, which will generally give us either /opt/onbld
66 # or the user's workspace.
67 #
68 WHICH_SCM=$(dirname $nightly_path)/which_scm
69 if [[ ! -x $WHICH_SCM ]]; then
70 WHICH_SCM=which_scm
71 fi
72
73 function fatal_error
74 {
75 print -u2 "nightly: $*"
76 exit 1
77 }
78
79 #
80 # Function to do a DEBUG and non-DEBUG build. Needed because we might
81 # need to do another for the source build, and since we only deliver DEBUG or
82 # non-DEBUG packages.
83 #
84 # usage: normal_build
85 #
86 function normal_build {
87
88 typeset orig_p_FLAG="$p_FLAG"
89 typeset crypto_signer="$CODESIGN_USER"
90
91 suffix=""
92
93 # non-DEBUG build begins
94
95 if [ "$F_FLAG" = "n" ]; then
96 set_non_debug_build_flags
97 CODESIGN_USER="$crypto_signer" \
98 build "non-DEBUG" "$suffix-nd" "-nd" "$MULTI_PROTO"
99 else
100 echo "\n==== No non-DEBUG $open_only build ====\n" >> "$LOGFILE"
101 fi
102
103 # non-DEBUG build ends
104
105 # DEBUG build begins
106
107 if [ "$D_FLAG" = "y" ]; then
108 set_debug_build_flags
109 CODESIGN_USER="$crypto_signer" \
110 build "DEBUG" "$suffix" "" "$MULTI_PROTO"
111 else
112 echo "\n==== No DEBUG $open_only build ====\n" >> "$LOGFILE"
113 fi
114
115 # DEBUG build ends
116
117 p_FLAG="$orig_p_FLAG"
118 }
119
120 #
121 # usage: run_hook HOOKNAME ARGS...
122 #
123 # If variable "$HOOKNAME" is defined, insert a section header into
124 # our logs and then run the command with ARGS
125 #
126 function run_hook {
127 HOOKNAME=$1
128 eval HOOKCMD=\$$HOOKNAME
129 shift
130
131 if [ -n "$HOOKCMD" ]; then
132 (
133 echo "\n==== Running $HOOKNAME command: $HOOKCMD ====\n"
134 ( $HOOKCMD "$@" 2>&1 )
135 if [ "$?" -ne 0 ]; then
136 # Let exit status propagate up
137 touch $TMPDIR/abort
138 fi
139 ) | tee -a $mail_msg_file >> $LOGFILE
140
141 if [ -f $TMPDIR/abort ]; then
142 build_ok=n
143 echo "\nAborting at request of $HOOKNAME" |
144 tee -a $mail_msg_file >> $LOGFILE
145 exit 1
146 fi
147 fi
148 }
149
150 # Return library search directive as function of given root.
151 function myldlibs {
152 echo "-L$1/lib -L$1/usr/lib"
153 }
154
155 # Return header search directive as function of given root.
156 function myheaders {
157 echo "-I$1/usr/include"
158 }
159
160 #
161 # Function to do the build, including package generation.
162 # usage: build LABEL SUFFIX ND MULTIPROTO
163 # - LABEL is used to tag build output.
164 # - SUFFIX is used to distinguish files (e.g., DEBUG vs non-DEBUG,
165 # open-only vs full tree).
166 # - ND is "-nd" (non-DEBUG builds) or "" (DEBUG builds).
167 # - If MULTIPROTO is "yes", it means to name the proto area according to
168 # SUFFIX. Otherwise ("no"), (re)use the standard proto area.
169 #
170 function build {
171 LABEL=$1
172 SUFFIX=$2
173 ND=$3
174 MULTIPROTO=$4
175 INSTALLOG=install${SUFFIX}-${MACH}
176 NOISE=noise${SUFFIX}-${MACH}
177 PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
178
179 ORIGROOT=$ROOT
180 [ $MULTIPROTO = no ] || export ROOT=$ROOT$SUFFIX
181
182 export ENVLDLIBS1=`myldlibs $ROOT`
183 export ENVCPPFLAGS1=`myheaders $ROOT`
184
185 this_build_ok=y
186 #
187 # Build OS-Networking source
188 #
189 echo "\n==== Building OS-Net source at `date` ($LABEL) ====\n" \
190 >> $LOGFILE
191
192 rm -f $SRC/${INSTALLOG}.out
193 cd $SRC
194 /bin/time $MAKE -e install 2>&1 | \
195 tee -a $SRC/${INSTALLOG}.out >> $LOGFILE
196
197 echo "\n==== Build errors ($LABEL) ====\n" >> $mail_msg_file
198 egrep ":" $SRC/${INSTALLOG}.out |
199 egrep -e "(^${MAKE}:|[ ]error[: \n])" | \
200 egrep -v "Ignoring unknown host" | \
201 egrep -v "cc .* -o error " | \
202 egrep -v "warning" | tee $TMPDIR/build_errs${SUFFIX} \
203 >> $mail_msg_file
204 if [[ -s $TMPDIR/build_errs${SUFFIX} ]]; then
205 build_ok=n
206 this_build_ok=n
207 fi
208 grep "bootblock image is .* bytes too big" $SRC/${INSTALLOG}.out \
209 >> $mail_msg_file
210 if [ "$?" = "0" ]; then
211 build_ok=n
212 this_build_ok=n
213 fi
214
215 echo "\n==== Build warnings ($LABEL) ====\n" >>$mail_msg_file
216 egrep -i warning: $SRC/${INSTALLOG}.out \
217 | egrep -v '^tic:' \
218 | egrep -v "symbol (\`|')timezone' has differing types:" \
219 | egrep -v "parameter <PSTAMP> set to" \
220 | egrep -v "Ignoring unknown host" \
221 | egrep -v "redefining segment flags attribute for" \
222 | tee $TMPDIR/build_warnings${SUFFIX} >> $mail_msg_file
223 if [[ -s $TMPDIR/build_warnings${SUFFIX} ]]; then
224 build_ok=n
225 this_build_ok=n
226 fi
227
228 echo "\n==== Ended OS-Net source build at `date` ($LABEL) ====\n" \
229 >> $LOGFILE
230
231 echo "\n==== Elapsed build time ($LABEL) ====\n" >>$mail_msg_file
232 tail -3 $SRC/${INSTALLOG}.out >>$mail_msg_file
233
234 if [ "$i_FLAG" = "n" ]; then
235 rm -f $SRC/${NOISE}.ref
236 if [ -f $SRC/${NOISE}.out ]; then
237 mv $SRC/${NOISE}.out $SRC/${NOISE}.ref
238 fi
239 grep : $SRC/${INSTALLOG}.out \
240 | egrep -v '^/' \
241 | egrep -v '^(Start|Finish|real|user|sys|./bld_awk)' \
242 | egrep -v '^tic:' \
243 | egrep -v '^mcs' \
244 | egrep -v '^LD_LIBRARY_PATH=' \
245 | egrep -v 'ar: creating' \
246 | egrep -v 'ar: writing' \
247 | egrep -v 'conflicts:' \
248 | egrep -v ':saved created' \
249 | egrep -v '^stty.*c:' \
250 | egrep -v '^mfgname.c:' \
251 | egrep -v '^uname-i.c:' \
252 | egrep -v '^volumes.c:' \
253 | egrep -v '^lint library construction:' \
254 | egrep -v 'tsort: INFORM:' \
255 | egrep -v 'stripalign:' \
256 | egrep -v 'chars, width' \
257 | egrep -v "symbol (\`|')timezone' has differing types:" \
258 | egrep -v 'PSTAMP' \
259 | egrep -v '|%WHOANDWHERE%|' \
260 | egrep -v '^Manifying' \
261 | egrep -v 'Ignoring unknown host' \
262 | egrep -v 'Processing method:' \
263 | egrep -v '^Writing' \
264 | egrep -v 'spellin1:' \
265 | egrep -v '^adding:' \
266 | egrep -v "^echo 'msgid" \
267 | egrep -v '^echo ' \
268 | egrep -v '\.c:$' \
269 | egrep -v '^Adding file:' \
270 | egrep -v 'CLASSPATH=' \
271 | egrep -v '\/var\/mail\/:saved' \
272 | egrep -v -- '-DUTS_VERSION=' \
273 | egrep -v '^Running Mkbootstrap' \
274 | egrep -v '^Applet length read:' \
275 | egrep -v 'bytes written:' \
276 | egrep -v '^File:SolarisAuthApplet.bin' \
277 | egrep -v -i 'jibversion' \
278 | egrep -v '^Output size:' \
279 | egrep -v '^Solo size statistics:' \
280 | egrep -v '^Using ROM API Version' \
281 | egrep -v '^Zero Signature length:' \
282 | egrep -v '^Note \(probably harmless\):' \
283 | egrep -v '::' \
284 | egrep -v -- '-xcache' \
285 | egrep -v '^\+' \
286 | egrep -v '^cc1: note: -fwritable-strings' \
287 | egrep -v 'svccfg-native -s svc:/' \
288 | sort | uniq >$SRC/${NOISE}.out
289 if [ ! -f $SRC/${NOISE}.ref ]; then
290 cp $SRC/${NOISE}.out $SRC/${NOISE}.ref
291 fi
292 echo "\n==== Build noise differences ($LABEL) ====\n" \
293 >>$mail_msg_file
294 diff $SRC/${NOISE}.ref $SRC/${NOISE}.out >>$mail_msg_file
295 fi
296
297 #
298 # Re-sign selected binaries using signing server
299 # (gatekeeper builds only)
300 #
301 if [ -n "$CODESIGN_USER" -a "$this_build_ok" = "y" ]; then
302 echo "\n==== Signing proto area at `date` ====\n" >> $LOGFILE
303 signing_file="${TMPDIR}/signing"
304 rm -f ${signing_file}
305 export CODESIGN_USER
306 signproto $SRC/tools/codesign/creds 2>&1 | \
307 tee -a ${signing_file} >> $LOGFILE
308 echo "\n==== Finished signing proto area at `date` ====\n" \
309 >> $LOGFILE
310 echo "\n==== Crypto module signing errors ($LABEL) ====\n" \
311 >> $mail_msg_file
312 egrep 'WARNING|ERROR' ${signing_file} >> $mail_msg_file
313 if (( $? == 0 )) ; then
314 build_ok=n
315 this_build_ok=n
316 fi
317 fi
318
319 #
320 # Building Packages
321 #
322 if [ "$p_FLAG" = "y" -a "$this_build_ok" = "y" ]; then
323 if [ -d $SRC/pkg ]; then
324 echo "\n==== Creating $LABEL packages at `date` ====\n" \
325 >> $LOGFILE
326 echo "Clearing out $PKGARCHIVE ..." >> $LOGFILE
327 rm -rf $PKGARCHIVE >> "$LOGFILE" 2>&1
328 mkdir -p $PKGARCHIVE >> "$LOGFILE" 2>&1
329
330 rm -f $SRC/pkg/${INSTALLOG}.out
331 cd $SRC/pkg
332 /bin/time $MAKE -e install 2>&1 | \
333 tee -a $SRC/pkg/${INSTALLOG}.out >> $LOGFILE
334
335 echo "\n==== package build errors ($LABEL) ====\n" \
336 >> $mail_msg_file
337
338 egrep "${MAKE}|ERROR|WARNING" $SRC/pkg/${INSTALLOG}.out | \
339 grep ':' | \
340 grep -v PSTAMP | \
341 egrep -v "Ignoring unknown host" | \
342 tee $TMPDIR/package >> $mail_msg_file
343 if [[ -s $TMPDIR/package ]]; then
344 build_extras_ok=n
345 this_build_ok=n
346 fi
347 else
348 #
349 # Handle it gracefully if -p was set but there so
350 # no pkg directory.
351 #
352 echo "\n==== No $LABEL packages to build ====\n" \
353 >> $LOGFILE
354 fi
355 else
356 echo "\n==== Not creating $LABEL packages ====\n" >> $LOGFILE
357 fi
358
359 ROOT=$ORIGROOT
360 }
361
362 # Usage: dolint /dir y|n
363 # Arg. 2 is a flag to turn on/off the lint diff output
364 function dolint {
365 if [ ! -d "$1" ]; then
366 echo "dolint error: $1 is not a directory"
367 exit 1
368 fi
369
370 if [ "$2" != "y" -a "$2" != "n" ]; then
371 echo "dolint internal error: $2 should be 'y' or 'n'"
372 exit 1
373 fi
374
375 lintdir=$1
376 dodiff=$2
377 base=`basename $lintdir`
378 LINTOUT=$lintdir/lint-${MACH}.out
379 LINTNOISE=$lintdir/lint-noise-${MACH}
380 export ENVLDLIBS1=`myldlibs $ROOT`
381 export ENVCPPFLAGS1=`myheaders $ROOT`
382
383 set_debug_build_flags
384
385 #
386 # '$MAKE lint' in $lintdir
387 #
388 echo "\n==== Begin '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
389
390 # remove old lint.out
391 rm -f $lintdir/lint.out $lintdir/lint-noise.out
392 if [ -f $lintdir/lint-noise.ref ]; then
393 mv $lintdir/lint-noise.ref ${LINTNOISE}.ref
394 fi
395
396 rm -f $LINTOUT
397 cd $lintdir
398 #
399 # Remove all .ln files to ensure a full reference file
400 #
401 rm -f Nothing_to_remove \
402 `find . \( -name SCCS -o -name .hg -o -name .svn -o -name .git \) \
403 -prune -o -type f -name '*.ln' -print `
404
405 /bin/time $MAKE -ek lint 2>&1 | \
406 tee -a $LINTOUT >> $LOGFILE
407
408 echo "\n==== '$MAKE lint' of $base ERRORS ====\n" >> $mail_msg_file
409
410 grep "$MAKE:" $LINTOUT |
411 egrep -v "Ignoring unknown host" | \
412 tee $TMPDIR/lint_errs >> $mail_msg_file
413 if [[ -s $TMPDIR/lint_errs ]]; then
414 build_extras_ok=n
415 fi
416
417 echo "\n==== Ended '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
418
419 echo "\n==== Elapsed time of '$MAKE lint' of $base ====\n" \
420 >>$mail_msg_file
421 tail -3 $LINTOUT >>$mail_msg_file
422
423 rm -f ${LINTNOISE}.ref
424 if [ -f ${LINTNOISE}.out ]; then
425 mv ${LINTNOISE}.out ${LINTNOISE}.ref
426 fi
427 grep : $LINTOUT | \
428 egrep -v '^(real|user|sys)' |
429 egrep -v '(library construction)' | \
430 egrep -v ': global crosschecks' | \
431 egrep -v 'Ignoring unknown host' | \
432 egrep -v '\.c:$' | \
433 sort | uniq > ${LINTNOISE}.out
434 if [ ! -f ${LINTNOISE}.ref ]; then
435 cp ${LINTNOISE}.out ${LINTNOISE}.ref
436 fi
437
438 if [ "$dodiff" != "n" ]; then
439 echo "\n==== lint warnings $base ====\n" \
440 >>$mail_msg_file
441 # should be none, though there are a few that were filtered out
442 # above
443 egrep -i '(warning|lint):' ${LINTNOISE}.out \
444 | sort | uniq | tee $TMPDIR/lint_warns >> $mail_msg_file
445 if [[ -s $TMPDIR/lint_warns ]]; then
446 build_extras_ok=n
447 fi
448 echo "\n==== lint noise differences $base ====\n" \
449 >> $mail_msg_file
450 diff ${LINTNOISE}.ref ${LINTNOISE}.out \
451 >> $mail_msg_file
452 fi
453 }
454
455 #
456 # Build and install the onbld tools.
457 #
458 # usage: build_tools DESTROOT
459 #
460 # returns non-zero status if the build was successful.
461 #
462 function build_tools {
463 DESTROOT=$1
464
465 INSTALLOG=install-${MACH}
466
467 echo "\n==== Building tools at `date` ====\n" \
468 >> $LOGFILE
469
470 rm -f ${TOOLS}/${INSTALLOG}.out
471 cd ${TOOLS}
472 /bin/time $MAKE TOOLS_PROTO=${DESTROOT} -e install 2>&1 | \
473 tee -a ${TOOLS}/${INSTALLOG}.out >> $LOGFILE
474
475 echo "\n==== Tools build errors ====\n" >> $mail_msg_file
476
477 egrep ":" ${TOOLS}/${INSTALLOG}.out |
478 egrep -e "(${MAKE}:|[ ]error[: \n])" | \
479 egrep -v "Ignoring unknown host" | \
480 egrep -v warning | tee $TMPDIR/tools_errors >> $mail_msg_file
481
482 if [[ -s $TMPDIR/tools_errors ]]; then
483 return 1
484 fi
485 return 0
486 }
487
488 #
489 # Set up to use locally installed tools.
490 #
491 # usage: use_tools TOOLSROOT
492 #
493 function use_tools {
494 TOOLSROOT=$1
495
496 #
497 # If we're not building ON workspace, then the TOOLSROOT
498 # settings here are clearly ignored by the workspace
499 # makefiles, prepending nonexistent directories to PATH is
500 # harmless, and we clearly do not wish to override
501 # ONBLD_TOOLS.
502 #
503 # If we're building an ON workspace, then the prepended PATH
504 # elements should supercede the preexisting ONBLD_TOOLS paths,
505 # and we want to override ONBLD_TOOLS to catch the tools that
506 # don't have specific path env vars here.
507 #
508 # So the only conditional behavior is overriding ONBLD_TOOLS,
509 # and we check for "an ON workspace" by looking for
510 # ${TOOLSROOT}/opt/onbld.
511 #
512
513 STABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/stabs
514 export STABS
515 CTFSTABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfstabs
516 export CTFSTABS
517 GENOFFSETS=${TOOLSROOT}/opt/onbld/bin/genoffsets
518 export GENOFFSETS
519
520 CTFCONVERT=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfconvert
521 export CTFCONVERT
522 CTFMERGE=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfmerge
523 export CTFMERGE
524
525 CTFCVTPTBL=${TOOLSROOT}/opt/onbld/bin/ctfcvtptbl
526 export CTFCVTPTBL
527 CTFFINDMOD=${TOOLSROOT}/opt/onbld/bin/ctffindmod
528 export CTFFINDMOD
529
530 if [ "$VERIFY_ELFSIGN" = "y" ]; then
531 ELFSIGN=${TOOLSROOT}/opt/onbld/bin/elfsigncmp
532 else
533 ELFSIGN=${TOOLSROOT}/opt/onbld/bin/${MACH}/elfsign
534 fi
535 export ELFSIGN
536
537 PATH="${TOOLSROOT}/opt/onbld/bin/${MACH}:${PATH}"
538 PATH="${TOOLSROOT}/opt/onbld/bin:${PATH}"
539 export PATH
540
541 if [ -d "${TOOLSROOT}/opt/onbld" ]; then
542 ONBLD_TOOLS=${TOOLSROOT}/opt/onbld
543 export ONBLD_TOOLS
544 fi
545
546 echo "\n==== New environment settings. ====\n" >> $LOGFILE
547 echo "STABS=${STABS}" >> $LOGFILE
548 echo "CTFSTABS=${CTFSTABS}" >> $LOGFILE
549 echo "CTFCONVERT=${CTFCONVERT}" >> $LOGFILE
550 echo "CTFMERGE=${CTFMERGE}" >> $LOGFILE
551 echo "CTFCVTPTBL=${CTFCVTPTBL}" >> $LOGFILE
552 echo "CTFFINDMOD=${CTFFINDMOD}" >> $LOGFILE
553 echo "ELFSIGN=${ELFSIGN}" >> $LOGFILE
554 echo "PATH=${PATH}" >> $LOGFILE
555 echo "ONBLD_TOOLS=${ONBLD_TOOLS}" >> $LOGFILE
556 }
557
558 function staffer {
559 if [ $ISUSER -ne 0 ]; then
560 "$@"
561 else
562 arg="\"$1\""
563 shift
564 for i
565 do
566 arg="$arg \"$i\""
567 done
568 eval su $STAFFER -c \'$arg\'
569 fi
570 }
571
572 #
573 # Verify that the closed bins are present
574 #
575 function check_closed_bins {
576 if [[ ! -d "$ON_CLOSED_BINS" ]]; then
577 echo "ON_CLOSED_BINS must point to the closed binaries tree."
578 build_ok=n
579 exit 1
580 fi
581 }
582
583 #
584 # wrapper over wsdiff.
585 # usage: do_wsdiff LABEL OLDPROTO NEWPROTO
586 #
587 function do_wsdiff {
588 label=$1
589 oldproto=$2
590 newproto=$3
591
592 wsdiff="wsdiff"
593 [ "$t_FLAG" = y ] && wsdiff="wsdiff -t"
594
595 echo "\n==== Getting object changes since last build at `date`" \
596 "($label) ====\n" | tee -a $LOGFILE >> $mail_msg_file
597 $wsdiff -s -r ${TMPDIR}/wsdiff.results $oldproto $newproto 2>&1 | \
598 tee -a $LOGFILE >> $mail_msg_file
599 echo "\n==== Object changes determined at `date` ($label) ====\n" | \
600 tee -a $LOGFILE >> $mail_msg_file
601 }
602
603 #
604 # Functions for setting build flags (DEBUG/non-DEBUG). Keep them
605 # together.
606 #
607
608 function set_non_debug_build_flags {
609 export RELEASE_BUILD ; RELEASE_BUILD=
610 unset EXTRA_OPTIONS
611 unset EXTRA_CFLAGS
612 }
613
614 function set_debug_build_flags {
615 unset RELEASE_BUILD
616 unset EXTRA_OPTIONS
617 unset EXTRA_CFLAGS
618 }
619
620
621 MACH=`uname -p`
622
623 if [ "$OPTHOME" = "" ]; then
624 OPTHOME=/opt
625 export OPTHOME
626 fi
627
628 USAGE='Usage: nightly [-in] [+t] [-V VERS ] <env_file>
629
630 Where:
631 -i Fast incremental options (no clobber, lint, check)
632 -n Do not do a bringover
633 +t Use the build tools in $ONBLD_TOOLS/bin
634 -V VERS set the build version string to VERS
635
636 <env_file> file in Bourne shell syntax that sets and exports
637 variables that configure the operation of this script and many of
638 the scripts this one calls. If <env_file> does not exist,
639 it will be looked for in $OPTHOME/onbld/env.
640
641 non-DEBUG is the default build type. Build options can be set in the
642 NIGHTLY_OPTIONS variable in the <env_file> as follows:
643
644 -A check for ABI differences in .so files
645 -C check for cstyle/hdrchk errors
646 -D do a build with DEBUG on
647 -F do _not_ do a non-DEBUG build
648 -G gate keeper default group of options (-au)
649 -I integration engineer default group of options (-ampu)
650 -M do not run pmodes (safe file permission checker)
651 -N do not run protocmp
652 -R default group of options for building a release (-mp)
653 -U update proto area in the parent
654 -V VERS set the build version string to VERS
655 -f find unreferenced files
656 -i do an incremental build (no "make clobber")
657 -l do "make lint" in $LINTDIRS (default: $SRC y)
658 -m send mail to $MAILTO at end of build
659 -n do not do a bringover
660 -p create packages
661 -r check ELF runtime attributes in the proto area
662 -t build and use the tools in $SRC/tools (default setting)
663 +t Use the build tools in $ONBLD_TOOLS/bin
664 -u update proto_list_$MACH and friends in the parent workspace;
665 when used with -f, also build an unrefmaster.out in the parent
666 -w report on differences between previous and current proto areas
667 '
668 #
669 # A log file will be generated under the name $LOGFILE
670 # for partially completed build and log.`date '+%F'`
671 # in the same directory for fully completed builds.
672 #
673
674 # default values for low-level FLAGS; G I R are group FLAGS
675 A_FLAG=n
676 C_FLAG=n
677 D_FLAG=n
678 F_FLAG=n
679 f_FLAG=n
680 i_FLAG=n; i_CMD_LINE_FLAG=n
681 l_FLAG=n
682 M_FLAG=n
683 m_FLAG=n
684 N_FLAG=n
685 n_FLAG=n
686 p_FLAG=n
687 r_FLAG=n
688 t_FLAG=y
689 U_FLAG=n
690 u_FLAG=n
691 V_FLAG=n
692 w_FLAG=n
693 #
694 build_ok=y
695 build_extras_ok=y
696
697 #
698 # examine arguments
699 #
700
701 OPTIND=1
702 while getopts +intV: FLAG
703 do
704 case $FLAG in
705 i ) i_FLAG=y; i_CMD_LINE_FLAG=y
706 ;;
707 n ) n_FLAG=y
708 ;;
709 +t ) t_FLAG=n
710 ;;
711 V ) V_FLAG=y
712 V_ARG="$OPTARG"
713 ;;
714 \? ) echo "$USAGE"
715 exit 1
716 ;;
717 esac
718 done
719
720 # correct argument count after options
721 shift `expr $OPTIND - 1`
722
723 # test that the path to the environment-setting file was given
724 if [ $# -ne 1 ]; then
725 echo "$USAGE"
726 exit 1
727 fi
728
729 # check if user is running nightly as root
730 # ISUSER is set non-zero if an ordinary user runs nightly, or is zero
731 # when root invokes nightly.
732 /usr/bin/id | grep '^uid=0(' >/dev/null 2>&1
733 ISUSER=$?; export ISUSER
734
735 #
736 # force locale to C
737 LC_COLLATE=C; export LC_COLLATE
738 LC_CTYPE=C; export LC_CTYPE
739 LC_MESSAGES=C; export LC_MESSAGES
740 LC_MONETARY=C; export LC_MONETARY
741 LC_NUMERIC=C; export LC_NUMERIC
742 LC_TIME=C; export LC_TIME
743
744 # clear environment variables we know to be bad for the build
745 unset LD_OPTIONS
746 unset LD_AUDIT LD_AUDIT_32 LD_AUDIT_64
747 unset LD_BIND_NOW LD_BIND_NOW_32 LD_BIND_NOW_64
748 unset LD_BREADTH LD_BREADTH_32 LD_BREADTH_64
749 unset LD_CONFIG LD_CONFIG_32 LD_CONFIG_64
750 unset LD_DEBUG LD_DEBUG_32 LD_DEBUG_64
751 unset LD_DEMANGLE LD_DEMANGLE_32 LD_DEMANGLE_64
752 unset LD_FLAGS LD_FLAGS_32 LD_FLAGS_64
753 unset LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64
754 unset LD_LOADFLTR LD_LOADFLTR_32 LD_LOADFLTR_64
755 unset LD_NOAUDIT LD_NOAUDIT_32 LD_NOAUDIT_64
756 unset LD_NOAUXFLTR LD_NOAUXFLTR_32 LD_NOAUXFLTR_64
757 unset LD_NOCONFIG LD_NOCONFIG_32 LD_NOCONFIG_64
758 unset LD_NODIRCONFIG LD_NODIRCONFIG_32 LD_NODIRCONFIG_64
759 unset LD_NODIRECT LD_NODIRECT_32 LD_NODIRECT_64
760 unset LD_NOLAZYLOAD LD_NOLAZYLOAD_32 LD_NOLAZYLOAD_64
761 unset LD_NOOBJALTER LD_NOOBJALTER_32 LD_NOOBJALTER_64
762 unset LD_NOVERSION LD_NOVERSION_32 LD_NOVERSION_64
763 unset LD_ORIGIN LD_ORIGIN_32 LD_ORIGIN_64
764 unset LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_64
765 unset LD_PROFILE LD_PROFILE_32 LD_PROFILE_64
766
767 unset CONFIG
768 unset GROUP
769 unset OWNER
770 unset REMOTE
771 unset ENV
772 unset ARCH
773 unset CLASSPATH
774 unset NAME
775
776 #
777 # To get ONBLD_TOOLS from the environment, it must come from the env file.
778 # If it comes interactively, it is generally TOOLS_PROTO, which will be
779 # clobbered before the compiler version checks, which will therefore fail.
780 #
781 unset ONBLD_TOOLS
782
783 #
784 # Setup environmental variables
785 #
786 if [ -f /etc/nightly.conf ]; then
787 . /etc/nightly.conf
788 fi
789
790 if [ -f $1 ]; then
791 if [[ $1 = */* ]]; then
792 . $1
793 else
794 . ./$1
795 fi
796 else
797 if [ -f $OPTHOME/onbld/env/$1 ]; then
798 . $OPTHOME/onbld/env/$1
799 else
800 echo "Cannot find env file as either $1 or $OPTHOME/onbld/env/$1"
801 exit 1
802 fi
803 fi
804
805 # contents of stdenv.sh inserted after next line:
806 # STDENV_START
807 # STDENV_END
808
809 # Check if we have sufficient data to continue...
810 [[ -v CODEMGR_WS ]] || fatal_error "Error: Variable CODEMGR_WS not set."
811 if [[ "${NIGHTLY_OPTIONS}" == ~(F)n ]] ; then
812 # Check if the gate data are valid if we don't do a "bringover" below
813 [[ -d "${CODEMGR_WS}" ]] || \
814 fatal_error "Error: ${CODEMGR_WS} is not a directory."
815 [[ -f "${CODEMGR_WS}/usr/src/Makefile" ]] || \
816 fatal_error "Error: ${CODEMGR_WS}/usr/src/Makefile not found."
817 fi
818
819 #
820 # place ourselves in a new task, respecting BUILD_PROJECT if set.
821 #
822 if [ -z "$BUILD_PROJECT" ]; then
823 /usr/bin/newtask -c $$
824 else
825 /usr/bin/newtask -c $$ -p $BUILD_PROJECT
826 fi
827
828 ps -o taskid= -p $$ | read build_taskid
829 ps -o project= -p $$ | read build_project
830
831 #
832 # See if NIGHTLY_OPTIONS is set
833 #
834 if [ "$NIGHTLY_OPTIONS" = "" ]; then
835 NIGHTLY_OPTIONS="-aBm"
836 fi
837
838 #
839 # If BRINGOVER_WS was not specified, let it default to CLONE_WS
840 #
841 if [ "$BRINGOVER_WS" = "" ]; then
842 BRINGOVER_WS=$CLONE_WS
843 fi
844
845 #
846 # If BRINGOVER_FILES was not specified, default to usr
847 #
848 if [ "$BRINGOVER_FILES" = "" ]; then
849 BRINGOVER_FILES="usr"
850 fi
851
852 check_closed_bins
853
854 #
855 # Note: changes to the option letters here should also be applied to the
856 # bldenv script. `d' is listed for backward compatibility.
857 #
858 NIGHTLY_OPTIONS=-${NIGHTLY_OPTIONS#-}
859 OPTIND=1
860 while getopts +ABCDdFfGIilMmNnpRrtUuw FLAG $NIGHTLY_OPTIONS
861 do
862 case $FLAG in
863 A ) A_FLAG=y
864 ;;
865 B ) D_FLAG=y
866 ;; # old version of D
867 C ) C_FLAG=y
868 ;;
869 D ) D_FLAG=y
870 ;;
871 F ) F_FLAG=y
872 ;;
873 f ) f_FLAG=y
874 ;;
875 G ) u_FLAG=y
876 ;;
877 I ) m_FLAG=y
878 p_FLAG=y
879 u_FLAG=y
880 ;;
881 i ) i_FLAG=y
882 ;;
883 l ) l_FLAG=y
884 ;;
885 M ) M_FLAG=y
886 ;;
887 m ) m_FLAG=y
888 ;;
889 N ) N_FLAG=y
890 ;;
891 n ) n_FLAG=y
892 ;;
893 p ) p_FLAG=y
894 ;;
895 R ) m_FLAG=y
896 p_FLAG=y
897 ;;
898 r ) r_FLAG=y
899 ;;
900 +t ) t_FLAG=n
901 ;;
902 U ) if [ -z "${PARENT_ROOT}" ]; then
903 echo "PARENT_ROOT must be set if the U flag is" \
904 "present in NIGHTLY_OPTIONS."
905 exit 1
906 fi
907 NIGHTLY_PARENT_ROOT=$PARENT_ROOT
908 if [ -n "${PARENT_TOOLS_ROOT}" ]; then
909 NIGHTLY_PARENT_TOOLS_ROOT=$PARENT_TOOLS_ROOT
910 fi
911 U_FLAG=y
912 ;;
913 u ) u_FLAG=y
914 ;;
915 w ) w_FLAG=y
916 ;;
917 \? ) echo "$USAGE"
918 exit 1
919 ;;
920 esac
921 done
922
923 if [ $ISUSER -ne 0 ]; then
924 # Set default value for STAFFER, if needed.
925 if [ -z "$STAFFER" -o "$STAFFER" = "nobody" ]; then
926 STAFFER=`/usr/xpg4/bin/id -un`
927 export STAFFER
928 fi
929 fi
930
931 if [ -z "$MAILTO" -o "$MAILTO" = "nobody" ]; then
932 MAILTO=$STAFFER
933 export MAILTO
934 fi
935
936 PATH="$OPTHOME/onbld/bin:$OPTHOME/onbld/bin/${MACH}:/usr/ccs/bin"
937 PATH="$PATH:$OPTHOME/SUNWspro/bin:/usr/bin:/usr/sbin:/usr/ucb"
938 PATH="$PATH:/usr/openwin/bin:/usr/sfw/bin:/opt/sfw/bin:."
939 export PATH
940
941 # roots of source trees, both relative to $SRC and absolute.
942 relsrcdirs="."
943 abssrcdirs="$SRC"
944
945 PROTOCMPTERSE="protocmp.terse -gu"
946 POUND_SIGN="#"
947 # have we set RELEASE_DATE in our env file?
948 if [ -z "$RELEASE_DATE" ]; then
949 RELEASE_DATE=$(LC_ALL=C date +"%B %Y")
950 fi
951 BUILD_DATE=$(LC_ALL=C date +%Y-%b-%d)
952 BASEWSDIR=$(basename $CODEMGR_WS)
953 DEV_CM="\"@(#)SunOS Internal Development: $LOGNAME $BUILD_DATE [$BASEWSDIR]\""
954
955 # we export POUND_SIGN, RELEASE_DATE and DEV_CM to speed up the build process
956 # by avoiding repeated shell invocations to evaluate Makefile.master
957 # definitions.
958 export POUND_SIGN RELEASE_DATE DEV_CM
959
960 maketype="distributed"
961 if [[ -z "$MAKE" ]]; then
962 MAKE=dmake
963 elif [[ ! -x "$MAKE" ]]; then
964 echo "\$MAKE is set to garbage in the environment"
965 exit 1
966 fi
967 # get the dmake version string alone
968 DMAKE_VERSION=$( $MAKE -v )
969 DMAKE_VERSION=${DMAKE_VERSION#*: }
970 # focus in on just the dotted version number alone
971 DMAKE_MAJOR=$( echo $DMAKE_VERSION | \
972 sed -e 's/.*\<\([^.]*\.[^ ]*\).*$/\1/' )
973 # extract the second (or final) integer
974 DMAKE_MINOR=${DMAKE_MAJOR#*.}
975 DMAKE_MINOR=${DMAKE_MINOR%%.*}
976 # extract the first integer
977 DMAKE_MAJOR=${DMAKE_MAJOR%%.*}
978 CHECK_DMAKE=${CHECK_DMAKE:-y}
979 # x86 was built on the 12th, sparc on the 13th.
980 if [ "$CHECK_DMAKE" = "y" -a \
981 "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/12" -a \
982 "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/13" -a \( \
983 "$DMAKE_MAJOR" -lt 7 -o \
984 "$DMAKE_MAJOR" -eq 7 -a "$DMAKE_MINOR" -lt 4 \) ]; then
985 if [ -z "$DMAKE_VERSION" ]; then
986 echo "$MAKE is missing."
987 exit 1
988 fi
989 echo `whence $MAKE`" version is:"
990 echo " ${DMAKE_VERSION}"
991 cat <<EOF
992
993 This version may not be safe for use, if you really want to use this version
994 anyway add the following to your environment to disable this check:
995
996 CHECK_DMAKE=n
997 EOF
998 exit 1
999 fi
1000 export PATH
1001 export MAKE
1002
1003 if [ "${SUNWSPRO}" != "" ]; then
1004 PATH="${SUNWSPRO}/bin:$PATH"
1005 export PATH
1006 fi
1007
1008 hostname=$(uname -n)
1009 if [[ $DMAKE_MAX_JOBS != +([0-9]) || $DMAKE_MAX_JOBS -eq 0 ]]
1010 then
1011 maxjobs=
1012 if [[ -f $HOME/.make.machines ]]
1013 then
1014 # Note: there is a hard tab and space character in the []s
1015 # below.
1016 egrep -i "^[ ]*$hostname[ \.]" \
1017 $HOME/.make.machines | read host jobs
1018 maxjobs=${jobs##*=}
1019 fi
1020
1021 if [[ $maxjobs != +([0-9]) || $maxjobs -eq 0 ]]
1022 then
1023 # default
1024 maxjobs=4
1025 fi
1026
1027 export DMAKE_MAX_JOBS=$maxjobs
1028 fi
1029
1030 DMAKE_MODE=parallel;
1031 export DMAKE_MODE
1032
1033 if [ -z "${ROOT}" ]; then
1034 echo "ROOT must be set."
1035 exit 1
1036 fi
1037
1038 #
1039 # if -V flag was given, reset VERSION to V_ARG
1040 #
1041 if [ "$V_FLAG" = "y" ]; then
1042 VERSION=$V_ARG
1043 fi
1044
1045 TMPDIR="/tmp/nightly.tmpdir.$$"
1046 export TMPDIR
1047 rm -rf ${TMPDIR}
1048 mkdir -p $TMPDIR || exit 1
1049 chmod 777 $TMPDIR
1050
1051 #
1052 # Keep elfsign's use of pkcs11_softtoken from looking in the user home
1053 # directory, which doesn't always work. Needed until all build machines
1054 # have the fix for 6271754
1055 #
1056 SOFTTOKEN_DIR=$TMPDIR
1057 export SOFTTOKEN_DIR
1058
1059 #
1060 # Tools should only be built non-DEBUG. Keep track of the tools proto
1061 # area path relative to $TOOLS, because the latter changes in an
1062 # export build.
1063 #
1064 # TOOLS_PROTO is included below for builds other than usr/src/tools
1065 # that look for this location. For usr/src/tools, this will be
1066 # overridden on the $MAKE command line in build_tools().
1067 #
1068 TOOLS=${SRC}/tools
1069 TOOLS_PROTO_REL=proto/root_${MACH}-nd
1070 TOOLS_PROTO=${TOOLS}/${TOOLS_PROTO_REL}; export TOOLS_PROTO
1071
1072 unset CFLAGS LD_LIBRARY_PATH LDFLAGS
1073
1074 # create directories that are automatically removed if the nightly script
1075 # fails to start correctly
1076 function newdir {
1077 dir=$1
1078 toadd=
1079 while [ ! -d $dir ]; do
1080 toadd="$dir $toadd"
1081 dir=`dirname $dir`
1082 done
1083 torm=
1084 newlist=
1085 for dir in $toadd; do
1086 if staffer mkdir $dir; then
1087 newlist="$ISUSER $dir $newlist"
1088 torm="$dir $torm"
1089 else
1090 [ -z "$torm" ] || staffer rmdir $torm
1091 return 1
1092 fi
1093 done
1094 newdirlist="$newlist $newdirlist"
1095 return 0
1096 }
1097 newdirlist=
1098
1099 [ -d $CODEMGR_WS ] || newdir $CODEMGR_WS || exit 1
1100
1101 # since this script assumes the build is from full source, it nullifies
1102 # variables likely to have been set by a "ws" script; nullification
1103 # confines the search space for headers and libraries to the proto area
1104 # built from this immediate source.
1105 ENVLDLIBS1=
1106 ENVLDLIBS2=
1107 ENVLDLIBS3=
1108 ENVCPPFLAGS1=
1109 ENVCPPFLAGS2=
1110 ENVCPPFLAGS3=
1111 ENVCPPFLAGS4=
1112 PARENT_ROOT=
1113
1114 export ENVLDLIBS3 ENVCPPFLAGS1 ENVCPPFLAGS2 ENVCPPFLAGS3 ENVCPPFLAGS4 \
1115 ENVLDLIBS1 ENVLDLIBS2 PARENT_ROOT
1116
1117 PKGARCHIVE_ORIG=$PKGARCHIVE
1118
1119 #
1120 # Juggle the logs and optionally send mail on completion.
1121 #
1122
1123 function logshuffle {
1124 LLOG="$ATLOG/log.`date '+%F.%H:%M'`"
1125 if [ -f $LLOG -o -d $LLOG ]; then
1126 LLOG=$LLOG.$$
1127 fi
1128 mkdir $LLOG
1129 export LLOG
1130
1131 if [ "$build_ok" = "y" ]; then
1132 mv $ATLOG/proto_list_${MACH} $LLOG
1133
1134 if [ -f $ATLOG/proto_list_tools_${MACH} ]; then
1135 mv $ATLOG/proto_list_tools_${MACH} $LLOG
1136 fi
1137
1138 if [ -f $TMPDIR/wsdiff.results ]; then
1139 mv $TMPDIR/wsdiff.results $LLOG
1140 fi
1141
1142 if [ -f $TMPDIR/wsdiff-nd.results ]; then
1143 mv $TMPDIR/wsdiff-nd.results $LLOG
1144 fi
1145 fi
1146
1147 #
1148 # Now that we're about to send mail, it's time to check the noise
1149 # file. In the event that an error occurs beyond this point, it will
1150 # be recorded in the nightly.log file, but nowhere else. This would
1151 # include only errors that cause the copying of the noise log to fail
1152 # or the mail itself not to be sent.
1153 #
1154
1155 exec >>$LOGFILE 2>&1
1156 if [ -s $build_noise_file ]; then
1157 echo "\n==== Nightly build noise ====\n" |
1158 tee -a $LOGFILE >>$mail_msg_file
1159 cat $build_noise_file >>$LOGFILE
1160 cat $build_noise_file >>$mail_msg_file
1161 echo | tee -a $LOGFILE >>$mail_msg_file
1162 fi
1163 rm -f $build_noise_file
1164
1165 case "$build_ok" in
1166 y)
1167 state=Completed
1168 ;;
1169 i)
1170 state=Interrupted
1171 ;;
1172 *)
1173 state=Failed
1174 ;;
1175 esac
1176
1177 if [[ $state != "Interrupted" && $build_extras_ok != "y" ]]; then
1178 state=Failed
1179 fi
1180
1181 NIGHTLY_STATUS=$state
1182 export NIGHTLY_STATUS
1183
1184 run_hook POST_NIGHTLY $state
1185 run_hook SYS_POST_NIGHTLY $state
1186
1187 #
1188 # mailx(1) sets From: based on the -r flag
1189 # if it is given.
1190 #
1191 mailx_r=
1192 if [[ -n "${MAILFROM}" ]]; then
1193 mailx_r="-r ${MAILFROM}"
1194 fi
1195
1196 cat $build_time_file $build_environ_file $mail_msg_file \
1197 > ${LLOG}/mail_msg
1198 if [ "$m_FLAG" = "y" ]; then
1199 cat ${LLOG}/mail_msg | /usr/bin/mailx ${mailx_r} -s \
1200 "Nightly ${MACH} Build of `basename ${CODEMGR_WS}` ${state}." \
1201 ${MAILTO}
1202 fi
1203
1204 if [ "$u_FLAG" = "y" -a "$build_ok" = "y" ]; then
1205 staffer cp ${LLOG}/mail_msg $PARENT_WS/usr/src/mail_msg-${MACH}
1206 staffer cp $LOGFILE $PARENT_WS/usr/src/nightly-${MACH}.log
1207 fi
1208
1209 mv $LOGFILE $LLOG
1210 }
1211
1212 #
1213 # Remove the locks and temporary files on any exit
1214 #
1215 function cleanup {
1216 logshuffle
1217
1218 [ -z "$lockfile" ] || staffer rm -f $lockfile
1219 [ -z "$atloglockfile" ] || rm -f $atloglockfile
1220 [ -z "$ulockfile" ] || staffer rm -f $ulockfile
1221 [ -z "$Ulockfile" ] || rm -f $Ulockfile
1222
1223 set -- $newdirlist
1224 while [ $# -gt 0 ]; do
1225 ISUSER=$1 staffer rmdir $2
1226 shift; shift
1227 done
1228 rm -rf $TMPDIR
1229 }
1230
1231 function cleanup_signal {
1232 build_ok=i
1233 # this will trigger cleanup(), above.
1234 exit 1
1235 }
1236
1237 trap cleanup 0
1238 trap cleanup_signal 1 2 3 15
1239
1240 #
1241 # Generic lock file processing -- make sure that the lock file doesn't
1242 # exist. If it does, it should name the build host and PID. If it
1243 # doesn't, then make sure we can create it. Clean up locks that are
1244 # known to be stale (assumes host name is unique among build systems
1245 # for the workspace).
1246 #
1247 function create_lock {
1248 lockf=$1
1249 lockvar=$2
1250
1251 ldir=`dirname $lockf`
1252 [ -d $ldir ] || newdir $ldir || exit 1
1253 eval $lockvar=$lockf
1254
1255 while ! staffer ln -s $hostname.$STAFFER.$$ $lockf 2> /dev/null; do
1256 basews=`basename $CODEMGR_WS`
1257 ls -l $lockf | nawk '{print $NF}' | IFS=. read host user pid
1258 if [ "$host" != "$hostname" ]; then
1259 echo "$MACH build of $basews apparently" \
1260 "already started by $user on $host as $pid."
1261 exit 1
1262 elif kill -s 0 $pid 2>/dev/null; then
1263 echo "$MACH build of $basews already started" \
1264 "by $user as $pid."
1265 exit 1
1266 else
1267 # stale lock; clear it out and try again
1268 rm -f $lockf
1269 fi
1270 done
1271 }
1272
1273 #
1274 # Return the list of interesting proto areas, depending on the current
1275 # options.
1276 #
1277 function allprotos {
1278 typeset roots="$ROOT"
1279
1280 if [[ "$F_FLAG" = n && "$MULTI_PROTO" = yes ]]; then
1281 roots="$roots $ROOT-nd"
1282 fi
1283
1284 echo $roots
1285 }
1286
1287 # Ensure no other instance of this script is running on this host.
1288 # LOCKNAME can be set in <env_file>, and is by default, but is not
1289 # required due to the use of $ATLOG below.
1290 if [ -n "$LOCKNAME" ]; then
1291 create_lock /tmp/$LOCKNAME "lockfile"
1292 fi
1293 #
1294 # Create from one, two, or three other locks:
1295 # $ATLOG/nightly.lock
1296 # - protects against multiple builds in same workspace
1297 # $PARENT_WS/usr/src/nightly.$MACH.lock
1298 # - protects against multiple 'u' copy-backs
1299 # $NIGHTLY_PARENT_ROOT/nightly.lock
1300 # - protects against multiple 'U' copy-backs
1301 #
1302 # Overriding ISUSER to 1 causes the lock to be created as root if the
1303 # script is run as root. The default is to create it as $STAFFER.
1304 ISUSER=1 create_lock $ATLOG/nightly.lock "atloglockfile"
1305 if [ "$u_FLAG" = "y" ]; then
1306 create_lock $PARENT_WS/usr/src/nightly.$MACH.lock "ulockfile"
1307 fi
1308 if [ "$U_FLAG" = "y" ]; then
1309 # NIGHTLY_PARENT_ROOT is written as root if script invoked as root.
1310 ISUSER=1 create_lock $NIGHTLY_PARENT_ROOT/nightly.lock "Ulockfile"
1311 fi
1312
1313 # Locks have been taken, so we're doing a build and we're committed to
1314 # the directories we may have created so far.
1315 newdirlist=
1316
1317 #
1318 # Create mail_msg_file
1319 #
1320 mail_msg_file="${TMPDIR}/mail_msg"
1321 touch $mail_msg_file
1322 build_time_file="${TMPDIR}/build_time"
1323 build_environ_file="${TMPDIR}/build_environ"
1324 touch $build_environ_file
1325 #
1326 # Move old LOGFILE aside
1327 # ATLOG directory already made by 'create_lock' above
1328 #
1329 if [ -f $LOGFILE ]; then
1330 mv -f $LOGFILE ${LOGFILE}-
1331 fi
1332 #
1333 # Build OsNet source
1334 #
1335 START_DATE=`date`
1336 SECONDS=0
1337 echo "\n==== Nightly $maketype build started: $START_DATE ====" \
1338 | tee -a $LOGFILE > $build_time_file
1339
1340 echo "\nBuild project: $build_project\nBuild taskid: $build_taskid" | \
1341 tee -a $mail_msg_file >> $LOGFILE
1342
1343 # make sure we log only to the nightly build file
1344 build_noise_file="${TMPDIR}/build_noise"
1345 exec </dev/null >$build_noise_file 2>&1
1346
1347 run_hook SYS_PRE_NIGHTLY
1348 run_hook PRE_NIGHTLY
1349
1350 echo "\n==== list of environment variables ====\n" >> $LOGFILE
1351 env >> $LOGFILE
1352
1353 echo "\n==== Nightly argument issues ====\n" | tee -a $mail_msg_file >> $LOGFILE
1354
1355 if [ "$N_FLAG" = "y" ]; then
1356 if [ "$p_FLAG" = "y" ]; then
1357 cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1358 WARNING: the p option (create packages) is set, but so is the N option (do
1359 not run protocmp); this is dangerous; you should unset the N option
1360 EOF
1361 else
1362 cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1363 Warning: the N option (do not run protocmp) is set; it probably shouldn't be
1364 EOF
1365 fi
1366 echo "" | tee -a $mail_msg_file >> $LOGFILE
1367 fi
1368
1369 if [ "$D_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
1370 #
1371 # In the past we just complained but went ahead with the lint
1372 # pass, even though the proto area was built non-DEBUG. It's
1373 # unlikely that non-DEBUG headers will make a difference, but
1374 # rather than assuming it's a safe combination, force the user
1375 # to specify a DEBUG build.
1376 #
1377 echo "WARNING: DEBUG build not requested; disabling lint.\n" \
1378 | tee -a $mail_msg_file >> $LOGFILE
1379 l_FLAG=n
1380 fi
1381
1382 if [ "$f_FLAG" = "y" ]; then
1383 if [ "$i_FLAG" = "y" ]; then
1384 echo "WARNING: the -f flag cannot be used during incremental" \
1385 "builds; ignoring -f\n" | tee -a $mail_msg_file >> $LOGFILE
1386 f_FLAG=n
1387 fi
1388 if [ "${l_FLAG}${p_FLAG}" != "yy" ]; then
1389 echo "WARNING: the -f flag requires -l, and -p;" \
1390 "ignoring -f\n" | tee -a $mail_msg_file >> $LOGFILE
1391 f_FLAG=n
1392 fi
1393 fi
1394
1395 if [ "$w_FLAG" = "y" -a ! -d $ROOT ]; then
1396 echo "WARNING: -w specified, but $ROOT does not exist;" \
1397 "ignoring -w\n" | tee -a $mail_msg_file >> $LOGFILE
1398 w_FLAG=n
1399 fi
1400
1401 if [ "$t_FLAG" = "n" ]; then
1402 #
1403 # We're not doing a tools build, so make sure elfsign(1) is
1404 # new enough to safely sign non-crypto binaries. We test
1405 # debugging output from elfsign to detect the old version.
1406 #
1407 newelfsigntest=`SUNW_CRYPTO_DEBUG=stderr /usr/bin/elfsign verify \
1408 -e /usr/lib/security/pkcs11_softtoken.so.1 2>&1 \
1409 | egrep algorithmOID`
1410 if [ -z "$newelfsigntest" ]; then
1411 echo "WARNING: /usr/bin/elfsign out of date;" \
1412 "will only sign crypto modules\n" | \
1413 tee -a $mail_msg_file >> $LOGFILE
1414 export ELFSIGN_OBJECT=true
1415 elif [ "$VERIFY_ELFSIGN" = "y" ]; then
1416 echo "WARNING: VERIFY_ELFSIGN=y requires" \
1417 "the -t flag; ignoring VERIFY_ELFSIGN\n" | \
1418 tee -a $mail_msg_file >> $LOGFILE
1419 fi
1420 fi
1421
1422 case $MULTI_PROTO in
1423 yes|no) ;;
1424 *)
1425 echo "WARNING: MULTI_PROTO is \"$MULTI_PROTO\"; " \
1426 "should be \"yes\" or \"no\"." | tee -a $mail_msg_file >> $LOGFILE
1427 echo "Setting MULTI_PROTO to \"no\".\n" | \
1428 tee -a $mail_msg_file >> $LOGFILE
1429 export MULTI_PROTO=no
1430 ;;
1431 esac
1432
1433 echo "\n==== Build version ====\n" | tee -a $mail_msg_file >> $LOGFILE
1434 echo $VERSION | tee -a $mail_msg_file >> $LOGFILE
1435
1436 # Save the current proto area if we're comparing against the last build
1437 if [ "$w_FLAG" = "y" -a -d "$ROOT" ]; then
1438 if [ -d "$ROOT.prev" ]; then
1439 rm -rf $ROOT.prev
1440 fi
1441 mv $ROOT $ROOT.prev
1442 fi
1443
1444 # Same for non-DEBUG proto area
1445 if [ "$w_FLAG" = "y" -a "$MULTI_PROTO" = yes -a -d "$ROOT-nd" ]; then
1446 if [ -d "$ROOT-nd.prev" ]; then
1447 rm -rf $ROOT-nd.prev
1448 fi
1449 mv $ROOT-nd $ROOT-nd.prev
1450 fi
1451
1452 #
1453 # Echo the SCM type of the parent workspace, this can't just be which_scm
1454 # as that does not know how to identify various network repositories.
1455 #
1456 function parent_wstype {
1457 typeset scm_type junk
1458
1459 CODEMGR_WS="$BRINGOVER_WS" "$WHICH_SCM" 2>/dev/null \
1460 | read scm_type junk
1461 if [[ -z "$scm_type" || "$scm_type" == unknown ]]; then
1462 # Probe BRINGOVER_WS to determine its type
1463 if [[ $BRINGOVER_WS == ssh://* ]]; then
1464 scm_type="mercurial"
1465 elif [[ $BRINGOVER_WS == http://* ]] && \
1466 wget -q -O- --save-headers "$BRINGOVER_WS/?cmd=heads" | \
1467 egrep -s "application/mercurial" 2> /dev/null; then
1468 scm_type="mercurial"
1469 else
1470 scm_type="none"
1471 fi
1472 fi
1473
1474 # fold both unsupported and unrecognized results into "none"
1475 case "$scm_type" in
1476 mercurial)
1477 ;;
1478 *) scm_type=none
1479 ;;
1480 esac
1481
1482 echo $scm_type
1483 }
1484
1485 # Echo the SCM types of $CODEMGR_WS and $BRINGOVER_WS
1486 function child_wstype {
1487 typeset scm_type junk
1488
1489 # Probe CODEMGR_WS to determine its type
1490 if [[ -d $CODEMGR_WS ]]; then
1491 $WHICH_SCM | read scm_type junk || exit 1
1492 fi
1493
1494 case "$scm_type" in
1495 none|git|mercurial)
1496 ;;
1497 *) scm_type=none
1498 ;;
1499 esac
1500
1501 echo $scm_type
1502 }
1503
1504 SCM_TYPE=$(child_wstype)
1505
1506 #
1507 # Decide whether to clobber
1508 #
1509 if [ "$i_FLAG" = "n" -a -d "$SRC" ]; then
1510 echo "\n==== Make clobber at `date` ====\n" >> $LOGFILE
1511
1512 cd $SRC
1513 # remove old clobber file
1514 rm -f $SRC/clobber.out
1515 rm -f $SRC/clobber-${MACH}.out
1516
1517 # Remove all .make.state* files, just in case we are restarting
1518 # the build after having interrupted a previous 'make clobber'.
1519 find . \( -name SCCS -o -name .hg -o -name .svn -o -name .git \
1520 -o -name 'interfaces.*' \) -prune \
1521 -o -name '.make.*' -print | xargs rm -f
1522
1523 $MAKE -ek clobber 2>&1 | tee -a $SRC/clobber-${MACH}.out >> $LOGFILE
1524 echo "\n==== Make clobber ERRORS ====\n" >> $mail_msg_file
1525 grep "$MAKE:" $SRC/clobber-${MACH}.out |
1526 egrep -v "Ignoring unknown host" | \
1527 tee $TMPDIR/clobber_errs >> $mail_msg_file
1528
1529 if [[ -s $TMPDIR/clobber_errs ]]; then
1530 build_extras_ok=n
1531 fi
1532
1533 if [[ "$t_FLAG" = "y" ]]; then
1534 echo "\n==== Make tools clobber at `date` ====\n" >> $LOGFILE
1535 cd ${TOOLS}
1536 rm -f ${TOOLS}/clobber-${MACH}.out
1537 $MAKE TOOLS_PROTO=$TOOLS_PROTO -ek clobber 2>&1 | \
1538 tee -a ${TOOLS}/clobber-${MACH}.out >> $LOGFILE
1539 echo "\n==== Make tools clobber ERRORS ====\n" \
1540 >> $mail_msg_file
1541 grep "$MAKE:" ${TOOLS}/clobber-${MACH}.out \
1542 >> $mail_msg_file
1543 if (( $? == 0 )); then
1544 build_extras_ok=n
1545 fi
1546 rm -rf ${TOOLS_PROTO}
1547 mkdir -p ${TOOLS_PROTO}
1548 fi
1549
1550 typeset roots=$(allprotos)
1551 echo "\n\nClearing $roots" >> "$LOGFILE"
1552 rm -rf $roots
1553
1554 # Get back to a clean workspace as much as possible to catch
1555 # problems that only occur on fresh workspaces.
1556 # Remove all .make.state* files, libraries, and .o's that may
1557 # have been omitted from clobber. A couple of libraries are
1558 # under source code control, so leave them alone.
1559 # We should probably blow away temporary directories too.
1560 cd $SRC
1561 find $relsrcdirs \( -name SCCS -o -name .hg -o -name .svn \
1562 -o -name .git -o -name 'interfaces.*' \) -prune -o \
1563 \( -name '.make.*' -o -name 'lib*.a' -o -name 'lib*.so*' -o \
1564 -name '*.o' \) -print | \
1565 grep -v 'tools/ctf/dwarf/.*/libdwarf' | xargs rm -f
1566 else
1567 echo "\n==== No clobber at `date` ====\n" >> $LOGFILE
1568 fi
1569
1570 type bringover_mercurial > /dev/null 2>&1 || function bringover_mercurial {
1571 typeset -x PATH=$PATH
1572
1573 # If the repository doesn't exist yet, then we want to populate it.
1574 if [[ ! -d $CODEMGR_WS/.hg ]]; then
1575 staffer hg init $CODEMGR_WS
1576 staffer echo "[paths]" > $CODEMGR_WS/.hg/hgrc
1577 staffer echo "default=$BRINGOVER_WS" >> $CODEMGR_WS/.hg/hgrc
1578 touch $TMPDIR/new_repository
1579 fi
1580
1581 typeset -x HGMERGE="/bin/false"
1582
1583 #
1584 # If the user has changes, regardless of whether those changes are
1585 # committed, and regardless of whether those changes conflict, then
1586 # we'll attempt to merge them either implicitly (uncommitted) or
1587 # explicitly (committed).
1588 #
1589 # These are the messages we'll use to help clarify mercurial output
1590 # in those cases.
1591 #
1592 typeset mergefailmsg="\
1593 ***\n\
1594 *** nightly was unable to automatically merge your changes. You should\n\
1595 *** redo the full merge manually, following the steps outlined by mercurial\n\
1596 *** above, then restart nightly.\n\
1597 ***\n"
1598 typeset mergepassmsg="\
1599 ***\n\
1600 *** nightly successfully merged your changes. This means that your working\n\
1601 *** directory has been updated, but those changes are not yet committed.\n\
1602 *** After nightly completes, you should validate the results of the merge,\n\
1603 *** then use hg commit manually.\n\
1604 ***\n"
1605
1606 #
1607 # For each repository in turn:
1608 #
1609 # 1. Do the pull. If this fails, dump the output and bail out.
1610 #
1611 # 2. If the pull resulted in an extra head, do an explicit merge.
1612 # If this fails, dump the output and bail out.
1613 #
1614 # Because we can't rely on Mercurial to exit with a failure code
1615 # when a merge fails (Mercurial issue #186), we must grep the
1616 # output of pull/merge to check for attempted and/or failed merges.
1617 #
1618 # 3. If a merge failed, set the message and fail the bringover.
1619 #
1620 # 4. Otherwise, if a merge succeeded, set the message
1621 #
1622 # 5. Dump the output, and any message from step 3 or 4.
1623 #
1624
1625 typeset HG_SOURCE=$BRINGOVER_WS
1626 if [ ! -f $TMPDIR/new_repository ]; then
1627 HG_SOURCE=$TMPDIR/open_bundle.hg
1628 staffer hg --cwd $CODEMGR_WS incoming --bundle $HG_SOURCE \
1629 -v $BRINGOVER_WS > $TMPDIR/incoming_open.out
1630
1631 #
1632 # If there are no incoming changesets, then incoming will
1633 # fail, and there will be no bundle file. Reset the source,
1634 # to allow the remaining logic to complete with no false
1635 # negatives. (Unlike incoming, pull will return success
1636 # for the no-change case.)
1637 #
1638 if (( $? != 0 )); then
1639 HG_SOURCE=$BRINGOVER_WS
1640 fi
1641 fi
1642
1643 staffer hg --cwd $CODEMGR_WS pull -u $HG_SOURCE \
1644 > $TMPDIR/pull_open.out 2>&1
1645 if (( $? != 0 )); then
1646 printf "%s: pull failed as follows:\n\n" "$CODEMGR_WS"
1647 cat $TMPDIR/pull_open.out
1648 if grep "^merging.*failed" $TMPDIR/pull_open.out > /dev/null 2>&1; then
1649 printf "$mergefailmsg"
1650 fi
1651 touch $TMPDIR/bringover_failed
1652 return
1653 fi
1654
1655 if grep "not updating" $TMPDIR/pull_open.out > /dev/null 2>&1; then
1656 staffer hg --cwd $CODEMGR_WS merge \
1657 >> $TMPDIR/pull_open.out 2>&1
1658 if (( $? != 0 )); then
1659 printf "%s: merge failed as follows:\n\n" \
1660 "$CODEMGR_WS"
1661 cat $TMPDIR/pull_open.out
1662 if grep "^merging.*failed" $TMPDIR/pull_open.out \
1663 > /dev/null 2>&1; then
1664 printf "$mergefailmsg"
1665 fi
1666 touch $TMPDIR/bringover_failed
1667 return
1668 fi
1669 fi
1670
1671 printf "updated %s with the following results:\n" "$CODEMGR_WS"
1672 cat $TMPDIR/pull_open.out
1673 if grep "^merging" $TMPDIR/pull_open.out >/dev/null 2>&1; then
1674 printf "$mergepassmsg"
1675 fi
1676 printf "\n"
1677
1678 #
1679 # Per-changeset output is neither useful nor manageable for a
1680 # newly-created repository.
1681 #
1682 if [ -f $TMPDIR/new_repository ]; then
1683 return
1684 fi
1685
1686 printf "\nadded the following changesets to open repository:\n"
1687 cat $TMPDIR/incoming_open.out
1688 }
1689
1690 type bringover_none > /dev/null 2>&1 || function bringover_none {
1691 echo "Couldn't figure out what kind of SCM to use for $BRINGOVER_WS."
1692 touch $TMPDIR/bringover_failed
1693 }
1694
1695 #
1696 # Decide whether to bringover to the codemgr workspace
1697 #
1698 if [ "$n_FLAG" = "n" ]; then
1699 PARENT_SCM_TYPE=$(parent_wstype)
1700
1701 if [[ $SCM_TYPE != none && $SCM_TYPE != $PARENT_SCM_TYPE ]]; then
1702 echo "cannot bringover from $PARENT_SCM_TYPE to $SCM_TYPE, " \
1703 "quitting at `date`." | tee -a $mail_msg_file >> $LOGFILE
1704 exit 1
1705 fi
1706
1707 run_hook PRE_BRINGOVER
1708
1709 echo "\n==== bringover to $CODEMGR_WS at `date` ====\n" >> $LOGFILE
1710 echo "\n==== BRINGOVER LOG ====\n" >> $mail_msg_file
1711
1712 eval "bringover_${PARENT_SCM_TYPE}" 2>&1 |
1713 tee -a $mail_msg_file >> $LOGFILE
1714
1715 if [ -f $TMPDIR/bringover_failed ]; then
1716 rm -f $TMPDIR/bringover_failed
1717 build_ok=n
1718 echo "trouble with bringover, quitting at `date`." |
1719 tee -a $mail_msg_file >> $LOGFILE
1720 exit 1
1721 fi
1722
1723 #
1724 # It's possible that we used the bringover above to create
1725 # $CODEMGR_WS. If so, then SCM_TYPE was previously "none,"
1726 # but should now be the same as $BRINGOVER_WS.
1727 #
1728 [[ $SCM_TYPE = none ]] && SCM_TYPE=$PARENT_SCM_TYPE
1729
1730 run_hook POST_BRINGOVER
1731
1732 check_closed_bins
1733
1734 else
1735 echo "\n==== No bringover to $CODEMGR_WS ====\n" >> $LOGFILE
1736 fi
1737
1738 # Safeguards
1739 [[ -v CODEMGR_WS ]] || fatal_error "Error: Variable CODEMGR_WS not set."
1740 [[ -d "${CODEMGR_WS}" ]] || fatal_error "Error: ${CODEMGR_WS} is not a directory."
1741 [[ -f "${CODEMGR_WS}/usr/src/Makefile" ]] || fatal_error "Error: ${CODEMGR_WS}/usr/src/Makefile not found."
1742
1743 echo "\n==== Build environment ====\n" | tee -a $build_environ_file >> $LOGFILE
1744
1745 # System
1746 whence uname | tee -a $build_environ_file >> $LOGFILE
1747 uname -a 2>&1 | tee -a $build_environ_file >> $LOGFILE
1748 echo | tee -a $build_environ_file >> $LOGFILE
1749
1750 # make
1751 whence $MAKE | tee -a $build_environ_file >> $LOGFILE
1752 $MAKE -v | tee -a $build_environ_file >> $LOGFILE
1753 echo "number of concurrent jobs = $DMAKE_MAX_JOBS" |
1754 tee -a $build_environ_file >> $LOGFILE
1755
1756 #
1757 # Report the compiler versions.
1758 #
1759
1760 if [[ ! -f $SRC/Makefile ]]; then
1761 build_ok=n
1762 echo "\nUnable to find \"Makefile\" in $SRC." | \
1763 tee -a $build_environ_file >> $LOGFILE
1764 exit 1
1765 fi
1766
1767 ( cd $SRC
1768 for target in cc-version cc64-version java-version; do
1769 echo
1770 #
1771 # Put statefile somewhere we know we can write to rather than trip
1772 # over a read-only $srcroot.
1773 #
1774 rm -f $TMPDIR/make-state
1775 export SRC
1776 if $MAKE -K $TMPDIR/make-state -e $target 2>/dev/null; then
1777 continue
1778 fi
1779 touch $TMPDIR/nocompiler
1780 done
1781 echo
1782 ) | tee -a $build_environ_file >> $LOGFILE
1783
1784 if [ -f $TMPDIR/nocompiler ]; then
1785 rm -f $TMPDIR/nocompiler
1786 build_ok=n
1787 echo "Aborting due to missing compiler." |
1788 tee -a $build_environ_file >> $LOGFILE
1789 exit 1
1790 fi
1791
1792 # as
1793 whence as | tee -a $build_environ_file >> $LOGFILE
1794 as -V 2>&1 | head -1 | tee -a $build_environ_file >> $LOGFILE
1795 echo | tee -a $build_environ_file >> $LOGFILE
1796
1797 # Check that we're running a capable link-editor
1798 whence ld | tee -a $build_environ_file >> $LOGFILE
1799 LDVER=`ld -V 2>&1`
1800 echo $LDVER | tee -a $build_environ_file >> $LOGFILE
1801 LDVER=`echo $LDVER | sed -e "s/.*-1\.\([0-9]*\).*/\1/"`
1802 if [ `expr $LDVER \< 422` -eq 1 ]; then
1803 echo "The link-editor needs to be at version 422 or higher to build" | \
1804 tee -a $build_environ_file >> $LOGFILE
1805 echo "the latest stuff. Hope your build works." | \
1806 tee -a $build_environ_file >> $LOGFILE
1807 fi
1808
1809 #
1810 # Build and use the workspace's tools if requested
1811 #
1812 if [[ "$t_FLAG" = "y" ]]; then
1813 set_non_debug_build_flags
1814
1815 build_tools ${TOOLS_PROTO}
1816 if (( $? != 0 )); then
1817 build_ok=n
1818 else
1819 use_tools $TOOLS_PROTO
1820 fi
1821 fi
1822
1823 # timestamp the start of the normal build; the findunref tool uses it.
1824 touch $SRC/.build.tstamp
1825
1826 normal_build
1827
1828 ORIG_SRC=$SRC
1829 BINARCHIVE=${CODEMGR_WS}/bin-${MACH}.cpio.Z
1830
1831
1832 #
1833 # There are several checks that need to look at the proto area, but
1834 # they only need to look at one, and they don't care whether it's
1835 # DEBUG or non-DEBUG.
1836 #
1837 if [[ "$MULTI_PROTO" = yes && "$D_FLAG" = n ]]; then
1838 checkroot=$ROOT-nd
1839 else
1840 checkroot=$ROOT
1841 fi
1842
1843 if [ "$build_ok" = "y" ]; then
1844 echo "\n==== Creating protolist system file at `date` ====" \
1845 >> $LOGFILE
1846 protolist $checkroot > $ATLOG/proto_list_${MACH}
1847 echo "==== protolist system file created at `date` ====\n" \
1848 >> $LOGFILE
1849
1850 if [ "$N_FLAG" != "y" ]; then
1851
1852 E1=
1853 f1=
1854 for f in $f1; do
1855 if [ -f "$f" ]; then
1856 E1="$E1 -e $f"
1857 fi
1858 done
1859
1860 E2=
1861 f2=
1862 if [ -d "$SRC/pkg" ]; then
1863 f2="$f2 exceptions/packaging"
1864 fi
1865
1866 for f in $f2; do
1867 if [ -f "$f" ]; then
1868 E2="$E2 -e $f"
1869 fi
1870 done
1871 fi
1872
1873 if [ "$N_FLAG" != "y" -a -d $SRC/pkg ]; then
1874 echo "\n==== Validating manifests against proto area ====\n" \
1875 >> $mail_msg_file
1876 ( cd $SRC/pkg ; $MAKE -e protocmp ROOT="$checkroot" ) | \
1877 tee $TMPDIR/protocmp_noise >> $mail_msg_file
1878 if [[ -s $TMPDIR/protocmp_noise ]]; then
1879 build_extras_ok=n
1880 fi
1881 fi
1882
1883 if [ "$N_FLAG" != "y" -a -f "$REF_PROTO_LIST" ]; then
1884 echo "\n==== Impact on proto area ====\n" >> $mail_msg_file
1885 if [ -n "$E2" ]; then
1886 ELIST=$E2
1887 else
1888 ELIST=$E1
1889 fi
1890 $PROTOCMPTERSE \
1891 "Files in yesterday's proto area, but not today's:" \
1892 "Files in today's proto area, but not yesterday's:" \
1893 "Files that changed between yesterday and today:" \
1894 ${ELIST} \
1895 -d $REF_PROTO_LIST \
1896 $ATLOG/proto_list_${MACH} \
1897 >> $mail_msg_file
1898 fi
1899 fi
1900
1901 if [[ "$u_FLAG" == "y" && "$build_ok" == "y" && \
1902 "$build_extras_ok" == "y" ]]; then
1903 staffer cp $ATLOG/proto_list_${MACH} \
1904 $PARENT_WS/usr/src/proto_list_${MACH}
1905 fi
1906
1907 # Update parent proto area if necessary. This is done now
1908 # so that the proto area has either DEBUG or non-DEBUG kernels.
1909 # Note that this clears out the lock file, so we can dispense with
1910 # the variable now.
1911 if [ "$U_FLAG" = "y" -a "$build_ok" = "y" ]; then
1912 echo "\n==== Copying proto area to $NIGHTLY_PARENT_ROOT ====\n" | \
1913 tee -a $LOGFILE >> $mail_msg_file
1914 rm -rf $NIGHTLY_PARENT_ROOT/*
1915 unset Ulockfile
1916 mkdir -p $NIGHTLY_PARENT_ROOT
1917 if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
1918 ( cd $ROOT; tar cf - . |
1919 ( cd $NIGHTLY_PARENT_ROOT; umask 0; tar xpf - ) ) 2>&1 |
1920 tee -a $mail_msg_file >> $LOGFILE
1921 fi
1922 if [[ "$MULTI_PROTO" = yes && "$F_FLAG" = n ]]; then
1923 rm -rf $NIGHTLY_PARENT_ROOT-nd/*
1924 mkdir -p $NIGHTLY_PARENT_ROOT-nd
1925 cd $ROOT-nd
1926 ( tar cf - . |
1927 ( cd $NIGHTLY_PARENT_ROOT-nd; umask 0; tar xpf - ) ) 2>&1 |
1928 tee -a $mail_msg_file >> $LOGFILE
1929 fi
1930 if [ -n "${NIGHTLY_PARENT_TOOLS_ROOT}" ]; then
1931 echo "\n==== Copying tools proto area to $NIGHTLY_PARENT_TOOLS_ROOT ====\n" | \
1932 tee -a $LOGFILE >> $mail_msg_file
1933 rm -rf $NIGHTLY_PARENT_TOOLS_ROOT/*
1934 mkdir -p $NIGHTLY_PARENT_TOOLS_ROOT
1935 if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
1936 ( cd $TOOLS_PROTO; tar cf - . |
1937 ( cd $NIGHTLY_PARENT_TOOLS_ROOT;
1938 umask 0; tar xpf - ) ) 2>&1 |
1939 tee -a $mail_msg_file >> $LOGFILE
1940 fi
1941 fi
1942 fi
1943
1944 #
1945 # ELF verification: ABI (-A) and runtime (-r) checks
1946 #
1947 if [[ ($build_ok = y) && (($A_FLAG = y) || ($r_FLAG = y)) ]]; then
1948 # Directory ELF-data.$MACH holds the files produced by these tests.
1949 elf_ddir=$SRC/ELF-data.$MACH
1950
1951 # If there is a previous ELF-data backup directory, remove it. Then,
1952 # rotate current ELF-data directory into its place and create a new
1953 # empty directory
1954 rm -rf $elf_ddir.ref
1955 if [[ -d $elf_ddir ]]; then
1956 mv $elf_ddir $elf_ddir.ref
1957 fi
1958 mkdir -p $elf_ddir
1959
1960 # Call find_elf to produce a list of the ELF objects in the proto area.
1961 # This list is passed to check_rtime and interface_check, preventing
1962 # them from separately calling find_elf to do the same work twice.
1963 find_elf -fr $checkroot > $elf_ddir/object_list
1964
1965 if [[ $A_FLAG = y ]]; then
1966 echo "\n==== Check versioning and ABI information ====\n" | \
1967 tee -a $LOGFILE >> $mail_msg_file
1968
1969 # Produce interface description for the proto. Report errors.
1970 interface_check -o -w $elf_ddir -f object_list \
1971 -i interface -E interface.err
1972 if [[ -s $elf_ddir/interface.err ]]; then
1973 tee -a $LOGFILE < $elf_ddir/interface.err \
1974 >> $mail_msg_file
1975 build_extras_ok=n
1976 fi
1977
1978 # If ELF_DATA_BASELINE_DIR is defined, compare the new interface
1979 # description file to that from the baseline gate. Issue a
1980 # warning if the baseline is not present, and keep going.
1981 if [[ "$ELF_DATA_BASELINE_DIR" != '' ]]; then
1982 base_ifile="$ELF_DATA_BASELINE_DIR/interface"
1983
1984 echo "\n==== Compare versioning and ABI information" \
1985 "to baseline ====\n" | \
1986 tee -a $LOGFILE >> $mail_msg_file
1987 echo "Baseline: $base_ifile\n" >> $LOGFILE
1988
1989 if [[ -f $base_ifile ]]; then
1990 interface_cmp -d -o $base_ifile \
1991 $elf_ddir/interface > $elf_ddir/interface.cmp
1992 if [[ -s $elf_ddir/interface.cmp ]]; then
1993 echo | tee -a $LOGFILE >> $mail_msg_file
1994 tee -a $LOGFILE < \
1995 $elf_ddir/interface.cmp \
1996 >> $mail_msg_file
1997 build_extras_ok=n
1998 fi
1999 else
2000 echo "baseline not available. comparison" \
2001 "skipped" | \
2002 tee -a $LOGFILE >> $mail_msg_file
2003 fi
2004
2005 fi
2006 fi
2007
2008 if [[ $r_FLAG = y ]]; then
2009 echo "\n==== Check ELF runtime attributes ====\n" | \
2010 tee -a $LOGFILE >> $mail_msg_file
2011
2012 # If we're doing a DEBUG build the proto area will be left
2013 # with debuggable objects, thus don't assert -s.
2014 if [[ $D_FLAG = y ]]; then
2015 rtime_sflag=""
2016 else
2017 rtime_sflag="-s"
2018 fi
2019 check_rtime -i -m -v $rtime_sflag -o -w $elf_ddir \
2020 -D object_list -f object_list -E runtime.err \
2021 -I runtime.attr.raw
2022 if (( $? != 0 )); then
2023 build_extras_ok=n
2024 fi
2025
2026 # check_rtime -I output needs to be sorted in order to
2027 # compare it to that from previous builds.
2028 sort $elf_ddir/runtime.attr.raw > $elf_ddir/runtime.attr
2029 rm $elf_ddir/runtime.attr.raw
2030
2031 # Report errors
2032 if [[ -s $elf_ddir/runtime.err ]]; then
2033 tee -a $LOGFILE < $elf_ddir/runtime.err \
2034 >> $mail_msg_file
2035 build_extras_ok=n
2036 fi
2037
2038 # If there is an ELF-data directory from a previous build,
2039 # then diff the attr files. These files contain information
2040 # about dependencies, versioning, and runpaths. There is some
2041 # overlap with the ABI checking done above, but this also
2042 # flushes out non-ABI interface differences along with the
2043 # other information.
2044 echo "\n==== Diff ELF runtime attributes" \
2045 "(since last build) ====\n" | \
2046 tee -a $LOGFILE >> $mail_msg_file >> $mail_msg_file
2047
2048 if [[ -f $elf_ddir.ref/runtime.attr ]]; then
2049 diff $elf_ddir.ref/runtime.attr \
2050 $elf_ddir/runtime.attr \
2051 >> $mail_msg_file
2052 fi
2053 fi
2054
2055 # If -u set, copy contents of ELF-data.$MACH to the parent workspace.
2056 if [[ "$u_FLAG" = "y" ]]; then
2057 p_elf_ddir=$PARENT_WS/usr/src/ELF-data.$MACH
2058
2059 # If parent lacks the ELF-data.$MACH directory, create it
2060 if [[ ! -d $p_elf_ddir ]]; then
2061 staffer mkdir -p $p_elf_ddir
2062 fi
2063
2064 # These files are used asynchronously by other builds for ABI
2065 # verification, as above for the -A option. As such, we require
2066 # the file replacement to be atomic. Copy the data to a temp
2067 # file in the same filesystem and then rename into place.
2068 (
2069 cd $elf_ddir
2070 for elf_dfile in *; do
2071 staffer cp $elf_dfile \
2072 ${p_elf_ddir}/${elf_dfile}.new
2073 staffer mv -f ${p_elf_ddir}/${elf_dfile}.new \
2074 ${p_elf_ddir}/${elf_dfile}
2075 done
2076 )
2077 fi
2078 fi
2079
2080 # DEBUG lint of kernel begins
2081
2082 if [ "$i_CMD_LINE_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
2083 if [ "$LINTDIRS" = "" ]; then
2084 # LINTDIRS="$SRC/uts y $SRC/stand y $SRC/psm y"
2085 LINTDIRS="$SRC y"
2086 fi
2087 set $LINTDIRS
2088 while [ $# -gt 0 ]; do
2089 dolint $1 $2; shift; shift
2090 done
2091 else
2092 echo "\n==== No '$MAKE lint' ====\n" >> $LOGFILE
2093 fi
2094
2095 # "make check" begins
2096
2097 if [ "$i_CMD_LINE_FLAG" = "n" -a "$C_FLAG" = "y" ]; then
2098 # remove old check.out
2099 rm -f $SRC/check.out
2100
2101 rm -f $SRC/check-${MACH}.out
2102 cd $SRC
2103 $MAKE -ek check ROOT="$checkroot" 2>&1 | tee -a $SRC/check-${MACH}.out \
2104 >> $LOGFILE
2105 echo "\n==== cstyle/hdrchk errors ====\n" >> $mail_msg_file
2106
2107 grep ":" $SRC/check-${MACH}.out |
2108 egrep -v "Ignoring unknown host" | \
2109 sort | uniq | tee $TMPDIR/check_errors >> $mail_msg_file
2110
2111 if [[ -s $TMPDIR/check_errors ]]; then
2112 build_extras_ok=n
2113 fi
2114 else
2115 echo "\n==== No '$MAKE check' ====\n" >> $LOGFILE
2116 fi
2117
2118 echo "\n==== Find core files ====\n" | \
2119 tee -a $LOGFILE >> $mail_msg_file
2120
2121 find $abssrcdirs -name core -a -type f -exec file {} \; | \
2122 tee -a $LOGFILE >> $mail_msg_file
2123
2124 if [ "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
2125 echo "\n==== Diff unreferenced files (since last build) ====\n" \
2126 | tee -a $LOGFILE >>$mail_msg_file
2127 rm -f $SRC/unref-${MACH}.ref
2128 if [ -f $SRC/unref-${MACH}.out ]; then
2129 mv $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
2130 fi
2131
2132 findunref -S $SCM_TYPE -t $SRC/.build.tstamp -s usr $CODEMGR_WS \
2133 ${TOOLS}/findunref/exception_list 2>> $mail_msg_file | \
2134 sort > $SRC/unref-${MACH}.out
2135
2136 if [ ! -f $SRC/unref-${MACH}.ref ]; then
2137 cp $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
2138 fi
2139
2140 diff $SRC/unref-${MACH}.ref $SRC/unref-${MACH}.out >>$mail_msg_file
2141 fi
2142
2143 # Verify that the usual lists of files, such as exception lists,
2144 # contain only valid references to files. If the build has failed,
2145 # then don't check the proto area.
2146 CHECK_PATHS=${CHECK_PATHS:-y}
2147 if [ "$CHECK_PATHS" = y -a "$N_FLAG" != y ]; then
2148 echo "\n==== Check lists of files ====\n" | tee -a $LOGFILE \
2149 >>$mail_msg_file
2150 arg=-b
2151 [ "$build_ok" = y ] && arg=
2152 checkpaths $arg $checkroot > $SRC/checkpaths.out 2>&1
2153 if [[ -s $SRC/checkpaths.out ]]; then
2154 tee -a $LOGFILE < $SRC/checkpaths.out >> $mail_msg_file
2155 build_extras_ok=n
2156 fi
2157 fi
2158
2159 if [ "$M_FLAG" != "y" -a "$build_ok" = y ]; then
2160 echo "\n==== Impact on file permissions ====\n" \
2161 >> $mail_msg_file
2162
2163 abspkg=
2164 for d in $abssrcdirs; do
2165 if [ -d "$d/pkg" ]; then
2166 abspkg="$abspkg $d"
2167 fi
2168 done
2169
2170 if [ -n "$abspkg" ]; then
2171 for d in "$abspkg"; do
2172 ( cd $d/pkg ; $MAKE -e pmodes ) >> $mail_msg_file
2173 done
2174 fi
2175 fi
2176
2177 if [ "$w_FLAG" = "y" -a "$build_ok" = "y" ]; then
2178 if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
2179 do_wsdiff DEBUG $ROOT.prev $ROOT
2180 fi
2181
2182 if [[ "$MULTI_PROTO" = yes && "$F_FLAG" = n ]]; then
2183 do_wsdiff non-DEBUG $ROOT-nd.prev $ROOT-nd
2184 fi
2185 fi
2186
2187 END_DATE=`date`
2188 echo "==== Nightly $maketype build completed: $END_DATE ====" | \
2189 tee -a $LOGFILE >> $build_time_file
2190
2191 typeset -i10 hours
2192 typeset -Z2 minutes
2193 typeset -Z2 seconds
2194
2195 elapsed_time=$SECONDS
2196 ((hours = elapsed_time / 3600 ))
2197 ((minutes = elapsed_time / 60 % 60))
2198 ((seconds = elapsed_time % 60))
2199
2200 echo "\n==== Total build time ====" | \
2201 tee -a $LOGFILE >> $build_time_file
2202 echo "\nreal ${hours}:${minutes}:${seconds}" | \
2203 tee -a $LOGFILE >> $build_time_file
2204
2205 if [ "$u_FLAG" = "y" -a "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
2206 staffer cp ${SRC}/unref-${MACH}.out $PARENT_WS/usr/src/
2207
2208 #
2209 # Produce a master list of unreferenced files -- ideally, we'd
2210 # generate the master just once after all of the nightlies
2211 # have finished, but there's no simple way to know when that
2212 # will be. Instead, we assume that we're the last nightly to
2213 # finish and merge all of the unref-${MACH}.out files in
2214 # $PARENT_WS/usr/src/. If we are in fact the final ${MACH} to
2215 # finish, then this file will be the authoritative master
2216 # list. Otherwise, another ${MACH}'s nightly will eventually
2217 # overwrite ours with its own master, but in the meantime our
2218 # temporary "master" will be no worse than any older master
2219 # which was already on the parent.
2220 #
2221
2222 set -- $PARENT_WS/usr/src/unref-*.out
2223 cp "$1" ${TMPDIR}/unref.merge
2224 shift
2225
2226 for unreffile; do
2227 comm -12 ${TMPDIR}/unref.merge "$unreffile" > ${TMPDIR}/unref.$$
2228 mv ${TMPDIR}/unref.$$ ${TMPDIR}/unref.merge
2229 done
2230
2231 staffer cp ${TMPDIR}/unref.merge $PARENT_WS/usr/src/unrefmaster.out
2232 fi
2233
2234 #
2235 # All done save for the sweeping up.
2236 # (whichever exit we hit here will trigger the "cleanup" trap which
2237 # optionally sends mail on completion).
2238 #
2239 if [[ "$build_ok" == "y" && "$build_extras_ok" == "y" ]]; then
2240 exit 0
2241 fi
2242 exit 1