-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustc-book: Document -C target-feature=+crt-static
#71586
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
- Unknown CPU features go straight to LLVM and appear as LLVM warnings. | ||
- At configure time `crt-static` predicate is set even if the target doesn't support `crt-static`. | ||
- At link time `crt-static` is sometimes ignored | ||
if the target doesn't support it and sometimes not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I strongly suspect that #69519 was a hack rather than a proper solution, but I need some time to prepare a musl setup and verify things. (Proc-macros shouldn't be any different to cdylibs and dylibs with regards to linking behavior.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proc-macros shouldn't be any different to cdylibs and dylibs with regards to linking behavior
That was the problem 😉
TL;DR It's a hack.
Musl target is a "weirdo". Because of the legacy decisions it defaults to static linking so it cannot produce dylibs, cdylibs and proc-macros. Now lack of proc-macro support doesn't matter when cross-compiling from the host which supports them to musl.
It becomes difficult when using musl as the host toolchain. Since it defaults to static linking proc-macros don't work. To build them one had to use target-feature=-crt-static
and lose ability to statically link binaries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mati865
First, musl toolchain actually supports statically linking self-contained .so
s, despite the flag in rustc
target spec saying otherwise, I tried it (at least with "hello world"-like examples).
Second, that doesn't mean that we want to use it for proc macros (as well as cdylibs and dylibs) at the same time as we are building a statically linked executable.
So, one common RUSTFLAGS="-Ctarget-feature=+crt-static"
(or a target spec default) in this case brings collateral damage on the crates which it is not supposed to apply to.
I see multiple possible solutions here some of which could be more principled than what #69519 did.
- Automatically enable
-Ctarget-feature=-crt-static
for proc macro crates or all libraries in Cargo, modifying RUSTFLAGS. Question: how to opt-out? - Introduce a new options
-Ctarget-feature=+crt-static-dylib
controlling static linking of libraries instead of-Ctarget-feature=-crt-static
. It would almost never be used on Linux (not sure about windows-msvc and wasm). - Keep the existing meaning of
crt-static
, but introduce a new option-C disable-crt-static-for-dylibs
or something. Cargo would then use it for proc macro crates or all libraries. Question: how to opt-out? - Ignore
+crt-static
for dylibs if the target doesn't support it. This is fragile, musl actually supports it despite the current value of the flag of the musl target spec. If the flag is enabled, proc macros will break. - Ignore
+crt-static
for dylibs always. They are almost never used on Linux (not sure about windows-msvc and wasm).+crt-static-dylib
looks strictly better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Have two
crt-static
defaults in target specs - one for executables and one for libraries. Solves one half of the problem, but explicit+crt-static
in RUSTFLAGS will still cause collateral damage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll turn this into a proper issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This includes more than just documentation changes, but also implementation changes ,was that intended? |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updating the docs, they are a big improvement!
This comment has been minimized.
This comment has been minimized.
I haven't looked too too closely at this, but my main recommendation would be to not try to exhaustively document the state of things without a disclaimer. There's basically always one reason or another that |
|
||
- PE-based executables (Windows). | ||
The produced executable will contain code from all the user-level libraries, including | ||
[C Run-Time Libraries (CRT)](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What user-level libraries will it statically link to other than the CRT? For windows-msvc
crt-static
only controls whether the CRT (consisting of the VC Runtime and the UCRT) is statically linked and nothing else is affected. Also it only applies to windows-msvc
while windows-gnu
does not support crt-static
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What user-level libraries will it statically link to other than the CRT?
Rust crates.
And it should do that for native dependencies as well (#71647), but that doesn't make any difference on Windows since there's no libmylib.a
/libmylib.so
separation.
If after that anything is still linked dynamically, then we get into the *WARNING!*
clause below. It's not as dangerous in the Windows case though, since the goal there is not to produce a fully statically linked executable, like in the ELF case.
Also it only applies to
windows-msvc
whilewindows-gnu
does not supportcrt-static
.
Good catch.
This paragraph needs the same "If the target supports..." condition as the ELF paragraphs above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me crt-static
on Windows always had the impression that the only thing it controlled (and ever intended to control) was whether it linked to the static or dynamic CRT. I was not aware that it had any effect on whether a rust crate was linked statically or dynamically, as by default it will link rust crates statically unless you specify -Cprefer-dynamic
.
TODO: Mention that |
This is kind of blocked on #71651 now. |
TODO: Figure out what gcc/clang/ld/lld do on Linux if libc is linked statically, but something else is linked dynamically. |
We send both From #55566 (comment) quoting #40113 (comment):
|
☔ The latest upstream changes (presumably #71775) made this pull request unmergeable. Please resolve the merge conflicts. |
Bibliography 🙂: |
rustc_target: Remove `pre_link_args_crt` To regain some more control over the definition of `+crt-static` (rust-lang#71586). After rust-lang#71769 this target option wasn't used anywhere except for VxWorks, and I suspect that for VxWorks its use may be redundant as well.
I'll reopen this once the related issues are addressed. |
A preliminary for #70740.