Software Development Tips and Tricks


Swift 3.0 for Ubuntu 16.04 Xenial Xerus

Swift 3.0

In our zeal to get Swift 3.0 on as many Linux systems as possible we went ahead and got a jumpstart on building for Ubuntu 16.04, also known as Xenial Xerus, for X86 systems. Installation is as easy as using our APT repository with apt-get. Binaries are installed into /opt/swift/swift-3.0, so you will need to update your path after installing the 3.0 package. Editor’s note: For the rationale as to why we use /opt/swift rather than /usr/bin/, see this thread on the swift-dev mailing list.

1. Add the repository key

wget -qO- http://dev.iachieved.it/iachievedit.gpg.key | sudo apt-key add -

2. Add the Xenial repository to sources.list

echo "deb http://iachievedit-repos.s3.amazonaws.com/ xenial main" | sudo tee --append /etc/apt/sources.list

3. Run apt-get update

sudo apt-get update

4. Install swift-3.0!

sudo apt-get install swift-3.0

5. Update that PATH!

export PATH=/opt/swift/swift-3.0/usr/bin:$PATH

6. Try it out

git clone https://github.com/apple/example-package-dealer
cd example-packager-dealer
swift build
Compiling Swift Module 'FisherYates' (1 sources)
Linking Library:  .build/debug/FisherYates.a
Compiling Swift Module 'PlayingCard' (3 sources)
Linking Library:  .build/debug/PlayingCard.a
Compiling Swift Module 'DeckOfPlayingCards' (1 sources)
Linking Library:  .build/debug/DeckOfPlayingCards.a
Compiling Swift Module 'Dealer' (1 sources)
Linking Executable:  .build/debug/Dealer

Run it!



Q. Did Apple build these binaries?
A. No, I built them on my personal server using the instructions I posted here.

Q. What git revisions are included in the build?
A. You can use apt-cache show swift-3.0 to see this information. For example:

# apt-cache show swift-3.0
Package: swift-3.0
Conflicts: swift-2.2
Version: 1:3.0-0ubuntu10+xenial1
Architecture: amd64
Installed-Size: 370463
Maintainer: iachievedit (support@iachieved.it)
Depends: clang (>= 3.6), libicu-dev
Homepage: http://dev.iachieved.it/iachievedit/swift
Priority: optional
Section: development
Filename: pool/main/s/swift-3.0/swift-3.0_3.0-0ubuntu10+xenial1_amd64.deb
Size: 72513864
SHA256: b1bf548f353466ea72696089a8b666956a2603edb467eb0517e858eb1ba86511
SHA1: 5dd02b14d21f2e821040de3bb1052561653fcfcd
MD5sum: f2c3d3b9517a303cc86558b6c560a8d6
Description: Open Source Swift
 This is a packaged version of Open Source Swift 3.0 built from
 the following git revisions of the Apple Github repositories:
       Clang:  460d629e85
        LLVM:  8d0086ac3e
       Swift:  1abe85ab41
  Foundation:  4c15543f82
Description-md5: a6b1dd247c7584b61692a101d9d0e5fa

The source tree is untouched for each build.

Q. Do you test the binaries before you upload them?
A. The Swift build process tests the resulting binaries, and I then do run some basic tests and compile my own applications, but there is currently no separate exhaustive test suite.

Q. Are you releasing builds on a set schedule?
A. Not really, though I may try to stay in sync with the releases from Apple. The idea was to get something out for folks to experiment with and start coding Swift on Linux.

Q. Where is everything installed?
A. Everything gets put in /opt/swift/swift-3.0/usr.

Q. How do I decipher the package version number?
A. This was my first take on what I thought should be an appropriate package version number. Breaking it down, 3.0-0ubuntu10+xenial1 should be:

  • 3.0 is the version of Swift that is packaged
  • -0ubuntu10 indicates that this is the 2nd package for Ubuntu, with the 0 indicating that there is no upstream Debian package upon which this package was based
  • +xenial1 indicates that this package is for Xenial Xerus

I think I got that right, but if you feel otherwise please do drop me a line at support@iachieved.it.

How Does This Work?

