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