Daily Archives: December 12, 2015

Building Open Source Swift

Swift 3.0 Linux X86

Editor’s note: If you’re looking for a quick way to start working with Swift 3.0 now, try out our apt-get repository for Trusty Tahr, Wily Werewolf, and Xenial Xerus.

It’s been a little over six months since Apple released its Swift language into the open source community. Since then its various repositories have quickly climbed into the trending pages on Github. The projects are moving fast with thousands of commits a week and features being implemented on a daily basis. While one can certainly download the official SNAPSHOT release from the Swift downloads page, to stay on the bleeding edge you’ll want to learn how to compile your own release.

Getting Started

To effectively work with building Swift from the Github repositories you’re going to need a system with a decent amount of CPU and RAM. I’m personally using an 8-core desktop with 8G of RAM. In addition I suggest compiling against an SSD drive with an EXT4 filesystem. While I trust my long term data storage to ZFS with deduplication, I don’t want to compile against it.

Note: We’re using Ubuntu 15.10, and Apple also supports 14.04 and now 16.04. I haven’t even tried building on a pure Debian release or RedHat installation.

First, let’s install some prerequisites:

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

If you are on Ubuntu 14.04 you will also need to upgrade to Clang 3.6 and upgrade CMake to 3.4.3. Let’s start with getting clang-3.6:

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

Now we need to check out (sorry, clone) all of the repositories needed to “build Swift”. Fortunately the base swift repository contains an update-checkout script that will clone all of the repositories required:

# mkdir apple # You will want to do this where you have at least 4-6G of free space
# cd apple
# git clone https://github.com/apple/swift.git swift
# ./swift/utils/update-checkout --clone


While not quite as bad as building the Linux kernel, compiling Swift does take a while, particularly the first time. On my system it took roughly 40 minutes to compile and package everything. Rebuilding after updating the repository contents took around 7 minutes with no changes to the source, with most of that time spent executing the post-build testcases.

We’re going to use the buildbot_linux preset for the swift/utils/build-script utility. The preset is defined in build-presets.ini. Here you can see that it goes through specific build and install stages:

Here we go! In your ~/apple directory, or whereever you checked out all of the repositories:

./swift/utils/build-script --preset=buildbot_linux_1510 install_destdir=/tmp/install installable_package=/tmp/swift.tar.gz

You’ll notice our exact preset was buildbot_linux_1510, which for the time being is an alias to buildbot_linux. If you are building on an Ubuntu 16.04 system you can use builtbot_linux_1604. If you prefer you can also choose a different install_destdir and installable_package.

The output of the packaging step is a standard /usr/ directory layout with:

/usr/bin The swift compiler, lldb debugger, and various other tools get put here.
/usr/include For now this contains only lldb include headers.
/usr/lib All of the libraries, shared and static, that make up the Swift environment are here. For example, libFoundation.so, libswiftCore.so, etc.
/usr/local The packaging builtbot creates this directory but nothing lies within.
/usr/share For now a single man page is included! Go ahead, try it out with man swift.

To test out your new Swift compiler:

cd /tmp/install
./usr/bin/swift --version
Swift version 3.0-dev (LLVM 7bae82deaa, Clang 4b3278bec5, Swift 0cc49187bb)
Target: x86_64-unknown-linux-gnu

The 3.0-dev information is baked into the source code in Version.cpp by gleaning the information from CMakeLists.txt. The hex strings for LLVM, Clang, and Swift are, you guessed it, the git hash that the binary was built from.

Swift man page
Swift man page

Updating and Rebuilding

To keep current with the latest submissions to the repositories you can use the update-checkout helper script:

./swift/utils/update-checkout --all

After updating to rebuild (without cleaning) use the previous command:

./swift/utils/build-script --preset=buildbot_linux_1510 install_destdir=/tmp/install installable_package=/tmp/swift.tar.gz

To run a distclean of sorts just remove the build/buildbot_linux directory that was created in your top-level directory, or you can selectively remove subdirectories within buildbot_linux to retrigger a build of that component. For example, if we want to clean out the artifacts for Foundation and the Swift Package Manager and then rebuild:

rm -rf build/buildbot_linux/foundation-linux-x86_64 build/buildbot_linux/swiftpm-linux-x86_64
./swift/utils/build-script --preset=buildbot_linux_1404 install_destdir=/tmp/install installable_package=/tmp/swift.tar.gz


I am a fan of using the /opt/vendor directory structure for vendor packages. Once the build is complete you can use rsync to get it placed in an appropriate directory.

sudo rsync -a /tmp/install/ /opt/swift/swift-3.0/

Note: If you aren’t familiar with rsync be aware that trailing slashes are important!

