Build on manylinux_2_28 (glibc 2.28, GCC 14) - #17
Merged
Merged
Conversation
glibc 2.28 is the newest that still runs on Ubuntu 20.04 (2.31), the oldest release Hatchbox provisions. Building against it lets Ruby use statx (File.birthtime works from 2.7), copy_file_range and getrandom, which the glibc 2.17 builds compiled out, and moves off the end-of-life CentOS 7 image. GCC 14 rejects implicit function declarations, implicit int and incompatible pointer types, which Ruby 2.2 and older rely on (and which break their configure checks for OpenSSL functions), so 1.8 to 2.2 downgrade those four to warnings. Only flags GCC 8 and older also know: CFLAGS stays in rbconfig and reaches native gems built on servers with an older compiler. bin/package-linux keys its derived image and build volume by the container, so a new pin doesn't reuse the old toolchain's image or dependency builds.
…g files Merging libruby-static.a into one object (#16) made every mkmf probe link the whole of Ruby with its debug info: ~900 MB of linker memory per have_func on 3.4, which got four-way parallel gem installs OOM-killed in a 2 GB container, and a killed link reads as 'function missing' (json 3.0.2 then failed to compile). Nothing debugs through this archive; stripped, a probe takes ~50 MB (the published 2.17 builds took ~270 MB) and the archive shrinks from 156 MB to 15 MB. The installation test fails if it has debug sections again. The pkg-config files copied from the dependencies and Ruby's ruby-X.pc named the build tree; point them at ${pcfiledir}/../.. like the rest, and check it. Also blank rbconfig's RUST_LIB, a build-tree path only Ruby's own build uses.
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.
Moves every target from manylinux2014 (CentOS 7, glibc 2.17, GCC 10) to manylinux_2_28 (AlmaLinux 8, glibc 2.28, GCC 14).
Why 2.28
It is the newest glibc that still runs on Ubuntu 20.04 (2.31), the oldest release Hatchbox provisions; manylinux_2_34 would drop focal. It also covers Debian 10+ and RHEL 8+.
What it buys (verified on the new builds):
statx,copy_file_rangeandgetrandom, which the 2.17 builds compiled out.File.birthtimeworks on 2.7 and later (it raisedNotImplementedError); 2.2 to 2.6 predate Ruby's statx support, and 1.8 to 2.1 have noFile.birthtime.Changes
recipes/targets.yml: new pinned containers (2026.09.29-1, by digest),max_glibc: "2.28".recipes/series.yml: 1.8 to 2.2 downgrade the four GCC 14 permerrors (implicit function declaration, implicit int, int conversion, incompatible pointer types) to warnings. Without them 1.9.3/2.0/2.1/2.2 fail to compile, and their openssl extension's configure checks misdetect OpenSSL functions. Only flags GCC 8 also accepts: CFLAGS stays in rbconfig, and the two GCC-14-only flags (return-mismatch,declaration-missing-parameter-type) made every native gem build fail with an older compiler (caught by the package's own test, which compiles with the image's gcc 8cc).bin/package-linux: derived image and build volume keyed by the container, so a new pin doesn't reuse the old toolchain's image or dependency builds.Testing
CI: Build workflow dispatched on this branch for 1.8.7, 1.9.3, 2.0.0, 2.1.10, 2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.8, 3.0.7, 3.1.7, 3.2.11, 3.3.12, 3.4.11, 4.0.7: all 16 pass on both targets, YJIT variants included.
Local arm64 builds of the same 16, tested on Ubuntu 20.04 and 26.04: pg (from source, system libpq) + TLS Postgres 17 + HTTPS in both require orders pass on all 16 on 20.04; no termcap warning, no build paths in rbconfig, strscan 3.1.8 loads (2.4+), puma compiles against the bundled OpenSSL. Tarballs need at most GLIBC_2.28 and ship no run paths (except 4.0.7's pre-existing
/./lib).x86_64 CI artifacts of 1.8.7, 2.1.10, 2.7.8 and 3.4.11 (YJIT) on Ubuntu 20.04 amd64: pg/HTTPS both orders pass; YJIT enables;
File.birthtimeworks on 3.4.11.On Ubuntu 26.04 (GCC 15), a plain
gem install pgworks on the new builds, and pg 1.0.0 on 2.1.10 now compiles there (it fails on the current release).Rails deploy matrix on these builds (arm64, Ubuntu 24.04): fresh app, deployment bundle with native gems from source, migrations over TLS to Postgres, assets, runner with HTTPS, Puma HTTP and
ssl://form flow, both pg/openssl load orders. All pass: 1.8.7/Rails 3.2; 1.9.3, 2.0.0, 2.1.10/4.2; 2.2.10, 2.3.8, 2.4.10/5.2; 2.5.9, 2.6.10/6.1 (2.5.9 also without themailpin: strscan 3.1.8 now loads); 2.7.8, 3.0.7/7.1; 3.1.7/7.2; 3.2.11/8.0; 3.4.11, 4.0.7/8.1 (Solid Queue, YJIT). Same gem pins as the 2.17 builds; no termcap messages; no build-tree paths in rbconfig or any run path; compiler warnings in gem builds identical to the 2.17 builds.Also fixes a regression from #16 (merged, unreleased)
The Rails run caught it: merging
libruby-static.ainto one object made every mkmf probe link all of Ruby with its debug info, ~900 MB of linker memory perhave_funcon 3.4. Four parallel gem builds in 2 GB got OOM-killed, and a killed probe reads as "function missing" (json 3.0.2 then failed to compile). The merged object is now stripped of debug info: a probe link peaks at ~48 MB (published 2.17 builds: ~290 MB),libruby-static.adrops from ~155 MB to 14 MB, and the 3.4.11 YJIT tarball from ~92 MB to 59 MB. 3.4.11 and 4.0.7 on Rails 8.1 then pass with default parallelism and zero OOM kills. The installation test fails if the archive has debug sections again.Also in this PR:
lib/pkgconfig/*.pcno longer name the build tree (relocated to${pcfiledir}/../.., and checked), and rbconfig'sRUST_LIBbuild path is blanked.Known leftover (unchanged from the published builds): the bundled OpenSSL's compiled-in
OPENSSLDIRis a build-tree path, so OpenSSL looks foropenssl.cnfthere; certificate lookup is unaffected (the patchedopenssl.rbsupplies the system store).After merge
Every build changes. #16 is merged but not yet released, so one Release New Versions run with
replace_allpublishes both.