Static vs dynamic linking defaults for musl targets

Background

Rust currently has Tier 2 targets for a number of platforms using musl for libc (various flavors of ARM, MIPS and x86) as well as some Tier 3 targets (Hexagon, PowerPC, RISC-V, S390x and ARMv7 Thumb). Currently (most of) these targets statically link to musl libc during compilation. While that can be desirable to build fully functional statically linked binaries, this creates issues for musl based Linux distros which want to dynamically link libc. These issues have lead to a suboptimal experience for distro maintainers trying to bring Rust up in their distros.

Potential options

Create a new set of targets for dynamically linked musl

This is the approach taken by rust-lang/rust#82556. It involves creating a new set of -dynmusl targets which are dynamically linked.

  • Pros

    • Does not impact the current users of the -musl targets.
  • Cons

    • Rich Felker (musl author) strongly prefers -musl targets be dynamically linked as they would with other toolchains.
    • Distributions do not really want -dynmusl targets, for the same reason, but would accept them as a compromise.
    • The -musl targets are not consistently static-linked. Some targets have dynamic linking instead.
    • The target matrix gets even bigger.

Update existing musl targets to be dynamically linked

This is the alternate approach proposed as feedback to rust-lang/rust#82556. It involves changing the -musl targets to be consistently dynamically linked.

  • Pros

    • The behavior of the -musl targets would be more consistent (they are not right now as noted above), both internally and with other musl toolchains.
    • Distributions shipping rust toolchains strongly prefer this, because it means they won't have to patch custom targets in or change the -musl targets to get reasonable (sometimes necessary - proc_macros and graphics APIs require dynamic linking) behavior.
    • End-users of rustc snapshots on musl distributions won't be surprised to find their binaries statically linked by default, since the distribution-provided rustc is already patched to prefer dynamic linking. In other words, the official binaries Rust ships for musl (as provided by rustup) would functionally match what distros are shipping.
  • Cons

    • End users of rustc are impacted and would have to explicitly specify static linking, just like on glibc. A warning message could be included to provide guidance on this, though. A set of -embmusl (embedded musl) targets could also be added.

Recommendation

The general consensus seems to be that we should update the existing musl targets to be dynamically linked.

When the -musl port was first created for Rust, it was done to solve a specific use-case in the rust community: building compact redistributable binaries for Linux by statically-linking musl. However, the default settings for the -musl targets are incompatible with the needs of distributions shipping rustc and Rust software to their end users.

Unfortunately, for whatever reason, there was a lack of communication between musl-based distributions and the Rust team, which lead to the present situation where distributions have to modify the -musl targets due to the defaults being unusable for them. A practical example is building Firefox on musl-based distributions, where the statically-linked output from rustc is linked into a dynamic binary, leading to multiple independent copies of the libc linked into the program at runtime.

By changing the -musl targets to behave like other targets (not defaulting to static linking), we get a set of -musl targets that are analogous to any other musl toolchain. This solves the requirements of distributions and is likely less surprising to rustc users who are not familiar with the quirks of the -musl targets, at the expense of impacting -musl target users who expect the static linking feature.

Unresolved questions

  • Is changing the defaults for these targets feasible (in some sense, breaking the current behavior)?
  • How can we mitigate the impact to users of these targets?
  • What steps need to be taken to appropriately message this change to users?
  • If this is not feasible, should we add new targets for dynamically linked musl instead (and what name should they be given)?
Select a repo