Using Swift SDKs with Raspberry PIs
Generating Swift SDKs and cross-compiling for various Raspberry PI versions
One thing that has been possible for a while now is being able to cross-compile for different Linux architectures using Swift SDKs as per the SE-0387 proposal that was accepted and supported (experimentally) as of Swift 5.9. Starting with Swift 6.0 it was no longer “experimental”, and was Swift 6.1 was finally considered “completed”.
To facilitate generating these Swift SDKs, the swift-sdk-generator was created and has been incrementally updated to support generating Swift SDKs for not only Linux, but also WebAssembly (WASM) and FreeBSD as well. It is more than ready to be used for cross-compilation for Linux. Although this can be used for Linux servers (x86_64 or aarch64), this guide will focus on how to use the generator to create Swift SDKs for various Raspberry PIs, then using them to cross-compile Swift packages and deploying to Raspberry PI targets.
Supported Architectures
Before we begin, let’s look at the Raspberry PIs that are available, and how Swift supports (or does not support) them:
Raspberry Pi 1 (A, B, A+, B+, Zero, Zero W)
Architecture: armv6 (armel or armhf)
Linux Distributions: Raspberry PI OS (32-bit)
Swift Support: Unofficial (armhf-debian)
Raspberry Pi 2
Architecture: armv7 (armhf)
Linux Distributions: Raspberry PI OS (32-bit), Debian, Ubuntu
Swift Support: Unofficial (armhf-debian)
Raspberry Pi 3 (3, 3A+, 3B+, Zero 2 W), Raspberry Pi 4, Raspberry Pi 5
Architecture: aarch64 (arm64), backwards compatible with armv7 (armhf)
Linux Distributions: Raspberry Pi OS (32-bit or 64-bit), Debian, Ubuntu, Fedora, etc
Swift Support: Official (swift.org)
Although the Swift project does not yet officially support the 32-bit armv6 and armv7 architectures, unofficial artifacts have been compiled/created for the supported distributions by the Swift on Embedded Linux project at armhf-debian. Work is still ongoing to upstream this support to Swift.org, but will take some time.
WARNING: As of this writing, generating Swift SDKs for armv6 is not supported by the Swift SDK Generator. This is because the architecture is only supported by Raspberry Pi OS, and the generator does not yet support creating Raspberry Pi OS sysroots.
Get the Swift SDK Generator
Before we can generate Swift SDKs, we need to grab the swift-sdk-generator. Start by cloning the repo on a macOS or Linux host with Swift 5.9 or later installed. WSL2 works fine as well if you’re on Windows:
$ git clone https://github.com/swiftlang/swift-sdk-generator.git
$ cd swift-sdk-generatorMake sure you have the needed dependencies. On macOS:
$ brew bundle
Using xz
Using zstd
Using cmake
Using ninja
`brew bundle` complete! 4 Brewfile dependencies now installed.On Linux (Debian or Ubuntu), install:
$ sudo apt install zstd libsqlite3-devFinally, make sure you can compile the generator:
$ swift build
[1/1] Planning build
Building for debugging...
[15/15] Applying swift-sdk-generator
Build complete! (5.46s)Alright! Next we can run the generator to start creating some Swift SDKs.
Swift SDKs for 64-bit Raspberry PIs
Since aarch64 is supported officially by Swift (Raspberry Pi 3 and above), let’s start by generating and using Swift SDKs for this architecture. Since aarch64 artifacts are hosted on swift.org, the swift-sdk-generator can automatically download these to create Swift SDKs for it.
Let’s assume that you’re running Raspberry PI OS 12 (Bookworm) on your device. To generate the Swift SDK for it, use the following command:
$ swift run swift-sdk-generator make-linux-sdk --target aarch64-unknown-linux-gnu --distribution-name debian --distribution-version 12
Building for debugging...
[1/1] Write swift-version--73C290EA810FB7E9.txt
Build of product ‘swift-sdk-generator’ complete! (0.44s)
2025-11-28T02:29:57+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Downloading required toolchain packages...
2025-11-28T02:30:01+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Using downloaded artifacts from cache
2025-11-28T02:30:01+0000 info org.swift.swift-sdk-generator: distributionName=Debian distributionRelease=bookworm [SwiftSDKGenerator] Downloading and parsing packages lists...
2025-11-28T02:30:07+0000 info org.swift.swift-sdk-generator: distributionName=Debian packageCount=12 [SwiftSDKGenerator] Downloading packages...
2025-11-28T02:30:10+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Unpacking Swift distribution for the target triple...
2025-11-28T02:30:33+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Copying Swift core libraries for the target triple into Swift SDK bundle...
2025-11-28T02:30:37+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Removing unused toolchain components from target SDK...
2025-11-28T02:30:37+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Fixing up absolute symlinks...
2025-11-28T02:30:38+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Generating toolset JSON file...
2025-11-28T02:30:38+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Generating Swift SDK metadata JSON file...
2025-11-28T02:30:38+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Generating .artifactbundle info JSON file...
All done! Install the newly generated SDK with this command:
swift experimental-sdk install ~/swift-sdk-generator/Bundles/6.2.1-RELEASE_debian_bookworm_aarch64.artifactbundle
After that, use the newly installed SDK when building with this command:
swift build --experimental-swift-sdk 6.2.1-RELEASE_debian_bookworm_aarch64
2025-11-28T02:30:38+0000 info org.swift.swift-sdk-generator: elapsedTime=40 seconds [GeneratorCLI] Generator run finished successfully.If you notice above, the generator defaults to using the host installed version of Swift as the version of the Swift SDK to generate. In the example Swift 6.2.1 is installed and used, but if needed a different version can be specified with —-swift-version <VERSION>.
Now let’s install the generated Swift SDK using the command given from the generator output:
$ swift experimental-sdk install Bundles/6.2.1-RELEASE_debian_bookworm_aarch64.artifactbundle
warning: `swift experimental-sdk` command is deprecated and will be removed in a future version of SwiftPM. Use `swift sdk` instead.
Swift SDK bundle at `Bundles/6.2.1-RELEASE_debian_bookworm_aarch64.artifactbundle` successfully installed as 6.2.1-RELEASE_debian_bookworm_aarch64.artifactbundle.The warning above about “experimental-sdk” is only shown on Swift 6.0 and later. The generator still recommends it since it still supports Swift 5.9. This support will be removed sooner or later- you have been warned!
Now that the Swift SDK is installed, we can double check with the command:
$ swift sdk list
6.2.1-RELEASE_debian_bookworm_aarch64Alright, so let’s try to cross-compile a Swift package! For the purposes of this guide I like to recommend the hummingbird-examples since they are easy to compile and test out. Clone the repo:
$ git clone https://github.com/hummingbird-project/hummingbird-examplesThen, we can use the Swift SDK we have for aarch64 to compile the hello example:
$ cd hello
$ swift build --swift-sdk 6.2.1-RELEASE_debian_bookworm_aarch64
Building for debugging...
[908/908] Linking App
Build complete! (51.62s)If this worked, then we should have a binary that’ll work on the PI! Let’s check that it’s a valid file:
$ file .build/debug/App
.build/debug/App: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=d81c30581c3aa201f08c9ae9f3308bfc97673d59, with debug_info, not strippedLooks good.
Deploy and Run
Okay, let’s deploy Swift libraries and the binary to the PI. Make sure that SSH is enabled, then run the following command on the PI to prepare it:
user@raspberrypi$ sudo mkdir -p /usr/lib/swift/linux
user@raspberrypi$ sudo chown $USER:$USER /usr/lib/swift/linuxMoving forward, we assume that you will replace the raspberrypi name with the actual IP address or hostname of your PI.
Now we can deploy the Swift libraries (*.so files) to that folder using scp. These libraries are needed so that you can run that binary without having to static link it:
$ scp ~/.swiftpm/swift-sdks/6.2.1-RELEASE_debian_bookworm_aarch64.artifactbundle/6.2.1-RELEASE_debian_bookworm_aarch64/aarch64-unknown-linux-gnu/debian-bookworm.sdk/usr/lib/swift/linux/*.so user@raspberrypi:/usr/lib/swift/linux
lib_FoundationICU.so 100% 37MB 7.9MB/s 00:04
lib_InternalSwiftStaticMirror.so 100% 6039KB 16.5MB/s 00:00
lib_Testing_Foundation.so 100% 90KB 6.9MB/s 00:00
libBlocksRuntime.so 100% 69KB 4.8MB/s 00:00
libdispatch.so 100% 454KB 10.2MB/s 00:00
libFoundation.so 100% 8877KB 17.2MB/s 00:00
libFoundationEssentials.so 100% 9936KB 16.9MB/s 00:00
libFoundationInternationalization.so 100% 3851KB 16.7MB/s 00:00
libFoundationNetworking.so 100% 1797KB 15.0MB/s 00:00
libFoundationXML.so 100% 496KB 10.8MB/s 00:00
libswift_Builtin_float.so 100% 72KB 2.9MB/s 00:00
libswift_Concurrency.so 100% 1040KB 13.8MB/s 00:00
libswift_Differentiation.so 100% 666KB 13.1MB/s 00:00
libswift_RegexParser.so 100% 1636KB 15.4MB/s 00:00
libswift_StringProcessing.so 100% 1101KB 13.8MB/s 00:00
libswift_Volatile.so 100% 73KB 6.9MB/s 00:00
libswiftCore.so 100% 9496KB 10.1MB/s 00:00
libswiftDispatch.so 100% 353KB 9.2MB/s 00:00
libswiftDistributed.so 100% 224KB 12.8MB/s 00:00
libswiftGlibc.so 100% 103KB 9.8MB/s 00:00
libswiftObservation.so 100% 195KB 13.1MB/s 00:00
libswiftRegexBuilder.so 100% 204KB 12.2MB/s 00:00
libswiftRemoteMirror.so 100% 1442KB 16.4MB/s 00:00
libswiftRuntime.so 100% 1423KB 15.9MB/s 00:00
libswiftSwiftOnoneSupport.so 100% 494KB 12.8MB/s 00:00
libswiftSynchronization.so 100% 133KB 8.4MB/s 00:00
libTesting.so 100% 3054KB 16.0MB/s 00:00
libXCTest.so 100% 556KB 12.2MB/s 00:00Next, deploy the App binary to the PI:
$ scp .build/debug/App user@raspberrypi:~
App 100% 49MB 11.4MB/s 00:04Finally, run the binary back in an SSH session on the PI:
user@raspberrypi$ ./App -h 0.0.0.0
2025-11-28T08:25:54-0500 info Hummingbird : [HummingbirdCore] Server started and listening on 0.0.0.0:8080If you want, you can test that the HTTP server is working with a curl command from your machine:
$ curl http://raspberrypi:8080
HelloNice. Now that this works, the sky’s the limit…what else can you build and deploy to the Raspberry Pi with this Swift SDK?
Swift SDKs for 32-bit Raspberry PIs
My previous blog post described how to cross-compile and deploy to 32-bit PIs, but using the old “destination.json”-style SDKs. However, since now the swift-sdk-generator can create Swift SDKs for armv7, let’s have a look at how we use the artifacts provided by the armhf-debian repo to create Swift SDKs instead.
Let’s start by grabbing some artifacts from the repo. If we assume that we are running Raspberry PI OS 12 (Bookworm, 32-bit) on a Raspberry Pi 2 or later (which is armv7), we can download the appropriate artifact from the releases page:
$ wget https://github.com/swift-embedded-linux/armhf-debian/releases/download/6.2.1/swift-6.2.1-RELEASE-debian-bookworm-armv7-install.tar.gzWe need to extract this *.tar.gz into a new folder:
$ mkdir swift-6.2.1-RELEASE-debian-bookworm-armv7-install
$ tar -xf swift-6.2.1-RELEASE-debian-bookworm-armv7-install.tar.gz -C swift-6.2.1-RELEASE-debian-bookworm-armv7-installNext, go to the swift-sdk-generator folder and generate the Swift SDK for armv7-unknown-linux-gnueabihf (passed to --target) instead, and pointing to these artifacts:
$ swift run swift-sdk-generator make-linux-sdk --target armv7-unknown-linux-gnueabihf --distribution-name debian --distribution-version 12 --target-swift-package-path /path/to/swift-6.2.1-RELEASE-debian-bookworm-armv7-install
Build of product ‘swift-sdk-generator’ complete! (17.09s)
2025-11-29T18:17:11+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Downloading required toolchain packages...
2025-11-29T18:17:11+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Using downloaded artifacts from cache
2025-11-29T18:17:11+0000 info org.swift.swift-sdk-generator: distributionName=Debian distributionRelease=bookworm [SwiftSDKGenerator] Downloading and parsing packages lists...
2025-11-29T18:17:17+0000 info org.swift.swift-sdk-generator: distributionName=Debian packageCount=12 [SwiftSDKGenerator] Downloading packages...
2025-11-29T18:17:19+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Copying Swift core libraries for the target triple into Swift SDK bundle...
2025-11-29T18:17:23+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Removing unused toolchain components from target SDK...
2025-11-29T18:17:23+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Fixing up absolute symlinks...
2025-11-29T18:17:24+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Generating toolset JSON file...
2025-11-29T18:17:24+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Generating Swift SDK metadata JSON file...
2025-11-29T18:17:24+0000 info org.swift.swift-sdk-generator: [SwiftSDKGenerator] Generating .artifactbundle info JSON file...
All done! Install the newly generated SDK with this command:
swift experimental-sdk install ~/swift-sdk-generator/Bundles/6.2.1-RELEASE_debian_bookworm_armv7.artifactbundle
After that, use the newly installed SDK when building with this command:
swift build --experimental-swift-sdk 6.2.1-RELEASE_debian_bookworm_armv7
2025-11-29T18:17:24+0000 info org.swift.swift-sdk-generator: elapsedTime=13 seconds [GeneratorCLI] Generator run finished successfully.Install the Swift SDK using the provided command, then check the ID in the list of installed Swift SDKs:
$ swift experimental-sdk install ~/swift-sdk-generator/Bundles/6.2.1-RELEASE_debian_bookworm_armv7.artifactbundle
$ swift sdk list
6.2.1-RELEASE_debian_bookworm_aarch64
6.2.1-RELEASE_debian_bookworm_armv7Alright, so that worked- let’s try to build a hummingbird example using the armv7 Swift SDK!
$ cd hummingbird-examples/hello
$ swift build --swift-sdk 6.2.1-RELEASE_debian_bookworm_armv7
Building for debugging...
[927/927] Linking App
Build complete! (76.27s)Check that the generated App binary is for the correct architecture:
$ file .build/debug/App
.build/debug/App: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=223ec3d2faee61d9c032de51b2304cec010f5dba, with debug_info, not strippedDeploy and Run
The steps for deploying the 32-bit Swift runtime and binary are pretty-much identical as for 64-bit architectures. Follow the same steps to prepare the target filesystem with the /usr/lib/swift/linux directory:
user@raspberrypi32$ sudo mkdir -p /usr/lib/swift/linux
user@raspberrypi32$ sudo chown $USER:$USER /usr/lib/swift/linuxThen, deploy the *.so files from the armv7 Swift SDK, like this:
$ scp ~/.swiftpm/swift-sdks/6.2.1-RELEASE_debian_bookworm_armv7.artifactbundle/6.2.1-RELEASE_debian_bookworm_armv7/armv7-unknown-linux-gnueabihf/debian-bookworm.sdk/usr/lib/swift/linux/*.so user@raspberrypi32:/usr/lib/swift/linux
lib_FoundationICU.so 100% 36MB 7.0MB/s 00:05
lib_Testing_Foundation.so 100% 73KB 5.2MB/s 00:00
libBlocksRuntime.so 100% 10KB 2.4MB/s 00:00
libdispatch.so 100% 318KB 6.4MB/s 00:00
libFoundation.so 100% 11MB 8.1MB/s 00:01
libFoundationEssentials.so 100% 14MB 8.2MB/s 00:01
libFoundationInternationalization.so 100% 5592KB 8.2MB/s 00:00
libFoundationNetworking.so 100% 2377KB 8.0MB/s 00:00
libFoundationXML.so 100% 545KB 7.0MB/s 00:00
libswift_Builtin_float.so 100% 10KB 2.4MB/s 00:00
libswift_Concurrency.so 100% 934KB 7.5MB/s 00:00
libswift_Differentiation.so 100% 582KB 7.1MB/s 00:00
libswift_RegexParser.so 100% 1708KB 7.9MB/s 00:00
libswift_StringProcessing.so 100% 1110KB 7.7MB/s 00:00
libswift_Volatile.so 100% 12KB 2.7MB/s 00:00
libswiftCore.so 100% 9012KB 1.0MB/s 00:08
libswiftDispatch.so 100% 406KB 7.1MB/s 00:00
libswiftDistributed.so 100% 176KB 6.9MB/s 00:00
libswiftGlibc.so 100% 73KB 5.9MB/s 00:00
libswiftObservation.so 100% 122KB 6.5MB/s 00:00
libswiftRegexBuilder.so 100% 135KB 6.7MB/s 00:00
libswiftRemoteMirror.so 100% 1430KB 8.0MB/s 00:00
libswiftSwiftOnoneSupport.so 100% 400KB 7.1MB/s 00:00
libswiftSynchronization.so 100% 96KB 6.3MB/s 00:00
libTesting.so 100% 4086KB 8.2MB/s 00:00
libXCTest.so 100% 835KB 7.6MB/s 00:00 This assumes that the raspberrypi32 name is replaced with the real hostname or IP address of your Raspberry PI that is running Raspberry PI OS 32-bit.
$ scp .build/debug/App user@raspberrypi32:~
App 100% 73MB 7.6MB/s 00:09SSH into the PI, and then run the app:
user@raspberrypi32$ ./App -h 0.0.0.0
2025-11-28T08:25:54-0500 info Hummingbird : [HummingbirdCore] Server started and listening on 0.0.0.0:8080Test it by using curl:
$ curl http://raspberrypi32:8080
HelloAwesome! So now you have Swift actually running on a 32-bit Raspberry PI…pretty cool huh?
Static Linking
With either the aarch64 or armv7 Swift SDKs it’s possible to statically link the Swift stdlib into the generated binaries to avoid having to deploy the Swift runtime *.so files to the board manually. This makes the binary (much) larger but provides some flexibility if you are testing different Swift versions on a single board, or even just wanting to quickly get something running on the board.
To use the Swift SDKs to statically compile the binary, just add —static-swift-stdlib to the swift build invocation:
# aarch64
$ swift build --swift-sdk 6.2.1-RELEASE_debian_bookworm_aarch64 --static-swift-stdlib
# armv7
$ swift build --swift-sdk 6.2.1-RELEASE_debian_bookworm_armv7 --static-swift-stdlibAs you can see, the binary is larger:
$ du -hs .build/debug/App
127M .build/debug/AppBut then it includes the entire Swift runtime and Foundation libraries you need to run it. Please note that glibc is NOT included, but is not an issue since you are using the Swift SDK to compile for the glibc version that’s on the Raspberry PI!
Conclusions
In 2025 it’s totally possible to cross-compile nearly all Linux-compatible Swift packages for Raspberry PIs using Swift SDKs. It does take some work to generate these Swift SDKs using the generator, but in the future I envision having pre-built Swift SDKs for this purpose on swift.org or elsewhere. Alternatively, scripts could be created to make using the generator itself easier- think of an interactive script that can clone the swift-sdk-generator, then ask a few questions about which target, Swift version, and distribution to build for, and install the Swift SDK after it’s been generated…
I hope this post helps others who are interested in trying out Swift on Raspberry PI, but who do not want to try to compile Swift packages directly on the board. These instructions should be compatible with other aarch64 and armv7 SBCs (like the Orange PI) that might run Debian or Ubuntu as well, although I have not tried them for myself. And as always, if you have issues or questions, please let me know!


