1#!/bin/sh 2# 3# Copyright (c) 2004-2010, Apple Computer, Inc. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14# its contributors may be used to endorse or promote products derived 15# from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 21# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30PREFIX=/usr/local 31PWDP=$(pwd -P) 32 33COMMONFILE=buildscripts/darwinbuild.common 34 35DARWIN_BUILDROOT=$(pwd) 36 37build="" 38action="install" 39target="" 40configuration="" 41version="" 42 43nosource="YES" 44 45USE_CHROOT=NO 46INSTALL_XCODE="NO" 47 48### 49### Include some common subroutines 50### 51 52. "$COMMONFILE" 53 54shopt -s nullglob 55 56### 57### DarwinBuild must be run as root. Enforce this. 58### 59if [ "$EUID" != "0" ]; then 60 echo "Error: xnu-build must be run as root." 1>&2 61 exit 1 62fi 63 64projnam=xnu 65project=$(git tag -l | tail -n1) 66 67if [ ! $project ]; then 68 echo "You must check out this project from git." 69 exit 1 70fi 71 72### 73### We do our building in private/var/tmp since it's 74### likely to be out of the way of our dependencies 75### and is supposed to be writable by everyone. 76### 77 78vartmp="private/var/tmp" 79mkdir -p "$BuildRoot/$vartmp" 80chmod 1777 "$BuildRoot/$vartmp" 81 82### 83### Define the SRCROOT, OBJROOT, SYMROOT, and DSTROOT. 84### This script refers to the absolute paths of the build 85### directory, and should use REAL_SRCROOT, etc. 86### If USE_CHROOT, then the environment variables will have 87### the BuildRoot prefix omitted because the chroot 88### will make all paths relative to that point. 89### 90 91DARWIN_BUILDROOT="/private/var/tmp/BuildRoot" 92 93project_tag=$(git describe --dirty) 94 95buildtool="make" 96version="${project/$projnam-/}" 97build_version=$(($(GetBuildVersion $DARWIN_BUILDROOT/{Logs,Symbols,Headers,Roots}/$projnam/$project_tag.*) + 1)) 98 99REAL_SRCROOT="/SourceCache/$projnam/$project_tag" 100 101if [ -e $REAL_SRCROOT ]; then 102 rm -rf $REAL_SRCROOT 103fi 104 105git clone $(pwd) $REAL_SRCROOT 106REAL_OBJROOT="$BuildRoot/$vartmp/$projnam/Objects/$project_tag~$build_version" 107REAL_SYMROOT="$BuildRoot/$vartmp/$projnam/Symbols/$project_tag~$build_version" 108REAL_DSTROOT="$BuildRoot/$vartmp/$projnam/Roots/$project_tag~$build_version" 109 110mkdir -p $REAL_SRCROOT $REAL_OBJROOT $REAL_SYMROOT $REAL_DSTROOT 111 112### 113### Read in the environment 114### 115 116LOG="$DARWIN_BUILDROOT/Logs/$projnam/$project_tag.log~$build_version" 117TRACELOG="$BuildRoot/private/var/tmp/$projnam/$project_tag.trace~$build_version" 118mkdir -p "$DARWIN_BUILDROOT/Logs/$projnam" 119 120if [ "$USE_CHROOT" == "YES" ]; then 121 prefix="$BuildRoot" 122else 123 prefix="" 124fi 125export SRCROOT="${REAL_SRCROOT/$prefix/}" 126export OBJROOT="${REAL_OBJROOT/$prefix/}" 127export SYMROOT="${REAL_SYMROOT/$prefix/}" 128export DSTROOT="${REAL_DSTROOT/$prefix/}" 129 130TARGET_CONFIGS=$(cat machine_configuration | xargs) 131 132# Hide this variable from the unset 133export -n SRCROOT OBJROOT SYMROOT DSTROOT PLATFORM 134export -n DARWIN_BUILDROOT DARWINBUILD_BUILD DARWINXREF_DB_FILE 135export -n USE_CHROOT INSTALL_XCODE TARGET_CONFIGS EXTERNAL_BUILD_FLAGS 136 137# Screen sets this to a multi-line value which causes trouble 138unset TERMCAP 139OLDIFS="$IFS" 140IFS=$'\n' 141for X in $(printenv) ; do 142 X=${X/=*/} 143 eval "unset $X" 144done 145IFS="$OLDIFS" 146 147export SRCROOT OBJROOT SYMROOT DSTROOT 148export DARWIN_BUILDROOT DARWINBUILD_BUILD DARWINXREF_DB_FILE 149export USE_CHROOT INSTALL_XCODE 150 151export PATH=/bin:/sbin:/usr/bin:/usr/sbin/:/usr/local/bin:/usr/local/sbin 152export SHELL="/bin/sh" 153export HOME="/var/root" 154export LOGNAME="root" 155export USER="root" 156export GROUP="wheel" 157 158build_string="" 159 160if [ "$buildtool" == "xcodebuild" -a "$target" != "" ]; then 161 build_string="$build_string -target \"$target\"" 162elif [ "$target" != "" ]; then 163 action="$target" 164fi 165 166# 167# append build configuration to $action, if any 168# this is only applicable to xcodebuild 169# 170if [ "$buildtool" == "xcodebuild" -a "$configuration" != "" ]; then 171 build_string="$build_string -configuration \"$configuration\"" 172fi 173 174### 175### Write out the build script that will be used. 176### This may or may not be executed in a chroot. 177### We want things like the gcc version to be picked 178### up from the chroot. 179### 180 181SCRIPT="$BuildRoot/$vartmp/$projnam/build-$project_tag~$build_version.sh" 182 183cat <<-EOF > $SCRIPT 184 #!/bin/sh 185 echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 186 echo "BUILDING $project_tag~$build_version on \$(date 2>/dev/null)" 187 echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 188 echo 'Build configuration:' 189 echo " Build host: \$(hostname 2>/dev/null)" 190 echo ' Build tool: $buildtool' 191 echo ' Build action: $action' 192 echo " Build number: $build" 193 echo " Host kernel version: \$(uname -v 2>/dev/null)" 194 echo " cc version: \$(gcc -v 2>&1 | tail -n 1 2>/dev/null)" 195 # Panther cctools unlinks -o target, so don't use /dev/null 196 echo " cctools version: \$(as -v -o /.devnull < /dev/null 2>&1 | cut -c 22- 2>/dev/null)" 197EOF 198if [ "$logdeps" == "YES" ]; then 199 if [ "$USE_CHROOT" == "YES" ]; then 200 if [ "$DARWINTRACE" -nt "$BuildRoot/usr/lib/darwintrace.dylib" ]; then 201 mkdir -p "$BuildRoot/usr/lib" 202 cp "$DARWINTRACE" \ 203 "$BuildRoot/usr/lib/darwintrace.dylib" 204 fi 205 echo "export DARWINTRACE_LOG=\"${TRACELOG/$BuildRoot/}\"" >> $SCRIPT 206 echo "export DYLD_INSERT_LIBRARIES=/usr/lib/darwintrace.dylib" >> $SCRIPT 207 else 208 echo "export DARWINTRACE_LOG=\"${TRACELOG}\"" >> $SCRIPT 209 echo "export DYLD_INSERT_LIBRARIES=$DARWINTRACE" >> $SCRIPT 210 fi 211 212 echo "export DYLD_FORCE_FLAT_NAMESPACE=1" >> $SCRIPT 213fi 214 215if [ "$INSTALL_XCODE" == "YES" ]; then 216 echo "*** Redirecting ..." 217 echo "DARWINTRACE_REDIRECT=\"${BuildRoot}\"" 218 echo "DARWINTRACE_LOG=\"${TRACELOG}\"" 219 echo "DYLD_INSERT_LIBRARIES=$DARWINTRACE" 220 echo "DYLD_FORCE_FLAT_NAMESPACE=1" 221 echo "" 222 echo "export DARWINTRACE_REDIRECT=\"${BuildRoot}\"" >> $SCRIPT 223 echo "export DARWINTRACE_LOG=\"${TRACELOG}\"" >> $SCRIPT 224 echo "export DYLD_INSERT_LIBRARIES=$DARWINTRACE" >> $SCRIPT 225 echo "export DYLD_FORCE_FLAT_NAMESPACE=1" >> $SCRIPT 226fi 227 228if [ "$buildtool" == "xcodebuild" ]; then 229cat <<-EOF >> $SCRIPT 230 echo " xcode version: \$(sh -c \\\"$buildtool -version\\\")" 231EOF 232else 233cat <<-EOF >> $SCRIPT 234 echo " make version: \$(sh -c \\\"$buildtool -version\\\" | head -1 2>/dev/null)" 235EOF 236fi 237 238cat <<-EOF >> $SCRIPT 239 echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 240 echo 'Build parameters:' 241 echo SRCROOT: '$SRCROOT' 242 echo OBJROOT: '$OBJROOT' 243 echo SYMROOT: '$SYMROOT' 244 echo DSTROOT: '$DSTROOT' 245EOF 246### 247### Add in the build environment variables from darwinxref 248### 249build_string="$build_string $EXTERNAL_BUILD_FLAGS \"SRCROOT=$SRCROOT\" \"OBJROOT=$OBJROOT\" \"SYMROOT=$SYMROOT\" \"DSTROOT=$DSTROOT\" \"TARGET_CONFIGS=$TARGET_CONFIGS\"" 250 251OLDIFS="$IFS" 252IFS=$'\n' 253for X in \ 254 "RC_ProjectName=$projnam" \ 255 "RC_ProjectSourceVersion=$version" \ 256 "RC_ProjectNameAndSourceVersion=$project" \ 257 "RC_ProjectBuildVersion=$build_version" \ 258 $XREF_ENV ; do 259 echo "echo '${X/=*/}: ${X/*=/}'" >> $SCRIPT 260 eval "export -- \"$X\"" 261 build_string="$build_string \"$X\"" 262done 263IFS="$OLDIFS" 264 265cat <<-EOF >> $SCRIPT 266 echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 267 echo 'Environment variables:' 268EOF 269 270OLDIFS="$IFS" 271IFS=$'\n' 272for X in $(printenv | sort) ; do 273 echo "echo '$X'" >> $SCRIPT 274done 275IFS="$OLDIFS" 276 277cat <<-EOF >> $SCRIPT 278 echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 279 echo $buildtool $action '$build_string' \< /dev/null 280 echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 281 echo '' 282 echo 'Build log begins here:' 283 echo '' 284 cd '$SRCROOT' 285EOF 286cat <<-EOF >> $SCRIPT 287 if [ -x /bin/date ]; then 288 START_DATE=\$(date "+%s") 289 fi 290 $buildtool $action $build_string < /dev/null 291 EXIT_STATUS="\$?" 292 if [ -x /bin/date ]; then 293 END_DATE=\$(date "+%s") 294 ELAPSED_TIME=\$((\$END_DATE - \$START_DATE)) 295 fi 296 echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 297 if [ -x /bin/date ]; then 298 echo " BUILD TIME: \$((\$ELAPSED_TIME / 3600))h \$((\$ELAPSED_TIME / 60))m \$((\$ELAPSED_TIME % 60))s" 299 fi 300 echo "EXIT STATUS: \$EXIT_STATUS" 301 exit \$EXIT_STATUS 302EOF 303 304chmod ugo+x $SCRIPT 305 306 307ExitHandler() { 308 ### Once for fdsec 309 [ -z "$(echo $BuildRoot/dev/*)" ] || umount "$BuildRoot/dev" 310 ### Twice for devfs 311 [ -z "$(echo $BuildRoot/dev/*)" ] || umount "$BuildRoot/dev" 312 ### Thrice for volfs 313 [ -z "$(echo $BuildRoot/.vol/*)" ] || chroot "$BuildRoot" umount /.vol 314} 315 316 317if [ "$USE_CHROOT" == "YES" ] ; then 318 ### 319 ### Mount devfs in the chroot 320 ### We'll make /dev/null our de-facto test for the existence of devfs 321 ### 322 ### Warning: 323 ### This must be done *BEFORE* the call to chroot, otherwise there is 324 ### no way to unmount the filesystem except rebooting. 325 ### 326 echo "*** Mounting special filesystems ..." 327 trap ExitHandler EXIT 328 329 if [ ! -c "$BuildRoot/dev/null" ]; then 330 echo "Mounting devfs ..." 331 mkdir -p "$BuildRoot/dev" 332 mount -t devfs stdin "$BuildRoot/dev" 333 mount -t fdesc -o union stdin "$BuildRoot/dev" 334 else 335 echo "devfs appears to exist ..." 336 fi 337 338 if [ -x /sbin/mount_volfs ]; then 339 # volfs is no longer present (nor needed) on Leopard. 340 if [ -z "$(echo $BuildRoot/.vol/*)" ]; then 341 echo "Mounting volfs ..." 342 [ -d "$BuildRoot/sbin" ] || mkdir -p "$BuildRoot/sbin" 343 [ -x "$BuildRoot/sbin/mount_volfs" ] || \ 344 cp /sbin/mount_volfs "$BuildRoot/sbin/" 345 [ -x "$BuildRoot/sbin/umount" ] || \ 346 cp /sbin/umount "$BuildRoot/sbin/" 347 [ -d "$BuildRoot/.vol" ] || mkdir -p "$BuildRoot/.vol" 348 ## If the directory is empty, assume volfs not mounted 349 chroot "$BuildRoot" /sbin/mount_volfs "/.vol" 350 else 351 echo "volfs appears to be mounted ..." 352 fi 353 fi 354 355 ### 356 ### Actually invoke the build tool here 357 ### 358 chroot -u root -g wheel $BuildRoot $vartmp/$projnam/build-$project_tag~$build_version.sh 2>&1 | tee -a "$LOG"; 359 EXIT_STATUS="${PIPESTATUS[0]}" 360else 361 ### 362 ### Actually invoke the build tool here 363 ### 364 $BuildRoot/$vartmp/$projnam/build-$project_tag~$build_version.sh 2>&1 | tee -a "$LOG" 365 EXIT_STATUS="${PIPESTATUS[0]}" 366 367 ### 368 ### Clean up the logging 369 ### 370 if [ "$logdeps" == "YES" ]; then 371 export -n DYLD_INSERT_LIBRARIES DYLD_FORCE_FLAT_NAMESPACE DARWINTRACE_LOG 372 fi 373fi 374 375if [ "$EXIT_STATUS" == "0" ]; then 376 ### 377 ### Building was successful, copy the results out of the 378 ### build root and into the Root cache 379 ### 380 381 if [ "$action" == "installhdrs" ]; then 382 ### Output the manifest 383 MANIFEST="/tmp/$projnam.$$" 384 "$DARWINXREF" register "$projnam" "$REAL_DSTROOT" | tee "$MANIFEST" 385 SHA1=$(cat "$MANIFEST" | $DIGEST) 386 mkdir -p "$REAL_DSTROOT/usr/local/darwinbuild/receipts" 387 cp "$MANIFEST" "$REAL_DSTROOT/usr/local/darwinbuild/receipts/$SHA1" 388 ln -s "$SHA1" "$REAL_DSTROOT/usr/local/darwinbuild/receipts/$projnam.hdrs" 389 rm -f "$MANIFEST" 390 391 mkdir -p "$DARWIN_BUILDROOT/Headers/$projnam/$project.hdrs~$build_version" 392 ditto "$REAL_DSTROOT" "$DARWIN_BUILDROOT/Headers/$projnam/$project.hdrs~$build_version" 393 else 394 mkdir -p "$DARWIN_BUILDROOT/Roots/$projnam/" 395 rm -f "$DARWIN_BUILDROOT/Roots/$projnam/$project_tag.root" 396 rm -f "$DARWIN_BUILDROOT/Roots/$projnam/$project_tag.sym" 397 ln -s "$REAL_DSTROOT" "$DARWIN_BUILDROOT/Roots/$projnam/$project_tag.root" 398 ln -s "$REAL_SYMROOT" "$DARWIN_BUILDROOT/Roots/$projnam/$project_tag.sym" 399 fi 400fi 401 402exit $EXIT_STATUS 403