fix(build): link libc after the IREE archives so integration tests link - #1275
Merged
Conversation
Any integration test built with `xla-iree` failed to link on aarch64:
/usr/bin/ld: libiree_runtime_unified.a(call.c.o): undefined reference to
symbol '__stack_chk_guard@@GLIBC_2.17'
/usr/bin/ld: /lib/ld-linux-aarch64.so.1: error adding symbols:
DSO missing from command line
`rustc-link-arg` can only append, so the IREE archives land after rustc's own
`-lc`. `call.c.o` is built with the stack protector and references
`__stack_chk_guard`, and that reference therefore appears with no libc left
after it. The symbol is not in libc itself (`libc.so.6` lists it as UND); the
definition is in `ld-linux-aarch64.so.1`, reachable through libc's DT_NEEDED,
which is why ld names the dynamic linker rather than libc. Repeating `-lc`
after the archives puts libc where the pending reference can reach it.
Established by ablation rather than assumed: the trailing `-lc` alone fixes the
link, and `-Wl,--copy-dt-needed-entries` alone does not, because that flag only
governs inputs following it and rustc appends our args after its `-lc`. The
policy flag is therefore not shipped; it would have been a global relaxation
that can hide a genuinely missing `-l` elsewhere in the same link, for no gain.
Verified by linking four targets: `molmo2_xla_vision_parity` and
`cli_help_consistency` under `cuda,xla-iree` (both previously failed),
`molmo2_xla_vision_parity` under `xla-diagnostics` and `chat_template_kwargs`
under `cuda,xla-iree` (both previously passed, still pass), plus
`cargo check --features cuda --all-targets` for the default build.
The `IREE_DIST` and macOS recipes are left alone. `IREE_DIST` emits a nearly
identical group and is likely affected the same way, but neither an
`IREE_DIST` tree nor a macOS host is available here to confirm it by an actual
link, and this file should not carry unverified link changes.
Also drops the `link_args.insert(5, ...)` magic index. Adding one entry ahead
of it would have moved the vendored printf archive out of the group silently,
so the conditional entry is now pushed positionally, and each library in the
group carries the reason it is there.
4 tasks
inureyes
added a commit
that referenced
this pull request
Aug 21, 2026
`TECHNICAL_REPORTS/.keep-reports` opts this repository into tracking reports, and the report is meant to land inside the squash merge rather than trail it. These three merged without one, so they are added here after the fact. The reports carry the parts that do not survive in a diff. #916's recorded blocker was a TF32 artifact in the MLX oracle rather than an emitter defect, and its gate had only ever run on a single-crop solid-color image. #1275's first fix attempt shipped a redundant global linker flag until each half was ablated separately. #1273 is trivial as a change and only interesting because a compile error sat in `main` unseen, which is what #1270 tracks. Both language versions are included, matching the existing convention.
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.
Summary
Repeat
-lcafter the IREE archives in theIREE_CUDA_HOMElink recipe, so integration tests built withxla-ireelink on aarch64.Before this, any such test failed with:
Why the obvious reading of that error is wrong
The error names the dynamic linker, which invites the conclusion that the fix is to link it, or that libc is missing entirely. Neither holds:
libc.so.6does not define__stack_chk_guard. It isUNDthere. The definition is inld-linux-aarch64.so.1, reachable only through libc'sDT_NEEDED.rustc-link-argcan only append, so the IREE archives land after rustc's own-lc.call.c.ois compiled with the stack protector, so its reference to__stack_chk_guardappears at a point where no libc follows it.Repeating
-lcafter the archives puts libc where the pending reference can reach it, and ld then resolves through libc'sDT_NEEDEDas it does for any ordinary C program.The fix is minimal because it was ablated, not guessed
The first attempt here added
-Wl,--copy-dt-needed-entries, on the theory that the transitive resolution was what ld was refusing. That flag alone does not work: rustc appends our args after its-lc, so the flag lands at argument 80 while-lcis at argument 29, and it only governs inputs that follow it.Ablating each half on the real link:
-lconly-Wl,--copy-dt-needed-entriesonlySo the policy flag is not shipped. It would have been a global relaxation that can hide a genuinely missing
-lelsewhere in the same link, in exchange for nothing.Verification
Four targets linked, covering both previously-failing and previously-passing cases:
molmo2_xla_vision_paritycuda,xla-ireecli_help_consistencycuda,xla-ireemolmo2_xla_vision_parityxla-diagnosticschat_template_kwargscuda,xla-ireePlus
cargo check --features cuda --all-targetsclean, andcargo fmt --all -- --check.The two previously-passing rows matter as much as the failing ones: the failure was never uniform across targets, so a fix verified only on a failing target could have regressed the rest.
Not changed
The
IREE_DISTand macOS recipes are untouched.IREE_DISTemits a nearly identical group and is likely affected the same way, but this host has neither anIREE_DISTtree nor macOS, so neither can be confirmed by an actual link. Issue #1274 asks for those recipes to be either unchanged or verified, and unverified link changes do not belong in this file.Also in this change
link_args.insert(5, ...)is gone. Adding a single entry ahead of it would have moved the vendored printf archive out of the--start-groupblock with no error, so the conditional entry is now pushed positionally. Each library in the group also carries the reason it is present, which #1274 asks for.Left open
Why the failure was target-dependent and feature-dependent is not fully explained.
chat_template_kwargslinked undercuda,xla-ireewhilemolmo2_xla_vision_paritydid not, and the samemolmo2_xla_vision_paritylinked underxla-diagnostics. Both working binaries carryld-linux-aarch64.so.1as an explicitDT_NEEDEDand the failing links do not, so something in those link lines was already pulling it in. Thesurgerydefault feature was suspected and is neither confirmed nor ruled out. This fix removes the ordering dependency for every target, so the asymmetry stops mattering in practice, but it is recorded here rather than left as folklore.Closes #1274