1*19c3b8c2SApple OSS Distributions#!/bin/bash 2*19c3b8c2SApple OSS Distributions# 3*19c3b8c2SApple OSS Distributions# Script that rsyncs a source/build tree to a remote server, performs a build, 4*19c3b8c2SApple OSS Distributions# and copies the result back 5*19c3b8c2SApple OSS Distributions# 6*19c3b8c2SApple OSS Distributions 7*19c3b8c2SApple OSS Distributions# This script is invoked instead of the initial recursive make(1) in ./Makefile. 8*19c3b8c2SApple OSS Distributions# First it must cache all binaries that might be used during the build by 9*19c3b8c2SApple OSS Distributions# calling "make print_exports" (any target would work) with an overriden xcrun(1) 10*19c3b8c2SApple OSS Distributions# which caches tools an SDKs into ./BUILD/obj/BuildTools. When the combined 11*19c3b8c2SApple OSS Distributions# source+build tree is rsync-ed to the remote server, we run a script to 12*19c3b8c2SApple OSS Distributions# re-initiate the build using an overriden xcrun(1) which hands back 13*19c3b8c2SApple OSS Distributions# cached tools in ./BUILD/obj/BuildTools instead of whatever Xcode tools are on 14*19c3b8c2SApple OSS Distributions# the remote system (or if no Xcode tools are installed remotely). Finally, 15*19c3b8c2SApple OSS Distributions# the build results are copied back locally. 16*19c3b8c2SApple OSS Distributions# 17*19c3b8c2SApple OSS Distributions 18*19c3b8c2SApple OSS Distributionsfunction die() { 19*19c3b8c2SApple OSS Distributions echo "$1" 1>&2 20*19c3b8c2SApple OSS Distributions exit 1 21*19c3b8c2SApple OSS Distributions} 22*19c3b8c2SApple OSS Distributions 23*19c3b8c2SApple OSS Distributions 24*19c3b8c2SApple OSS DistributionsTARGET= 25*19c3b8c2SApple OSS Distributionsdeclare -a ARGS 26*19c3b8c2SApple OSS Distributionsdeclare -a REMOTEARGS 27*19c3b8c2SApple OSS Distributionsindex=0 28*19c3b8c2SApple OSS Distributionsfor arg in "$@"; do 29*19c3b8c2SApple OSS Distributions case $arg in 30*19c3b8c2SApple OSS Distributions _REMOTEBUILD_TARGET=*) 31*19c3b8c2SApple OSS Distributions TARGET=`echo $arg | awk -F= '{print $2}'` 32*19c3b8c2SApple OSS Distributions continue 33*19c3b8c2SApple OSS Distributions ;; 34*19c3b8c2SApple OSS Distributions _REMOTEBUILD_MAKE=*) 35*19c3b8c2SApple OSS Distributions MAKE=`echo $arg | awk -F= '{print $2}'` 36*19c3b8c2SApple OSS Distributions continue 37*19c3b8c2SApple OSS Distributions ;; 38*19c3b8c2SApple OSS Distributions REMOTEBUILD=*) 39*19c3b8c2SApple OSS Distributions # Don't restart another remote build remotely 40*19c3b8c2SApple OSS Distributions ;; 41*19c3b8c2SApple OSS Distributions SRCROOT=*) 42*19c3b8c2SApple OSS Distributions continue 43*19c3b8c2SApple OSS Distributions ;; 44*19c3b8c2SApple OSS Distributions OBJROOT=*) 45*19c3b8c2SApple OSS Distributions continue 46*19c3b8c2SApple OSS Distributions ;; 47*19c3b8c2SApple OSS Distributions SYMROOT=*) 48*19c3b8c2SApple OSS Distributions continue 49*19c3b8c2SApple OSS Distributions ;; 50*19c3b8c2SApple OSS Distributions DSTROOT=*) 51*19c3b8c2SApple OSS Distributions continue 52*19c3b8c2SApple OSS Distributions ;; 53*19c3b8c2SApple OSS Distributions CCHROOT=*) 54*19c3b8c2SApple OSS Distributions continue 55*19c3b8c2SApple OSS Distributions ;; 56*19c3b8c2SApple OSS Distributions RC_XBS=*) 57*19c3b8c2SApple OSS Distributions # Remote build isn't chrooted or special in any way 58*19c3b8c2SApple OSS Distributions arg="VERBOSE=YES" 59*19c3b8c2SApple OSS Distributions continue 60*19c3b8c2SApple OSS Distributions ;; 61*19c3b8c2SApple OSS Distributions VERBOSE=YES) 62*19c3b8c2SApple OSS Distributions set -x 63*19c3b8c2SApple OSS Distributions ;; 64*19c3b8c2SApple OSS Distributions esac 65*19c3b8c2SApple OSS Distributions ARGS[$index]="$arg" 66*19c3b8c2SApple OSS Distributions REMOTEARGS[$index]="\"$arg\"" 67*19c3b8c2SApple OSS Distributions index=$(($index+1)) 68*19c3b8c2SApple OSS Distributionsdone 69*19c3b8c2SApple OSS Distributions 70*19c3b8c2SApple OSS Distributions 71*19c3b8c2SApple OSS DistributionsRSYNC_ARGS="-azvh" 72*19c3b8c2SApple OSS DistributionsARGS[$index]="REMOTEBUILD=" 73*19c3b8c2SApple OSS DistributionsREMOTEARGS[$index]="\"REMOTEBUILD=\"" 74*19c3b8c2SApple OSS Distributions 75*19c3b8c2SApple OSS Distributions# For some targets like installsrc, we can't to a remote build 76*19c3b8c2SApple OSS DistributionsSKIPREMOTE=0 77*19c3b8c2SApple OSS Distributionscase $TARGET in 78*19c3b8c2SApple OSS Distributions clean) 79*19c3b8c2SApple OSS Distributions SKIPREMOTE=1 80*19c3b8c2SApple OSS Distributions ;; 81*19c3b8c2SApple OSS Distributions installsrc) 82*19c3b8c2SApple OSS Distributions SKIPREMOTE=1 83*19c3b8c2SApple OSS Distributions ;; 84*19c3b8c2SApple OSS Distributions installopensource) 85*19c3b8c2SApple OSS Distributions SKIPREMOTE=1 86*19c3b8c2SApple OSS Distributions ;; 87*19c3b8c2SApple OSS Distributions cscope) 88*19c3b8c2SApple OSS Distributions SKIPREMOTE=1 89*19c3b8c2SApple OSS Distributions ;; 90*19c3b8c2SApple OSS Distributions tags) 91*19c3b8c2SApple OSS Distributions SKIPREMOTE=1 92*19c3b8c2SApple OSS Distributions ;; 93*19c3b8c2SApple OSS Distributions help) 94*19c3b8c2SApple OSS Distributions SKIPREMOTE=1 95*19c3b8c2SApple OSS Distributions ;; 96*19c3b8c2SApple OSS Distributionsesac 97*19c3b8c2SApple OSS Distributions 98*19c3b8c2SApple OSS Distributionsif [ $SKIPREMOTE -eq 1 ]; then 99*19c3b8c2SApple OSS Distributions exec "$MAKE" "$TARGET" "${ARGS[@]}" 100*19c3b8c2SApple OSS Distributionsfi 101*19c3b8c2SApple OSS Distributions 102*19c3b8c2SApple OSS DistributionsSRC="$(pwd -P)" 103*19c3b8c2SApple OSS DistributionsSRCNAME="$(basename $SRC)" 104*19c3b8c2SApple OSS Distributions 105*19c3b8c2SApple OSS Distributions# Pick up build locations passed in the environment 106*19c3b8c2SApple OSS DistributionsOBJROOT="${OBJROOT}" 107*19c3b8c2SApple OSS DistributionsSYMROOT="${SYMROOT}" 108*19c3b8c2SApple OSS DistributionsDSTROOT="${DSTROOT}" 109*19c3b8c2SApple OSS Distributions 110*19c3b8c2SApple OSS Distributionsif [ -z "${OBJROOT}" ]; then 111*19c3b8c2SApple OSS Distributions die "OBJROOT not set in environment" 112*19c3b8c2SApple OSS Distributionsfi 113*19c3b8c2SApple OSS Distributionsmkdir -p "${OBJROOT}" || die "Could not create ${OBJROOT}" 114*19c3b8c2SApple OSS Distributions 115*19c3b8c2SApple OSS Distributionsif [ -z "${SYMROOT}" ]; then 116*19c3b8c2SApple OSS Distributions die "SYMROOT not set in environment" 117*19c3b8c2SApple OSS Distributionsfi 118*19c3b8c2SApple OSS Distributionsmkdir -p "${SYMROOT}" || die "Could not create ${SYMROOT}" 119*19c3b8c2SApple OSS Distributions 120*19c3b8c2SApple OSS Distributionsif [ -z "${DSTROOT}" ]; then 121*19c3b8c2SApple OSS Distributions die "DSTROOT not set in environment" 122*19c3b8c2SApple OSS Distributionsfi 123*19c3b8c2SApple OSS Distributionsmkdir -p "${DSTROOT}" || die "Could not create ${DSTROOT}" 124*19c3b8c2SApple OSS Distributions 125*19c3b8c2SApple OSS Distributionsif [ "$REMOTEBUILD" = "$SPECIALREMOTEBUILD" ]; then 126*19c3b8c2SApple OSS Distributions : 127*19c3b8c2SApple OSS Distributionselse 128*19c3b8c2SApple OSS Distributions DOINSTALLSRC=0 129*19c3b8c2SApple OSS Distributions REMOTE_SRCREL="./" 130*19c3b8c2SApple OSS Distributions BUILDTOOLSDIR="$OBJROOT" 131*19c3b8c2SApple OSS Distributions REMOTE_BUILDTOOLSREL="./BUILD/obj" 132*19c3b8c2SApple OSS Distributions BUILDSCRIPTDIR="$OBJROOT" 133*19c3b8c2SApple OSS Distributions REMOTE_BUILDSCRIPTREL="./BUILD/obj" 134*19c3b8c2SApple OSS Distributions BUILDSCRIPTNAME="build.sh" 135*19c3b8c2SApple OSS Distributions if [ ! -d "${OBJROOT}/SETUP" ]; then 136*19c3b8c2SApple OSS Distributions RSYNC_DELETE_EXCLUDED="--delete-excluded" 137*19c3b8c2SApple OSS Distributions else 138*19c3b8c2SApple OSS Distributions RSYNC_DELETE_EXCLUDED="" 139*19c3b8c2SApple OSS Distributions fi 140*19c3b8c2SApple OSS Distributions if [ ! -e "${SYMROOT}/" ]; then 141*19c3b8c2SApple OSS Distributions RSYNC_DELETE_SYMROOT=1 142*19c3b8c2SApple OSS Distributions else 143*19c3b8c2SApple OSS Distributions RSYNC_DELETE_SYMROOT=0 144*19c3b8c2SApple OSS Distributions fi 145*19c3b8c2SApple OSS Distributions if [ ! -e "${DSTROOT}/" ]; then 146*19c3b8c2SApple OSS Distributions RSYNC_DELETE_DSTROOT=1 147*19c3b8c2SApple OSS Distributions else 148*19c3b8c2SApple OSS Distributions RSYNC_DELETE_DSTROOT=0 149*19c3b8c2SApple OSS Distributions fi 150*19c3b8c2SApple OSS Distributions TARBUILDDIRS=0 151*19c3b8c2SApple OSS Distributionsfi 152*19c3b8c2SApple OSS Distributions 153*19c3b8c2SApple OSS Distributionsecho "Caching build tools..." 1>&2 154*19c3b8c2SApple OSS Distributionsmkdir -p "${BUILDTOOLSDIR}" || die "Could not create BUILDTOOLSDIR" 155*19c3b8c2SApple OSS Distributions$MAKE print_exports "${ARGS[@]}" XCRUN="${SRC}/tools/xcrun_cache.sh -c \"${BUILDTOOLSDIR}\"" >/dev/null || die "Could not cache build tools" 156*19c3b8c2SApple OSS Distributions 157*19c3b8c2SApple OSS Distributions# Cache the make(1) binary itself 158*19c3b8c2SApple OSS DistributionsMAKE_SDKROOT=`"${SRC}/tools/xcrun_cache.sh" -u "${BUILDTOOLSDIR}" -sdk / -show-sdk-path` 159*19c3b8c2SApple OSS Distributions"${SRC}/tools/xcrun_cache.sh" -c "${BUILDTOOLSDIR}" -sdk "${MAKE_SDKROOT}" -find make >/dev/null || die "Could not cache make" 160*19c3b8c2SApple OSS Distributions 161*19c3b8c2SApple OSS Distributions# Create a canned build script that can restart the build on the remote server. 162*19c3b8c2SApple OSS Distributionsmkdir -p "${BUILDSCRIPTDIR}" || die "Could not create BUILDSCRIPTDIR" 163*19c3b8c2SApple OSS Distributionscat > "${BUILDSCRIPTDIR}/${BUILDSCRIPTNAME}" <<EOF 164*19c3b8c2SApple OSS Distributions#!/bin/sh 165*19c3b8c2SApple OSS Distributionsmkdir -p /private/tmp 166*19c3b8c2SApple OSS Distributionsmkdir -p /private/var/tmp 167*19c3b8c2SApple OSS Distributionsmkdir -p "\${TMPDIR}" 168*19c3b8c2SApple OSS Distributionscd "${REMOTE_SRCREL}" 169*19c3b8c2SApple OSS Distributionsmkdir -p ./BUILD/obj 170*19c3b8c2SApple OSS Distributionsmkdir -p ./BUILD/sym 171*19c3b8c2SApple OSS Distributionsmkdir -p ./BUILD/dst 172*19c3b8c2SApple OSS DistributionsMAKE=\`\$PWD/tools/xcrun_cache.sh -u "\$PWD/${REMOTE_BUILDTOOLSREL}" -sdk / -find make\` 173*19c3b8c2SApple OSS Distributionsif [ -z "\${MAKE}" ]; then exit 1; fi 174*19c3b8c2SApple OSS Distributions\${MAKE} ${TARGET} ${REMOTEARGS[@]} XCRUN="\$PWD/tools/xcrun_cache.sh -u \"\$PWD/${REMOTE_BUILDTOOLSREL}\"" 175*19c3b8c2SApple OSS Distributionsret=\$? 176*19c3b8c2SApple OSS Distributionsif [ \$ret -eq 0 ]; then 177*19c3b8c2SApple OSS Distributionsif [ ${TARBUILDDIRS} -eq 1 ]; then 178*19c3b8c2SApple OSS Distributionstar jcf ./BUILD/obj.tar.bz2 --exclude=\*.o --exclude=\*.cpo --exclude=\*.d --exclude=\*.cpd --exclude=\*.non_lto --exclude=\*.ctf --exclude=conf -C ./BUILD/obj . || exit 1 179*19c3b8c2SApple OSS Distributionstar jcf ./BUILD/sym.tar.bz2 -C ./BUILD/sym . || exit 1 180*19c3b8c2SApple OSS Distributionstar jcf ./BUILD/dst.tar.bz2 -C ./BUILD/dst . || exit 1 181*19c3b8c2SApple OSS Distributionsfi 182*19c3b8c2SApple OSS Distributionsfi 183*19c3b8c2SApple OSS Distributionsexit \$ret 184*19c3b8c2SApple OSS DistributionsEOF 185*19c3b8c2SApple OSS Distributionschmod a+x "${BUILDSCRIPTDIR}/${BUILDSCRIPTNAME}" 186*19c3b8c2SApple OSS Distributions#echo "Build script is:" 187*19c3b8c2SApple OSS Distributions#cat "${BUILDSCRIPTDIR}/${BUILDSCRIPTNAME}" 188*19c3b8c2SApple OSS Distributions 189*19c3b8c2SApple OSS Distributionsmkdir -p "${BUILDTOOLSDIR}/empty" 190*19c3b8c2SApple OSS Distributions 191*19c3b8c2SApple OSS Distributionsif [ "$REMOTEBUILD" = "$SPECIALREMOTEBUILD" ]; then 192*19c3b8c2SApple OSS Distributions : 193*19c3b8c2SApple OSS Distributionselse 194*19c3b8c2SApple OSS Distributions 195*19c3b8c2SApple OSS Distributions REMOTEBUILD="$REMOTEBUILD" 196*19c3b8c2SApple OSS Distributions REMOTEBUILDPATH="$REMOTEBUILDPATH" 197*19c3b8c2SApple OSS Distributions 198*19c3b8c2SApple OSS Distributions if [ -z "$REMOTEBUILDPATH" ]; then 199*19c3b8c2SApple OSS Distributions WHOAMI=`whoami` 200*19c3b8c2SApple OSS Distributions case "${REMOTEBUILD}" in 201*19c3b8c2SApple OSS Distributions *@*) 202*19c3b8c2SApple OSS Distributions WHOAMI=`echo "${REMOTEBUILD}" | awk -F@ '{print $1}'` 203*19c3b8c2SApple OSS Distributions ;; 204*19c3b8c2SApple OSS Distributions esac 205*19c3b8c2SApple OSS Distributions REMOTEBUILDPATH="/tmp/$WHOAMI" 206*19c3b8c2SApple OSS Distributions fi 207*19c3b8c2SApple OSS Distributions 208*19c3b8c2SApple OSS Distributions# Construct a unique remote path 209*19c3b8c2SApple OSS Distributions eval `stat -s "${SRC}"` 210*19c3b8c2SApple OSS Distributions 211*19c3b8c2SApple OSS Distributions REMOTEBUILDPATH="${REMOTEBUILDPATH}/$st_ino/${SRCNAME}/" 212*19c3b8c2SApple OSS Distributions echo "Remote path is ${REMOTEBUILD}:${REMOTEBUILDPATH}" 1>&2 213*19c3b8c2SApple OSS Distributions 214*19c3b8c2SApple OSS Distributions ssh $REMOTEBUILD "mkdir -p \"${REMOTEBUILDPATH}/BUILD/\"{obj,sym,dst}" || die "Could not make remote build directory" 215*19c3b8c2SApple OSS Distributions 216*19c3b8c2SApple OSS Distributions # Copy source only 217*19c3b8c2SApple OSS Distributions rsync $RSYNC_ARGS --delete --exclude=\*~ --exclude=.svn --exclude=.git --exclude=/BUILD . $REMOTEBUILD:"${REMOTEBUILDPATH}" || die "Could not rsync source tree" 218*19c3b8c2SApple OSS Distributions 219*19c3b8c2SApple OSS Distributions # Copy partial OBJROOT (just build tools and build script), and optionally delete everything else 220*19c3b8c2SApple OSS Distributions rsync $RSYNC_ARGS --delete $RSYNC_DELETE_EXCLUDED --include=/build.sh --include=/BuildTools --include=/BuildTools/\*\* --exclude=\* "${OBJROOT}/" $REMOTEBUILD:"${REMOTEBUILDPATH}/BUILD/obj/" || die "Could not rsync build tree" 221*19c3b8c2SApple OSS Distributions 222*19c3b8c2SApple OSS Distributions # Delete remote SYMROOT if it has been deleted locally 223*19c3b8c2SApple OSS Distributions if [ "$RSYNC_DELETE_SYMROOT" -eq 1 ]; then 224*19c3b8c2SApple OSS Distributions rsync $RSYNC_ARGS --delete "${BUILDTOOLSDIR}/empty/" $REMOTEBUILD:"${REMOTEBUILDPATH}/BUILD/sym/" || die "Could not rsync delete SYMROOT" 225*19c3b8c2SApple OSS Distributions fi 226*19c3b8c2SApple OSS Distributions 227*19c3b8c2SApple OSS Distributions # Delete remote DSTROOT if it has been deleted locally 228*19c3b8c2SApple OSS Distributions if [ "$RSYNC_DELETE_DSTROOT" -eq 1 ]; then 229*19c3b8c2SApple OSS Distributions rsync $RSYNC_ARGS --delete "${BUILDTOOLSDIR}/empty/" $REMOTEBUILD:"${REMOTEBUILDPATH}/BUILD/dst/" || die "Could not rsync delete DSTROOT" 230*19c3b8c2SApple OSS Distributions fi 231*19c3b8c2SApple OSS Distributions 232*19c3b8c2SApple OSS Distributions # Start the build 233*19c3b8c2SApple OSS Distributions echo ssh $REMOTEBUILD "/bin/bash -c 'cd \"${REMOTEBUILDPATH}\" && ${REMOTE_BUILDSCRIPTREL}/${BUILDSCRIPTNAME}'" 1>&2 234*19c3b8c2SApple OSS Distributions ssh $REMOTEBUILD "/bin/bash -c 'cd \"${REMOTEBUILDPATH}\" && ${REMOTE_BUILDSCRIPTREL}/${BUILDSCRIPTNAME}'" || die "Could not complete remote build" 235*19c3b8c2SApple OSS Distributions 236*19c3b8c2SApple OSS Distributions # Copy back build results except for object files (which might be several GB) 237*19c3b8c2SApple OSS Distributions echo "Copying results back..." 238*19c3b8c2SApple OSS Distributions rsync $RSYNC_ARGS --no-o --no-g --exclude=\*.o --exclude=\*.cpo --exclude=\*.d --exclude=\*.cpd --exclude=\*.non_lto --exclude=\*.ctf $REMOTEBUILD:"${REMOTEBUILDPATH}/BUILD/obj/" "${OBJROOT}/" || die "Could not rsync build results" 239*19c3b8c2SApple OSS Distributions rsync $RSYNC_ARGS --no-o --no-g $REMOTEBUILD:"${REMOTEBUILDPATH}/BUILD/sym/" "${SYMROOT}/" || die "Could not rsync build results" 240*19c3b8c2SApple OSS Distributions rsync $RSYNC_ARGS --no-o --no-g $REMOTEBUILD:"${REMOTEBUILDPATH}/BUILD/dst/" "${DSTROOT}/" || die "Could not rsync build results" 241*19c3b8c2SApple OSS Distributions 242*19c3b8c2SApple OSS Distributionsfi 243*19c3b8c2SApple OSS Distributions 244*19c3b8c2SApple OSS Distributionsexit 0 245