Update your PATH to include /opt/swift/swift-3.0/usr/bin and you should be good to go! Try out your own personal Swift build with the Swift Package Manager.

Get the Code

We’ve included some helper scripts on Github.

# git clone https://github.com/iachievedit/package-swift

Start with running get.sh to clone all of the required Github repositories. Then for your first build, run package.sh and go watch an episode Walking Dead or Game of Thrones. When you get back you should have an install directory with your own version of Swift.

To refresh your sources run update.sh and then rebuild with package.sh.

A Look at the BeagleBoard X15

First things first, don’t call it the BeagleBone X15! This is a BeagleBoard. Affectionately named “The Beast” by its creators, the BeagleBoard X15 is a powerful ARM-based desktop computing/multimedia device. With an MSRP of $239 it provides more CPU horsepower, more RAM, and a large assortment of IO peripherals.

The Beast
The Beast

For example, the BeagleBone Black comes with a single USB2.0 port. The X15 is equipped with 3 USB 3.0 host ports, 1 USB 2.0 host port, and 1 USB 2.0 client port. In addition while devices such as Raspberry Pi and Black have a single 10/100 Ethernet connector, the X15 comes with 2 Gigabit RJ45 ports. When you’re moving data across the network (say, downloading the Linux kernel or copying release image files), that extra bandwidth comes in quite handy.

But wait, there’s more! The X15 comes packed with a lot of computing power thanks to its Texas Instruments Sitara AM5728 dual-core ARM Cortex-A15 clocked at 1.5GHz. Combine that with 2GB of RAM and you’ve got a beefy little machine.

But enough about the precise specifications, you can read all of those here. Let’s make sure we talk about what the BeagleBoard X15 is not. It isn’t a Raspberry Pi and it isn’t a BeagleBone Black, and it definitely isn’t an Arduino. What you won’t find on this board are GPIO headers to turn LEDs off and on, run lines out to play with SPI or I2C devices, or connect capes (also referred to as shields by the Arduino folks). There are expansion slots available on the underside of the board which can be used to add PCIe, LCD, and mSATA connections, but the design as it stands doesn’t appear to be for quickly prototyping circuits like with Arduino, Pi, and BeagleBone.

Serial Console

The X15 does have a standard serial port header for connecting something like a Serial FTDI cable. The ground (black) pin is towards the 12V barrel connector. The standard serial connection settings 115200,8,N,1 apply. Having this connection is handy if you are working with the X15 boot loader U-Boot.


USB2.0 Port

There’s also a USB 2.0 port hiding next to the Ethernet connector. It’s actually a eSATA/USB hybrid port, so if you need to connect another USB device and don’t need the eSATA port, connect it here.


Flashing the X15

Like the BeagleBone and other ARM development boards, the X15 also comes with a 4GB eMMC so you can flash a bootable image to it. To do so, head over to the X15 Weekly builds and download an image. The process for flashing the X15 is similar to that of the BeagleBone Black.

Although there are two images (flasher and non-flasher) posted, they are the same with one exception: the contents of /boot/uEnv.txt. The flasher image has the following in its uEnv.txt:

As with the BeagleBone, you can turn a non-flasher load into a flasher by uncommenting the cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh line in /boot/uEnv.txt. I highly recommend you cabling up to the serial port if you make it a habit of flashing your board; it greatly aids in debugging and learning how the flashing process works.


Now let’s turn to everyone’s favorite method of determining the capabilities of a new computing device, benchmarks. I’m going to be using the sysbench application and running a CPU test for the BeagleBoard X15, BeagleBone Black, and a Wandboard Quad. The sysbench CPU test verifies prime numbers using the trial division method. By default it will verify primes up to 10,000.

System –num-threads total time total time taken by event execution
BeagleBone Black 1 286.4899s 286.4704
BeagleBoard X15 1 112.2594s 112.2518
Wandboard Quad 1 228.2226s 228.2110
BeagleBoard X15 2 56.5488s 113.0862
Wandboard Quad 4 57.1758s 228.6204

Now I will confess, I always have to take a moment and reread the definition of “total time taken by event execution”. When the number of threads equals 1 total time and total time taken by event execution should be roughly the same. For multicore systems one should utilize the cores by specifying the number of threads to be the same as the number of cores. So, for the X15, we use 2 threads, and likewise, for the Wandboard Quad, we use 4. The results are interesting in that the X15 doesn’t really perform much better than the Wandboard Quad for this benchmark when all cores are utilized. You can see however that one X15 core head-to-head with one Wandboard Quad core, the Cortex-A15 performs much better than the A9.

This is, of course, all academic and doesn’t represent a real-world test. Next up, let’s look at compiling with the X15!

Compiling with the X15

