Compiling Swift on a Raspberry Pi 2 (February 2016 Update) and a Script to Clone and Build Open Source Swift

Nakano at Night
Since I previously wrote about compiling Swift on a Raspberry Pi 2 the process has become much more straightforward. Pull requests for ARMv7 support from hpux735 have been accepted, so compiling your own copy is simply a matter of creating a massive swap and following the official instructions in the README. There’s even a buildbot preset for the job: “buildbot_linux_armv7.”

Today my build command looks something like this:

swift/utils/build-script --preset=buildbot_linux_armv7 install_destdir=/home/pi/testing/dest installable_package=/home/pi/testing/swift-2016-02-08.tar.gz

I don’t actually type the command above very often. Instead, I generally use the Bash script below to clone the repositories, run the Swift build script with my preferred options, and collect some system statistics during the build. It’s not particularly pretty, but it gets the job done:-)

A Script to Clone and Build Open Source Swift

  • Usage: ./clone-build-swift _[a directory for the build]_
  • Description: Creates a directory for the build, clones official or alternative Swift repositories from Github, kicks off processes to monitor system statistics, free disk space, and CPU temperature, and runs the Swift build script using either a long command line or a buildbot preset.
  • Statistics are saved in build directory as swift-build-{cputemp|df|vmstats}-DATE.
  • The output of the build is ‘installed’ into [build directory]//dest, and an installable archive is produced: [build directory]/swift-DATE.tar.gz.
#!/usr/bin/env bash

# Build open source Swift in a specified directory after cloning the appropriate Github repos.

# Select an alternative Github account (such as hpux735 for William Dillon's forks) to clone swift, swift-llvm, swift-lldb, and swift-corelibs-foundation repos from.
ALTREPO="apple"

# Interval for collecting vmstat, df, and CPU temperature data
STATINTERVAL=300

DATE=$(date +%F)

BUILDDIR=$(pwd)/$1

# Uncommment for a preset-based build
PRESET="buildbot_linux_armv7"
BUILDCOMMAND="swift/utils/build-script --preset=$PRESET install_destdir=$BUILDDIR/dest installable_package=$BUILDDIR/swift-$DATE.tar.gz"

# Uncomment to specify build script options individually
# BUILDCOMMAND="swift/utils/build-script --no-assertions --no-swift-stdlib-assertions --llbuild --xctest --lldb --release --foundation -- --swift-enable-ast-verifier=0 --install-swift --install-lldb --install-llbuild --install-xctest --install-foundation --install-prefix=/usr '--swift-install-components=compiler;clang-builtin-headers;stdlib;sdk-overlay;dev' --build-swift-static-stdlib=1 --skip-test-lldb=1 --install-destdir=$BUILDDIR/dest --installable-package=$BUILDDIR/swift-$DATE.tar.gz --reconfigure"

################################################################
# End of configuration
################################################################

################################################################
# Functions to clean things up on exit
################################################################
#
# We need to explicitly kill vmstat on Ctrl-C. Our loops will stop automatically
kill_vmstat()
{
	kill $VMSTATPID
	echo
	exit 130
}

# Shutdown processes collecting system statistics
# For our while loops we actually need to kill the subprocesses as well (see http://stackoverflow.com/a/4452488 )
kill_all_stats()
{
	DFCHILDPID=$(ps --ppid $DFPID -o pid --no-heading)
	CPUTEMPCHILDPID=$(ps --ppid $CPUTEMPPID -o pid --no-heading)
	kill $VMSTATPID $DFPID $DFCHILDPID $CPUTEMPPID $CPUTEMPCHILDPID
}
################################################################
# Script body
################################################################

# Some sanity checks
if [[ $# -eq 0 ]] ; then
	echo "Usage: $(basename $BASH_SOURCE) [build directory]"
	exit 1
fi

if [ -d $1 ]; then
	echo "Build directory already exists. Please specify a new directory."
	exit 1
fi

# Create build directory
echo "Creating build directory $BUILDDIR"
echo

mkdir -p $BUILDDIR/dest
cd $BUILDDIR

echo "ALTREPO: $ALTREPO"
echo
echo "BUILDCOMMAND:"
echo $BUILDCOMMAND
echo
echo "Starting build"
echo "--------------------"

# Start collecting statistics
vmstat $STATINTERVAL >> swift-build-vmstats-$DATE &
VMSTATPID=$!

(while df -h --output=avail / >> swift-build-df-$DATE; do sleep $STATINTERVAL; done; )&
DFPID=$!

(while cat /sys/class/thermal/thermal_zone0/temp >> swift-build-cputemp-$DATE; do sleep $STATINTERVAL; done; )&
CPUTEMPPID=$!

# Disown sub-processes so we don't get debugging messages when they're killed (see http://stackoverflow.com/a/23645819 )
disown $VMSTATPID $DFPID $CPUTEMPPID

# Make sure vmstat gets killed on Ctrl-C
trap kill_vmstat SIGINT

# Clone repos
git clone https://github.com/$ALTREPO/swift.git swift
git clone https://github.com/$ALTREPO/swift-llvm.git llvm
git clone https://github.com/apple/swift-clang.git clang
git clone https://github.com/$ALTREPO/swift-lldb.git lldb
git clone https://github.com/apple/swift-cmark.git cmark
git clone https://github.com/apple/swift-llbuild.git llbuild
git clone https://github.com/apple/swift-package-manager.git swiftpm
git clone https://github.com/apple/swift-corelibs-xctest.git
git clone https://github.com/$ALTREPO/swift-corelibs-foundation.git

time eval $BUILDCOMMAND

kill_all_stats

echo "Done!"