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