Repository navigation
fix(npm): build linux-gnu prebuilds against a glibc 2.17 floor - #469
Merged
Merged
Conversation
The `*-linux-*-gnu` npm prebuilds were linked on bare ubuntu-latest and inherited its glibc: the shipped `.node` required GLIBC_2.39 (Rust std's weak `pidfd_spawnp` / `pidfd_getpid`), so it failed to load on RHEL 9, AL2023 and Debian 12. Build both linux-gnu targets with napi-rs's `--use-napi-cross`, whose GCC toolchain links against a glibc 2.17 sysroot. That is the floor the Python wheels already get from maturin-action's `manylinux: auto` (manylinux2014). libxkbcommon is the only system library xa11y-linux links, and the cross sysroot lacks it, so it is exposed to the linker from a directory holding only that one `.so`; putting the runner's whole multiarch libdir on `-L` would let its libc.so shadow the sysroot's. The aarch64 job's gcc-aarch64-linux-gnu linker env is removed: `--use-napi-cross` only sets the linker when it is unset, so leaving it would silently restore the bug. Guard it so it cannot regress: - `.github/scripts/check_glibc_floor.py` reads `.gnu.version_r` straight from the ELF (no binutils, works on the cross-built aarch64 object) and fails, naming the offending symbols, when any GLIBC_* need exceeds `--max`. It also fails on an object with no GLIBC_* needs at all, so a parser bug or wrong input cannot pass. Self-tests on synthesized ELF32/ELF64, LE/BE objects plus the running interpreter run in the CI `python` job and `cargo xtask test-harness`. - publish.yml runs it after each linux-gnu build, before upload. - The CI `js` job on Linux now builds the binding the same way, runs the guard, loads the `.node` in an AlmaLinux 9 container, and runs the unit tests against that binary, so a regression fails on the PR rather than at release time. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01DqmE11zWLkMi4JgzFdRP8a
Writing RUSTFLAGS to GITHUB_ENV replaced the workflow-level -Dwarnings for every later step in the job. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01DqmE11zWLkMi4JgzFdRP8a
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.
Fixes #462.
Change
--use-napi-cross, which uses a GCC toolchain with a glibc 2.17 sysroot. That matches the manylinux2014 floor the Python wheels get frommanylinux: auto./usr/lib/<multiarch>instead would put the runner'slibc.soon the search path and undo the floor..github/scripts/check_glibc_floor.py --max 2.17parses the ELF version tables in pure Python and fails on anyGLIBC_*version above the floor. On failure it names the symbols responsible. It also fails onGLIBC_PRIVATE, on a file with no GLIBC references, and on input that isn't ELF. It has 12 pytest tests.jsjob builds the same way, runs the guard, and loads the.nodein analmalinux:9container (glibc 2.34). The guard's self-tests run in thepythonjob and incargo xtask test-harness.RUSTFLAGSis appended to rather than replaced, so the workflow-level-Dwarningsstill applies.Tests
GLIBC_2.39(pidfd_getpid,pidfd_spawnp).GLIBC_2.15and arm64GLIBC_2.17.npm testpasses, 152/152, against the floor-built binary.Only verifiable in CI or at release
Not addressed
The binary still has a hard
NEEDED libxkbcommon.so.0, as before. Loading it at runtime withxkbcommon-dlwould be a follow-up.Generated by Claude Code