Thursday, December 17, 2015

Swift runs on Linux... But what about my favourite distribution?

Swift is Open Source, you can install it on linux. Here is the instruction for an Ubuntu install. But wait... My favourite distribution is Fedora! Oh! Oh! Oh! I hear Santa Claus, I think it is time for a contribution: let's package Swift as a RPM!

TL;DR: Download Swift RPM from here

Building Swift on Fedora 23

Here is a summary of my journey in trying to build Swift on Fedora:
  • I've started with a brand new install of Fedora23. I've downloaded the ISO from here and I run the install on a Virtual Machine.
  • As stated in System Requirements, there is a list of dependencies to fetch:
    • for Ubuntu
    • cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config
    • which translates into Fedora platform:
    • cmake ninja-build clang python-devel libuuid-devel libicu-devel libbsd-devel libedit-devel libxml2-devel libsqlite3x-devel swig gcc-c++ pkgconfig
    Notice libncurses5_dev and icu-devtools are not needed for Fedora, they seem to be fetched already either by transitive dependencies or a default of the platform.
  • Clone Swift github repo as an entry point
  • git clone
    cd swift
    ./utils/update-checkout --clone
    Here I sticked to Swift documentation. update-checkout is a python script that will clone all the required repositories needed to build Swift from source. It will also make sure the directory structure matches the build's need. This is the directory structure you get:

    Notice how swift-lldb github repo matches lldb directory but swift-corelibs-foundation stays swift-corelibs-foundation :]
  • Install ninja
  • Ninja is the current recommended build system for building Swift. It turns out that ninja's little name on Fedora is ninja-build. But CMake calls it ninja, so I've symlinked ninja to point to ninja-build:
    dnf install -y ninja-build 
    sudo ln -s /usr/bin/ninja-build /usr/bin/ninja
  • Launch the build:
  • ./utils/build-script -t
    This is a basic build which will end up with binaries not packaged. Be aware that the build can be quite intensive on memory, I had my build crashed a couple of times. I had to restart it, but thanks goodness, it's an incremental build. On success, go to ../build/Ninja-DebugAssert/swift-linux-x86_64/bin, you'll find swiftc and you can write your first swift code but... This Swift runtime is missing lots of components. For example, to build foundation:
    ./utils/build-script -l -b -p --foundation
    and so on...
    There must be a better way! When in doubt, use the help command is my mantra. I found this statement about preset mode. Using buildbot_linux preset made the trick! Thanks man.

Packaging in RPM

My next step was to nicely packaged Swift into an RPM for any given Swift tag. I have to confess that I'm quite new to RPM packaging ;) So I get inspired by existing RPM like ninja-build. Besides, there is tons of documentation. I've used quite a lot.

While installing, the main issue I faced was: in Fedora, python2.7 is installed in /usr/lib64 and the CMakeList.txt is looking in lib, I workaround the issue by overriding lldb/scripts/CMakeLists.txt just before building and installing. Thanks sed. There might be better ways, I will look into making a PR to swift-lldb.

Eventually I come up with this repo:
RPM can be directly downloading from release tab.

Running Swift RPM

Last but not least, to test the RPM, I've installed a brand new Fedora VM and run the following command:
sudo dnf install libbsd python gcc-c++ clang
sudo rpm -Uvh swift-2.2-SNAPSHOT20151210a.x86_64.rpm
You want to see it in action?
Clone a swift repo, I used Swifter. Run:
git clone
cd swifter
swift build

The end

I hope you've enjoyed my blog post. Feel free to contribute to the Swift RPM repo. Let's make Fedora and Swift best friends.