Since support for Linux armhf (armv6 and armv7) is not officially supported by the Swift project (swiftlang/swift), this is an effort to maintain community-supported builds of the runtime that can be used for cross-compilation to these architectures.
Some main goals:
- Build major versions of Swift since 5.10 and provide build artifacts for various distributions that support armv6 and armv7.
- Provide SDKs that can be downloaded and used to cross-compile user applications and libraries to armv6 and armv7.
- Maintain a CI that can build snapshots/nightly versions of Swift to find and fix issues.
Also check the armhf-action repo which contains a ready-made GitHub action for downloading, installing, and using the SDKs generated by this repo to cross-compile Swift packages for armv6 and armv7 from GitHub workflows.
The following Linux distributions are currently supported:
- Raspberry Pi OS (armv6 & armv7)
- 11: Bullseye
- 12: Bookworm
- Debian (armv7 only)
- 11: Bullseye
- 12: Bookworm
- Ubuntu (armv7 only)
- 20.04: Focal
- 22.04: Jammy
- 24.04: Noble
Notes:
- armv6 is only supported on Raspberry Pi OS distributions since it is the only distribution that supports the armv6 "hard-float" variant that is targeted by the repo. This means we can maintain compatibility with the full line of Raspberry Pi SBCs in this repo.
- Interim support for Ubuntu versions (20.10, 21.04, 23.10, etc) is possible by picking the closest LTS release and compiling for that, since glibc and and core library versions will likely be compatible.
Tip
If more distribution support is needed and/or desired, feel free to open an Issue to have it added. Or, consider adding support in the scripts and CI workflows and contributing it back!
This repo contains CI scripts that use GitHub actions to compile different versions of Swift for armv6/armv7 for different distributions. Artifacts are generated and published to CI runs that can be downloaded and used locally:
sysroot-$DISTRIBUTION
: Contains sysroot for the given distribution, used to compile Swift and included in SDKs.$SWIFT_TAG-$DISTRIBUTION-[armv6|armv7]-install
: Swift armv7 runtime built for the given distribution, can be installed to the target.$SWIFT_TAG-$DISTRIBUTION-[armv6|armv7]-sdk
: The cross-compilation SDK for the given distribution, must be installed to /opt to use.
To use the SDK that is generated by the CI or published to the Releases page, first extract it to /opt:
sudo tar -xf swift-6.1.2-RELEASE-debian-bookworm-armv7-sdk.tar.gz -C /opt
Then, from a Swift package, use the --destination
paramter to cross-compile it for the target:
swift build --destination /opt/swift-6.1.2-RELEASE-debian-bookworm-armv7/debian-bookworm.json
There are various options for compiling Swift for armhf with these scripts.
Note
These scripts require that Docker at least be installed with multi-platform support enabled. The multi-platform support is used to build sysroots for various distributions, based on container images from Docker Hub.
The easiest way to compile the runtime is inside of the provided Docker container. This ensures that you have the same version of Swift for the host as what you are compiling for the target.
Start by creating the default sysroot (debian bookworm), then run the build-in-container.sh
script:
./build-sysroot.sh debian bookworm
./build-in-container.sh
Things such as STAGING_DIR
, SWIFT_VERSION
, and SWIFT_TARGET_ARCH
can also be passed through environment variables:
./build-sysroot raspios bookworm
STAGING_DIR=sysroot-raspios-bookworm SWIFT_VERSION=6.0 SWIFT_TARGET_ARCH=armv6 ./build-in-container.sh
To build the Swift runtime on the host, you must have a matching version of Swift installed. It is recommended to use swiftly to make this simpler.
To build for the default (Debian Bookworm) for armv7, use the build.sh
script:
export SWIFT_NATIVE_PATH=/path/to/swift/toolchain
./build.sh
NOTE: The toolchain pointed to by SWIFT_NATIVE_PATH must match the version of Swift being built. If not, failures will occur in the compilation.
It is possible to build for armv6 as well by building and providing a sysroot for raspios, and changing the target to armv6 while invoking the build script:
export SWIFT_NATIVE_PATH=/path/to/swift/toolchain
./build-sysroot raspios bookworm
STAGING_DIR=sysroot-raspios-bookworm SWIFT_TARGET_ARCH=armv6 ./build.sh
Extra dependencies can also be installed into the sysroot if desired or needed, which in turn will be installed into the cross-compilation SDK (see Building a Cross Compilation SDK for Linux). To do this, add the EXTRA_DEPENDENCIES
environment variable:
EXTRA_DEPENDENCIES="libsqlite3-dev" ./build-sysroot ubuntu noble
STAGING_DIR=sysroot-ubuntu-noble ./build.sh
export SWIFT_PACKAGE_SRCDIR=/home/user/Developer/MySwiftPackage
./build.sh # Or skip if using cached build
./build-swift-package.sh
./generate-xcode-toolchain.sh
export SWIFT_PACKAGE_SRCDIR=/home/user/Developer/MySwiftPackage
export SWIFT_NATIVE_PATH=/tmp/cross-toolchain/debian-bookworm.sdk
./build-swift-package.sh
SWIFT_PACKAGE_SRCDIR
can be set to the root of your own packages to cross compile them using build-swift-package.sh
.
After building the armv6/armv7 runtime using the build.sh
script, you can generate a redistributable SDK
using the build-linux-cross-sdk.sh
script. You must provide the swift tag and distribution name:
SWIFT_TARGET_ARCH=armv7 ./build-linux-cross-sdk.sh swift-6.1.2-RELEASE ubuntu-noble
By default, the SDK will be generated to be installed at a path of /opt/$SWIFT_TAG-$DISTRIBUTION-armv7, but this can be customized by providing a different install prefix to the script:
export SDK_INSTALL_PREFIX=/home/myuser/swift-sdks
./build-linux-cross-sdk.sh swift-6.1.2-RELEASE ubuntu-noble