fix(linux): stop the packages needing a glibc newer than the target distro - #322
Merged
Conversation
…istro The Linux twin of the Visual C++ Redistributable bug: the linker binds every symbol to the newest version its BUILD machine offers, so `ubuntu-latest` silently decided the oldest distro these packages could run on. Nothing in the source asked for any of it. `__isoc23_strtol` is glibc 2.38's C23 redirect of `strtol`, `_ZSt21ios_base_library_initv` is what GCC 13.2+ emits into every translation unit that includes <iostream>, and `hypotf@GLIBC_2.35` is Rust's f32::hypot taking the newest version of a symbol that has existed since 2.2.5. Measured on the shipped 1.9.0 packages — the .deb, and the AppImage carries byte-identical binaries: whisper-stt-server and the libggml backends need GLIBC_2.38, so they die in ld.so before main() on Ubuntu 22.04, Debian 12 and RHEL 9 and transcription fails with a developer error shown to end users; and compositor_view.node needs GLIBC_2.35, so on RHEL 9 the preview renders nothing and every export falls back to the no-op compositor. The app still LAUNCHES on all of them, because Electron itself needs only 2.25 — which is exactly what makes this read as a broken app rather than a broken package. No package format catches it. The deb/rpm/pacman `depends` lists are hand-written in electron-builder.json5, and electron-builder passes fpm none of --rpm-autoreq*, so not even dnf generates the libc.so.6(GLIBC_2.38) requirement that would have refused the install on a machine that cannot run it. Pin both jobs that produce Linux natives to ubuntu-22.04 — the oldest distro the README claims, and the binding one against Debian 12 — and enforce the resulting ceiling on the built payload in before-pack.cjs, so bumping a runner image cannot quietly lower the reach again. The guard reads .gnu.version_r and deliberately not .gnu.version_d: libc and libstdc++ define every version they ever shipped, and reading definitions would report a bundled library as needing itself. It is parsed in Node for the same reason importedDlls() does not use dumpbin — binutils is not installed on every machine that packages this. patchelf gets its own step because 22.04 carries 0.14.3 and `--rename-dynamic-symbols` only arrived in 0.18.0. 0.18.0 is also exactly what the 24.04 image provided, so the compositor's symbol renaming is unchanged. RHEL/Rocky/Alma 9 (glibc 2.34) stay out of range, by exactly one symbol: the `hypotf` in compositor_view.node. Everything else in that addon is 2.34 or older. Closing that is a separate decision from this one.
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughLinux workflows now use Ubuntu 22.04 and verified ChangesLinux packaging compatibility
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant LinuxPackaging
participant NativePayloadValidation
participant ELFDiscovery
participant ELFParser
participant CompatibilityEnforcement
LinuxPackaging->>NativePayloadValidation: validate native payload
NativePayloadValidation->>ELFDiscovery: find nested ELF files
ELFDiscovery->>ELFParser: parse symbol-version requirements
ELFParser-->>CompatibilityEnforcement: return required runtime versions
CompatibilityEnforcement-->>LinuxPackaging: allow or reject packaging
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Linux twin of #321. Same bug class: a runtime dependency that is present on every build machine and absent on the target, so it works in CI and in local testing and dies on a user's box.
What was wrong
The linker binds each symbol to the newest version its build machine offers, so
ubuntu-latestsilently decided the oldest distro these packages could run on. Nothing in the source asked for any of it:__isoc23_strtol/strtoll/strtoul/strtoull— glibc 2.38's C23 redirect ofstrtol_ZSt21ios_base_library_initv— what GCC 13.2+ emits into every TU that includes<iostream>hypotf@GLIBC_2.35— Rust'sf32::hypottaking the newest version of a symbol that has existed since 2.2.5Measured on the shipped 1.9.0 packages (the
.deb; the AppImage carries byte-identical binaries, sha256-matched), reading.gnu.version_r:openscreen(Electron)So on Ubuntu 22.04 LTS (2.35), Debian 12 (2.36) and RHEL/Rocky/Alma 9 (2.34),
whisper-stt-serverand the ggml backends died inld.sobeforemain()— transcription and captions fail with a developer error shown to end users — and on RHEL 9compositor_view.nodefailedrequire()too, so the preview rendered nothing and every export fell back to the no-op compositor.The app still launches on all of them, because Electron itself only needs 2.25. That is what makes this read as a broken app rather than a broken package, with nothing in any log to say otherwise.
No package format catches it. The deb/rpm/pacman
dependslists are hand-written inelectron-builder.json5, and electron-builder passes fpm none of--rpm-autoreq*— so not evendnfgenerates thelibc.so.6(GLIBC_2.38)requirement that would have refused the install. README names Ubuntu 22.04 as the PipeWire baseline and offers an.rpmfor RHEL/CentOS.The fix
Pin both jobs that produce Linux natives to
ubuntu-22.04— the oldest distro the README claims, and the binding one against Debian 12 — and enforce the resulting ceiling on the built payload inbefore-pack.cjsso bumping a runner image cannot quietly lower the reach again.patchelfgets its own step: 22.04 carries 0.14.3 and--rename-dynamic-symbolsonly arrived in 0.18.0. 0.18.0 is also exactly what the 24.04 image provided, so the compositor's symbol renaming is unchanged.The guard reads
.gnu.version_rand deliberately not.gnu.version_d— libc and libstdc++ define every version they ever shipped, so reading definitions would report a bundled library as needing itself. It parses ELF in Node for the same reasonimportedDlls()does not use dumpbin: binutils is not installed on every machine that packages this. It carries the same "read nothing ⇒ the parser broke" assertion as the Windows guard.Verification
Both workflows run green on this branch, and the resulting packages were downloaded and re-measured the same way the bug was found:
hypotf)Floor: GLIBC 2.38 → 2.35, GLIBCXX 3.4.32 → 3.4.30. Every
__isoc23_*reference is gone. Ubuntu 22.04 LTS and Debian 12 now run the whole app.Image: ubuntu-22.04andpatchelf 0.18.0The ELF parser was also checked against
readelf -Von the real payload — 23/23 files agree — and the guard was confirmed to reject the old 1.9.0 payload, naming all 16 offending files.Not addressed here
RHEL/Rocky/Alma 9 is still out of range, on two counts:
hypotf@GLIBC_2.35in the compositor addon (2.34 available) andGLIBCXX_3.4.30in whisper-stt-server and libggml-vulkan (3.4.29 available). Closing that means building in a container (Rocky 9 or Debian 11), not a symbol tweak — a bigger decision, and a separate one. The README's.rpmsection still implies RHEL support; correcting that wording is a product call left out of this PR.ubuntu-22.04is still a published runner image but on a slower cadence than 24/26 — worth revisiting before it retires, at which point a container is the successor.Summary by CodeRabbit
Bug Fixes
Quality Improvements