Thanks for sqlite3.dart — the prebuilt-binary hook makes SQLCipher genuinely painless to ship, which is why I'm raising this rather than working around it.
The problem: the prebuilt Linux assets reference GLIBC_2.38, so an application bundling them fails to start on any distro older than that — including Ubuntu 22.04 LTS (glibc 2.35, supported to 2027) and Debian 12 (2.36, supported to 2028).
Evidence, from libsqlcipher.x64.linux.so in the sqlite3-3.3.4 release (sha256 46205b32…a0b63, matching asset_hashes.dart):
$ objdump -T libsqlcipher.x64.linux.so | grep GLIBC_2.38
0000000000000000 DF UND 0000000000000000 (GLIBC_2.38) __isoc23_strtol
One symbol, and it isn't deliberate: __isoc23_strtol is what glibc ≥ 2.38 headers transparently redirect a plain strtol() to. It's a fingerprint of the build host, not a feature the code uses. libsqlcipher.arm64.linux.so (sha256 6826ecd9…a78db) has the identical symbol — expected, since build_sqlite cross-compiles every Linux ABI from one runner.
Why I think this is cheap to fix: in .github/workflows/compile_sqlite.yml, both build_openssl and build_sqlite use runs-on: ${{ matrix.os }} with ubuntu-latest in the matrix, and install gcc-aarch64-linux-gnu etc. to cross-compile the other ABIs. Since every Linux ABI already comes from that single host, pinning it to ubuntu-22.04 would lower the floor for all of them at once:
strategy:
matrix:
os: [ubuntu-22.04, macos-latest, windows-latest]
Ubuntu 22.04 is glibc 2.35, and 22.04 runners are still available on GitHub Actions.
Questions, since you know the constraints better than I do:
Is ubuntu-latest deliberate here — e.g. do the sanitizer or Android jobs need a newer toolchain? Those could stay on ubuntu-latest independently; only the release-artifact jobs need the older host.
Would you rather set an explicit floor via a sysroot or -D_ISOC23_SOURCE-style opt-out than pin the runner? Either works for us; pinning just looked like the smallest change.
I've only measured the sqlcipher assets. Presumably the sqlite3 and sqlite3mc Linux assets from the same job have the same floor — worth checking if you take this on.
Workarounds we considered, for context on why I'm asking upstream: the hook resolves releaseTag from a const bound to the package version and user_defines exposes no tag or hash override, so pinning an older asset isn't possible from the consumer side — and the previous release (sqlite3-3.3.3, the first with sqlcipher assets) ships byte-identical binaries anyway (same sha256 and same BuildID), so there's nothing older to fall back to. Building SQLCipher ourselves means reproducing the static OpenSSL 3.6.2 cross-build too, which we'd rather not take on.
Happy to open the PR if you'd like — it's a one-line change, though only you can confirm it doesn't break the jobs I can't see the constraints on.
Thanks for sqlite3.dart — the prebuilt-binary hook makes SQLCipher genuinely painless to ship, which is why I'm raising this rather than working around it.
The problem: the prebuilt Linux assets reference GLIBC_2.38, so an application bundling them fails to start on any distro older than that — including Ubuntu 22.04 LTS (glibc 2.35, supported to 2027) and Debian 12 (2.36, supported to 2028).
Evidence, from libsqlcipher.x64.linux.so in the sqlite3-3.3.4 release (sha256 46205b32…a0b63, matching asset_hashes.dart):
$ objdump -T libsqlcipher.x64.linux.so | grep GLIBC_2.38
0000000000000000 DF UND 0000000000000000 (GLIBC_2.38) __isoc23_strtol
One symbol, and it isn't deliberate: __isoc23_strtol is what glibc ≥ 2.38 headers transparently redirect a plain strtol() to. It's a fingerprint of the build host, not a feature the code uses. libsqlcipher.arm64.linux.so (sha256 6826ecd9…a78db) has the identical symbol — expected, since build_sqlite cross-compiles every Linux ABI from one runner.
Why I think this is cheap to fix: in .github/workflows/compile_sqlite.yml, both build_openssl and build_sqlite use runs-on: ${{ matrix.os }} with ubuntu-latest in the matrix, and install gcc-aarch64-linux-gnu etc. to cross-compile the other ABIs. Since every Linux ABI already comes from that single host, pinning it to ubuntu-22.04 would lower the floor for all of them at once:
strategy:
matrix:
os: [ubuntu-22.04, macos-latest, windows-latest]
Ubuntu 22.04 is glibc 2.35, and 22.04 runners are still available on GitHub Actions.
Questions, since you know the constraints better than I do:
Is ubuntu-latest deliberate here — e.g. do the sanitizer or Android jobs need a newer toolchain? Those could stay on ubuntu-latest independently; only the release-artifact jobs need the older host.
Would you rather set an explicit floor via a sysroot or -D_ISOC23_SOURCE-style opt-out than pin the runner? Either works for us; pinning just looked like the smallest change.
I've only measured the sqlcipher assets. Presumably the sqlite3 and sqlite3mc Linux assets from the same job have the same floor — worth checking if you take this on.
Workarounds we considered, for context on why I'm asking upstream: the hook resolves releaseTag from a const bound to the package version and user_defines exposes no tag or hash override, so pinning an older asset isn't possible from the consumer side — and the previous release (sqlite3-3.3.3, the first with sqlcipher assets) ships byte-identical binaries anyway (same sha256 and same BuildID), so there's nothing older to fall back to. Building SQLCipher ourselves means reproducing the static OpenSSL 3.6.2 cross-build too, which we'd rather not take on.
Happy to open the PR if you'd like — it's a one-line change, though only you can confirm it doesn't break the jobs I can't see the constraints on.