Skip to content

When linking statically, native libraries should go inside --start-group/--end-group for robustness #76992

Open
@joshtriplett

Description

@joshtriplett

When rustc links rlib libraries, it puts all the libraries inside a --start-group/--end-group pair, causing the linker to resolve backreferences from a library later in the command line to one earlier in the command line.

However, when rustc links native libraries, it puts libraries on the command line in whatever order it encountered them in code.

With shared linking, that works fine. But with static linking, the order has a crucial semantic significance: symbols in a library will get thrown away unless a library listed previously on the command line has a corresponding unresolved symbol.

Rust #[link] directives don't account for this, and crates in general don't worry about link order, precisely because dynamic linking is the default. When linking statically to multiple libraries, where one depends on another, this is very likely to result in symbol resolution failures at link time. In addition, if libraries have circular references (such as between glibc and libgcc), there is no order that will allow the libraries to link without duplicating at least one library, which seems like something #[link] directives should not need to account for.

I would propose that when linking statically, Rust should always put all libraries, both rlibs and native libraries, inside one large --start-group/--end-group pair, which will allow the linker to handle symbol references both backwards and forwards, as well as circular symbol dependencies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions