Skip to content

Include self-contained -L in native-static-libs - #159145

Open
alyssais wants to merge 1 commit into
rust-lang:mainfrom
alyssais:native-static-libs
Open

Include self-contained -L in native-static-libs#159145
alyssais wants to merge 1 commit into
rust-lang:mainfrom
alyssais:native-static-libs

Conversation

@alyssais

Copy link
Copy Markdown
Contributor

(I suggest reviewing with whitespace ignored.)

rustc uses heuristics to determine whether the self-contained path should be on the linker search path. It's important to get these right, because if self-contained is improperly missing from the search path, linking will fail (as seen here), but if it's improperly present, a broken executable can be produced due to e.g. linking two different libcs (as seen here and here). All of this works reasonably well when rustc is doing the linking, but when linking is done externally, there's a problem: there's no way for a build tool to know whether rustc would include the self-contained path or not. Without a way to find this out from rustc, the only way for a build tool to correctly link with a staticlib produced by rustc is to exactly reimplement rustc's heuristics. Not ideal.

The existing rustc --print native-static-libs option exists to enable build tools to find out what linker flags should be used when linking a rustc-produced staticlib. Without including the argument to add the self-contained directory to the search path when necessary, though, it doesn't meet its intended purpose — build tools relying on native-static-libs will still sometimes do the wrong thing. Fixing this will make it possible for build tools to link the correct self-contained libraries when necessary, without each build tool having to match rustc's heuristics itself. This will enable fixing real problems encountered with Meson, where either self-contained libraries were not found, or self-contained libraries were incorrectly linked.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 11, 2026
@rustbot

rustbot commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

r? @TaKO8Ki

rustbot has assigned @TaKO8Ki.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: codegen, compiler
  • codegen, compiler expanded to 75 candidates
  • Random selection from 18 candidates

rustc uses heuristics to determine whether the self-contained path
should be on the linker search path.  It's important to get these
right, because if self-contained is improperly missing from the search
path, linking will fail (as seen in [1]), but if it's improperly
present, a broken executable can be produced due to e.g. linking two
different libcs (as seen in [2][3]).  All of this works reasonably
well when rustc is doing the linking, but when linking is done
externally, there's a problem: there's no way for a build tool to know
whether rustc would include the self-contained path or not.  Without a
way to find this out from rustc, the only way for a build tool to
correctly link with a staticlib produced by rustc is to exactly
reimplement rustc's heuristics.  Not ideal.

The existing rustc --print native-static-libs option exists to enable
build tools to find out what linker flags should be used when linking
a rustc-produced staticlib.  Without including the argument to add the
self-contained directory to the search path when necessary, though, it
doesn't meet its intended purpose — build tools relying on
`native-static-libs` will still sometimes do the wrong thing.  Fixing
this will make it possible for build tools to link the correct
self-contained libraries when necessary, without each build tool
having to match rustc's heuristics itself.  This will enable fixing
real problems encountered with Meson, where either self-contained
libraries were not found, or self-contained libraries were incorrectly
linked.

[1]: mesonbuild/meson#15216
[2]: https://bugs.gentoo.org/970166
[3]: https://bugs.gentoo.org/967728
@alyssais
alyssais force-pushed the native-static-libs branch from 0d8d502 to 6d07079 Compare July 11, 2026 18:30
@bjorn3

bjorn3 commented Jul 12, 2026

Copy link
Copy Markdown
Member

If you are building a staticlib, I wouldn't expect it to contain self-contained artifacts. Whatever executable/dylib you link it into already has to either provide those artifacts for itself or get them from the system even if the rust staticlib wasn't linked in. The self-contained artifacts consists of a linker, libraries and object files (think crt*.o) a regular C toolchain for the target would ship. The self-contained artifacts allow you to link without needing a C toolchain for the target. For Meson I would expect a C toolchain to already be available for the C code that gets link too. Or is the use case for this building pure Rust applications with Meson?

@alyssais

Copy link
Copy Markdown
Contributor Author

The staticlib in this case does not contain/bundle artifacts, but it might expect to link with e.g. rustc's self-contained libunwind. If I build a staticlib with rustc's +crt-static x86_64-unknown-linux-musl target, it's expected to be ultimately linked with libunwind even though the musl C toolchain probably doesn't provide that by default. In a mixed Rust+C program, if rustc does the final link, it will link with the self-contained libunwind. Presumably, since the libunwind requirement is coming from the Rust part, that same libunwind (from rustc's self-contained directory) should be used when the C toolchain happens to be doing the final link.

@alyssais

Copy link
Copy Markdown
Contributor Author

(Building pure Rust applications with Meson works fine, because then rustc does the final link.)

@bjorn3

bjorn3 commented Jul 12, 2026

Copy link
Copy Markdown
Member

The standard library needs either libunwind or libgcc (libgcc_eh.a or libgcc_s.so) as unwinder. It is important that only one unwinder ends up getting linked into the entire program to ensure dynamic registration of unwind tables will always be done against the same unwinder as the one that does the actual unwinding. If your C toolchain comes with libgcc instead of libunwind you should probably link against that instead. If your C toolchain provides neither, is it not capable of compiling C++ code?

@alyssais

alyssais commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

I believe it provides libgcc_eh.a, but per bootstrap.example.toml, rustc will only ever use libunwind for musl +crt-static, not libgcc_eh.

rust/bootstrap.example.toml

Lines 1075 to 1077 in f0b782b

# the behavior is depend on the libc. On musl target, 'no' and 'in-tree' both
# means static link to the in-tree build of llvm libunwind, and 'system' means
# static link to `libunwind.a` provided by system. Due to the limitation of glibc,

@alyssais

Copy link
Copy Markdown
Contributor Author

(And if I am supposed to link against libgcc_eh anyway, that means I can't trust the output of native-static-libs, which includes -lunwind, even though it may not exist outside of self-contained.)

@TaKO8Ki

TaKO8Ki commented Jul 21, 2026

Copy link
Copy Markdown
Member

r? compiler

@rustbot rustbot assigned JohnTitor and unassigned TaKO8Ki Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants