Rollup merge of #156814 - cezarbbb:fix-issue-156714, r=jieyouxu

Extend macOS deployment target mismatch filter to cover dylib and new ld formats

The `deployment_mismatch` filter in `report_linker_output` only matched the old ld64 format for object files. With linker-messages promoted to warn-by-default in rust-lang/rust#153968, unfiltered deployment target warnings from dylibs and the new Apple linker (ld_prime) now surface as noise for users who never set `MACOSX_DEPLOYMENT_TARGET`.

Fixes rust-lang/rust#156714.

At present, the filter works only covered the specific format:

`ld: warning: object file (...) was built for newer 'macOS' version (...) than being linked (...)`

This was fine because linker-messages was `Allow-by-default` — nobody saw the other formats anyway. Then rust-lang/rust#153968 promoted it to Warn, and the gaps became visible.

Broadens the filter to cover all known ld deployment target version mismatch formats:

`ld: warning: object file (...)` — old ld64, already handled
`ld: warning: dylib (...)` — old ld64, was missing
All Apple platforms (`iOS`, `tvOS`, `watchOS`, `xrOS`, etc.), not just `macOS`
`ld: building for <platform>-A.B, but linking with dylib '...' which was built for newer version C.D` — new linker (ld_prime, Xcode 15+), the exact format from rust-lang/rust#156714

All matched messages are downgraded to `linker_info` (Allow-by-default), consistent with the existing behavior for the object file case.
This commit is contained in:
Jonathan Brouwer
2026-05-27 08:14:26 +02:00
committed by GitHub
5 changed files with 61 additions and 5 deletions
+9 -3
View File
@@ -781,9 +781,15 @@ fn for_each(bytes: &[u8], mut f: impl FnMut(&str, &mut String)) -> String {
// FIXME: Tracked by https://github.com/rust-lang/rust/issues/136113
let deployment_mismatch = |line: &str| {
line.starts_with("ld: warning: object file (")
&& line.contains("was built for newer 'macOS' version")
&& line.contains("than being linked")
// ld64 (object files + dylibs) and ld_prime (object files only):
(line.starts_with("ld: ")
&& line.contains("was built for newer")
&& line.contains("than being linked"))
// ld_prime (Xcode 15+, dylibs only):
|| (line.starts_with("ld: ")
&& line.contains("building for")
&& line.contains("but linking with")
&& line.contains("which was built for newer version"))
};
// FIXME: This is a real warning we would like to show, but it hits too many crates
// to want to turn it on immediately.
@@ -0,0 +1,11 @@
warning: NORMALIZED_DYLIB_DEPLOYMENT_MISMATCH_LINKER_WARNING
|
note: the lint level is defined here
--> main_dylib.rs:1:9
|
1 | #![warn(linker_info, linker_messages)]
| ^^^^^^^^^^^
warning: 1 warning emitted
@@ -0,0 +1,8 @@
#![warn(linker_info, linker_messages)]
unsafe extern "C" {
safe fn foo();
}
fn main() {
foo();
}
@@ -1,4 +1,6 @@
// ignore-tidy-linelength
//! Tests that deployment target linker warnings are shown as `linker-info`, not `linker-messages`
//! See <https://github.com/rust-lang/rust/issues/156714>
//@ only-macos
@@ -7,6 +9,12 @@
use run_make_support::{diff, rustc};
fn main() {
let ld64_obj = r"ld: warning: object file \(.*\) was built for newer .+ version \(\d+\.\d+\) than being linked \(\d+\.\d+\)";
let ld_prime_obj = r"ld: warning: object file \(.*\) was built for newer '.+' version \(\d+\.\d+\) than being linked \(\d+\.\d+\)";
let ld64_dylib = r"ld: warning: dylib \(.*\) was built for newer .+ version \(\d+\.\d+\) than being linked \(\d+\.\d+\)";
let ld_prime_dylib = r"ld: warning: building for [^ ,]+, but linking with dylib '[^']*' which was built for newer version [0-9.]+";
// Test 1: static archive (object file mismatch)
cc().arg("-c").arg("-mmacosx-version-min=15.5").output("foo.o").input("foo.c").run();
llvm_ar().obj_to_ar().output_input("libfoo.a", "foo.o").run();
@@ -21,6 +29,29 @@ fn main() {
diff()
.expected_file("warnings.txt")
.actual_text("(rustc -W linker-info)", &warnings)
.normalize(r"\(.*/rmake_out/", "(TEST_DIR/")
.normalize(ld64_obj, "NORMALIZED_OBJECT_DEPLOYMENT_MISMATCH_LINKER_WARNING")
.normalize(ld_prime_obj, "NORMALIZED_OBJECT_DEPLOYMENT_MISMATCH_LINKER_WARNING")
.run();
// Test 2: shared library (dylib mismatch)
cc().arg("-shared")
.arg("-mmacosx-version-min=15.5")
.output("libbar.dylib")
.input("foo.c")
.run();
let dylib_warnings = rustc()
.arg("-lbar")
.link_arg("-mmacosx-version-min=11.2")
.input("main_dylib.rs")
.crate_type("bin")
.run()
.stderr_utf8();
diff()
.expected_file("dylib_warnings.txt")
.actual_text("(rustc -W linker-info dylib)", &dylib_warnings)
.normalize(ld64_dylib, "NORMALIZED_DYLIB_DEPLOYMENT_MISMATCH_LINKER_WARNING")
.normalize(ld_prime_dylib, "NORMALIZED_DYLIB_DEPLOYMENT_MISMATCH_LINKER_WARNING")
.run();
}
@@ -1,4 +1,4 @@
warning: ld: warning: object file (TEST_DIR/libfoo.a[2](foo.o)) was built for newer 'macOS' version (15.5) than being linked (11.2)
warning: NORMALIZED_OBJECT_DEPLOYMENT_MISMATCH_LINKER_WARNING
|
note: the lint level is defined here