SDK missing libngtcp2 and libsqlite3.so symlink — standalone Android apps crash or fail to link
## Summary
Two missing dependencies in the SDK cause issues for standalone Android apps:
1. **libngtcp2** — `libcurl.so` has `NEEDED: libngtcp2.so` and `NEEDED: libngtcp2_crypto_ossl.so`, but `libngtcp2` is not in the `termuxPackages` list. Apps crash at startup with `UnsatisfiedLinkError`.
2. **libsqlite3.so symlink** — the SDK's flatten step removes Termux's `libsqlite3.so` symlink but doesn't recreate it, leaving only the oddly-named `libsqlite3.51.2.so`. Any package using the system sqlite3 module (e.g. via `link "sqlite3"` in a `systemLibrary` target) fails to link.
## Root Cause
### libngtcp2
`termuxPackages` includes `libnghttp3` (HTTP/3 protocol layer) but omits `libngtcp2` (QUIC transport layer). Both are required by Termux's libcurl since the recent addition of HTTP/3 support ([termux/termux-packages@079e41583](https://github.com/termux/termux-packages/commit/079e41583)):
```
$ curl -fsSL ".../binary-aarch64/Packages" | grep -A5 "^Package: libcurl$"
Version: 8.18.0-1
Depends: libnghttp2, libnghttp3, libngtcp2, libssh2, openssl (>= 1:3.2.1-1), zlib
```
Confirmed via `readelf`:
```
$ readelf -d libcurl.so | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libngtcp2.so]
0x0000000000000001 (NEEDED) Shared library: [libngtcp2_crypto_ossl.so]
```
### libsqlite3.so symlink
The flatten step ([`1d027a4d`](https://github.com/finagolfin/swift-android-sdk/commit/1d027a4df0)) removes all symlinks and then renames versioned files matching the `lib*.so.X.Y.Z` pattern (version digits after `.so`). Termux's `libsqlite3.so → libsqlite3.51.2.so` symlink gets removed, but `libsqlite3.51.2.so` isn't renamed because the `.51.2` is before `.so` — the flatten code sees `soVersion = ""` and treats it as unversioned. The result is only `libsqlite3.51.2.so` remains, with no `libsqlite3.so`.
## Why CI doesn't catch it
~~CI tests run inside the Termux app context (`run-as com.termux`), where `libngtcp2.so` is already available as a system library. Standalone Android apps have no Termux runtime, so the library is missing from the linker path.~~
**Correction** (per @finagolfin): None of the packages tested in CI use FoundationNetworking, and CI doesn't build an APK with the Swift runtime — which is what would check these unused libcurl dependencies. Similarly, no tested packages link sqlite3 via a systemLibrary target.
## Fix
### libngtcp2
One-line change in `get-packages-and-swift-source.swift`:
```diff
-// libcurl needs zlib, libnghttp3, libnghttp2, libssh2, and openssl
-var termuxPackages = ["libandroid-execinfo", "libandroid-spawn", "libandroid-spawn-static", "libcurl", "zlib", "libxml2", "libnghttp3", "libnghttp2", "libssh2", "openssl", "liblzma", "libiconv"]
+// libcurl needs zlib, libnghttp3, libngtcp2, libnghttp2, libssh2, and openssl
+var termuxPackages = ["libandroid-execinfo", "libandroid-spawn", "libandroid-spawn-static", "libcurl", "zlib", "libxml2", "libnghttp3", "libngtcp2", "libnghttp2", "libssh2", "openssl", "liblzma", "libiconv"]
```
### libsqlite3.so symlink
Add a post-flatten fixup to create the symlink, e.g.:
```swift
// Handle libsqlite3 which uses non-standard versioning (libsqlite3.51.2.so instead of libsqlite3.so.51.2)
if fmd.fileExists(atPath: sopath("libsqlite3.51.2.so")) && !fmd.fileExists(atPath: sopath("libsqlite3.so")) {
try fmd.createSymbolicLink(atPath: sopath("libsqlite3.so"), withDestinationPath: "libsqlite3.51.2.so")
}
```
## Affected versions
6.2.4 (and likely 6.3 snapshots — same `termuxPackages` list and flatten logic)
## Workaround
**libngtcp2:** Download the `libngtcp2` package from the Termux repo (it contains both `libngtcp2.so` and `libngtcp2_crypto_ossl.so`), patch with `patchelf` (fix RUNPATH to `$ORIGIN`, replace NEEDED `libssl.so.3` → `libssl.so` and `libcrypto.so.3` → `libcrypto.so` to match the SDK's flattened library names), and copy into the SDK sysroot.
**libsqlite3.so:** Create symlinks manually: `ln -sf libsqlite3.51.2.so libsqlite3.so` in each arch directory.
3 条评论