Include self-contained -L in native-static-libs - #159145
Conversation
|
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
6d07079
Compare
|
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 |
|
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. |
|
(Building pure Rust applications with Meson works fine, because then rustc does the final link.) |
|
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 |
|
(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.) |
|
r? compiler |
(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.