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