Setting up a Swift Development Environment

Over the holidays I thought I should start learning something new – a new language or something, and I’ve been wanting to get back to doing some IOS development for a while, so it seemed to be a good time to start digging into swift. While I’m making all the mistakes and learning, I thought I’d chronicle the effort. I am taking a page from Brent Simmon’s Swift Dev Diaries, which I found immensely useful and informative. So this is the first of my swift dev diaries.

To give myself something concrete to work on, I thought I might help out with open source  swift itself. The swift package manager caught my eye as a starting place. For getting started resources, we have the github repo http://github.com/apple/swift-package-manager, the mailing list swift-build-dev, and a bug tracker. And then on the mailing list, I saw there was also a slack channel, specifically for swiftpm (unofficial and all that).

The bug I decided to tackle as a starting pointlooked reasonably constrained: SR-3275 – originally a crash report, but updated to reflect a request for improved output about why a failure occurred. The bug report led me to want to verify my update on MacOS and Linux, which started this post – which includes a bit of “how to” to develop for Swift project manager on Linux as well. The same could be used for any “server side swift”.

There are instructions on how to set things up, but it’s slightly behind as of the latest development snapshot. I set up a Vagrant based development environment, starting with IBM-Swift‘s work initial server-side swift work, and updating it to make a development snapshot work. The work itself is under a branch called swift-dev-branch, updated to start with Ubuntu 16.04 and adding in a number of dependencies that aren’t yet documented in the swift.org documentation as yet.

If you want to try out the Vagrant setup, you can my Vagrantfile from git and give it a whirl – I’ll happily take updates. You’ll need to have Vagrant and Virtualbox pre-installed.

git clone https://github.com/heckj/vagrant-ubuntu-swift-dev
cd vagrant-ubuntu-swift-dev
git checkout swift-dev-branch
vagrant up && vagrant ssh

It will take a bit of time to build, downloading the base image and snapshot, but once built is pretty fast to work with. If for some reason you want to destroy it all and start from scratch:

vagrant destroy -f && vagrant box update && vagrant up

should do the trick, wiping the local VM and starting afresh.

As a proof of concept, I used it to run the swiftpm build and test sequence:

vagrant ssh:

mkdir -p ~/src
cd ~/src/
git clone https://github.com/apple/swift-package-manager swiftpm
cd ~/src/swiftpm
Utilities/bootstrap test

While I was poking around at this, Ankit provided a number of tips through the Slack channel and shared his development setup/aliases which utilize a Docker image. I have some of those files in my repository as well now, trying them out – but I don’t have it all worked out for an “easy flow” as yet. Perhaps a topic for a future swift dev diary entry.

I wanted to mention a blog post about Bhargav Gurlanka‘s SwiftPM development workflow, which was also useful. It focused on how to use rsync to replicate data between MacOS and a Virtualbox instance to run testing on both MacOS and Ubuntu/Linux based swift.

One of the more hints I got is to use the build product from bootstrap directly for testing, which can operate in parallel, and hence run faster.

.build/debug/swift-test --parallel

That speeds up a complete test run quite considerably. It improved from 3 minutes 31 seconds to run via bootstrap to 1 minute 51 seconds – and it is a lot less visual output – on my old laptop.

I also found quite a bit of benefit to use swift-test to list the tests and to run a specific test while I was poking at things:

.build/debug/swift-test -l
.build/debug/swift-test -s FunctionalTests.MiscellaneousTestCase/testCanKillSubprocessOnSigInt

Which I was doing a fair bit of while working on digging through the code.

I haven’t quite got “using Xcode with a swift development toolchain snapshot” really nailed down as yet – I keep running into strange side issues that are hard to diagnose, but it’s definitely possible – I’ve just not been able to make it repeatably consistent.

The notes at https://github.com/apple/swift-package-manager#development are a good starting point, and from there you can use the environment variable “TOOLCHAINS” to let Xcode know to use your snapshot and go from there. The general pattern that I’ve used to date:

  1. download and install a swift development snapshot from https://swift.org/download/#releases
  2. export TOOLCHAINS=swift
  3. Utilities\bootstrap –generate-xcodeproj
  4. open SwiftPM.xcodeproj

and go from there. Xcode uses it’s own locations for build products, so make sure you invoke the build from Xcode “Build for Testing” prior to invoking any tests.

If Xcode was open before you invoked the “export TOOLCHAINS=swift” and then opened the project, you might want to close it and invoke it from the “open” command as I did above – that makes sure the environment variables are present and respected in Xcode while you’re working with the development toolchain.