Software Development Tips and Tricks


Xenial Xerus Ethernet Fixup for the Raspberry Pi

Xenial Xerus has a peculiar bug that can cause a Raspberry Pi to lose Ethernet connectivity after a reboot. Several individuals noticed it after an apt-get update && apt-get -y upgrade while following instructions for building Swift on a Pi 3.

To fix this, power down the Pi, remove the microSD card and reinsert it into another system and then mount the Pi filesystem with something like:

# mkdir pifs
# mount /dev/sdX2 pifs

where X depends on where your microSD was mapped. I turn to dmesg|tail to find this:

[6099875.497524] usb-storage 2-4:1.0: USB Mass Storage device detected
[6099875.497771] scsi host21: usb-storage 2-4:1.0
[6099876.498806] scsi 21:0:0:0: Direct-Access     Generic  STORAGE DEVICE   0817 PQ: 0 ANSI: 6
[6099876.499682] sd 21:0:0:0: Attached scsi generic sg8 type 0
[6099876.832189] sd 21:0:0:0: [sdi] 31293440 512-byte logical blocks: (16.0 GB/14.9 GiB)
[6099876.833257] sd 21:0:0:0: [sdi] Write Protect is off
[6099876.833266] sd 21:0:0:0: [sdi] Mode Sense: 23 00 00 00
[6099876.834375] sd 21:0:0:0: [sdi] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[6099876.840573]  sdi: sdi1 sdi2
[6099876.845072] sd 21:0:0:0: [sdi] Attached SCSI removable disk

In this case /dev/sdi2 is used.

Once your filesystem is mounted navigate over to the Pi’s /var/log/ directory:

# mount /dev/sdX2 pifs
# cd pifs/var/log

Using grep -a, search for the phrase renamed from in syslog:

root@darthvader:/tmp/pifs/var/log# grep -a "renamed from" syslog
Sep  4 21:59:59 ubuntu kernel: [    5.533471] smsc95xx 1-1.1:1.0 enxb827eb9721d5: renamed from eth0

Notice the new Ethernet device name enxb827eb9721d5. Now go to the /etc/network/interfaces.d/ directory on the Pi filesystem:

root@darthvader:/tmp/pifs/var/log# cd ../../
root@darthvader:/tmp/pifs# cd etc/network/interfaces.d/

Edit 50-cloud-init.cfg and replace instances of eth0 with the new device name enxb827eb9721d5:

# cat 50-cloud-init.cfg
auto lo
iface lo inet loopback

auto enxb827eb9721d5
iface enxb827eb9721d5 inet dhcp

Unmount the filesystem:

# cd /tmp/
# umount pifs

Return the microSD card to the Pi and reapply power. Your Pi’s Ethernet should now be available.

A special thanks to @tjw for providing clues to the fix for this issue!


Building Swift 3.0 on a Raspberry Pi 3

Swift 3.0 Swift 3.0 Swift 3.0

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 swift-corelibs-libdispatch).

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:

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.

Install Xenial

We will not be using Raspbian here, but rather Ubuntu Xenial. Obtain Xenial with curl or wget and then write the filesystem out to your microSD card with dd.

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).

Using Linux

# 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 /dev/sdh.

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/rYOUR_DEVICE. Using /dev/YOUR_DEVICE can be painfully slow, as explained here.

To find 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 diskutil and 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 wget, xzcat, and dd commands are a critical part of your toolbox. Get comfortable with them.

Update Xenial

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 ubuntu@ubuntu.local first, but if that fails use your router LAN page to determine the IP address. The default password is ubuntu.

# ssh ubuntu@
The authenticity of host ' (' 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 '' (ECDSA) to the list of known hosts.
ubuntu@'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 htop (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.

Use package-swift

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

By default 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 pull to get the latest patchset
  • package.sh – Runs the Swift build-script with a preset named buildbot_linux_armv7.

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 get.sh and update.sh scripts in that they detect we are building on a ARMv7 processor and thus need William Dillon’s swift-llvm fork.

Let’s Do This

Remember to make sure you have:

  • installed all of the prerequisite packages
  • enabled 1GB of swap space
  • cloned package-swift from Github

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.

# ./patch.sh

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 PATH with export PATH=/opt/swift/swift-3.0/usr/bin:$PATH. To properly use swiftc and 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

Getting Help

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 admin@iachieved.it 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.


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.