macOS deployment target defaults differ between rustc, cc-rs and clang #136113
Labels
A-linkage
Area: linking into static, shared libraries and binaries
C-tracking-issue
Category: An issue tracking the progress of sth. like the implementation of an RFC
O-apple
Operating system: Apple (macOS, iOS, tvOS, visionOS, watchOS)
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
T-libs
Relevant to the library team, which will review and decide on the PR/issue.
When
MACOSX_DEPLOYMENT_TARGET
is not set, rustc defaults to macOS 10.12 for Intel targets and 11.0 for aarch64 targets:rust/compiler/rustc_codegen_ssa/src/back/apple.rs
Line 69 in f85c6de
rust/compiler/rustc_codegen_ssa/src/back/apple.rs
Line 87 in f85c6de
However, this does not match the default behavior for
clang
, which defaults to the selected SDK versions; unless changed otherwise, a C program built withclang
uses the macOS host version as deployment target. Thecc-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:
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 viacc
would not run into a deployment target mismatch; without such a change, it's too likely to be a false positive.)The text was updated successfully, but these errors were encountered: