You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Consider making cfg(target_feature = "crt-static") available *only* for link-time configuration #72510
cfg predicates used for link-time configuration (#[link(cfg(predicate))]#37406#72059) may want to use data that is available only long after the regular cfg expansion happens.
For example,
whether we are linking an executable or library (that's the case for crt-static)
We can come up with some predicate value during regular cfg expansion, but it may be different from the predicate value that we really want at link time.
Is cfg(target_feature = "crt-static") ever used for regular cfg expansion?
It was created mostly with link-time configuration in mind.
We probably need to check it with crater.
Do people even use cfg(feature = "crt-static")? The only time I can think of is either in libc or in build scripts to decide how to build C/C++ code (in which case they pull it from environment variables and not cfg directly).
So, right now the value of crt-static predicate is evaluated during regular cfg expansion, even if it's used during link-time configuration.
After #69519 (which introduced separate crt-static defaults for executables and libraries basically) this scheme is incorrect, and means that proc macro crates can get linked with static libc anyway in some cases.
So in addition to deprecating expansion time use of this predicate we also need to move its actual evaluation to link time where the crate type is known.
(To clarify, both "expansion time" and "link time" are about building the final binary, #[link(cfg)] is still lazy.)
Unfortunately, cfgs in #[link] attributes also need to be evaluated before linking during codegen to determine library kinds.
One query using them is is_dllimport_foreign_item used to set dllimport attributes.
Another one is is_statically_included_foreign_item used to determine reachable non-generic items for symbol exports (reachable_non_generics_provider).
library/unwind and the libc crate both use #[link(name = "...", cfg(target_feature = "crt-static")] to switch between static and dynamic linking of libc and libunwind/libgcc.
After #69519 (which introduced separate crt-static defaults for executables and libraries basically) this scheme is incorrect, and means that proc macro crates can get linked with static libc anyway in some cases.
A crate can only either be an executable, a library or a proc-macro. So different defaults between those categories shouldn't be an issue in theory.
EDIT: Ah it is internal and unstable, and therefore not in the reference. I still have no idea what it does though.^^
Basically it means only apply the #[link] attribute when the cfg in question evaluates to true in the context of the crate that does the actual linking rather than in the crate that used #[link].
And to be clear, the cfg(feature = "crt-static") in the issue title and description does not exist, that should be cfg(target_feature = "crt-static"), right?
changed the title [-]Consider making `cfg(feature = "crt-static")` available *only* for link-time configuration[/-][+]Consider making `cfg(target_feature = "crt-static")` available *only* for link-time configuration[/+]on Aug 5, 2026
Activity
retep998 commentedon May 23, 2020
Do people even use
cfg(feature = "crt-static")? The only time I can think of is either inlibcor in build scripts to decide how to build C/C++ code (in which case they pull it from environment variables and notcfgdirectly).petrochenkov commentedon May 24, 2020
@retep998
I wouldn't expect such use, but who knows, we need to check at least.
petrochenkov commentedon May 24, 2020
So, right now the value of
crt-staticpredicate is evaluated during regularcfgexpansion, even if it's used during link-time configuration.After #69519 (which introduced separate
crt-staticdefaults for executables and libraries basically) this scheme is incorrect, and means that proc macro crates can get linked with static libc anyway in some cases.So in addition to deprecating expansion time use of this predicate we also need to move its actual evaluation to link time where the crate type is known.
(To clarify, both "expansion time" and "link time" are about building the final binary,
#[link(cfg)]is still lazy.)petrochenkov commentedon Jun 14, 2020
Unfortunately,
cfgs in#[link]attributes also need to be evaluated before linking during codegen to determine library kinds.One query using them is
is_dllimport_foreign_itemused to set dllimport attributes.Another one is
is_statically_included_foreign_itemused to determine reachable non-generic items for symbol exports (reachable_non_generics_provider).RalfJung commentedon Aug 5, 2026
I don't know, but I'd love to kill every part of this target feature that we can kill. IMO it should be a
-Cflag instead.bjorn3 commentedon Aug 5, 2026
library/unwind and the libc crate both use
#[link(name = "...", cfg(target_feature = "crt-static")]to switch between static and dynamic linking of libc and libunwind/libgcc.As for regular cfg expansion, a fair amount of tests make use of it to check if crt-static is correctly enabled/disabled. And it looks like some crates use it as workaround for
#[link(.., cfg(...)]not being stable as well as for other use cases: https://github.com/search?q=%2Ftarget_feature+%3D+%22crt-static%22%2F+language%3Arust&type=codeA crate can only either be an executable, a library or a proc-macro. So different defaults between those categories shouldn't be an issue in theory.
RalfJung commentedon Aug 5, 2026
RalfJung commentedon Aug 5, 2026
Oh you edited the text. Where is
cfginlinkdocumented? It is not mentioned in the page I'd expected it in.EDIT: Ah it is internal and unstable, and therefore not in the reference. I still have no idea what it does though.^^
bjorn3 commentedon Aug 5, 2026
Basically it means only apply the
#[link]attribute when the cfg in question evaluates to true in the context of the crate that does the actual linking rather than in the crate that used#[link].RalfJung commentedon Aug 5, 2026
And to be clear, the
cfg(feature = "crt-static")in the issue title and description does not exist, that should becfg(target_feature = "crt-static"), right?bjorn3 commentedon Aug 5, 2026
Yeah
[-]Consider making `cfg(feature = "crt-static")` available *only* for link-time configuration[/-][+]Consider making `cfg(target_feature = "crt-static")` available *only* for link-time configuration[/+]RalfJung commentedon Aug 5, 2026
Okay, thanks for confirming.
I don't think we should have link-time
cfg(target_feature = "crt-static")either, it shouldn't be called a "target feature" at all.12101111 commentedon Aug 5, 2026
Please consider this usage: https://github.com/EmbarkStudios/crash-handling/blob/171a88b5a914ffff8607cbe8763d8c4dd59fbd02/crash-handler/src/unix/pthread_interpose.rs#L65