Skip to content

Consider making cfg(target_feature = "crt-static") available *only* for link-time configuration #72510

Open

Description

@petrochenkov

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,

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.

Activity

  1. added
    A-linkageArea: linking into static, shared libraries and binaries
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    T-langRelevant to the language team
    on May 23, 2020
  2. retep998 commented on May 23, 2020

    @retep998
    Contributor

    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).

  3. petrochenkov commented on May 24, 2020

    @petrochenkov
    ContributorAuthor

    @retep998
    I wouldn't expect such use, but who knows, we need to check at least.

  4. petrochenkov commented on May 24, 2020

    @petrochenkov
    ContributorAuthor

    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.)

  5. self-assigned this
    on Jun 8, 2020
  6. petrochenkov commented on Jun 14, 2020

    @petrochenkov
    ContributorAuthor

    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).

  7. RalfJung commented on Aug 5, 2026

    @RalfJung
    Member

    Is cfg(feature = "crt-static") ever used for regular cfg expansion?

    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 -C flag instead.

  8. bjorn3 commented on Aug 5, 2026

    @bjorn3
    Member

    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=code

    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.

  9. RalfJung commented on Aug 5, 2026

    @RalfJung
  10. RalfJung commented on Aug 5, 2026

    @RalfJung
    Member

    Oh you edited the text. Where is cfg in link documented? 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.^^

  11. bjorn3 commented on Aug 5, 2026

    @bjorn3
    Member

    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].

  12. RalfJung commented on Aug 5, 2026

    @RalfJung
    Member

    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?

  13. bjorn3 commented on Aug 5, 2026

    @bjorn3
    Member

    Yeah

  14. 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
  15. RalfJung commented on Aug 5, 2026

    @RalfJung
    Member

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-linkageArea: linking into static, shared libraries and binariesC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions