Description
When MACOSX_DEPLOYMENT_TARGET
is not set, rustc defaults to macOS 10.12 for Intel targets and 11.0 for aarch64 targets:
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.)