1#!/bin/sh 2 3# 4# This shell-script is argument-compatible with xcrun(1) as invoked 5# by xnu's Makefiles. Additionally, it supports caching tools 6# in the local build directory. It is tightly coupled to exactly 7# the queries that MakeInc.cmd makes, in exactly the order it makes 8# them. ./tools/remote_build.sh invokes this indirectly in caching 9# mode, so '$(XCRUN) -sdk foo -find bar' copies 'bar' from wherever 10# it is on-disk into ./BUILD/BuildData, and returns that path to the 11# caller. In '-u' mode on a remote build server, cache tools 12# relative to the current build directory are returned without 13# actually calling through to xcrun(1), since the remote build 14# server may not even have Xcode installed. 15# 16 17SDKROOT="" 18FINDTOOL="" 19SDKQUERY="" 20VERBOSE="" 21OBJROOT="" 22CACHE=0 23 24# echo "Calling $0 $@" 1>&2 25 26while [ $# -gt 0 ]; do 27 case "$1" in 28 -c) 29 CACHE=1 30 shift 31 OBJROOT="$1" 32 shift 33 ;; 34 -u) 35 CACHE=0 36 shift 37 OBJROOT="$1" 38 shift 39 ;; 40 -sdk) 41 shift 42 SDKROOT="$1" 43 shift 44 ;; 45 -verbose) 46 VERBOSE="$1" 47 shift 48 set -x 49 ;; 50 -find) 51 shift 52 FINDTOOL="$1" 53 shift 54 ;; 55 -show-sdk-path) 56 SDKQUERY="$1" 57 shift 58 ;; 59 -show-sdk-platform-path) 60 SDKQUERY="$1" 61 shift 62 ;; 63 -show-sdk-version) 64 SDKQUERY="$1" 65 shift 66 ;; 67 *) 68 echo "Unrecognized argument $1" 1>&2 69 exit 1 70 esac 71done 72 73function CreateFile() { 74 local string="$1" 75 local filepath="$2" 76 echo "${string}" > "${filepath}.new" 77 cmp -s "${filepath}" "${filepath}.new" 78 if [ $? -eq 0 ]; then 79 rm "${filepath}.new" 80 else 81 mv "${filepath}.new" "${filepath}" 82 fi 83} 84 85if [ $CACHE -eq 1 ]; then 86 87 if [ -n "$SDKQUERY" ]; then 88 # MakeInc.cmd makes SDK queries up-front first. Generally the 89 # SDKROOT that is an input to these are one of: 90 # "macosx" => Host SDK 91 # "iphonehostXXX" => iPhone Host SDK 92 # other shortcut or full path => Target SDK 93 # 94 # Once an initial lookup is made, subsequent SDKROOTs for 95 # that same SDK may use a full path or cached path 96 SDKTYPE="" 97 case "$SDKROOT" in 98 macosx) 99 SDKTYPE="host" 100 ;; 101 iphonehost*) 102 SDKTYPE="iphonehost" 103 ;; 104 *) 105 if [ -f "$SDKROOT/.sdktype" ]; then 106 SDKTYPE=`cat "$SDKROOT/.sdktype"` 107 else 108 SDKTYPE="target" 109 fi 110 ;; 111 esac 112 113 # A cached SDK path can be passed to xcrun, so 114 # we need the original on-disk path 115 if [ -f "$SDKROOT/.realsdkpath" ]; then 116 REALSDKROOT=`cat "$SDKROOT/.realsdkpath"` 117 else 118 REALSDKROOT="$SDKROOT" 119 fi 120 121 SDKPROPERTY=`/usr/bin/xcrun $VERBOSE -sdk "$REALSDKROOT" "$SDKQUERY"` 122 if [ $? -ne 0 ]; then 123 exit $? 124 fi 125 126 case $SDKQUERY in 127 -show-sdk-path) 128 # Cache the SDK locally, and transform the resulting SDKPROPERTY 129 if [ -z "$SDKPROPERTY" ]; then 130 SDKPROPERTY="/" 131 SDKNAME="Slash.sdk" 132 else 133 SDKNAME=$(basename "${SDKPROPERTY}") 134 fi 135 mkdir -p "${OBJROOT}/BuildTools/${SDKNAME}" 136 mkdir -p "${OBJROOT}/BuildTools/${SDKNAME}/usr/include" 137 rsync -aq --exclude=c++ --exclude=php --exclude=soc "${SDKPROPERTY}/usr/include/" "${OBJROOT}/BuildTools/${SDKNAME}/usr/include/" 138 if [ "$SDKTYPE" = "iphonehost" ]; then 139 mkdir -p "${OBJROOT}/BuildTools/${SDKNAME}/usr/local/lib/system" 140 rsync -aq "${SDKPROPERTY}/usr/local/lib/system/" "${OBJROOT}/BuildTools/${SDKNAME}/usr/local/lib/system/" 141 else 142 mkdir -p "${OBJROOT}/BuildTools/${SDKNAME}/usr/lib" 143 rsync -aq "${SDKPROPERTY}/usr/lib/libSystem"* "${OBJROOT}/BuildTools/${SDKNAME}/usr/lib/" 144 rsync -aq "${SDKPROPERTY}/usr/lib/libc++"* "${OBJROOT}/BuildTools/${SDKNAME}/usr/lib/" 145 rsync -aq "${SDKPROPERTY}/usr/lib/libstdc++"* "${OBJROOT}/BuildTools/${SDKNAME}/usr/lib/" 146 mkdir -p "${OBJROOT}/BuildTools/${SDKNAME}/usr/lib/system" 147 rsync -aq --exclude=\*_debug.dylib --exclude=\*_profile.dylib "${SDKPROPERTY}/usr/lib/system/" "${OBJROOT}/BuildTools/${SDKNAME}/usr/lib/system/" 148 fi 149 if [ -f "${SDKPROPERTY}/usr/local/libexec/availability.pl" ]; then 150 mkdir -p "${OBJROOT}/BuildTools/${SDKNAME}/usr/local/libexec" 151 rsync -aq "${SDKPROPERTY}/usr/local/libexec/availability.pl" "${OBJROOT}/BuildTools/${SDKNAME}/usr/local/libexec/" 152 fi 153 CreateFile "${SDKPROPERTY}" "${OBJROOT}/BuildTools/${SDKNAME}/.realsdkpath" 154 CreateFile "${SDKTYPE}" "${OBJROOT}/BuildTools/${SDKNAME}/.sdktype" 155 CreateFile "BuildTools/${SDKNAME}" "${OBJROOT}/BuildTools/.${SDKTYPE}sdk" 156 echo "${OBJROOT}/BuildTools/${SDKNAME}" 157 exit 0 158 ;; 159 -show-sdk-platform-path) 160 PLATFORMNAME=$(basename "${SDKPROPERTY}") 161 mkdir -p "${OBJROOT}/BuildTools/${PLATFORMNAME}" 162 if [ -f "${SDKPROPERTY}/usr/local/standalone/firmware/device_map.db" ]; then 163 mkdir -p "${OBJROOT}/BuildTools/${PLATFORMNAME}/usr/local/standalone/firmware" 164 rsync -aq "${SDKPROPERTY}/usr/local/standalone/firmware/device_map.db" \ 165 "${OBJROOT}/BuildTools/${PLATFORMNAME}/usr/local/standalone/firmware/" 166 fi 167 CreateFile "BuildTools/${PLATFORMNAME}" "${OBJROOT}/BuildTools/.targetplatform" 168 echo "${OBJROOT}/BuildTools/${PLATFORMNAME}" 169 exit 0 170 ;; 171 -show-sdk-version) 172 CreateFile "${SDKPROPERTY}" "${OBJROOT}/BuildTools/.targetsdkversion" 173 echo "${SDKPROPERTY}" 174 exit 0 175 ;; 176 esac 177 178 elif [ -n "$FINDTOOL" ]; then 179 180 # We assume SDK Queries have been performed first and subsequent 181 # SDKROOTs used to find tools are all using cached SDKs in 182 # the build directory, in which case metadata is present 183 184 if [ ! -f "$SDKROOT/.realsdkpath" ]; then 185 exit 1 186 fi 187 REALSDKROOT=`cat "$SDKROOT/.realsdkpath"` 188 189 if [ ! -f "$SDKROOT/.sdktype" ]; then 190 exit 1 191 fi 192 SDKTYPE=`cat "$SDKROOT/.sdktype"` 193 194 TOOLPATH=`/usr/bin/xcrun $VERBOSE -sdk "$REALSDKROOT" -find "$FINDTOOL"` 195 if [ $? -ne 0 ]; then 196 exit $? 197 fi 198 199 # Keep the parent directory when caching tools, along with Host vs. Target 200 TOOLNAME=$(basename "${TOOLPATH}") 201 TOOLDIR=$(basename $(dirname "${TOOLPATH}")) 202 if [ "$SDKTYPE" = "host" ]; then 203 NEWTOOLPATH="${OBJROOT}/BuildTools/Host/${TOOLDIR}/${TOOLNAME}" 204 mkdir -p "${OBJROOT}/BuildTools/Host" 205 CreateFile "BuildTools/Host/${TOOLDIR}/${TOOLNAME}" "${OBJROOT}/BuildTools/Host/.${TOOLNAME}" 206 else 207 NEWTOOLPATH="${OBJROOT}/BuildTools/Target/${TOOLDIR}/${TOOLNAME}" 208 mkdir -p "${OBJROOT}/BuildTools/Target" 209 CreateFile "BuildTools/Target/${TOOLDIR}/${TOOLNAME}" "${OBJROOT}/BuildTools/Target/.${TOOLNAME}" 210 fi 211 mkdir -p $(dirname "${NEWTOOLPATH}") 212 rsync -aq "${TOOLPATH}" "${NEWTOOLPATH}" 213 case "${TOOLNAME}" in 214 clang) 215 mkdir -p $(dirname $(dirname "${NEWTOOLPATH}"))/lib/clang 216 rsync -aq $(dirname "${TOOLPATH}")/ld $(dirname "${NEWTOOLPATH}")/ld 217 rsync -aq $(dirname $(dirname "${TOOLPATH}"))/lib/clang/ $(dirname $(dirname "${NEWTOOLPATH}"))/lib/clang/ 218 rsync -aq $(dirname $(dirname "${TOOLPATH}"))/lib/libLTO.dylib $(dirname $(dirname "${NEWTOOLPATH}"))/lib/libLTO.dylib 219 ;; 220 bison) 221 mkdir -p $(dirname $(dirname "${NEWTOOLPATH}"))/share/bison 222 rsync -aq $(dirname $(dirname "${TOOLPATH}"))/share/bison/ $(dirname $(dirname "${NEWTOOLPATH}"))/share/bison/ 223 ;; 224 esac 225 226 echo "${NEWTOOLPATH}" 227 exit 0 228 else 229 echo "Unrecognized option" 1>&2 230 exit 1 231 fi 232fi 233 234# When using cached SDK information, first try to do 235# an initial classification, and then read properties from 236# cached locations 237SDKTYPE="" 238case "$SDKROOT" in 239 macosx) 240 SDKTYPE="host" 241 ;; 242 iphonehost*) 243 SDKTYPE="iphonehost" 244 ;; 245 *) 246 if [ -f "$SDKROOT/.sdktype" ]; then 247 SDKTYPE=`cat "$SDKROOT/.sdktype"` 248 else 249 SDKTYPE="target" 250 fi 251 ;; 252esac 253 254if [ -n "$FINDTOOL" ]; then 255 TOOLNAME=$(basename "${FINDTOOL}") 256 if [ "${SDKTYPE}" = "host" ]; then 257 RELPATH=`cat ${OBJROOT}/BuildTools/Host/.${TOOLNAME}` 258 else 259 RELPATH=`cat ${OBJROOT}/BuildTools/Target/.${TOOLNAME}` 260 fi 261 echo "${OBJROOT}/${RELPATH}" 262else 263 case $SDKQUERY in 264 -show-sdk-path) 265 RELPATH=`cat ${OBJROOT}/BuildTools/.${SDKTYPE}sdk` 266 echo "${OBJROOT}/${RELPATH}" 267 ;; 268 -show-sdk-platform-path) 269 RELPATH=`cat ${OBJROOT}/BuildTools/.targetplatform` 270 echo "${OBJROOT}/${RELPATH}" 271 ;; 272 -show-sdk-version) 273 echo `cat ${OBJROOT}/BuildTools/.targetsdkversion` 274 ;; 275 esac 276fi 277