fix(build): stage libstdc++.a before the guards; fail the job when the container aborts (#49) - #50
Merged
Conversation
…pletion The x86_64-only intrinsics guard aborts the container script under set -e, and libstdc++.a was staged after it, so it never got copied. A container abort does not fail the job (docker run returning non-zero does not stop the step), so the tarball shipped short and green. Broken artifacts: every x86_64 musl tarball since the guard landed (8.3.32, 8.3.33, 8.4.24, 8.5.9 verified) and x86_64-gnu on PHP 8.3 (8.3.32, 8.3.33). aarch64 skips the guard and is unaffected. - stage libstdc++.a right after the archives, before any guard - container writes /output/.build-complete last; Package SDK fails if it is absent - Package SDK fails when lib/ carries libicuuc.a without libstdc++.a - skip the SHA-NI symbol assertion below PHP 8.4: SHA256_Transform_shani was added in 8.4, so the check could never pass on 8.3 - musl x86_64 HAVE_FUNC_ATTRIBUTE_TARGET warns instead of failing; it has been undefined there since before the guard existed and is its own bug
This was referenced Aug 23, 2026
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 #49.
lib/libstdc++.ahas been missing from a growing set of Linux x86_64 SDK tarballs since 2026-07-09. ICU is C++, so anything static-linking those SDKs dies onoperator new,__cxa_begin_catch,__gxx_personality_v0, and__cxxabiv1vtables.Root cause
The container staging script runs under
set -euxand ordered its work:libstdc++.awas staged last, after the guards. The x86_64-only intrinsics guard (added in43267a7, 2026-07-09) aborts the script underset -e, so the staging step never ran. Two independent abort paths, both confirmed against shipped artifacts:grep -q "define HAVE_FUNC_ATTRIBUTE_TARGET 1"fails on every Alpine x86_64 build — it is/* #undef */in the shippedphp_config.hof 8.3.31, 8.3.33 and 8.5.9. The CFLAGS override from43267a7works on almalinux and has never worked on Alpine.nm libphp.a | grep -q SHA256_Transform_shanifails on PHP 8.3 — that symbol enteredext/hash/hash_sha.cin PHP 8.4 and is absent from 8.3'slibphp.a.aarch64 skips the guard entirely (
if [ "$(uname -m)" = "x86_64" ]), which is exactly why every aarch64 tarball is intact.The regression therefore begins at
43267a7, not at the 8.3.33 build.Why CI never noticed
A container-side abort does not fail the job.
docker runexiting non-zero does not stop the step.mkdir -p /outputruns long before the guards, so once/outputexists an aborted script still produces a green job and a short tarball. (Observed behaviour; the reason the exit status doesn't propagate on this fleet was not determined, and the fix does not depend on it.)That is the real defect — the missing file is one symptom of it.
Blast radius
Verified by listing archive members of the published tarballs.
Missing
lib/libstdc++.a:linux-x86_64-gnulinux-x86_64(musl)Intact: every aarch64 tarball (incl. 8.3.33),
linux-x86_64-gnuon 8.4/8.5,8.4.24-linux-x86_64-gnu-nts, and everything built before 2026-07-09.Secondary damage in the affected tarballs:
bin/php-config --libsenumerateslib/*.a, so it also omits-lstdc++; andTHIRD-PARTY-NOTICES.txtadvertises a bundled libstdc++ that isn't present.The change
libstdc++.aimmediately after the archive/header copy, before any guard runs./output/.build-completeas its final statement;Package SDKfails if it is absent. This closes the class rather than this one instance — any future early abort now reds the build instead of shipping a truncated tarball.Package SDKfails whenlib/containslibicuuc.awithoutlibstdc++.a— the exact inconsistent pair that shipped.HAVE_FUNC_ATTRIBUTE_TARGETundefined is now a hard error on glibc and a::warning::on musl (see below).Validation
Two builds dispatched with
release_tag_suffix=-libstdcxxfix, so production tags were never touched.linux-x86_64-gnu): logs showStaged libstdc++.a,HAVE_FUNC_ATTRIBUTE_TARGET is defined,skipping SHA-NI symbol check, PHP 8.3.33 predates it, andtouch /output/.build-complete. Both newPackage SDKguards passed.linux-x86_64, musl): same, with the intrinsics regression now surfacing as a visible warning instead of silently truncating the tarball.Resulting tarballs carry 38 archives each, and the only delta versus the shipped broken ones is
+ ./lib/libstdc++.a. No sentinel file leaked into the payload. The staged archive provides every symbol the downstream link was missing:_Znwm,__cxa_begin_catch,__gxx_personality_v0,_ZNSt18condition_variableC1Ev,_ZTVN10__cxxabiv120__si_class_type_infoE.Known gap, filed separately
The musl x86_64 SDKs have shipped without SHA-NI/PCLMUL/AVX2 resolvers continuously since 8.3.31 — the CFLAGS override never applied on Alpine. That is an independent bug; it is a warning here rather than an error so it doesn't block musl builds, and it needs its own fix.
After merge
Affected releases need re-dispatching without a suffix to replace the published assets.
v8.3.33linux-x86_64-gnuis the urgent one: it blocks #47 (Windows PHP 8.3 shipping with OPcache silently disabled) via ephpm/ephpm#373.