Skip to content

Build Android Swift packages with the toolchain's default build system - #119

Merged
marcprux merged 3 commits into
skiptools:mainfrom
piercifani:android-build-default-build-system
Sep 26, 2026
Merged

marcprux merged 3 commits into
skiptools:mainfrom
piercifani:android-build-default-build-system

Conversation

@piercifani

@piercifani piercifani commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

#106 pinned the generated buildAndroidSwiftPackage task to --build-system native as a stopgap while swiftlang/swift-build#1363 was open: swiftbuild's build output folder no longer included the target triple, which multi-architecture exports (--arch aarch64 --arch armv7) rely on to collect each architecture's libraries.

That issue was closed on 2026-07-13, and Swift 6.4's swiftbuild writes per-architecture product folders (out/Products/Release-android-aarch64, out/Products/Release-android-armv7). Meanwhile every 6.4 build prints the '--build-system native' has been deprecated and will be removed warning. Once SwiftPM drops native, the generated task stops building.

This PR makes three changes:

  1. Removes the flag, so skip android build uses the toolchain's default engine. Toolchains before 6.4 default to native, so nothing changes for them. On 6.4 and later, the Android build moves to swiftbuild.
  2. Teaches loadPeerLibrary swiftbuild's product folder. For Robolectric it only looked in the native engine's .build/<lib>/swift/<triple>/debug/, but swiftbuild writes the host library to .build/<lib>/swift/out/Products/Debug on macOS and Debug-linux-<arch> on Linux. It now falls back to that folder when the native path doesn't exist. This already breaks on main for anyone whose host swift build runs on swiftbuild: on main, swift test in this repo with Xcode 27 / Swift 6.4 fails every Robolectric test with error: missing library: …/<triple>/debug/lib<Module>.dylib. The first CI run of this PR hit the same failure on the ubuntu-24.04, nightly-main job.
  3. Passes the module cache as a driver option, -Xswiftc -module-cache-path -Xswiftc <path>, instead of -Xfrontend pairs. The nightly toolchain's swiftbuild reads -module-cache-path from the swiftc flags, took the following -Xfrontend as the directory, and failed with Cannot recursively create directory at non-absolute path: -Xfrontend. Under the native build system the two forms are equivalent: the module cache is still written to build/swift/module-cache/<module>.

Verified

A 16-module bridged package (~2,400 Swift files), Swift 6.4.0 (Xcode 27) with the 6.4.0 Android SDK, skip 1.9.11, skip-bridge 0.17.3 + this change:

  • skip export --release --arch aarch64 --arch armv7: succeeds. All 16 AARs are produced, and each architecture's jni/ folder holds the same 28 libraries.
  • skip export --debug --arch aarch64 driven by the consuming app's Gradle build, then :app:assembleDebug: succeeds.
  • Release comparison against --build-system native, same checkout: the same 16 AARs with identical per-ABI library lists (28 each). Total native-library size is within 0.04% (arm64-v8a 439.0 → 439.2 MB, armeabi-v7a 420.0 → 419.9 MB), and the cold export went from 823 s to 808 s.
  • swift test in this repo, Xcode 27 / Swift 6.4 on macOS: main fails every Robolectric test with missing library. With this PR, all Robolectric suites pass, loading out/Products/Debug/lib<Module>.dylib.

One unrelated thing we noticed: jni-libs/<abi> is shared between debug and release, so a release export after a debug export can carry debug-only libraries such as libswiftSwiftOnoneSupport.so into the release AAR. Clearing the folder avoids it. This happens independently of the build engine.

🤖 Generated with Claude Code

The --build-system native pin from skiptools#106 was a stopgap for
swiftlang/swift-build#1363, which is fixed; swiftbuild now writes
per-architecture product folders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread Sources/SkipBridge/System.swift Outdated
piercifani and others added 2 commits September 25, 2026 23:58
loadPeerLibrary only looked in the native build system's
<triple>/debug folder, so Robolectric tests could not find the host
library once swift build defaulted to swiftbuild, which writes to
out/Products/<configuration>. Fall back to that folder when the native
path does not exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nightly toolchain's swiftbuild reads -module-cache-path from the
swiftc flags and took the following -Xfrontend as its value ("Cannot
recursively create directory at non-absolute path: -Xfrontend"). The
driver option is equivalent under the native build system.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@piercifani
piercifani force-pushed the android-build-default-build-system branch from 46e8993 to ed50343 Compare September 25, 2026 21:59
@piercifani
piercifani requested a review from marcprux September 25, 2026 21:59
@marcprux
marcprux merged commit 750b74e into skiptools:main Sep 26, 2026
8 of 9 checks passed
@piercifani
piercifani deleted the android-build-default-build-system branch September 26, 2026 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants