463 строки
12 KiB
Bash
463 строки
12 KiB
Bash
#!/bin/ksh
|
|
########################################################################
|
|
# buildall - automated multi-platform build tool
|
|
#
|
|
# 10/09/97 - marcel - created
|
|
# 10/13/97 - marcel - support shared build tree
|
|
# 2/11/98 - marcel - updated for 4.0 Beta builds (need -update)
|
|
# 2/26/98 - marcel - added -r, -t and host specifiers
|
|
# 7/01/99 - robodan - added VAR=value ability
|
|
# 8/01/99 - robodan - explicitly know about building on localhost
|
|
# 10/15/99 - robodan - remove older OSes from build list
|
|
# 2000/4/7 - robodan - Created mstone version
|
|
########################################################################
|
|
#
|
|
# This script is intended to do a set of UNIX builds for a
|
|
# given CVS module. It is designed to use 'rsh' between a
|
|
# set of trusting hosts and use shared NFS storage with common
|
|
# mount points (e.g. /u/username/...)
|
|
#
|
|
# To check if you have rights to rsh to a particular host, try:
|
|
# rsh hostname "echo $PATH"
|
|
# You may have to edit your .rhosts or /etc/hosts.equiv
|
|
#
|
|
# A target directory will be created based on the current date.
|
|
#
|
|
# A set of global build logs plus a log per platform are kept
|
|
# in a log directory under the target
|
|
#
|
|
# It will checkout a copy of the source, duplicate it for
|
|
# each platform and perform a set of remote builds in parallel.
|
|
# The script will exit when all the work has been completed.
|
|
#
|
|
# Example usage:
|
|
# cd ~/src; buildall msg
|
|
# Result:
|
|
# ~/src/19980210_40.1/
|
|
# ~/src/19980210_40.1/logs/...
|
|
# ~/src/19980210_40.1/src/...
|
|
# ...
|
|
#
|
|
|
|
# Buildhosts
|
|
DEFAULT_BUILDHOSTS="kimo nugget vsync shave purgatory trex0"
|
|
|
|
usage() {
|
|
echo ""
|
|
echo "usage: buildall [ make assigns... ] < -t | target > [ -r ] [ buildhosts... ]"
|
|
echo " [ -t | --test]: just test rsh and report OS versions."
|
|
echo " [-r | --respin]: rebuild in place using existing source."
|
|
echo " [-p | --postbuild]: Execute post build command too."
|
|
echo " [make assigns]: e.g. VARIANT=release"
|
|
echo " <target>: one of: mstone42"
|
|
echo " [buildhosts...]: default [$DEFAULT_BUILDHOSTS]"
|
|
echo ""
|
|
exit 1
|
|
}
|
|
|
|
########################################################################
|
|
# Set these defaults and options for your desired build
|
|
########################################################################
|
|
|
|
# Target base destination directory
|
|
DESTBASE=`pwd`
|
|
|
|
# Can we do multiple ARCH builds in same source tree
|
|
SHARESRC=yes
|
|
|
|
DESCRIPTION=""
|
|
BUILDHOSTS=""
|
|
RESPIN="no"
|
|
POSTBUILD="no"
|
|
JUST_TEST="no"
|
|
DESTTYPE=""
|
|
CO_CMD="cvs -d $CVSROOT -q checkout"
|
|
CHECKOUT=""
|
|
CHECKOUT2=""
|
|
#MOZCVSROOT=':pserver:anonymous@cvs.mozilla.org:/cvsroot'
|
|
MOZCVSROOT=':pserver:robodan%netscape.com@cvs.mozilla.org:/cvsroot'
|
|
|
|
MAKE="gmake"
|
|
MK_ARG=""
|
|
|
|
ARGS="$@"
|
|
|
|
for ARG in "$@"; do
|
|
|
|
# If this is a make assignment (FOO=whatever), add it to make command
|
|
# Arguments with quotes in them dont go all the way through.
|
|
# Make args trick: 'FOO=nop -j 2'
|
|
# The pre-post arg stuff uses hostnames as a switch, ugly calling syntax.
|
|
if [[ -n "`echo z$ARG | egrep '^z[A-Z0-9_]+=[^ ]'`" ]] ; then
|
|
if [[ -n "$DESCRIPTION" ]] ; then
|
|
echo "Arg after target is ignored! ($ARG)"
|
|
continue
|
|
fi
|
|
if [[ -z "$BUILDHOSTS" ]] ; then # pre args
|
|
MAKE="$MAKE $ARG"
|
|
else # post args
|
|
MK_ARG="$MK_ARG $ARG"
|
|
fi
|
|
continue
|
|
fi
|
|
|
|
# should we just rebuild todays latest source...
|
|
if [[ "$ARG" = "-r" || "$ARG" = "--respin" || "$ARG" = "respin" ]]; then
|
|
RESPIN="yes"
|
|
continue
|
|
fi
|
|
|
|
# should we just run post build command...
|
|
if [[ "$ARG" = "-p" || "$ARG" = "--postbuild" || "$ARG" = "postbuild" ]]; then
|
|
POSTBUILD="yes"
|
|
continue
|
|
fi
|
|
|
|
# should we just test remote connectivity and execute permissions...
|
|
if [[ "$ARG" = "-t" || "$ARG" = "--test" ]]; then
|
|
JUST_TEST="yes"
|
|
RESPIN="yes"
|
|
continue
|
|
fi
|
|
|
|
# We will pull source using: "$CHECKOUT"
|
|
# And build on each machine: "cd $BUILDDIR && $BUILDCMD"
|
|
|
|
|
|
# expand targets (but dont confuse hosts for targets (msg7))
|
|
|
|
# These will build just mstone
|
|
# expand targets (but dont confuse hosts for targets (msg7))
|
|
if [[ "$BUILDCMD" = "" && "$ARG" = mailstone* ]]; then
|
|
case ${ARG#mstone} in
|
|
"")
|
|
"42")
|
|
DESTTYPE=_MSTONE42
|
|
MS_BRANCH=""
|
|
#BUILDCMD="$MAKE $MK_ARG debug release"
|
|
#POSTCMD="$MAKE $MK_ARG all_DBG.OBJ all_OPT.OBJ"
|
|
BUILDCMD="$MAKE $MK_ARG rpackage"
|
|
POSTCMD="$MAKE $MK_ARG all_OPT"
|
|
;;
|
|
*)
|
|
echo "Unknown mstone version in $ARG"
|
|
echo "Try mstone42"
|
|
exit 1;;
|
|
esac
|
|
|
|
DESCRIPTION="Mstone $MS_BRANCH"
|
|
BUILDDIR=./mozilla/mstone
|
|
CVSROOT=$MOZCVSROOT
|
|
CHECKOUT="$CO_CMD $MS_BRANCH mozilla/mstone"
|
|
# BUG No way to unpack perl, gd, and gnuplot before building
|
|
continue
|
|
fi
|
|
|
|
#########################
|
|
# Other...
|
|
#########################
|
|
|
|
# These will print some tools info
|
|
if [[ "$ARG" = "tools" ]]; then
|
|
CHECKOUT="$CO_CMD modules"
|
|
BUILDDIR=.
|
|
BUILDCMD="which gcc && ls -l /tools/ns/bin/gcc && which gcc-2.7.2.1 && ls -l /tools/ns/bin/gcc-2.7.2.1"
|
|
continue
|
|
fi
|
|
|
|
#########################
|
|
# Everything else is assumed to be a hostname
|
|
#########################
|
|
|
|
BUILDHOSTS="$ARG $BUILDHOSTS"
|
|
|
|
done # for ARG in $*; do
|
|
|
|
if [[ "$BUILDHOSTS" = "" ]]; then
|
|
BUILDHOSTS=$DEFAULT_BUILDHOSTS
|
|
fi
|
|
|
|
if [[ "$BUILDCMD" = "" && "$JUST_TEST" = "no" ]]; then
|
|
usage
|
|
fi
|
|
|
|
########################################################################
|
|
# You shouldn't have to modify stuff below here too much
|
|
########################################################################
|
|
|
|
# Who and Where are we
|
|
PROG=buildall
|
|
RSH=rsh
|
|
SYS=`uname -s`
|
|
echo SYS=$SYS
|
|
if [[ "$SYS" = "HP-UX" ]]; then
|
|
RSH=remsh
|
|
fi
|
|
|
|
########################################################################
|
|
# Simple log output function
|
|
########################################################################
|
|
|
|
log() {
|
|
# echo "[`date +\"%Y/%m/%d %H:%M:%S\"`] $PROG: $*"
|
|
echo "`date +\"%H:%M:%S\"` $PROG: $*"
|
|
}
|
|
|
|
########################################################################
|
|
# Error
|
|
########################################################################
|
|
|
|
quit() {
|
|
log "$* (exiting)..."
|
|
exit 1
|
|
}
|
|
|
|
# Where should the work be done
|
|
REV=1
|
|
WORKDIR=$DESTBASE/`date +"%Y%m%d"`$DESTTYPE.$REV
|
|
LASTWORKDIR=$WORKDIR
|
|
LASTREV=$REV
|
|
|
|
while [[ -d $WORKDIR ]]; do
|
|
LASTREV=$REV
|
|
let "REV= REV + 1"
|
|
LASTWORKDIR=$WORKDIR
|
|
WORKDIR=$DESTBASE/`date +"%Y%m%d"`$DESTTYPE.$REV
|
|
done
|
|
|
|
if [[ "$RESPIN" = "yes" ]]; then
|
|
WORKDIR=$LASTWORKDIR
|
|
REV=$LASTREV
|
|
fi
|
|
BUILDREV=$REV
|
|
|
|
if [[ ! -d $WORKDIR && "$RESPIN" = "yes" ]]; then
|
|
quit "missing expected respin workdir ($WORKDIR)"
|
|
fi
|
|
|
|
mkdir -p $WORKDIR
|
|
|
|
# Where to send logs
|
|
LOGDIR=$WORKDIR/logs
|
|
[[ -d $LOGDIR ]] || mkdir $LOGDIR
|
|
|
|
# What tool to use for compressed tar
|
|
if [[ -x /tools/ns/bin/tar ]] ; then # ROBDAN 9-15-98 for Linux
|
|
TAR=/tools/ns/bin/tar
|
|
else
|
|
TAR=tar
|
|
fi
|
|
|
|
SRCDIR=$WORKDIR/src
|
|
SRCTAR=$WORKDIR/src.tar.gz
|
|
|
|
########################################################################
|
|
# The function which extracts the source and prepares for copies
|
|
########################################################################
|
|
|
|
prepare_source() {
|
|
log "Preparing source code..."
|
|
mkdir $SRCDIR
|
|
(cd $SRCDIR;
|
|
log "Extracting source in $SRCDIR...";
|
|
log "$CHECKOUT > $LOGDIR/cvs-co.txt";
|
|
$CHECKOUT > $LOGDIR/cvs-co.txt;
|
|
RET=$?
|
|
if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $CHECKOUT"; fi
|
|
if [[ "$CHECKOUT2" != "" ]]; then
|
|
log "$CHECKOUT2 >> $LOGDIR/cvs-co.txt";
|
|
$CHECKOUT2 >> $LOGDIR/cvs-co.txt;
|
|
RET=$?
|
|
if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $CHECKOUT2"; fi
|
|
fi
|
|
log "Listing source...";
|
|
ls -Rl > $LOGDIR/src-ls-Rl.txt
|
|
log "Archiving source..."
|
|
$TAR czf $SRCTAR .
|
|
)
|
|
RET=$?
|
|
if [[ $RET -ne 0 ]]; then
|
|
quit "### Failed($RET): cannot prepare source";
|
|
else
|
|
log "Source extraction complete";
|
|
fi
|
|
}
|
|
|
|
########################################################################
|
|
# The function which does a build
|
|
########################################################################
|
|
|
|
do_rbuild() {
|
|
OSDEST=$1
|
|
|
|
if [ "$SHARESRC" = "yes" ]; then
|
|
RSRCDIR=$SRCDIR
|
|
else
|
|
RSRCDIR=$WORKDIR/$OSDEST
|
|
fi
|
|
|
|
[[ -d $RSRCDIR ]] || mkdir -p $RSRCDIR
|
|
|
|
cd $RSRCDIR;
|
|
|
|
# do any late variable expansions
|
|
RAWCMD=$BUILDCMD
|
|
BUILDCMD=$(eval echo $RAWCMD)
|
|
|
|
if [[ $RHOST = localhost ]] ; then
|
|
log "Build locally for $OSDEST ($BUILDCMD)...";
|
|
cd $BUILDDIR && pwd && $BUILDCMD && echo $PROG: Success
|
|
RET=$?
|
|
if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $OSDEST build"; fi
|
|
|
|
log "Completed local build..."
|
|
return
|
|
fi
|
|
|
|
if [[ "$SHARESRC" != "yes" ]]; then
|
|
log "Extracting source for $OSDEST...";
|
|
$RSH $RHOST -n "cd $RSRCDIR && pwd && $TAR xzf $SRCTAR";
|
|
RET=$?
|
|
if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $OSDEST source extraction"; fi
|
|
else
|
|
log "Using common source in $RSRCDIR";
|
|
fi
|
|
|
|
log "Building for $OSDEST ($BUILDCMD)...";
|
|
$RSH $RHOST -n "cd $RSRCDIR/$BUILDDIR && pwd && $BUILDCMD && echo $PROG: Success"
|
|
RET=$?
|
|
if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $OSDEST build"; fi
|
|
|
|
log "Completed $OSDEST...";
|
|
}
|
|
|
|
buildhost() {
|
|
RHOST=$1
|
|
|
|
log "Query $RHOST configuration...";
|
|
|
|
if [[ $RHOST = localhost ]] ; then
|
|
uname -s > /tmp/$$.$RHOST 2>&1
|
|
else
|
|
$RSH $RHOST -n "uname -s" > /tmp/$$.$RHOST 2>&1
|
|
RET=$?
|
|
if [[ $RET -ne 0 ]]; then
|
|
quit "..[$RHOST] ### Failed($RET): $RSH $RHOST -n \"uname -s\"";
|
|
fi
|
|
fi
|
|
ROSTYPE=`tail -1 /tmp/$$.$RHOST`
|
|
|
|
if [[ "$ROSTYPE" = "AIX" ]]; then
|
|
$RSH $RHOST -n "uname -v" > /tmp/$$.$RHOST 2>&1
|
|
ROSTYPE=${ROSTYPE}`tail -1 /tmp/$$.$RHOST`
|
|
fi
|
|
|
|
if [[ $RHOST = localhost ]] ; then
|
|
uname -r > /tmp/$$.$RHOST 2>&1
|
|
else
|
|
$RSH $RHOST -n "uname -r" > /tmp/$$.$RHOST 2>&1
|
|
fi
|
|
ROSREV=`tail -1 /tmp/$$.$RHOST`
|
|
rm /tmp/$$.$RHOST
|
|
|
|
if [[ $RHOST = localhost ]] ; then
|
|
OSDEST=`hostname | cut -f1 -d.`-${ROSTYPE}${ROSREV}
|
|
else
|
|
OSDEST=${RHOST}-${ROSTYPE}${ROSREV}
|
|
fi
|
|
log "..Building on [$OSDEST]..."
|
|
|
|
REV=1 # find unique logfile name
|
|
OSLOG=$LOGDIR/$OSDEST.$REV
|
|
while [[ -f $OSLOG ]]; do
|
|
let "REV = REV + 1"
|
|
OSLOG=$LOGDIR/$OSDEST.$REV
|
|
done
|
|
|
|
if [[ "$JUST_TEST" = "yes" ]]; then
|
|
echo "$PROG: Success" > $OSLOG
|
|
else
|
|
( do_rbuild $OSDEST ) > $OSLOG 2>&1
|
|
fi
|
|
|
|
grep "$PROG: Success" $OSLOG > /dev/null
|
|
RET=$?
|
|
if [[ $RET -eq 0 ]]; then
|
|
RESULT="SUCCESS";
|
|
else
|
|
RESULT="FAILURE($RET)";
|
|
fi
|
|
log "..Completed [$OSDEST] <$RESULT>.";
|
|
}
|
|
|
|
########################################################################
|
|
# The function which initiates all the builds
|
|
########################################################################
|
|
|
|
do_builds() {
|
|
log "Launching builds..."
|
|
|
|
for HOST in $BUILDHOSTS; do
|
|
buildhost $HOST &
|
|
done
|
|
}
|
|
|
|
########################################################################
|
|
# main
|
|
########################################################################
|
|
|
|
main() {
|
|
if [[ "$JUST_TEST" = "yes" ]]; then
|
|
log "Automated test starting..."
|
|
else
|
|
log "Automated build of [$DESCRIPTION] starting..."
|
|
fi
|
|
log ""
|
|
log " ARGS = $ARGS"
|
|
log " BUILDHOSTS = $BUILDHOSTS"
|
|
log " WORKDIR = $WORKDIR"
|
|
log " SRCDIR = $SRCDIR"
|
|
log " LOGDIR = $LOGDIR"
|
|
log " CHECKOUT = $CHECKOUT"
|
|
log " BUILDDIR = $BUILDDIR"
|
|
log " BUILDCMD = $BUILDCMD"
|
|
log " RESPIN = $RESPIN"
|
|
log ""
|
|
|
|
[[ "$RESPIN" = "no" ]] && prepare_source
|
|
do_builds
|
|
log "Waiting for all builds to complete..."
|
|
wait
|
|
log "All builds completed."
|
|
|
|
if [[ -n "$POSTCMD" && "$POSTBUILD" = "yes" ]] ; then
|
|
log "Running post build command."
|
|
|
|
REV=1 # find unique logfile name
|
|
POSTLOG=$LOGDIR/postbuild.$REV
|
|
while [[ -f $POSTLOG ]]; do
|
|
let "REV = REV + 1"
|
|
POSTLOG=$LOGDIR/postbuild.$REV
|
|
done
|
|
|
|
echo "Dir $SRCDIR/$BUILDDIR" > $POSTLOG
|
|
echo "Cmd $POSTCMD" >> $POSTLOG
|
|
(cd $SRCDIR/$BUILDDIR && $POSTCMD && echo $PROG: Success) >> $POSTLOG 2>&1
|
|
|
|
log "Post build command completed."
|
|
elif [[ -n "$POSTCMD" ]] ; then
|
|
echo "Skipping post build command: $POSTCMD"
|
|
fi
|
|
}
|
|
|
|
REV=1
|
|
PROGLOG=$LOGDIR/$PROG.$REV
|
|
|
|
while [[ -f $PROGLOG ]]; do
|
|
REV=`expr $REV + 1`
|
|
PROGLOG=$LOGDIR/$PROG.$REV
|
|
done
|
|
|
|
main | tee $PROGLOG 2>&1
|
|
exit 0
|