Skip to content

bzlmod: expose per-triple linker_preference in the rust extension (opt specific triples into rust-lld) #4096

Description

@kevinpark1217

Is your feature request related to a problem? Please describe.

linker_preference / the toolchain_linker_preference build setting (added in #3665) lets a rust_toolchain link via the bundled rust-lld instead of the cc toolchain's linker. The tools repositories are built with include_linker = True (rust/private/repositories.bzl), so every generated toolchain already exposes //:rust-lld and sets rust_toolchain.linker = "//:rust-lld" — the linker is available.

However, the bzlmod rust module extension's toolchain tag (rust/extensions.bzl) does not expose linker_preference (or linker) — neither once per rust.toolchain() call nor per target triple. Under bzlmod the only way to engage rust-lld is the global build setting --@rules_rust//rust/settings:toolchain_linker_preference=rust, which applies to every registered toolchain.

That is all-or-nothing, which doesn't fit a setup that registers a host toolchain alongside a cross-compilation target that is intentionally linked through a configured cc toolchain. Concretely: I want rust-lld for x86_64-unknown-linux-gnu host links — to avoid the deprecated gold linker that rules_cc's cc auto-detection falls back to when an unversioned ld.lld isn't on the host (rust-lang/rust#141748) — while leaving a *-unknown-linux-musl cross target linked via its (hermetic) cc toolchain. The global setting can't express that.

Describe the solution you'd like

A per-triple linker preference on the extension's toolchain tag, mirroring the existing extra_rustc_flags_triples:

rust.toolchain(
    versions = ["1.xx.0"],
    extra_target_triples = ["aarch64-unknown-linux-musl"],
    linker_preference_triples = {
        "x86_64-unknown-linux-gnu": "rust",
    },
)

Only the listed triples would get linker_preference; the rest keep the default (cc toolchain). Exposing a non-triple linker_preference on the tag (applied to all toolchains from that call) would also help, but per-triple is what's needed for mixed host/cross setups.

Describe alternatives you've considered

  • Global --@rules_rust//rust/settings:toolchain_linker_preference=rust: works, but flips every registered toolchain to rust-lld, including cross targets that should keep their cc-toolchain linker.
  • extra_rustc_flags_triples with -Clinker-features=+lld / -Clink-self-contained=+linker: both are unstable on stable rustc (error: ... is unstable, and also requires the -Z unstable-options flag), so not viable without RUSTC_BOOTSTRAP.
  • Hand-defining a rust_toolchain with linker_preference = "rust": gives up the extension's hermetic toolchain download / versions management.

Additional context

The per-triple plumbing is largely in place — rust/extensions.bzl already has extra_rustc_flags_triples; rust_toolchain.linker_preference honors a per-toolchain value over the global setting (rust/toolchain.bzl); and //:rust-lld + rust_toolchain.linker exist on the generated toolchains. The only missing piece is surfacing linker_preference (ideally per-triple) through the module extension.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions