Skip to content

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

Open
@Fulgen301

Description

@Fulgen301

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

"macos" => (10, 12, 0),

("macos", "aarch64", _) => (11, 0, 0),

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.)

Metadata

Metadata

Assignees

Labels

A-linkageArea: linking into static, shared libraries and binariesC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCO-appleOperating system: Apple (macOS, iOS, tvOS, visionOS, watchOS)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libsRelevant to the library team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions