android: drive the Android Swift bridge link with the unwrapped swift-driver (unbreak Build (Android)) #37
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
key-store/key.store!37
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/android-bridge-unwrapped-swift-driver"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Build (Android) has failed on every executed run since 2026-06-19 (last green: run 10734, 2026-05-28) with:
Root cause (not runner/toolchain drift)
Reproduced byte-for-byte on the forge with the exact CI store paths (
skip-swift-toolchain-6.2.3vyqr501…,skip-swift-sdk-home-6.2.3ixwjfap5…, NDK 27.0.12077973). The direct bridge builder from4d9e989a(2026-06-14) calls the Nix toolchain'sswiftc, which is the cc-wrapper-derived shell wrapper fromPackages/swift-flake/build/wrapper.sh. On Linux it unconditionally injects host glibc/gcc flags into every non-wasm invocation (-L<glibc>/lib,-B<glibc>/lib,-idirafter <glibc-dev>/include,-nostdlibinc,-resource-dir=<clang-wrapper>,-Xlinker -dynamic-linker=<x86_64 ld.so>). swift-driver forwards those-Ldirs to the NDK clang ahead of the Android sysroot, so-lc/-ldlresolve to x86_64 glibc'slibc.solinker script; itsOUTPUT_FORMAT(elf64-x86-64)flips lld's target machine to x86_64, and lld then rejects the (correct)--fix-cortex-a53-843419the NDK clang added for aarch64-android. On macOS the wrapper clears allNIX_*flags, which is why the 06-14 rewrite looked fine locally and never worked on Linux CI.Proof (forge, NDK lld):
ld.lld -m aarch64linux --fix-cortex-a53-843419 -shared … AndroidJNIShim.o→ OK; add-L<glibc>/lib … -lc→ the exact error.Fix
Scripts/build-android-bridge.sh: invoke the unwrappedswift-driver(--driver-mode=swiftc,SWIFT_DRIVER_SWIFT_FRONTEND_EXEC→ real frontend), i.e. what the wrapper execs after its host-flag injection and what the nix cc-wrapper's multi-target warning itself recommends. Falls back toswiftcif the toolchain has no resolvable driver..so's ELF machine per ABI so host-flag leakage fails loudly.libc++_sharedexplicitly and stagelibc++_shared.sofrom the NDK sysroot next to the bridge.libswiftCore.soalready NEEDS it, but runtime deps were only copied from the Swift resource dir, so the packaged bridge could neverdlopenon device (SwiftHardwareKeyStoreHostswallows theUnsatisfiedLinkError, so it was silent). Bionic libs in the same sysroot dir stay excluded..forgejo/workflows/build-android.yml:bazel_targetinput, defaultbuild_release_stamp, so the manual workflow exercises the same target as the release lane (unsigned APK+AAB incl. the bridge) instead of a bridge-less debug APK.Verification
Scripts/build-android-bridge.shlinks both ABIs (AArch64/X86-64, all LOADs 16 KiB-aligned,libc++_shared.soin NEEDED and staged);Scripts/android/prepare-skip-core.sh --print-envexportsKEYSTORE_SKIP_BRIDGE_JNI_DIRin ~11s.Build: Androidon this branch withbazel_target=build_release_stamp: run 17026 got past the bridge (both ABIs linked on the real runner) and then hitcompileReleaseKotlin:KeyStoreWebDAVClient.kt:114 Unresolved reference 'chunkedStreamingMode'— a Kotlin bug from1edba7a6(2026-06-14) that was masked all along because the bridge failed first in the same genrule. Fixed in the second commit (setChunkedStreamingMode(...)); re-probe = run 17049.Follow-up (not in this PR):
Packages/swift-flake/build/wrapper.shstill contaminates any non-wasm cross target on Linux; generalizing its wasm exemption to "any non-host-target" is the principled fix but rebuilds every Swift toolchain derivation (incl. the web/wasm lane), so it is deliberately left out of this unbreak.fde3c057c3ea760c4b4a