From d57505762d270bd3b6f7b9fd9719c66d9e20e067 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 10:16:07 -0400 Subject: [PATCH 01/11] Add Docker image for the official Swift Android SDK 6.3.2 --- .github/docker/Dockerfile | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/docker/Dockerfile diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile new file mode 100644 index 0000000..420b1c9 --- /dev/null +++ b/.github/docker/Dockerfile @@ -0,0 +1,19 @@ +# Build image for cross-compiling the package with the official +# Swift SDK for Android. +FROM swift:6.3.2-noble + +ARG SWIFT_SDK_URL=https://download.swift.org/swift-6.3.2-release/android/swift-6.3.2-RELEASE/swift-6.3.2-RELEASE-android-24-0.1.artifactbundle.tar.gz +ARG SWIFT_SDK_CHECKSUM= + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates curl unzip \ + && rm -rf /var/lib/apt/lists/* + +RUN if [ -n "$SWIFT_SDK_CHECKSUM" ]; then \ + swift sdk install "$SWIFT_SDK_URL" --checksum "$SWIFT_SDK_CHECKSUM"; \ + else \ + swift sdk install "$SWIFT_SDK_URL"; \ + fi \ + && swift sdk list + +WORKDIR /package From 49054a5a506910960fb0ffb6cecf97699b48268f Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 10:16:22 -0400 Subject: [PATCH 02/11] Add CI workflow building with the official Swift Android SDK in Docker --- .github/workflows/docker.yml | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..108600d --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,45 @@ +name: Docker + +on: + push: + branches: [master] + workflow_dispatch: + pull_request: + +jobs: + android: + name: Android (Swift SDK ${{ matrix.swift }} / API ${{ matrix.android-api }}) + runs-on: ubuntu-24.04 + timeout-minutes: 90 + strategy: + fail-fast: false + matrix: + swift: ['6.3.2'] + android-api: ['28', '29', '31', '33'] + arch: ['aarch64', 'armv7', 'x86_64'] + steps: + - uses: actions/checkout@v6 + + - name: "Build Docker image" + run: | + docker build \ + --tag swift-android-sdk:${{ matrix.swift }} \ + --file .github/docker/Dockerfile \ + .github/docker + + - name: "Build Swift Package for Android (${{ matrix.arch }})" + run: | + case "${{ matrix.arch }}" in + aarch64) TRIPLE="aarch64-unknown-linux-android${{ matrix.android-api }}" ;; + armv7) TRIPLE="armv7-unknown-linux-androideabi${{ matrix.android-api }}" ;; + x86_64) TRIPLE="x86_64-unknown-linux-android${{ matrix.android-api }}" ;; + esac + SDK="$(echo "$TRIPLE" | sed 's/[0-9]*$/24/')" + docker run --rm \ + --volume "$PWD:/package" \ + --env ANDROID_SDK_VERSION=${{ matrix.android-api }} \ + swift-android-sdk:${{ matrix.swift }} \ + swift build \ + --swift-sdk "$SDK" \ + -Xswiftc -target -Xswiftc "$TRIPLE" \ + -Xcc -target -Xcc "$TRIPLE" From 94a5a05a75974c2f5ec9225185af12a884d9949d Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 12:33:46 -0400 Subject: [PATCH 03/11] Fix Swift Android SDK download URL and checksum --- .github/docker/Dockerfile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile index 420b1c9..899658d 100644 --- a/.github/docker/Dockerfile +++ b/.github/docker/Dockerfile @@ -2,18 +2,14 @@ # Swift SDK for Android. FROM swift:6.3.2-noble -ARG SWIFT_SDK_URL=https://download.swift.org/swift-6.3.2-release/android/swift-6.3.2-RELEASE/swift-6.3.2-RELEASE-android-24-0.1.artifactbundle.tar.gz -ARG SWIFT_SDK_CHECKSUM= +ARG SWIFT_SDK_URL=https://download.swift.org/swift-6.3.2-release/android-sdk/swift-6.3.2-RELEASE/swift-6.3.2-RELEASE_android.artifactbundle.tar.gz +ARG SWIFT_SDK_CHECKSUM=939e933549d12d28f2e0bf71019d734d309859e9773c572657ce565a81f85d68 RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl unzip \ && rm -rf /var/lib/apt/lists/* -RUN if [ -n "$SWIFT_SDK_CHECKSUM" ]; then \ - swift sdk install "$SWIFT_SDK_URL" --checksum "$SWIFT_SDK_CHECKSUM"; \ - else \ - swift sdk install "$SWIFT_SDK_URL"; \ - fi \ +RUN swift sdk install "$SWIFT_SDK_URL" --checksum "$SWIFT_SDK_CHECKSUM" \ && swift sdk list WORKDIR /package From daf840a67891cc4ef84c2674cb2b890264208e17 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 12:33:46 -0400 Subject: [PATCH 04/11] Select the installed Swift SDK identifier by architecture --- .github/workflows/docker.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 108600d..2f6123f 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,7 +8,7 @@ on: jobs: android: - name: Android (Swift SDK ${{ matrix.swift }} / API ${{ matrix.android-api }}) + name: Android (Swift SDK ${{ matrix.swift }} / API ${{ matrix.android-api }} / ${{ matrix.arch }}) runs-on: ubuntu-24.04 timeout-minutes: 90 strategy: @@ -34,12 +34,20 @@ jobs: armv7) TRIPLE="armv7-unknown-linux-androideabi${{ matrix.android-api }}" ;; x86_64) TRIPLE="x86_64-unknown-linux-android${{ matrix.android-api }}" ;; esac - SDK="$(echo "$TRIPLE" | sed 's/[0-9]*$/24/')" docker run --rm \ --volume "$PWD:/package" \ --env ANDROID_SDK_VERSION=${{ matrix.android-api }} \ + --env TRIPLE="$TRIPLE" \ swift-android-sdk:${{ matrix.swift }} \ - swift build \ - --swift-sdk "$SDK" \ - -Xswiftc -target -Xswiftc "$TRIPLE" \ - -Xcc -target -Xcc "$TRIPLE" + bash -c ' + set -eu + # the installed Swift SDK identifier carries its own minimum API level, + # so look it up by architecture and override the target triple below + PREFIX=$(echo "$TRIPLE" | sed "s/[0-9]*$//") + SDK=$(swift sdk list | grep -m1 "^$PREFIX") + echo "Using Swift SDK: $SDK (target $TRIPLE)" + swift build \ + --swift-sdk "$SDK" \ + -Xswiftc -target -Xswiftc "$TRIPLE" \ + -Xcc -target -Xcc "$TRIPLE" + ' From 9286aefbc407ceb972173df33cda1f31749749e1 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 12:39:08 -0400 Subject: [PATCH 05/11] Record supported Android triples in the Docker image --- .github/docker/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile index 899658d..5f7a1ea 100644 --- a/.github/docker/Dockerfile +++ b/.github/docker/Dockerfile @@ -12,4 +12,10 @@ RUN apt-get update \ RUN swift sdk install "$SWIFT_SDK_URL" --checksum "$SWIFT_SDK_CHECKSUM" \ && swift sdk list +# record the triples the installed Swift SDK supports, so a build can select one by architecture +RUN find / -path '*swift-sdks*' -name 'swift-sdk.json' -exec cat {} + \ + | grep -o '"[a-z0-9_]*-unknown-linux-android[a-z]*[0-9]*"' \ + | tr -d '"' | sort -u > /usr/local/share/swift-android-triples \ + && cat /usr/local/share/swift-android-triples + WORKDIR /package From 9336a83fb8761052871d1d6338ee11ed0c9b6baa Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 12:39:08 -0400 Subject: [PATCH 06/11] Select the Swift SDK triple recorded in the Docker image --- .github/workflows/docker.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 2f6123f..89905d7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -41,10 +41,10 @@ jobs: swift-android-sdk:${{ matrix.swift }} \ bash -c ' set -eu - # the installed Swift SDK identifier carries its own minimum API level, - # so look it up by architecture and override the target triple below + # the Swift SDK ships a fixed minimum API level per triple, + # so select it by architecture and override the target triple below PREFIX=$(echo "$TRIPLE" | sed "s/[0-9]*$//") - SDK=$(swift sdk list | grep -m1 "^$PREFIX") + SDK=$(grep -m1 "^$PREFIX" /usr/local/share/swift-android-triples) echo "Using Swift SDK: $SDK (target $TRIPLE)" swift build \ --swift-sdk "$SDK" \ From 23ffc047fc16ec924cf72e2ef5259b934f7bfd34 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 13:00:53 -0400 Subject: [PATCH 07/11] Build against the Swift SDK sysroot without overriding the target triple --- .github/workflows/docker.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 89905d7..fb40631 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -30,24 +30,20 @@ jobs: - name: "Build Swift Package for Android (${{ matrix.arch }})" run: | case "${{ matrix.arch }}" in - aarch64) TRIPLE="aarch64-unknown-linux-android${{ matrix.android-api }}" ;; - armv7) TRIPLE="armv7-unknown-linux-androideabi${{ matrix.android-api }}" ;; - x86_64) TRIPLE="x86_64-unknown-linux-android${{ matrix.android-api }}" ;; + aarch64) PREFIX="aarch64-unknown-linux-android" ;; + armv7) PREFIX="armv7-unknown-linux-androideabi" ;; + x86_64) PREFIX="x86_64-unknown-linux-android" ;; esac docker run --rm \ --volume "$PWD:/package" \ --env ANDROID_SDK_VERSION=${{ matrix.android-api }} \ - --env TRIPLE="$TRIPLE" \ + --env PREFIX="$PREFIX" \ swift-android-sdk:${{ matrix.swift }} \ bash -c ' set -eu - # the Swift SDK ships a fixed minimum API level per triple, - # so select it by architecture and override the target triple below - PREFIX=$(echo "$TRIPLE" | sed "s/[0-9]*$//") + # the Swift SDK bundles one sysroot per architecture with its own + # minimum API level; ANDROID_SDK_VERSION selects the package features SDK=$(grep -m1 "^$PREFIX" /usr/local/share/swift-android-triples) - echo "Using Swift SDK: $SDK (target $TRIPLE)" - swift build \ - --swift-sdk "$SDK" \ - -Xswiftc -target -Xswiftc "$TRIPLE" \ - -Xcc -target -Xcc "$TRIPLE" + echo "Using Swift SDK: $SDK (ANDROID_SDK_VERSION=$ANDROID_SDK_VERSION)" + swift build --swift-sdk "$SDK" ' From 966be6f42fc17a2807ab2b76b0e02f4eae48cb8a Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 13:36:59 -0400 Subject: [PATCH 08/11] Provide the Android NDK sysroot required by the Swift SDK --- .github/docker/Dockerfile | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile index 5f7a1ea..da9b128 100644 --- a/.github/docker/Dockerfile +++ b/.github/docker/Dockerfile @@ -4,18 +4,28 @@ FROM swift:6.3.2-noble ARG SWIFT_SDK_URL=https://download.swift.org/swift-6.3.2-release/android-sdk/swift-6.3.2-RELEASE/swift-6.3.2-RELEASE_android.artifactbundle.tar.gz ARG SWIFT_SDK_CHECKSUM=939e933549d12d28f2e0bf71019d734d309859e9773c572657ce565a81f85d68 +ARG ANDROID_NDK_VERSION=r27d + +ENV ANDROID_NDK_HOME=/usr/local/lib/android/sdk/ndk/${ANDROID_NDK_VERSION} RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl unzip \ && rm -rf /var/lib/apt/lists/* +# the Swift SDK links against the NDK sysroot, which it does not bundle +RUN mkdir -p "$(dirname "$ANDROID_NDK_HOME")" \ + && curl -fsSL -o /tmp/ndk.zip \ + "https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux.zip" \ + && unzip -q /tmp/ndk.zip -d /tmp \ + && mv "/tmp/android-ndk-${ANDROID_NDK_VERSION}" "$ANDROID_NDK_HOME" \ + && rm /tmp/ndk.zip + RUN swift sdk install "$SWIFT_SDK_URL" --checksum "$SWIFT_SDK_CHECKSUM" \ && swift sdk list -# record the triples the installed Swift SDK supports, so a build can select one by architecture -RUN find / -path '*swift-sdks*' -name 'swift-sdk.json' -exec cat {} + \ - | grep -o '"[a-z0-9_]*-unknown-linux-android[a-z]*[0-9]*"' \ - | tr -d '"' | sort -u > /usr/local/share/swift-android-triples \ - && cat /usr/local/share/swift-android-triples +# the artifact bundle expects the NDK sysroot at `ndk-sysroot` inside the bundle +RUN BUNDLE=$(dirname "$(find / -path '*swift-sdks*' -name 'swift-sdk.json' | head -1)") \ + && ln -s "$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot" "$BUNDLE/ndk-sysroot" \ + && test -f "$BUNDLE/ndk-sysroot/usr/include/jni.h" WORKDIR /package From 224cacef092f49a6c0a50fc42d314df6a36c9ad1 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 13:36:59 -0400 Subject: [PATCH 09/11] Select the Swift SDK triple by API level and disable swift-syntax prebuilts --- .github/workflows/docker.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index fb40631..9268c69 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -30,20 +30,17 @@ jobs: - name: "Build Swift Package for Android (${{ matrix.arch }})" run: | case "${{ matrix.arch }}" in - aarch64) PREFIX="aarch64-unknown-linux-android" ;; - armv7) PREFIX="armv7-unknown-linux-androideabi" ;; - x86_64) PREFIX="x86_64-unknown-linux-android" ;; + aarch64) TRIPLE="aarch64-unknown-linux-android${{ matrix.android-api }}" ;; + armv7) TRIPLE="armv7-unknown-linux-android${{ matrix.android-api }}" ;; + x86_64) TRIPLE="x86_64-unknown-linux-android${{ matrix.android-api }}" ;; esac docker run --rm \ --volume "$PWD:/package" \ --env ANDROID_SDK_VERSION=${{ matrix.android-api }} \ - --env PREFIX="$PREFIX" \ + --env TRIPLE="$TRIPLE" \ swift-android-sdk:${{ matrix.swift }} \ bash -c ' set -eu - # the Swift SDK bundles one sysroot per architecture with its own - # minimum API level; ANDROID_SDK_VERSION selects the package features - SDK=$(grep -m1 "^$PREFIX" /usr/local/share/swift-android-triples) - echo "Using Swift SDK: $SDK (ANDROID_SDK_VERSION=$ANDROID_SDK_VERSION)" - swift build --swift-sdk "$SDK" + # the prebuilt swift-syntax bundle omits SwiftIfConfig, which swift-java needs + swift build --swift-sdk "$TRIPLE" --disable-prebuilts ' From 00f5380fd8a05c696a743682b375f0adb48e98f5 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 13:41:12 -0400 Subject: [PATCH 10/11] Use the correct flag to disable swift-syntax prebuilts --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9268c69..49f08fb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -42,5 +42,5 @@ jobs: bash -c ' set -eu # the prebuilt swift-syntax bundle omits SwiftIfConfig, which swift-java needs - swift build --swift-sdk "$TRIPLE" --disable-prebuilts + swift build --swift-sdk "$TRIPLE" --disable-experimental-prebuilts ' From e8a138f6d645fe3fa8f32c81f2ce99f4b7688a03 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Jul 2026 13:49:53 -0400 Subject: [PATCH 11/11] Set up the NDK with the script shipped in the Swift SDK bundle --- .github/docker/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile index da9b128..1b97e2f 100644 --- a/.github/docker/Dockerfile +++ b/.github/docker/Dockerfile @@ -23,9 +23,10 @@ RUN mkdir -p "$(dirname "$ANDROID_NDK_HOME")" \ RUN swift sdk install "$SWIFT_SDK_URL" --checksum "$SWIFT_SDK_CHECKSUM" \ && swift sdk list -# the artifact bundle expects the NDK sysroot at `ndk-sysroot` inside the bundle +# the bundle ships a script that links the NDK sysroot, the clang resource +# directory and swiftrt.o into place, using ANDROID_NDK_HOME RUN BUNDLE=$(dirname "$(find / -path '*swift-sdks*' -name 'swift-sdk.json' | head -1)") \ - && ln -s "$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot" "$BUNDLE/ndk-sysroot" \ + && "$BUNDLE/scripts/setup-android-sdk.sh" \ && test -f "$BUNDLE/ndk-sysroot/usr/include/jni.h" WORKDIR /package