If you’ve ever tried cross-compiling for an ARM-based system, you know first hand it’s less than ideal. Getting a cross-compiling toolchain, building it, ensuring you have all of the right libraries on your host system to compile for the target. Though we’ve been cross-compiling for decades, it is still a pain. So along comes a device like the BeagleBone Black and you think, hey, I could compile my ARM binaries with this! Yes, you could, but you could also get from New York to LA on horseback. The fact is for compiling, both the RaspberryPi, BeagleBone Black, and other “credit-card sized” computers are woefully inadequate for the task.

When originally faced with having to frequently compile ARM packages, whether they be the Linux kernel or something like OpenCV, I turned to the Wandboard QUAD. Make no mistake, this board is no slouch. With a quadcore Cortex-A9 processor the Wandboard Quad is certainly going to have an easier time compiling than a Raspberry Pi or a BeagleBone Black. In fact, it’s a good reference to benchmark against the X15.

Unfortunately it’s a little difficult to get a side-by-side comparison with the Wandboard Quad because of the differences in IO. For example, let’s say we compiled OpenCV on the Quad with the source being on an NFS mount. Well, the Quad has only 100Mb Ethernet, whereas the X15 has 1000Mb. This in and of itself can make a difference. If we compiled the code onto a USB flash drive, the Quad is limited to USB2.0 vs. the X15s USB3.0.

Rather than wring our hands over getting an apples to apples comparison we’re going to use the MicroSD filesystem on the Quad and write to a Class10 microSD on the X15. It should be noted here that both SD cards are Class 10 “high speed” cards.

Our benchmark is going to be straightforward, taking time of make on both systems. For the Quad we’ll use make -j4, and for the X15 we’ll use make -j2. Neither system is running anything taxing in the background, but we didn’t go and specifically turn off every background daemon. No one does that in the real world so why hold up a benchmark that is contrived?

The verdict? The dual-core X15 compiled OpenCV 3.0.0 in 40 minutes compared to around 49 minutes with the Wandboard Quad. Now, this was with compiling on the X15 on the microSD card. I switched the X15 over to using a USB3.0 mass storage drive and compiled OpenCV from scratch in about 36 minutes. As someone who has, in previous lives, been responsible for managing the builds of multiple environments, I can say that every minute you can shave off makes a big difference in your release cycle velocity. Invest in a lot of cores and the fastest disk you can afford, preferably SSD!

What About Other Uses?

Q. How’s the performance as a desktop environment? Can I run LibreOffice and Gimp?
A. I have been using the BeagleBoard X15 as a headless build server, and will likely continue to do so.

Q. What about running Android?
A. I know some folks use these higher-end ARM boards for Android development. I haven’t done enough Android development to write with any authority on the X15’s suitability. I have to believe given the horsepower the 1.5GHz Cortex-A15 brings though it should be a great platform for Android development.

Q. What about the PRUs and DSPs?
A. Confession time: I’ve never used the programmable realtime units (PRUs) on the BeagleBone Black, and I haven’t had any need for DSP processing in my applications. However if you do have a need, the X15 has you covered with:

  • 4 PRUs
  • 2 TI C66x DSPs

With these capabilities the X15 is sure to find its way into automation controls, signal acquisition, audiovisual compression and processing applications, and anything else that benefits from these subsystems.

It’s Getting Toasty in Here

Due to the laws of physics there’s a price to pay for the extra power packed into the X15: heat. This board gets hot. In fact, the processor itself sits underneath a heat sink, and the board was designed to accommodate a fan.

If you install the lm-sensors package you can run sensors and view several thermal management attributes:

  • the status of the fan
  • the temperature as reported by the OMAP I2C temperature sensor
  • the temperature as reported by the DSPEVE and IVA thermal zones

Without a fan of some sort the I2C temperature sensor hovers around 57-60 C while the CPU is, for the most part, idle. However, once you crank up the workload it can quickly soar! In this graph the CPU was idle and then I built OpenCV utilizing make -j2:


Once the CPU reached 75 C I hit the switch on a little desk fan. This serves to cool it down to around 35 C even under 100% CPU utilization.

It remains to be seen the types of enclosures that will be developed for the X15. If you’re using it on your desk as a build machine there’s probably no need for one. But when using this board let’s just say, don’t touch the heat sink if you aren’t cooling it off with something.

Final Thoughts

The BeagleBoard X15 is an impressive system that packs a punch in terms of CPU, RAM, and IO peripheral support. Combine that with its additional digital signal processing capabilities and programmable real-time units, and it is sure to find its way into a lot of applications. For myself, I’ve been using it for compiling software packages and couldn’t be happier. Plus, I’m itching to get a Swift on the BeagleBone! post written.