I used these awesome instructions on how to host a Debian package repository on Amazon S3. I tried to set up a Launchpad PPA, but quite frankly, got tired of trying to wade through all the metadata required to put together a simple package. I’m sure for hosting distribution repositories it’s all required, but for this it felt like overkill. The folks that develop fpm also have some choice things to say about it.

The packaging scripts we use to build everything and upload to the repository can be found Github. For Swift 3.0 make sure and look at the swift-3.0 branch.


Swift 3.0 on Raspberry Pi 2 and 3

Swift 3.0 Swift 3.0 Swift 3.0

There are a number of people working to bring Swift 3.0 to as many ARM-based systems as possible. This article is specifically about getting Swift 3.0 for your Raspberry Pi 2 or Raspberry Pi 3 that is running Ubuntu 16 (Xenial Xerus). It has not been tested for Raspbian variants (and likely doesn’t work).

A fair warning: support for Swift 3.0 on the Raspberry Pi (and all ARM devices) is still beta. Use it for prototyping and proof-on-concept work rather than building a product with it. Also, if you’re interested in joining the community of folks working on getting Swift 3.0 for ARM devices, come join us on Slack!

Xenial on a Raspberry Pi

You might not have even known Xenial for the Raspberry Pi existed; I didn’t! To grab it head over to the Ubuntu Wiki and get the distribution for your Pi. You will want to use at least an 8G SD card.

Install Swift 3.0

The team working on Swift for ARM is using Jenkins to build the Raspberry Pi binaries natively on a Raspberry Pi 3. As in, this is the build machine!

Swift 3.0 Build Machine

Swift 3.0 Build Machine

For the curious check out the Jenkins build project. Quite frankly, I’m amazed that it only took 6 hours to compile Swift.

Now, on your Raspberry Pi, grab and extract the Swift 3.0 build artifact into a directory and set your PATH with something like:

Note: You aren’t tied to putting Swift 3.0 in $HOME, I typically use /opt/swift/swift-3.0.

Now, let’s give it a spin!

Create a file called helloWorld.swift:

You can use swift helloWorld.swift to execute the file like a script:

# swift helloWorld.swift
Hello, world!

Or, you can compile the file into an executable with swiftc if you have clang installed and configured properly:

# swiftc helloWorld.swift
# ./helloWorld
Hello world!

If swiftc failed with error: link command failed with exit code 127 there’s a good chance you don’t have clang installed and configured properly:

sudo apt-get update
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

Let’s look at a few other tidbits:

Importing Glibc works!


Compile (swiftc swiftcat.swift) and run (swiftcat)!

Bridging to C routines

Linking against compiled object files works!




Compile and link everything together:

# clang -c escapetext.c
# swiftc -c escapeswift.swift -import-objc-header escapetext.h
# swiftc escapeswift.o escapetext.o -o escapeswift -lcurl

And run:

# ./escapeswift "foo > bar"
Escaped text:  foo%20%3E%20bar

Swift Package Manager

Unless you enjoy writing makefiles and build scripts (and trust me, some do), the Swift Package Manager is here to help manage software package dependencies. We’ll be writing more about the SwiftPM available in Swift 3.0, but are excited to provide a version that works on armv7 devices. Try this out:

# mkdir finalCountdown && cd finalCountdown
# swift package init --type executable
Creating executable package: finalCountdown
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/

Replace the contents of Sources/main.swift with

Now, run swift build to build your finalCountdown application:

# swift build
Compile Swift Module 'finalCountdown' (1 sources)
Linking .build/debug/finalCountdown
# .build/debug/finalCountdown
Entering thread
Exiting thread


For a random smattering of Swift 3.0 applications that have been run on both x86 and armv7 systems, check out the moreswift swift-3.0 branch.

What Version Is This?

The current builds available are not tracking the Swift 3.0 preview builds. To determine the Git hashes associated with the swift binary, type swift --version:

# swift --version
Swift version 3.0-dev (LLVM eb140647a6, Clang a9f2183da4, Swift bb43874ba1)

You can then, if you so choose go directly to the Swift repository commit with something like https://github.com/apple/swift/tree/bb43874ba1 to see the history beginning with the last commit incorporated into the build.


A lot of people have been apart of the effort to bring Swift to Linux ARM devices. This list is just a few of those individuals. Please do visit their blogs; there is a wealth of information and learnings therein.