rust-lang / rust-lang/rust

macOS deployment target defaults differ between rustc, cc-rs and clang

Open
#136,113 6 comments 4 reactions 1 assignee View on GitHub

@madsmtm is already working on this.

Since Jan 27, 2025.

A-linkage C-tracking-issue O-apple T-compiler T-libs
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

When MACOSX_DEPLOYMENT_TARGET is not set, rustc defaults to macOS 10.12 for Intel targets and 11.0 for aarch64 targets:

https://github.com/rust-lang/rust/blob/f85c6de55206dbee5ffedfd821df1503a7b92346/compiler/rustc_codegen_ssa/src/back/apple.rs#L69
https://github.com/rust-lang/rust/blob/f85c6de55206dbee5ffedfd821df1503a7b92346/compiler/rustc_codegen_ssa/src/back/apple.rs#L87

However, this does not match the default behavior for clang, which defaults to the selected SDK versions; unless changed otherwise, a C program built with clang uses the macOS host version as deployment target. The cc-rs crate also defaults to this behavior.

This difference in behavior causes issues when a Rust program has a dependency on a C library and does not set a minimum deployment target: The Rust binary tells the linker to target 10.12 / 11.0, but as the C library requires a higher minimum deployment target, a warning is emitted and the binary ends up targeting the higher version. This was recently observed with miri, which is built in a macOS 14 GitHub Runner:

ld: object file (/Users/runner/work/miri/miri/target/release/deps/libtikv_jemalloc_sys-80d1ddce8807bb5c.rlib[11](buf_writer.pic.o)) was built for newer 'macOS' version (14.5) than being linked (11.0)

In this case, miri does not have a deployment target set, so rustc tells the linker to emit a binary targeting 10.12; however, jemalloc-sys built jemalloc using clang's defaults, so it ended up targeting 14.5.

In a perfect world, projects would always set a deployment target and the linker would actually enforce that binaries cannot depend on objects that require a higher minimum macOS version instead of emitting a warning and targeting the higher version; alas, we're stuck with a warning with a not-so-great message. However, as incomprehensible the message may be, it is still indicative of a potential bug, especially if the user told the Rust part to create a binary targeting, say, 11.0, but the project then accidentally pulls in a dependency that targets 13.0 - the resulting binary would be created for 13.0 and might not run on 11.0 at all. Unfortunately, rustc can't not set a default deployment target by itself if the user hasn't specified one - it invokes the linker and has to pass it a deployment version; though it could compute the highest minimum version of all objects files it passes to the linker.

(@madsmtm has indicated wanting to change cc-rs's defaults to match rustc's behavior, so that a Rust program building a C library via cc would not run into a deployment target mismatch; without such a change, it's too likely to be a false positive.)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.