Compiling Swift from Source on the Raspberry PI

In late 2015, Swift was fully open sourced by Apple and hosted by GitHub. (you can find more info about both of these items on the Swift.org website and Apple’s Github.)

What this did was open up a lot of interesting opportunities and potential for a lot of people / projects / systems. I’m sure the first thing on a lot of people’s minds was… “will it run on X?”. Well the answer is… sure why not… Apple already provide ready-made packages for a few Linux variants and there are also ready-made packages out there for other platforms too, including android :o. There’s no fun in using a ready-made packages though right? if you’re insane enough, why not try to compile Swift on the Raspberry PI? Well thats what I did and here’s what I found out…

If you want to get a decent installation of Swift up and running, including the compiler, Foundation, stblib then the whole thing consists of 9 different git repo’s.

Initially I tried a Raspberry PI Zero ($5 Tiny Computer) running the latest Raspbian. Unfortunately, after trying a few times (with each cycle taking around 12 hours), I didn’t get very far at all. First I had to make some modifications to some of the repo compile time checks, then manually install newer versions of cmake / clang etc, try different compilation configurations etc… after which the PI Zero sadly didn’t have enough memory to get to the very end. So for the remainder of this post i’ll be using a Raspberry PI2 running the latest Ubuntu Mate image.

From here-on in, i’m gonna summarise a little, as getting this far took me a few days of hacking combined with trial and error, of which i’ll spare you the details.

 

Ubuntu Mate This is the OS you’re gonna need to load onto your microSD before continuing. You could try with Raspbian, but i’ve had mixed results. NOTE: this only works on armv7 based PI… so as of writing thats the Raspberry PI2.

A full clone of all repo’s you’ll need for Swift, as you’ll see below, a couple of the repo’s are not the official Apple ones, this is because they’ve had patches applied to them to aid in compilation on the Raspberry PI

UPDATE: 2017, You can now check-out all the repo’s directly from Apple and it will successfully compile as PI support has been merged in.

sudo apt-get install git -y
git clone https://github.com/apple/swift.git swift
git clone https://github.com/apple/swift-llvm.git llvm
git clone https://github.com/apple/swift-clang.git clang
git clone https://github.com/apple/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/apple/swift-corelibs-foundation.git

In case you still want to use the old repo’s, they’re here for reference.

sudo apt-get install git -y
git clone https://github.com/hpux735/swift.git swift
git clone https://github.com/apple/swift-llvm.git llvm
git clone https://github.com/apple/swift-clang.git clang
git clone https://github.com/hpux735/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/hpux735/swift-corelibs-foundation.git

Make sure to clone all of the above into the same parent folder, so you should end up with 9 different folders.

There are a few dependencies you will need to get the compilation going, along with a few others added in for your benefit, as you’ll need them immediately after.

sudo apt-get install build-essential cmake ninja-build clang python uuid-dev libicu48 libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config

Now comes the more nitty gritty part. You’re gonna need three resources for this compile. CPU, RAM and Disk Space. You can’t do a lot about CPU, however you can improve the RAM and Disk Space situation quite easily.

Assuming you haven’t already expanded your root filesystem to the extents of your microSD card, we’ll do this now using the easiest approach possible. There’s a neat little utility called raspi-config that is an aid to some of the common tasks you’ll need to do on your pi.

sudo apt-get install rasps-config -y

Now run it and choose “Expand Filesystem”, after you’ll see an option to change the Memory (RAM) Split between GPU and System, you’ll want to allocate as much as possible to the System for now, it’ll make the GUI a little sluggish but don’t worry about that for now… After you’ve changed the value reboot and thats it!

After all this, we still have a lack of RAM… likely around 1012MB (1024-12vmem) available. The compile of Swift will take a lot of memory to get things going, so we’re gonna enable a SWAP file. This essentially will allocate a portion of your microSD card for on-demand “RAM” that can be used when your actual RAM has ran out. Its very similar to how paging works on other platforms, but at the same time, completely different. The caveat is… SWAP on a microSD is very very slow, however you’ll have to make do.

sudo apt-get install dphys-swapfile

This will enable a file to be used for SWAP, usually on Linux you slice off a specific partition for this purpose, but as its only going to be temporary whilst we compile Swift, we’ll use our approach.

Now that all the above is complete, we’re ready to get on with compiling 🙂 We’re going to build a “release” configuration of Swift with no-assertions enabled, what this will do is greatly speed up the compile time (by around a factor of 2) whilst reducing the memory usage required. The trade-off is that you won’t have debug symbols or a great ability to poke around. For our needs, it’ll suffice.

From the parent folder you cloned the 9 repositories into, perform the following steps:

cd swift
utils/build-script -R --no-assertions

Now go and make a tea, watch a box-set of game of thrones and come back around 9 hours later… You’ll either find yourself with an Error, or a lovely compiled version of Swift on your Raspberry PI! If the latter is the case, lets take it for a spin!

~# nano helloworld.swift
  let message = "Hello World!"
  print(message)

hit (Ctrl+X)
hit (Y)

~# swiftc helloworld.swift

~# ./helloworld

Hello World!

Viola!

P.S I’m currently refining this post to add a script that performs all of the above.

Questions or comments, hit me up on Twitter @ArmstrongAtWork