-
Couldn't load subscription status.
- Fork 4
Swift on Raspberry Pi
Prev: Raspberry Pi Setup
Swift is my favorite programming language of the moment, and it's combination of a high-level syntax while still being compiled to native code, make it an attractive option for working with the Raspberry Pi hardware.
Unfortunately while the Linux port is an actively maintained and supported part of the project, it's intended for Intel processors.
The 32-bit ARM processor in the Raspberry Pi isn't natively supported by Swift, but there is an active community that attempts to make it work.
With a little effort, and with the patches from uraimo's buildSwiftOnARM repository, we can build a working toolchain.
Swift's build dependencies are documented in the README of the main repository.
sudo apt-get install 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 libblocksruntime-dev libcurl4-openssl-dev autoconf libtool systemtap-sdt-devAs of stretch, these are almost all of the correct versions.
The one exception is that the swig package in stretch is, unluckily, one of a couple of minor revisions that are known not to work with the Swift build process.
To work around this, we use the source from Debian unstable to build a version that will work:
wget http://http.debian.net/debian/pool/main/s/swig/swig_3.0.12-1.dsc \
http://http.debian.net/debian/pool/main/s/swig/swig_3.0.12.orig.tar.gz \
http://http.debian.net/debian/pool/main/s/swig/swig_3.0.12-1.debian.tar.xz
dpkg-source -x swig_3.0.12-1.dscsudo apt-get install bison debhelper dh-autoreconf default-jdk guile-2.0-dev libchicken-dev libperl-dev libpcre3-dev python-dev ruby ruby-dev tcl-dev tk-dev
(cd swig-3.0.12 && dpkg-buildpackage -uc -us)sudo dpkg -i swig_3.0.12-1_armhf.deb swig3.0_3.0.12-1_armhf.debA source build of Swift consists of more than the main repository for the language, but also the compiler, debugger, standard library, support libraries, and more.
We'll create a working directory to serve as the top-level for the build:
mkdir swift-source
cd swift-sourceThe master or HEAD of the repositories is the latest development version, intended for release alongside the next version of Xcode. We rarely want something that bleeding edge, and thanks to the community nature of the 32-bit ARM support, it rarely works anyway.
To checkout the Swift 4.1.1 release, we use the swift-4.1.1-RELEASE tag:
git clone -b swift-4.1-RELEASE https://github.com/apple/swift.git
./swift/utils/update-checkout --clone --tag swift-4.1-RELEASESwift 4.1.1 needs a few patches in order to build, which we can obtain from the buildSwiftOnARM project. We'll checkout that alongside our sources as well:
git clone https://github.com/uraimo/buildSwiftOnARM.gitWe'll then apply those to the appropriate repositories:
for PATCH in buildSwiftOnARM/*.diffs/*.diff; do \
( cd $(echo "$PATCH" \
| sed -e "s,[^/]*/,,;s,.diffs/.*,,") \
&& patch -p1 < ../"$PATCH" ); \
doneSwift comes with a script that manages building all of the different components and dependencies in the correct order (and in some cases, rebuilding them again).
The following arguments are those currently recommended for the Raspberry Pi:
./swift/utils/build-script \
--build-subdir out_linux \
-R \
--lldb \
--llbuild \
--xctest \
--swiftpm \
--foundation \
--libdispatch \
-- \
--install-libdispatch \
--install-foundation \
--install-swift \
--install-lldb \
--install-llbuild \
--install-xctest \
--install-swiftpm \
--install-prefix=/usr \
'--swift-install-components=autolink-driver;compiler;clang-builtin-headers;stdlib;swift-remote-mirror;sdk-overlay;dev' \
--build-swift-static-stdlib \
--build-swift-static-sdk-overlay \
--install-destdir=$(pwd)/install \
--installable-package=$(pwd)/swift-4.1.1.tar.gz \
--verbose-buildThis will create a build/ sub-directory containing the intermediate build output, a tree under install/ containing the staged for installation, and a swift-4.1.1.tar.gz package file of that tree.
Since Swift's support for the Raspberry Pi varies between releases, it's good practice to keep a working toolchain around as long as possible, and always give yourself the chance to rollback to a last known good one.
To achieve this, I like to install the binaries underneath /opt/swift with a tree for each version, rather than just unpacking it all into /usr each time.
Symlinks manage the current version:
sudo mkdir -p /opt/swift
sudo tar xzf swift-4.1.1.tar.gz -C /opt/swift
sudo mv /opt/swift/usr /opt/swift/4.1.1
sudo ln -sf /opt/swift/4.1.1/* /opt/swiftAdd /opt/swift/bin to your PATH for convenience:
echo 'PATH=$PATH:/opt/swift/bin' >> ~/.profileWe can now test it out.
swift --versionSwift version 4.1.1 (swift-4.1.1-RELEASE)
Target: armv7-unknown-linux-gnueabihfmkdir HelloWorld
cd HelloWorld
swift package init --type executableCreating executable package: HelloWorld
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/HelloWorld/main.swift
Creating Tests/swift buildCompile Swift Module 'HelloWorld' (1 sources)
Linking ./.build/debug/HelloWorldswift run HelloWorldHello, world!Next: Integers