Building Swift 3.0 on a Raspberry Pi 3
9/24/2016 Update: See our latest post on building Swift 3.0 on ARMv7 systems such as the Pi 3.
Editor’s Note: This post was updated on 9/4/2016 to reflect the recent updates for Swift 3.0 (in particular it now includes the build of
A number of folks have expressed interest in building Swift 3.0 on their own Raspberry Pi 3. These instructions are for those brave souls who want to do so!
To get started you’re going to need:
- a Raspberry Pi 3
- a UHS-I/class 10 microSD card with a capacity of 16GB or greater (I like the Patriot EP Series for the price combined with relatively high write speeds)
- Ubuntu Xenial 16.04
Note that this can be done; we’ve done it, and there are group of folks dedicated to working with Swift on ARM-based devices. Don’t give up. If you do decide to give up we aren’t ones to judge, just head over and download our prebuilt Swift 3.0 package for the Raspberry Pi 2 and 3.
We will not be using Raspbian here, but rather Ubuntu Xenial. Obtain Xenial with
wget and then write the filesystem out to your microSD card with
Note: You’ve read this warning before I’m sure, but it is critical that you put in the right device name where we reference
YOUR_DEVICE below. Failure to do so could destroy your data (they don’t call
dd disk destroyer for nothing).
# wget http://www.finnie.org/software/raspberrypi/ubuntu-rpi3/ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz # xzcat ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz | sudo dd of=/dev/YOUR_DEVICE bs=8M
To find your
YOUR_DEVICE insert the microSD into your Linux machine and run
dmesg|tail to see something like
[1255451.544316] usb-storage 4-2:1.0: USB Mass Storage device detected [1255451.544466] scsi host25: usb-storage 4-2:1.0 [1255452.545332] scsi 25:0:0:0: Direct-Access Generic STORAGE DEVICE 0817 PQ: 0 ANSI: 6 [1255452.545670] sd 25:0:0:0: Attached scsi generic sg8 type 0 [1255452.828405] sd 25:0:0:0: [sdh] 15523840 512-byte logical blocks: (7.94 GB/7.40 GiB) [1255452.829402] sd 25:0:0:0: [sdh] Write Protect is off [1255452.829409] sd 25:0:0:0: [sdh] Mode Sense: 23 00 00 00 [1255452.830400] sd 25:0:0:0: [sdh] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA [1255452.835967] sdh: sdh1 [1255452.840401] sd 25:0:0:0: [sdh] Attached SCSI removable disk
In this example your device is
Using OS X (macOS)
I personally prefer to use a separate Linux server for these types of operations, but you can use a Mac as well with homebrew:
# brew install wget xz # wget http://www.finnie.org/software/raspberrypi/ubuntu-rpi3/ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz # xzcat ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz|sudo dd of=/dev/rdisk3 bs=8m
Note when using
dd on the Mac its advisable to use
/dev/YOUR_DEVICE can be painfully slow, as explained here.
YOUR_DEVICE on a Mac, insert the microSD and run
diskutil list in a terminal. Look for the disk that that matches your SD card size (if you have other attached drives of the same size look also at its other attributes to ensure you are using the right one).
# diskutil list ... /dev/disk5 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *16.0 GB disk5 1: Windows_FAT_32 system-boot 134.2 MB disk5s1 2: Linux 15.9 GB disk5s2
If you are nervous about the steps with
dd, read this walkthrough to gain some confidence. As an aside, if you’re going to make a habit out of working with the Raspberry Pi the
dd commands are a critical part of your toolbox. Get comfortable with them.
Now that you have Xenial written to the microSD card, insert it into the Raspberry Pi 3 and power up! And yes, we’re assuming you have an Ethernet cable attached or you have network connectivity through the miniUSB. You can try to
ssh into the Pi with
ssh firstname.lastname@example.org first, but if that fails use your router LAN page to determine the IP address. The default password is
# ssh email@example.com The authenticity of host '192.168.1.115 (192.168.1.115)' can't be established. ECDSA key fingerprint is 62:e9:f9:09:d0:30:3c:c9:0e:47:a3:42:f5:2c:e2:ae. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.1.115' (ECDSA) to the list of known hosts. firstname.lastname@example.org's password: You are required to change your password immediately (root enforced) Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-1009-raspi2 armv7l) ... WARNING: Your password has expired. You must change your password now and login again! Changing password for ubuntu. (current) UNIX password:
Once you’ve changed your password log back in with the
ubuntu user (and your new password) and update the system with
sudo apt-get update.
Warning: Previous versions of this post suggested running
sudo apt-get upgrade -y as well. See the comments below for the workarounds if you cannot login via Ethernet afterwards.
Install Build Prerequisites
Compiling Swift requires a number of prerequisites. Get them in one fell swoop with:
# sudo apt-get install -y git cmake ninja-build clang uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config autoconf libtool systemtap-sdt-dev libcurl4-openssl-dev
Fortunately we didn’t have to discover the prerequisites iteratively (you know, when you download a repository and try to build it and discover what the prerequisites are, one at a time) because they are outlined in the Open Source Swift README.
I also like to include
sudo apt-get install -y htop) so I can see the Pi compile it’s little heart out:
Add Some Swap
While the Pi 3 does come with an impressive 1GB of RAM, that is still not enough to build Swift from beginning to end (it’s the linking steps that usually get us into trouble). Let’s add some swap to double that amount:
# cd /var/cache # sudo mkdir swap # cd swap # sudo fallocate -l 1G 1G.swap # sudo mkswap 1G.swap Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes) no label, UUID=184d002a-2f15-4b23-8360-8e792badc6a2 # sudo chmod 600 1G.swap # sudo swapon 1G.swap
Here’s an example of what happens when you don’t have swap enabled:
cd /root/workspace/Swift-3.0-Pi3-ARM-Incremental/build/buildbot_linux/swift-linux-armv7/bin && /usr/bin/cmake -E create_symlink swift swiftc && cd /root/workspace/Swift-3.0-Pi3-ARM-Incremental/build/buildbot_linux/swift-linux-armv7/bin && /usr/bin/cmake -E create_symlink swift swift-autolink-extract clang: error: unable to execute command: Killed clang: error: linker command failed due to signal (use -v to see invocation) ninja: build stopped: subcommand failed. ./swift/utils/build-script: fatal error: command terminated with a non-zero exit status 1, aborting
Doubling the amount of your Pi’s RAM with swap space that’s on a microSD card is not something you would typically do. Once we do hit the build phases that require us to dip into swap things will slow down, but the alternative is to crash with an out-of-memory error.
package-swift is our Github repository that has several helper scripts to make life a little easier building Swift.
# git clone https://github.com/iachievedit/package-swift # cd package-swift
package-swift will check out to the
swift-3.0 branch. This branch contains important patches needed to properly build Swift for ARM (to see them take a look in
patches/armv7, they are organized by the various repos they patch).
The scripts are pretty simple:
get.sh– Downloads all of the required repositories for building Swift
update.sh– Updates all of your local repositories with the latest on Github.
patch.sh– Applies any patches that the Swift on ARM team has put forward; from time to time we have to apply patches to get things working. Once a patch is no longer necessary we remove it, so before performing the actual build you will want to
git pullto get the latest patchset
package.sh– Runs the Swift
build-scriptwith a preset named
I suggest you look at each shell script and walk through the logic before executing. They are straightforward but it’s worth the time understanding what they are doing. Pay particular attention to the
update.sh scripts in that they detect we are building on a ARMv7 processor and thus need William Dillon’s
Let’s Do This
Remember to make sure you have:
- installed all of the prerequisite packages
- enabled 1GB of swap space
Now, clone all of the required repositories:
# cd package-swift # ./get.sh
On my SD card this step took about 15 minutes to download and write everything.
Next, apply patches. It is important to do the step to pick up patches that the Swift on ARM team has developed and tested. From time to time these patches change so make sure and pick up the latest.
Now, compile. The Swift on ARM team uses Jenkins to run this in a headless build job, but if you use
nohup to ensure your compile continues even if the terminal detaches you should be fine:
# nohup ./package.sh > swiftbuild.log&
To watch the output of the build use
tail -F swiftbuild.log.
Now, be prepared to wait! A clean build of Swift on a Raspberry Pi 3 can take upwards of 6 hours. The reward is well worth it, however, and that is a
swift.tar.gz bundle that can be installed on either a Raspberry Pi 2 or Pi 3 running Ubuntu Xenial (do not try to install this on a Raspbian machine, you will be sorry). I like to install Swift in
/opt/swift/ like so:
# cd /opt # mkdir -p swift/swift-3.0 # cd swift/swift-3.0 # tar -xzvf /path/to/swift.tar.gz
You can then set your
export PATH=/opt/swift/swift-3.0/usr/bin:$PATH. To properly use
swift build you will also need to run the following commands:
sudo apt-get install -y libicu-dev sudo apt-get install -y clang-3.6 sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100 sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100
There is a high likelihood that your build will fail the first time. In fact, it is possible that builds for ARM devices such as the Raspberry Pi 2 and 3 will be failing for days until someone is available to fix them. If you are having trouble compiling please feel free to send an e-mail to
email@example.com to get invited to the Swift for ARM Slack community.
I should probably put up a separate page just for this; a number of folks have been instrumental in getting Swift going on ARM devices. Folks like PJ have blazed the trail building Swift for the Raspberry Pi 1, and no article on Swift on the Pi is complete without mentioning William Dillon’s work.