Uh oh!
There was an error while loading. Please reload this page.
Include self-contained -L in native-static-libs - #159145
Conversation
rustbot
commented
Jul 11, 2026
r? @TaKO8Ki rustbot has assigned @TaKO8Ki. Use Why was this reviewer chosen?The reviewer was selected based on:
|
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
0d8d502 to
6d07079Comparebjorn3
commented
Jul 12, 2026
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 |
alyssais
commented
Jul 12, 2026
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
commented
Jul 12, 2026
(Building pure Rust applications with Meson works fine, because then rustc does the final link.) |
bjorn3
commented
Jul 12, 2026
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? |
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. Lines 1075 to 1077 in f0b782b |
alyssais
commented
Jul 12, 2026
(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
commented
Jul 21, 2026
r? compiler |
JohnTitor
commented
Aug 10, 2026
@rustbot reroll |
chenyukang
commented
Aug 24, 2026
@rustbot reroll |
adwinwhite
commented
Aug 25, 2026
@rustbot reroll |
mu001999
commented
Aug 25, 2026
@rustbot reroll |
saethlin
commented
Aug 26, 2026
r? me |
mati865
commented
Aug 26, 2026
Wouldn't the solution here be to link libunwind only if self-contained mode is active? |
bjorn3
commented
Aug 26, 2026
If we didn't explicitly link libunwind, no unwinder would be linked at all. |
mati865
commented
Aug 26, 2026
If we are not in self-contained mode the user has to supply Musl objects and libs, either by linking with I forgot that we handle unwind library linking via |
bjorn3
commented
Aug 26, 2026
If the user statically links the executable, linking libgcc is not enough. libgcc_eh also needs to be linked. And even if that may be the default of gcc and clang, we explicitly disable linking to default libraries on most targets. |
mati865
commented
Aug 26, 2026
My bad there, I thought of libgcc unwind library (libgcc{_eh,_s}) when writing libgcc.
Yeah, but then we explicitly link the unwind library. So, ideally for musl we'd link:
|
bjorn3
commented
Aug 26, 2026
We don't know if the host toolchain uses libgcc or compiler-rt, right? In the latter case libunwind would still be used I think. |
mati865
commented
Aug 26, 2026
Builtins and unwinder are two distinct things. First one is handled by Perhaps we could use target-feature akin to |
bjorn3
commented
Aug 26, 2026
libgcc_s contains both. So you can't use libunwind when dynamically linking libgcc. |
Well, yes it's a linker script that links
I don't understand. You cannot use libuwind when linking either libgcc unwinder, be it libgcc_s or libgcc_eh. Still you can use LLVM's EDIT: fixed typo. |
bjorn3
commented
Aug 26, 2026
If you statically link libgcc.a you have the option to use libunwind instead of libgcc_eh. If you dynamically link libgcc_s.so (which I assumed would be providing the compiler builtins instead of libgcc.a), you don't have the option to use libunwind. |
mati865
commented
Aug 26, 2026
I think I see where the confusion is coming from. You could say that symbols from So, to rephrase it. You (almost) always need the unwinder (shared: If we had target modifier to control the unwinder, we could let the user decide which one to use (unless I'm missing something). Rather than forcing one whether linking Musl statically or dynamically. But that's a much more complex solution. Coming back to the solution proposed by this PR, Regarding https://bugs.gentoo.org/967728 I suppose I think mesonbuild/meson#15216 is an unfortunate workaround for our shortcomings in this area, because AFAIK the files layout is an implementation detail and therefore not guaranteed. |
View all comments
(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-libsoption 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 onnative-static-libswill 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.