1 #!/bin/bash
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, Version 1.0 only
7 # (the "License"). You may not use this file except in compliance
8 # with the License.
9 #
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
14 #
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
20 #
21 # CDDL HEADER END
22 #
23 #
24 # Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
25 # Use is subject to license terms.
26 # Copyright (c) 2014 by Delphix. All rights reserved.
27 #
28
29 umask 022
30
31 #############################################################################
32 # functions.sh
33 #############################################################################
34 # Helper functions for building packages that should be common to all build
35 # scripts
36 #############################################################################
37
38 #############################################################################
39 # Process command line options
40 #############################################################################
41 process_opts() {
42 SCREENOUT=
43 FLAVOR=
44 OLDFLAVOR=
45 BUILDARCH=both
46 OLDBUILDARCH=
47 BATCH=
48 AUTOINSTALL=
49 DEPVER=
50 SKIP_PKGLINT=
51 while getopts "bipf:ha:d:lr:" opt; do
52 case $opt in
53 h)
54 show_usage
55 exit
56 ;;
57 \?)
58 show_usage
59 exit 2
60 ;;
61 l)
62 SKIP_PKGLINT=1
63 ;;
64 p)
65 SCREENOUT=1
66 ;;
67 b)
68 BATCH=1 # Batch mode - exit on error
69 ;;
70 i)
71 AUTOINSTALL=1
72 ;;
73 f)
74 FLAVOR=$OPTARG
75 OLDFLAVOR=$OPTARG # Used to see if the script overrides the
76 # flavor
77 ;;
78 r)
79 PKGSRVR=$OPTARG
80 ;;
81 a)
82 BUILDARCH=$OPTARG
83 OLDBUILDARCH=$OPTARG # Used to see if the script overrides the
84 # BUILDARCH variable
85 if [[ "$BUILDARCH" != "32" && "$BUILDARCH" != "64" &&
86 "$BUILDARCH" != "both" ]]; then
87 echo "Invalid build architecture specified: $BUILDARCH"
88 show_usage
89 exit 2
90 fi
91 ;;
92 d)
93 DEPVER=$OPTARG
94 ;;
95 esac
96 done
97 }
98
99 #############################################################################
100 # Show usage information
101 #############################################################################
102 show_usage() {
103 echo "Usage: $0 [-b] [-p] [-f FLAVOR] [-h] [-a 32|64|both] [-d DEPVER]"
104 echo " -b : batch mode (exit on errors without asking)"
105 echo " -i : autoinstall mode (install build deps)"
106 echo " -p : output all commands to the screen as well as log file"
107 echo " -l : skip pkglint check"
108 echo " -f FLAVOR : build a specific package flavor"
109 echo " -h : print this help text"
110 echo " -a ARCH : build 32/64 bit only, or both (default: both)"
111 echo " -d DEPVER : specify an extra dependency version (no default)"
112 echo " -r REPO : specify the IPS repo to use (default: $PKGSRVR)"
113 }
114
115 #############################################################################
116 # Log output of a command to a file
117 #############################################################################
118 logcmd() {
119 if [[ -z "$SCREENOUT" ]]; then
120 echo Running: "$@" >> $LOGFILE
121 "$@" >> $LOGFILE 2>&1
122 else
123 echo Running: "$@" | tee $LOGFILE
124 "$@" | tee $LOGFILE 2>&1
125 return ${PIPESTATUS[0]}
126 fi
127 }
128 logmsg() {
129 echo "$@" >> $LOGFILE
130 echo "$@"
131 }
132 logerr() {
133 # Print an error message and ask the user if they wish to continue
134 logmsg $@
135 if [[ -z $BATCH ]]; then
136 ask_to_continue "An Error occured in the build. "
137 else
138 exit 1
139 fi
140 }
141 ask_to_continue_() {
142 MSG=$2
143 STR=$3
144 RE=$4
145 # Ask the user if they want to continue or quit in the event of an error
146 echo -n "${1}${MSG} ($STR) "
147 read
148 while [[ ! "$REPLY" =~ $RE ]]; do
149 echo -n "continue? ($STR) "
150 read
151 done
152 }
153 ask_to_continue() {
154 ask_to_continue_ "${1}" "Do you wish to continue anyway?" "y/n" "[yYnN]"
155 if [[ "$REPLY" == "n" || "$REPLY" == "N" ]]; then
156 logmsg "===== Build aborted ====="
157 exit 1
158 fi
159 logmsg "===== User elected to continue after prompt. ====="
160 }
161
162 ask_to_install() {
163 PKG=$1
164 MSG=$2
165 if [[ -n "$AUTOINSTALL" ]]; then
166 logmsg "Auto-installing $PKG..."
167 logcmd sudo pkg install $PKG || logerr "pkg install $PKG failed"
168 return
169 fi
170 if [[ -n "$BATCH" ]]; then
171 logmsg "===== Build aborted ====="
172 exit 1
173 fi
174 ask_to_continue_ "$MSG " "Install/Abort?" "i/a" "[iIaA]"
175 if [[ "$REPLY" == "i" || "$REPLY" == "I" ]]; then
176 logcmd sudo pkg install $PKG || logerr "pkg install failed"
177 else
178 logmsg "===== Build aborted ====="
179 exit 1
180 fi
181 }
182
183 ask_to_pkglint() {
184 local MANIFEST=$1
185
186 ask_to_continue_ "" "Do you want to run pkglint at this time?" "y/n" "[yYnN]"
187 [[ "$REPLY" == "y" || "$REPLY" == "Y" ]]
188 }
189
190 #############################################################################
191 # URL encoding for package names, at least
192 #############################################################################
193 # This isn't real URL encoding, just a couple of common substitutions
194 url_encode() {
195 [ $# -lt 1 ] && logerr "Not enough arguments to url_encode(). Expecting a string to encode."
196 local encoded="$1";
197 encoded=`echo $encoded | sed -e 's!/!%2F!g' -e 's!+!%2B!g'`
198 encoded=`echo $encoded | sed -e 's/%../_/g;'`
199 echo $encoded
200 }
201
202 #############################################################################
203 # Some initialization
204 #############################################################################
205 # Set the LANG to C as the assembler will freak out on unicode in headers
206 LANG=C
207 export LANG
208 # Set the path - This can be overriden/extended in the build script
209 PATH="/opt/gcc-5.1.0/bin:/usr/ccs/bin:/usr/bin:/usr/sbin:/usr/gnu/bin:/usr/sfw/bin"
210 export PATH
211 # The dir where this file is located - used for sourcing further files
212 MYDIR=$PWD/`dirname $BASH_SOURCE[0]`
213 # The dir where this file was sourced from - this will be the directory of the
214 # build script
215 SRCDIR=$PWD/`dirname $0`
216
217 #############################################################################
218 # Load configuration options
219 #############################################################################
220 . $MYDIR/config.sh
221 . $MYDIR/site.sh
222
223 # Platform information
224 SUNOSVER=`uname -r` # e.g. 5.11
225
226 if [[ -f $LOGFILE ]]; then
227 mv $LOGFILE $LOGFILE.1
228 fi
229 process_opts $@
230 shift $((OPTIND - 1))
231
232 BasicRequirements(){
233 local needed=""
234 [[ -x /opt/gcc-5.1.0/bin/gcc ]] || needed+=" developer/gcc51"
235 [[ -x /usr/bin/ar ]] || needed+=" developer/object-file"
236 [[ -x /usr/bin/ld ]] || needed+=" developer/linker"
237 [[ -f /usr/lib/crt1.o ]] || needed+=" developer/library/lint"
238 [[ -x /usr/bin/gmake ]] || needed+=" developer/build/gnu-make"
239 [[ -f /usr/include/sys/types.h ]] || needed+=" system/header"
240 [[ -f /usr/include/math.h ]] || needed+=" system/library/math"
241 if [[ -n "$needed" ]]; then
242 logmsg "You appear to be missing some basic build requirements."
243 logmsg "To fix this run:"
244 logmsg " "
245 logmsg " sudo pkg install$needed"
246 if [[ -n "$BATCH" ]]; then
247 logmsg "===== Build aborted ====="
248 exit 1
249 fi
250 echo
251 for i in "$needed"; do
252 ask_to_install $i "--- Build-time dependency $i not found"
253 done
254 fi
255 }
256 BasicRequirements
257
258 #############################################################################
259 # Running as root is not safe
260 #############################################################################
261 if [[ "$UID" = "0" ]]; then
262 if [[ -n "$ROOT_OK" ]]; then
263 logmsg "--- Running as root, but ROOT_OK is set; continuing"
264 else
265 logerr "--- You cannot run this as root"
266 fi
267 fi
268
269 #############################################################################
270 # Print startup message
271 #############################################################################
272 [[ -z "$NOBANNER" ]] && logmsg "===== Build started at `date` ====="
273
274
275 #############################################################################
276 # Libtool -nostdlib hacking
277 # libtool doesn't put -nostdlib in the shared archive creation command
278 # we need it sometimes.
279 #############################################################################
280 libtool_nostdlib() {
281 FILE=$1
282 EXTRAS=$2
283 logcmd perl -pi -e 's#(\$CC.*\$compiler_flags)#$1 -nostdlib '"$EXTRAS"'#g;' $FILE ||
284 logerr "--- Patching libtool:$FILE for -nostdlib support failed"
285 }
286
287 #############################################################################
288 # Initialization function
289 #############################################################################
290 init() {
291 # Print out current settings
292 logmsg "Package name: $PKG"
293 # Selected flavor
294 if [[ -z "$FLAVOR" ]]; then
295 logmsg "Selected flavor: None (use -f to specify a flavor)"
296 else
297 logmsg "Selected Flavor: $FLAVOR"
298 fi
299 if [[ -n "$OLDFLAVOR" && "$OLDFLAVOR" != "$FLAVOR" ]]; then
300 logmsg "NOTICE - The flavor was overridden by the build script."
301 logmsg "The flavor specified on the command line was: $OLDFLAVOR"
302 fi
303 # Build arch
304 logmsg "Selected build arch: $BUILDARCH"
305 if [[ -n "$OLDBUILDARCH" && "$OLDBUILDARCH" != "$BUILDARCH" ]]; then
306 logmsg "NOTICE - The build arch was overridden by the build script."
307 logmsg "The build arch specified on the command line was: $OLDFLAVOR"
308 fi
309 # Extra dependency version
310 if [[ -z "$DEPVER" ]]; then
311 logmsg "Extra dependency: None (use -d to specify a version)"
312 else
313 logmsg "Extra dependency: $DEPVER"
314 fi
315 # Ensure SUMMARY and DESC are non-empty
316 if [[ -z "$SUMMARY" ]]; then
317 logerr "SUMMARY may not be empty. Please update your build script"
318 elif [[ -z "$DESC" ]]; then
319 logerr "DESC may not be empty. Please update your build script"
320 fi
321
322 # BUILDDIR can be used to manually specify what directory the program is
323 # built in (i.e. what the tarball extracts to). This defaults to the name
324 # and version of the program, which works in most cases.
325 if [[ -z $BUILDDIR ]]; then
326 BUILDDIR=$PROG-$VER
327 fi
328
329 RPATH=`echo $PKGSRVR | sed -e 's/^file:\/*/\//'`
330 if [[ "$RPATH" != "$PKGSRVR" ]]; then
331 if [[ ! -d $RPATH ]]; then
332 pkgrepo create $RPATH || \
333 logerr "Could not local repo"
334 pkgrepo add-publisher -s $RPATH $PKGPUBLISHER || \
335 logerr "Could not set publisher on repo"
336 fi
337 fi
338 pkgrepo get -s $PKGSRVR > /dev/null 2>&1 || \
339 logerr "The PKGSRVR ($PKGSRVR) isn't available. All is doomed."
340 verify_depends
341 }
342
343 #############################################################################
344 # Verify any dependencies
345 #############################################################################
346 verify_depends() {
347 logmsg "Verifying dependencies"
348 # Support old-style runtime deps
349 if [[ -n "$DEPENDS_IPS" && -n "$RUN_DEPENDS_IPS" ]]; then
350 # Either old way or new, not both.
351 logerr "DEPENDS_IPS is deprecated. Please list all runtime dependencies in RUN_DEPENDS_IPS."
352 elif [[ -n "$DEPENDS_IPS" && -z "$RUN_DEPENDS_IPS" ]]; then
353 RUN_DEPENDS_IPS=$DEPENDS_IPS
354 fi
355 # If only DEPENDS_IPS is used, assume the deps are build-time as well
356 if [[ -z "$BUILD_DEPENDS_IPS" && -n "$DEPENDS_IPS" ]]; then
357 BUILD_DEPENDS_IPS=$DEPENDS_IPS
358 fi
359 for i in $BUILD_DEPENDS_IPS; do
360 # Trim indicators to get the true name (see make_package for details)
361 case ${i:0:1} in
362 \=|\?)
363 i=${i:1}
364 ;;
365 \-)
366 # If it's an exclude, we should error if it's installed rather than missing
367 i=${i:1}
368 pkg info $i > /dev/null 2<&1 &&
369 logerr "--- $i cannot be installed while building this package."
370 continue
371 ;;
372 esac
373 pkg info $i > /dev/null 2<&1 ||
374 ask_to_install "$i" "--- Build-time dependency $i not found"
375 done
376 }
377
378 #############################################################################
379 # People that need this should call it explicitly
380 #############################################################################
381 run_autoconf() {
382 logmsg "Running autoconf"
383 pushd $TMPDIR/$BUILDDIR > /dev/null
384 logcmd autoconf || logerr "Failed to run autoconf"
385 popd > /dev/null
386 }
387
388 #############################################################################
389 # People that need this should call it explicitly
390 #############################################################################
391 run_automake() {
392 logmsg "Running automake"
393 pushd $TMPDIR/$BUILDDIR > /dev/null
394 logcmd automake || logerr "Failed to run automake"
395 popd > /dev/null
396 }
397
398 #############################################################################
399 # Stuff that needs to be done/set before we start building
400 #############################################################################
401 prep_build() {
402 logmsg "Preparing for build"
403
404 # Get the current date/time for the package timestamp
405 DATETIME=`TZ=UTC /usr/bin/date +"%Y%m%dT%H%M%SZ"`
406
407 logmsg "--- Creating temporary install dir"
408 # We might need to encode some special chars
409 PKGE=$(url_encode $PKG)
410 # For DESTDIR the '%' can cause problems for some install scripts
411 PKGD=${PKGE//%/_}
412 DESTDIR=$DTMPDIR/${PKGD}_pkg
413 if [[ -z $DONT_REMOVE_INSTALL_DIR ]]; then
414 logcmd chmod -R u+w $DESTDIR > /dev/null 2>&1
415 logcmd rm -rf $DESTDIR || \
416 logerr "Failed to remove old temporary install dir"
417 mkdir -p $DESTDIR || \
418 logerr "Failed to create temporary install dir"
419 fi
420 }
421
422 #############################################################################
423 # Applies patches contained in $PATCHDIR (default patches/)
424 #############################################################################
425 check_for_patches() {
426 if [[ -z $1 ]]; then
427 logmsg "Checking for patches in $PATCHDIR/"
428 else
429 logmsg "Checking for patches in $PATCHDIR/ ($1)"
430 fi
431 if [[ ! -d $SRCDIR/$PATCHDIR ]]; then
432 logmsg "--- No patches directory found"
433 return 1
434 fi
435 if [[ ! -f $SRCDIR/$PATCHDIR/series ]]; then
436 logmsg "--- No series file (list of patches) found"
437 return 1
438 fi
439 return 0
440 }
441
442 patch_source() {
443 if ! check_for_patches "in order to apply them"; then
444 logmsg "--- Not applying any patches"
445 else
446 logmsg "Applying patches"
447 # Read the series file for patch filenames
448 exec 3<"$SRCDIR/$PATCHDIR/series" # Open the series file with handle 3
449 pushd $TMPDIR/$BUILDDIR > /dev/null
450 while read LINE <&3 ; do
451 # Split Line into filename+args
452 patch_file $LINE
453 done
454 popd > /dev/null
455 exec 3<&- # Close the file
456 fi
457 }
458
459 patch_file() {
460 FILENAME=$1
461 shift
462 ARGS=$@
463 if [[ ! -f $SRCDIR/$PATCHDIR/$FILENAME ]]; then
464 logmsg "--- Patch file $FILENAME not found. Skipping patch."
465 return
466 fi
467 # Note - if -p is specified more than once, then the last one takes
468 # precedence, so we can specify -p1 at the beginning to default to -p1.
469 # -t - don't ask questions
470 # -N - don't try to apply a reverse patch
471 if ! logcmd $PATCH -p1 -t -N $ARGS < $SRCDIR/$PATCHDIR/$FILENAME; then
472 logerr "--- Patch $FILENAME failed"
473 else
474 logmsg "--- Applied patch $FILENAME"
475 fi
476 }
477
478 #############################################################################
479 # Attempt to download the given resource to the current directory.
480 #############################################################################
481 # Parameters
482 # $1 - resource to get
483 #
484 get_resource() {
485 local RESOURCE=$1
486 case ${MIRROR:0:1} in
487 /)
488 logcmd cp $MIRROR/$RESOURCE .
489 ;;
490 *)
491 URLPREFIX=$MIRROR
492 $WGET -a $LOGFILE $URLPREFIX/$RESOURCE
493 ;;
494 esac
495 }
496
497 #############################################################################
498 # Download source tarball if needed and extract it
499 #############################################################################
500 # Parameters
501 # $1 - directory name on the server
502 # $2 - program name
503 # $3 - program version
504 # $4 - target directory
505 #
506 # E.g.
507 # download_source myprog myprog 1.2.3 will try:
508 # http://mirrors.omniti.com/myprog/myprog-1.2.3.tar.gz
509 download_source() {
510 local DLDIR=$1
511 local PROG=$2
512 local VER=$3
513 local TARGETDIR=$4
514 if [[ -z $VER ]]; then
515 local ARCHIVEPREFIX=$PROG
516 else
517 local ARCHIVEPREFIX=$PROG-$VER
518 fi
519 if [[ -z $TARGETDIR ]]; then
520 # Default to $TMPDIR if no output dir specified
521 TARGETDIR=$TMPDIR
522 fi
523 # Create TARGETDIR if it doesn't exist
524 if [[ ! -d $TARGETDIR ]]; then
525 logmsg "Specified target directory $TARGETDIR does not exist. Creating it now."
526 logcmd mkdir -p $TARGETDIR
527 fi
528
529 pushd $TARGETDIR > /dev/null
530 logmsg "Checking for source directory"
531 if [ -d $BUILDDIR ]; then
532 logmsg "--- Source directory found"
533 if [ -n "$REMOVE_PREVIOUS" ]; then
534 logmsg "--- Removing previously extracted source directory (REMOVE_PREVIOUS=$REMOVE_PREVIOUS)"
535 logcmd rm -rf $BUILDDIR || \
536 logerr "Failed to remove source directory"
537 elif check_for_patches "to see if we need to remove the source dir"; then
538 logmsg "--- Patches are present, removing source directory"
539 logcmd rm -rf $BUILDDIR || \
540 logerr "Failed to remove source directory"
541 else
542 logmsg "--- Patches are not present and REMOVE_PREVIOUS is not set, keeping source directory"
543 popd > /dev/null
544 return
545 fi
546 else
547 logmsg "--- Source directory not found"
548 fi
549
550 # If we reach this point, the source directory was either not found, or it
551 # was removed due to patches being present.
552 logmsg "Checking for $PROG source archive"
553 find_archive $ARCHIVEPREFIX FILENAME
554 if [[ "$FILENAME" == "" ]]; then
555 # Try all possible archive names
556 logmsg "--- Archive not found."
557 logmsg "Downloading archive"
558 get_resource $DLDIR/$ARCHIVEPREFIX.tar.gz || \
559 get_resource $DLDIR/$ARCHIVEPREFIX.tar.bz2 || \
560 get_resource $DLDIR/$ARCHIVEPREFIX.tar.xz || \
561 get_resource $DLDIR/$ARCHIVEPREFIX.tgz || \
562 get_resource $DLDIR/$ARCHIVEPREFIX.tbz || \
563 get_resource $DLDIR/$ARCHIVEPREFIX.tar || \
564 get_resource $DLDIR/$ARCHIVEPREFIX.zip || \
565 logerr "--- Failed to download file"
566 find_archive $ARCHIVEPREFIX FILENAME
567 if [[ "$FILENAME" == "" ]]; then
568 logerr "Unable to find downloaded file."
569 fi
570 else
571 logmsg "--- $PROG source archive found"
572 fi
573 # Extract the archive
574 logmsg "Extracting archive: $FILENAME"
575 if ! logcmd extract_archive $FILENAME; then
576 logerr "--- Unable to extract archive."
577 fi
578 # Make sure the archive actually extracted some source where we expect
579 if [[ ! -d $BUILDDIR ]]; then
580 logerr "--- Extracted source is not in the expected location" \
581 " ($BUILDDIR)"
582 fi
583 popd > /dev/null
584 }
585
586 # Finds an existing archive and stores its value in a variable whose name
587 # is passed as a second parameter
588 # Example: find_archive myprog-1.2.3 FILENAME
589 # Stores myprog-1.2.3.tar.gz in $FILENAME
590 find_archive() {
591 FILES=`ls $1.{tar.bz2,tar.gz,tar.xz,tgz,tbz,tar,zip} 2>/dev/null`
592 FILES=${FILES%% *} # Take only the first filename returned
593 # This dereferences the second parameter passed
594 eval "$2=\"$FILES\""
595 }
596
597 # Extracts an archive regardless of its extension
598 extract_archive() {
599 if [[ ${1: -7} == ".tar.gz" || ${1: -4} == ".tgz" ]]; then
600 $GZIP -dc $1 | $TAR xvf -
601 elif [[ ${1: -8} == ".tar.bz2" || ${1: -4} == ".tbz" ]]; then
602 $BUNZIP2 -dc $1 | $TAR xvf -
603 elif [[ ${1: -7} == ".tar.xz" ]]; then
604 $XZCAT $1 | $TAR xvf -
605 elif [[ ${1: -4} == ".tar" ]]; then
606 $TAR xvf $1
607 elif [[ ${1: -4} == ".zip" ]]; then
608 $UNZIP $1
609 else
610 return 1
611 fi
612 }
613
614 #############################################################################
615 # Make the package
616 #############################################################################
617 make_package() {
618 logmsg "Making package"
619 case $BUILDARCH in
620 32)
621 BUILDSTR="32bit-"
622 ;;
623 64)
624 BUILDSTR="64bit-"
625 ;;
626 *)
627 BUILDSTR=""
628 ;;
629 esac
630 # Add the flavor name to the package if it is not the default
631 case $FLAVOR in
632 ""|default)
633 FLAVORSTR=""
634 ;;
635 *)
636 FLAVORSTR="$FLAVOR-"
637 ;;
638 esac
639 DESCSTR="$DESC"
640 if [[ -n "$FLAVORSTR" ]]; then
641 DESCSTR="$DESCSTR ($FLAVOR)"
642 fi
643 PKGSEND=/usr/bin/pkgsend
644 PKGLINT=/usr/bin/pkglint
645 PKGMOGRIFY=/usr/bin/pkgmogrify
646 PKGFMT=/usr/bin/pkgfmt
647 PKGDEPEND=/usr/bin/pkgdepend
648 P5M_INT=$TMPDIR/${PKGE}.p5m.int
649 P5M_INT2=$TMPDIR/${PKGE}.p5m.int.2
650 P5M_INT3=$TMPDIR/${PKGE}.p5m.int.3
651 P5M_FINAL=$TMPDIR/${PKGE}.p5m
652 MANUAL_DEPS=$TMPDIR/${PKGE}.deps.mog
653 GLOBAL_MOG_FILE=$MYDIR/global-transforms.mog
654 MY_MOG_FILE=$TMPDIR/${PKGE}.mog
655
656 ## Strip leading zeros in version components.
657 VER=`echo $VER | sed -e 's/\.0*\([1-9]\)/.\1/g;'`
658 if [[ -n "$FLAVOR" ]]; then
659 # We use FLAVOR instead of FLAVORSTR as we don't want the trailing dash
660 FMRI="${PKG}-${FLAVOR}@${VER},${SUNOSVER}-${PVER}"
661 else
662 FMRI="${PKG}@${VER},${SUNOSVER}-${PVER}"
663 fi
664 if [[ -n "$DESTDIR" ]]; then
665 logmsg "--- Generating package manifest from $DESTDIR"
666 logmsg "------ Running: $PKGSEND generate $DESTDIR > $P5M_INT"
667 $PKGSEND generate $DESTDIR > $P5M_INT || \
668 logerr "------ Failed to generate manifest"
669 else
670 logmsg "--- Looks like a meta-package. Creating empty manifest"
671 logcmd touch $P5M_INT || \
672 logerr "------ Failed to create empty manifest"
673 fi
674 logmsg "--- Generating package metadata"
675 echo "set name=pkg.fmri value=$FMRI" > $MY_MOG_FILE
676 # Set human-readable version, if it exists
677 if [[ -n "$VERHUMAN" ]]; then
678 logmsg "------ Setting human-readable version"
679 echo "set name=pkg.human-version value=\"$VERHUMAN\"" >> $MY_MOG_FILE
680 fi
681 echo "set name=pkg.summary value=\"$SUMMARY\"" >> $MY_MOG_FILE
682 echo "set name=pkg.descr value=\"$DESCSTR\"" >> $MY_MOG_FILE
683 echo "set name=publisher value=\"sa@omniti.com\"" >> $MY_MOG_FILE
684 if [[ -f $SRCDIR/local.mog ]]; then
685 LOCAL_MOG_FILE=$SRCDIR/local.mog
686 fi
687 logmsg "--- Applying transforms"
688 $PKGMOGRIFY $P5M_INT $MY_MOG_FILE $GLOBAL_MOG_FILE $LOCAL_MOG_FILE $* | $PKGFMT -u > $P5M_INT2
689 logmsg "--- Resolving dependencies"
690 (
691 set -e
692 $PKGDEPEND generate -md $DESTDIR $P5M_INT2 > $P5M_INT3
693 $PKGDEPEND resolve -m $P5M_INT3
694 ) || logerr "--- Dependency resolution failed"
695 echo > "$MANUAL_DEPS"
696 if [[ -n "$RUN_DEPENDS_IPS" ]]; then
697 logmsg "------ Adding manual dependencies"
698 for i in $RUN_DEPENDS_IPS; do
699 # IPS dependencies have multiple types, of which we care about four:
700 # require, optional, incorporate, exclude
701 # For backward compatibility, assume no indicator means type=require
702 # FMRI attributes are implicitly rooted so we don't have to prefix
703 # 'pkg:/' or worry about ambiguities in names
704 local DEPTYPE="require"
705 case ${i:0:1} in
706 \=)
707 DEPTYPE="incorporate"
708 i=${i:1}
709 ;;
710 \?)
711 DEPTYPE="optional"
712 i=${i:1}
713 ;;
714 \-)
715 DEPTYPE="exclude"
716 i=${i:1}
717 ;;
718 esac
719 case $i in
720 *@*)
721 depname=${i%@*}
722 explicit_ver=true
723 ;;
724 *)
725 depname=$i
726 explicit_ver=false
727 ;;
728 esac
729 # ugly grep, but pkgmogrify doesn't seem to provide any way to add
730 # actions while avoiding duplicates (except maybe by running it
731 # twice, using drop transform on the first run)
732 if grep -q "^depend .*fmri=[^ ]*$depname" "${P5M_INT3}.res"; then
733 autoresolved=true
734 else
735 autoresolved=false
736 fi
737 if $autoresolved && [ "$DEPTYPE" = "require" ]; then
738 if $explicit_ver; then
739 echo "<transform depend fmri=(.+/)?$depname -> set fmri $i>" >> $MANUAL_DEPS
740 fi
741 else
742 echo "depend type=$DEPTYPE fmri=$i" >> $MANUAL_DEPS
743 fi
744 done
745 fi
746 $PKGMOGRIFY "${P5M_INT3}.res" "$MANUAL_DEPS" | $PKGFMT -u > $P5M_FINAL
747 if [[ -z $SKIP_PKGLINT ]] && ( [[ -n $BATCH ]] || ask_to_pkglint ); then
748 $PKGLINT -c $TMPDIR/lint-cache -r $PKGSRVR $P5M_FINAL || \
749 logerr "----- pkglint failed"
750 fi
751 logmsg "--- Publishing package to $PKGSRVR"
752 if [[ -z $BATCH ]]; then
753 logmsg "Intentional pause: Last chance to sanity-check before publication!"
754 ask_to_continue
755 fi
756 if [[ -n "$DESTDIR" ]]; then
757 logcmd $PKGSEND -s $PKGSRVR publish -d $DESTDIR -d $TMPDIR/$BUILDDIR \
758 -d $SRCDIR -T \*.py $P5M_FINAL || \
759 logerr "------ Failed to publish package"
760 else
761 # If we're a metapackage (no DESTDIR) then there are no directories to check
762 logcmd $PKGSEND -s $PKGSRVR publish $P5M_FINAL || \
763 logerr "------ Failed to publish package"
764 fi
765 logmsg "--- Published $FMRI"
766 }
767
768 #############################################################################
769 # Make isaexec stub binaries
770 #############################################################################
771 make_isa_stub() {
772 logmsg "Making isaexec stub binaries"
773 [[ -z $ISAEXEC_DIRS ]] && ISAEXEC_DIRS="bin sbin"
774 for DIR in $ISAEXEC_DIRS; do
775 if [[ -d $DESTDIR$PREFIX/$DIR ]]; then
776 logmsg "--- $DIR"
777 pushd $DESTDIR$PREFIX/$DIR > /dev/null
778 make_isaexec_stub_arch $ISAPART
779 make_isaexec_stub_arch $ISAPART64
780 popd > /dev/null
781 fi
782 done
783 }
784
785 make_isaexec_stub_arch() {
786 for file in $1/*; do
787 [[ -f $file ]] || continue # Deals with empty dirs & non-files
788 # Check to make sure we don't have a script
789 read -n 4 < $file
790 file=`echo $file | sed -e "s/$1\///;"`
791 # Only copy non-binaries if we set NOSCRIPTSTUB
792 if [[ $REPLY != $'\177'ELF && -n "$NOSCRIPTSTUB" ]]; then
793 logmsg "------ Non-binary file: $file - copying instead"
794 cp $1/$file . && rm $1/$file
795 chmod +x $file
796 continue
797 fi
798 # Skip if we already made a stub for this file
799 [[ -f $file ]] && continue
800 logmsg "------ $file"
801 # Run the makeisa.sh script
802 CC=$CC \
803 logcmd $MYDIR/makeisa.sh $PREFIX/$DIR $file || \
804 logerr "--- Failed to make isaexec stub for $DIR/$file"
805 done
806 }
807
808 #############################################################################
809 # Build commands
810 #############################################################################
811 # Notes:
812 # - These methods are designed to work in the general case.
813 # - You can set CFLAGS/LDFLAGS (and CFLAGS32/CFLAGS64 for arch specific flags)
814 # - Configure flags are set in CONFIGURE_OPTS_32 and CONFIGURE_OPTS_64 with
815 # defaults set in config.sh. You can append to these variables or replace
816 # them if the defaults don't work for you.
817 # - In the normal case, where you just want to add --enable-feature, set
818 # CONFIGURE_OPTS. This will be appended to the end of CONFIGURE_CMD
819 # for both 32 and 64 bit builds.
820 # - Any of these functions can be overriden in your build script, so if
821 # anything here doesn't apply to the build process for your application,
822 # just override that function with whatever code you need. The build
823 # function itself can be overriden if the build process doesn't fit into a
824 # configure, make, make install pattern.
825 #############################################################################
826 make_clean() {
827 logmsg "--- make (dist)clean"
828 logcmd $MAKE distclean || \
829 logcmd $MAKE clean || \
830 logmsg "--- *** WARNING *** make (dist)clean Failed"
831 }
832
833 configure32() {
834 logmsg "--- configure (32-bit)"
835 CFLAGS="$CFLAGS $CFLAGS32" \
836 CXXFLAGS="$CXXFLAGS $CXXFLAGS32" \
837 CPPFLAGS="$CPPFLAGS $CPPFLAGS32" \
838 LDFLAGS="$LDFLAGS $LDFLAGS32" \
839 CC=$CC CXX=$CXX \
840 logcmd $CONFIGURE_CMD $CONFIGURE_OPTS_32 \
841 $CONFIGURE_OPTS || \
842 logerr "--- Configure failed"
843 }
844
845 configure64() {
846 logmsg "--- configure (64-bit)"
847 CFLAGS="$CFLAGS $CFLAGS64" \
848 CXXFLAGS="$CXXFLAGS $CXXFLAGS64" \
849 CPPFLAGS="$CPPFLAGS $CPPFLAGS64" \
850 LDFLAGS="$LDFLAGS $LDFLAGS64" \
851 CC=$CC CXX=$CXX \
852 logcmd $CONFIGURE_CMD $CONFIGURE_OPTS_64 \
853 $CONFIGURE_OPTS || \
854 logerr "--- Configure failed"
855 }
856
857 make_prog() {
858 [[ -n $NO_PARALLEL_MAKE ]] && MAKE_JOBS=""
859 if [[ -n $LIBTOOL_NOSTDLIB ]]; then
860 libtool_nostdlib $LIBTOOL_NOSTDLIB $LIBTOOL_NOSTDLIB_EXTRAS
861 fi
862 logmsg "--- make"
863 logcmd $MAKE $MAKE_JOBS || \
864 logerr "--- Make failed"
865 }
866
867 make_prog32() {
868 make_prog
869 }
870
871 make_prog64() {
872 make_prog
873 }
874
875 make_install() {
876 logmsg "--- make install"
877 logcmd $MAKE DESTDIR=${DESTDIR} install || \
878 logerr "--- Make install failed"
879 }
880
881 make_install32() {
882 make_install
883 }
884
885 make_install64() {
886 make_install
887 }
888
889 make_pure_install() {
890 # Make pure_install for perl modules so they don't touch perllocal.pod
891 logmsg "--- make install (pure)"
892 logcmd $MAKE DESTDIR=${DESTDIR} pure_install || \
893 logerr "--- Make pure_install failed"
894 }
895
896 make_param() {
897 logmsg "--- make $@"
898 logcmd $MAKE "$@" || \
899 logerr "--- $MAKE $1 failed"
900 }
901
902 # Helper function that can be called by build scripts to make in a specific dir
903 make_in() {
904 [[ -z $1 ]] && logerr "------ Make in dir failed - no dir specified"
905 [[ -n $NO_PARALLEL_MAKE ]] && MAKE_JOBS=""
906 logmsg "------ make in $1"
907 logcmd $MAKE $MAKE_JOBS -C $1 || \
908 logerr "------ Make in $1 failed"
909 }
910
911 # Helper function that can be called by build scripts to install in a specific
912 # dir
913 make_install_in() {
914 [[ -z $1 ]] && logerr "--- Make install in dir failed - no dir specified"
915 logmsg "------ make install in $1"
916 logcmd $MAKE -C $1 DESTDIR=${DESTDIR} install || \
917 logerr "------ Make install in $1 failed"
918 }
919
920 make_lintlibs() {
921 logmsg "Making lint libraries"
922
923 LINTLIB=$1
924 LINTLIBDIR=$2
925 LINTINCDIR=$3
926 LINTINCFILES=$4
927
928 [[ -z ${LINTLIB} ]] && logerr "not lint library specified"
929 [[ -z ${LINTINCFILES} ]] && LINTINCFILES="*.h"
930
931 cat <<EOF > ${DTMPDIR}/${PKGD}_llib-l${LINTLIB}
932 /* LINTLIBRARY */
933 /* PROTOLIB1 */
934 #include <sys/types.h>
935 #undef _LARGEFILE_SOURCE
936 EOF
937 pushd ${DESTDIR}${LINTINCDIR} > /dev/null
938 sh -c "eval /usr/gnu/bin/ls -U ${LINTINCFILES}" | \
939 sed -e 's/\(.*\)/#include <\1>/' >> ${DTMPDIR}/${PKGD}_llib-l${LINTLIB}
940 popd > /dev/null
941
942 pushd ${DESTDIR}${LINTLIBDIR} > /dev/null
943 logcmd /opt/sunstudio12.1/bin/lint -nsvx -I${DESTDIR}${LINTINCDIR} \
944 -o ${LINTLIB} ${DTMPDIR}/${PKGD}_llib-l${LINTLIB} || \
945 logerr "failed to generate 32bit lint library ${LINTLIB}"
946 popd > /dev/null
947
948 pushd ${DESTDIR}${LINTLIBDIR}/amd64 > /dev/null
949 logcmd /opt/sunstudio12.1/bin/lint -nsvx -I${DESTDIR}${LINTINCDIR} -m64 \
950 -o ${LINTLIB} ${DTMPDIR}/${PKGD}_llib-l${LINTLIB} || \
951 logerr "failed to generate 64bit lint library ${LINTLIB}"
952 popd > /dev/null
953 }
954
955 build() {
956 if [[ $BUILDARCH == "32" || $BUILDARCH == "both" ]]; then
957 build32
958 fi
959 if [[ $BUILDARCH == "64" || $BUILDARCH == "both" ]]; then
960 build64
961 fi
962 }
963
964 build32() {
965 pushd $TMPDIR/$BUILDDIR > /dev/null
966 logmsg "Building 32-bit"
967 export ISALIST="$ISAPART"
968 make_clean
969 configure32
970 make_prog32
971 make_install32
972 popd > /dev/null
973 unset ISALIST
974 export ISALIST
975 }
976
977 build64() {
978 pushd $TMPDIR/$BUILDDIR > /dev/null
979 logmsg "Building 64-bit"
980 make_clean
981 configure64
982 make_prog64
983 make_install64
984 popd > /dev/null
985 }
986
987 #############################################################################
988 # Build function for python programs
989 #############################################################################
990 pre_python_32() {
991 logmsg "prepping 32bit python build"
992 }
993 pre_python_64() {
994 logmsg "prepping 64bit python build"
995 }
996 python_build() {
997 if [[ -z "$PYTHON" ]]; then logerr "PYTHON not set"; fi
998 if [[ -z "$PYTHONPATH" ]]; then logerr "PYTHONPATH not set"; fi
999 if [[ -z "$PYTHONLIB" ]]; then logerr "PYTHONLIB not set"; fi
1000 logmsg "Building using python setup.py"
1001 pushd $TMPDIR/$BUILDDIR > /dev/null
1002
1003 ISALIST=i386
1004 export ISALIST
1005 pre_python_32
1006 logmsg "--- setup.py (32) build"
1007 logcmd $PYTHON ./setup.py build $PYBUILD32OPTS ||
1008 logerr "--- build failed"
1009 logmsg "--- setup.py (32) install"
1010 logcmd $PYTHON \
1011 ./setup.py install --root=$DESTDIR $PYINST32OPTS ||
1012 logerr "--- install failed"
1013
1014 ISALIST="amd64 i386"
1015 export ISALIST
1016 pre_python_64
1017 logmsg "--- setup.py (64) build"
1018 logcmd $PYTHON ./setup.py build $PYBUILD64OPTS ||
1019 logerr "--- build failed"
1020 logmsg "--- setup.py (64) install"
1021 logcmd $PYTHON \
1022 ./setup.py install --root=$DESTDIR $PYINST64OPTS ||
1023 logerr "--- install failed"
1024 popd > /dev/null
1025
1026 mv $DESTDIR/usr/lib/python2.6/site-packages $DESTDIR/usr/lib/python2.6/vendor-packages ||
1027 logerr "Cannot move from site-packages to vendor-packages"
1028 }
1029
1030 #############################################################################
1031 # Build/test function for perl modules
1032 #############################################################################
1033 # Detects whether to use Build.PL or Makefile.PL
1034 # Note: Build.PL probably needs Module::Build installed
1035 #############################################################################
1036 vendorizeperl() {
1037 logcmd mv $DESTDIR/usr/perl5/lib/site_perl $DESTDIR/usr/perl5/vendor_perl || logerr "can't move to vendor_perl"
1038 logcmd mkdir -p $DESTDIR/usr/perl5/${DEPVER}
1039 logcmd mv $DESTDIR/usr/perl5/man $DESTDIR/usr/perl5/${DEPVER}/man || logerr "can't move perl man"
1040 }
1041
1042 buildperl() {
1043 if [[ -f $SRCDIR/${PROG}-${VER}.env ]]; then
1044 logmsg "Sourcing environment file: $SRCDIR/${PROG}-${VER}.env"
1045 source $SRCDIR/${PROG}-${VER}.env
1046 fi
1047 if [[ $BUILDARCH == "32" || $BUILDARCH == "both" ]]; then
1048 buildperl32
1049 fi
1050 if [[ $BUILDARCH == "64" || $BUILDARCH == "both" ]]; then
1051 buildperl64
1052 fi
1053 }
1054
1055 buildperl32() {
1056 if [[ -f $SRCDIR/${PROG}-${VER}.env32 ]]; then
1057 logmsg "Sourcing environment file: $SRCDIR/${PROG}-${VER}.env32"
1058 source $SRCDIR/${PROG}-${VER}.env32
1059 fi
1060 pushd $TMPDIR/$BUILDDIR > /dev/null
1061 logmsg "Building 32-bit"
1062 export ISALIST="$ISAPART"
1063 local OPTS
1064 OPTS=${MAKEFILE_OPTS//_ARCH_/}
1065 OPTS=${OPTS//_ARCHBIN_/$ISAPART}
1066 if [[ -f Makefile.PL ]]; then
1067 make_clean
1068 makefilepl32 $OPTS
1069 make_prog
1070 [[ -n $PERL_MAKE_TEST ]] && make_param test
1071 make_pure_install
1072 elif [[ -f Build.PL ]]; then
1073 build_clean
1074 buildpl32 $OPTS
1075 build_prog
1076 [[ -n $PERL_MAKE_TEST ]] && build_test
1077 build_install
1078 fi
1079 popd > /dev/null
1080 unset ISALIST
1081 export ISALIST
1082 }
1083
1084 buildperl64() {
1085 if [[ -f $SRCDIR/${PROG}-${VER}.env64 ]]; then
1086 logmsg "Sourcing environment file: $SRCDIR/${PROG}-${VER}.env64"
1087 source $SRCDIR/${PROG}-${VER}.env64
1088 fi
1089 pushd $TMPDIR/$BUILDDIR > /dev/null
1090 logmsg "Building 64-bit"
1091 local OPTS
1092 OPTS=${MAKEFILE_OPTS//_ARCH_/$ISAPART64}
1093 OPTS=${OPTS//_ARCHBIN_/$ISAPART64}
1094 if [[ -f Makefile.PL ]]; then
1095 make_clean
1096 makefilepl64 $OPTS
1097 make_prog
1098 [[ -n $PERL_MAKE_TEST ]] && make_param test
1099 make_pure_install
1100 elif [[ -f Build.PL ]]; then
1101 build_clean
1102 buildpl64 $OPTS
1103 build_prog
1104 [[ -n $PERL_MAKE_TEST ]] && build_test
1105 build_install
1106 fi
1107 popd > /dev/null
1108 }
1109
1110 makefilepl32() {
1111 logmsg "--- Makefile.PL 32-bit"
1112 logcmd $PERL32 Makefile.PL PREFIX=$PREFIX $@ ||
1113 logerr "Failed to run Makefile.PL"
1114 }
1115
1116 makefilepl64() {
1117 logmsg "--- Makefile.PL 64-bit"
1118 logcmd $PERL64 Makefile.PL PREFIX=$PREFIX $@ ||
1119 logerr "Failed to run Makefile.PL"
1120 }
1121
1122 buildpl32() {
1123 logmsg "--- Build.PL 32-bit"
1124 logcmd $PERL32 Build.PL prefix=$PREFIX $@ ||
1125 logerr "Failed to run Build.PL"
1126 }
1127
1128 buildpl64() {
1129 logmsg "--- Build.PL 64-bit"
1130 logcmd $PERL64 Build.PL prefix=$PREFIX $@ ||
1131 logerr "Failed to run Build.PL"
1132 }
1133
1134 build_clean() {
1135 logmsg "--- Build (dist)clean"
1136 logcmd ./Build distclean || \
1137 logcmd ./Build clean || \
1138 logmsg "--- *** WARNING *** make (dist)clean Failed"
1139 }
1140
1141 build_prog() {
1142 logmsg "--- Build"
1143 logcmd ./Build ||
1144 logerr "Build failed"
1145 }
1146
1147 build_test() {
1148 logmsg "--- Build test"
1149 logcmd ./Build test ||
1150 logerr "Build test failed"
1151 }
1152
1153 build_install() {
1154 logmsg "--- Build install"
1155 logcmd ./Build pure_install --destdir=$DESTDIR || \
1156 logmsg "Build install failed"
1157 }
1158
1159 test_if_core() {
1160 logmsg "Testing whether $MODNAME is in core"
1161 logmsg "--- Ensuring ${PKG} is not installed"
1162 if logcmd pkg info ${PKG}; then
1163 logerr "------ Package ${PKG} appears to be installed. Please uninstall it."
1164 else
1165 logmsg "------ Not installed, good."
1166 fi
1167 if logcmd $PERL32 -M$MODNAME -e '1'; then
1168 # Module is in core, don't create a package
1169 logmsg "--- Module is in core for Perl $DEPVER. Not creating a package."
1170 exit 0
1171 else
1172 logmsg "--- Module is not in core for Perl $DEPVER. Continuing with build."
1173 fi
1174 }
1175
1176 #############################################################################
1177 # Scan the destination install and strip the non-stipped ELF objects
1178 #############################################################################
1179 strip_install() {
1180 logmsg "Stripping installation"
1181 pushd $DESTDIR > /dev/null || logerr "Cannot change to installation directory"
1182 while read file
1183 do
1184 if [[ "$1" = "-x" ]]; then
1185 ACTION=$(file $file | grep ELF | egrep -v "(, stripped|debugging)")
1186 else
1187 ACTION=$(file $file | grep ELF | grep "not stripped")
1188 fi
1189 if [[ -n "$ACTION" ]]; then
1190 logmsg "------ stripping $file"
1191 MODE=$(stat -c %a "$file")
1192 logcmd chmod 644 "$file" || logerr "chmod failed: $file"
1193 logcmd strip $* "$file" || logerr "strip failed: $file"
1194 logcmd chmod $MODE "$file" || logerr "chmod failed: $file"
1195 fi
1196 done < <(find . -depth -type f)
1197 popd > /dev/null
1198 }
1199
1200 #############################################################################
1201 # Clean up and print Done message
1202 #############################################################################
1203 clean_up() {
1204 logmsg "Cleaning up"
1205 if [[ -z $DONT_REMOVE_INSTALL_DIR ]]; then
1206 logmsg "--- Removing temporary install directory $DESTDIR"
1207 logcmd chmod -R u+w $DESTDIR > /dev/null 2>&1
1208 logcmd rm -rf $DESTDIR || \
1209 logerr "Failed to remove temporary install directory"
1210 logmsg "--- Cleaning up temporary manifest and transform files"
1211 logcmd rm -f $P5M_INT $P5M_INT2 $P5M_INT3 $P5M_FINAL $MY_MOG_FILE $MANUAL_DEPS || \
1212 logerr "Failed to remove temporary manifest and transform files"
1213 logmsg "Done."
1214 fi
1215 }
1216
1217 #############################################################################
1218 # Helper function that will let you save a predefined function so you can
1219 # override it and call it later
1220 #############################################################################
1221 save_function() {
1222 local ORIG_FUNC=$(declare -f $1)
1223 local NEWNAME_FUNC="$2${ORIG_FUNC#$1}"
1224 eval "$NEWNAME_FUNC"
1225 }
1226
1227 # Called by builds that need a PREBUILT_ILLUMOS actually finished.
1228 wait_for_prebuilt() {
1229 if [ ! -d ${PREBUILT_ILLUMOS:-/dev/null} ]; then
1230 logmsg "wait_for_prebuilt() called w/o PREBUILT_ILLUMOS. Bailing."
1231 clean_up
1232 exit 1
1233 fi
1234
1235 # -h means symbolic link. That's what nightly does.
1236 if [ ! -h $PREBUILT_ILLUMOS/log/nightly.lock ]; then
1237 logmsg "$PREBUILT_ILLUMOS already built (no nightly.lock present...)"
1238 return
1239 fi
1240
1241 # NOTE -> if the nightly finishes between the above check and now, we
1242 # can produce confusing output since nightly_pid will be empty.
1243 nightly_pid=`ls -lt $PREBUILT_ILLUMOS/log/nightly.lock | awk -F. '{print $4}'`
1244 # Wait for nightly to be finished if it's running.
1245 logmsg "Waiting for illumos nightly build $nightly_pid to be finished."
1246 logmsg "Amount of time waiting for illumos nightly follows."
1247 logcmd /bin/time pwait $nightly_pid
1248 if [ -h $PREBUILT_ILLUMOS/log/nightly.lock ]; then
1249 logmsg "Nightly lock present, but build not running. Bailing."
1250 if [[ -z $BATCH ]]; then
1251 ask_to_continue
1252 fi
1253 clean_up
1254 exit 1
1255 fi
1256 }
1257
1258 # Vim hints
1259 # vim:ts=4:sw=4:et: