Skip to content

Linking modifier whole-archive and link time cfg are not supported on bundled static libraries #99429

Closed

Description

@petrochenkov

This is more or less a part of #81490.

If you try to combine +whole-archive with (possibly implicit) +bundle you will encounter this error: "linking modifiers +bundle and +whole-archive are not compatible with each other when generating rlibs".
The whole-archive modifier is significantly limited due to this issue and cannot be used in foo-sys rlibs bundling their native libfoo.a dependencies, which is one of the main use cases.

We also have to enable the +whole-archive modifier implicitly in one ad hoc case (https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_ssa/src/back/link.rs#L2209-L2213) for backward compatibility, because it cannot be enabled manually.

cfg for bundled static libraries was implemented just enough to make the case of musl libc bundled into libc crate to work, but it doesn't work in general case.
(Note that musl libc no longer uses bundling, see #72274.)

Also see #88085 and #88161 for some discussion related to this issue.

Activity

  1. petrochenkov commented on Jul 18, 2022

    @petrochenkov
    ContributorAuthor

    We need to make bundled libraries behave more like regular static libraries libfoo.a.

    The simplest way, which is also most compatible with traditional tooling is to literally move them out of rlibs to separate .a files, like this

    .
    ├── libfoo-sys.rlib
    └── libfoo-sys.rlib.bundle
        └── libfoo.a
    

    It solves all the issues above:

    • libfoo.a can be passed to linker as a separate static library, with preserving all the static library semantics, thus it can be
      • wrapped into -whole-archive ... -no-whole-archive
      • not passed at all if some relevant link time cfg is false
      • moved to some other place on the command line if necessary, not necessarily next to libfoo-sys.rlib
    • it's also fast, rustc doesn't have to extract object files to some temporary .a file on the fly or something like that, when static library semantics are necessary.

    The problem is that we'll have to teach cargo to track these new extra files.
    Third party build systems will also need to support this (although it's possible that they never use bundling and always link their native libraries in their own way).

    If the separate file solution doesn't work out we'll need to figure out how to bundle object files into rlibs in some smarter way, with preserving their old structure, and then how to repack them on the fly if they need to be represented as a static library.

  2. added
    A-linkageArea: linking into static, shared libraries and binaries
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jul 18, 2022
  3. added a commit that references this issue on Aug 2, 2022
  4. added a commit that references this issue on Aug 14, 2022
  5. added a commit that references this issue on Aug 16, 2022
  6. added a commit that references this issue on Sep 2, 2022
  7. added a commit that references this issue on Sep 13, 2022
  8. petrochenkov commented on Feb 15, 2023

    @petrochenkov
    ContributorAuthor

    Support for this was implemented in #105601 under a feature gate #![feature(packed_bundled_libs)].
    I'm closing this issue, but we need to open a tracking issue for that feature.

  9. petrochenkov commented on Feb 15, 2023

    @petrochenkov
    ContributorAuthor

    The tracking issue - #108081.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-linkageArea: linking into static, shared libraries and binariesT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions