From 0bbd00b6b6b1926bd0ae312b5a317125acc14f78 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Fri, 12 Dec 2025 14:41:11 -0500 Subject: [PATCH 1/4] Split `is_msvc_link_exe` into a function --- compiler/rustc_codegen_ssa/src/back/link.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c8109db86e2f2..716eb31731d12 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -669,6 +669,14 @@ struct LinkerOutput { inner: String, } +fn is_msvc_link_exe(sess: &Session) -> bool { + let (linker_path, flavor) = linker_and_flavor(sess); + sess.target.is_like_msvc + && flavor == LinkerFlavor::Msvc(Lld::No) + // Match exactly "link.exe" + && linker_path.to_str() == Some("link.exe") +} + /// Create a dynamic library or executable. /// /// This will invoke the system linker/cc to create the resulting file. This links to all upstream @@ -855,11 +863,6 @@ fn link_natively( match prog { Ok(prog) => { - let is_msvc_link_exe = sess.target.is_like_msvc - && flavor == LinkerFlavor::Msvc(Lld::No) - // Match exactly "link.exe" - && linker_path.to_str() == Some("link.exe"); - if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); @@ -879,7 +882,7 @@ fn link_natively( if let Some(code) = prog.status.code() { // All Microsoft `link.exe` linking ror codes are // four digit numbers in the range 1000 to 9999 inclusive - if is_msvc_link_exe && (code < 1000 || code > 9999) { + if is_msvc_link_exe(sess) && (code < 1000 || code > 9999) { let is_vs_installed = find_msvc_tools::find_vs_version().is_ok(); let has_linker = find_msvc_tools::find_tool(sess.target.arch.desc(), "link.exe") @@ -918,7 +921,7 @@ fn link_natively( // Hide some progress messages from link.exe that we don't care about. // See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146 - if is_msvc_link_exe { + if is_msvc_link_exe(sess) { if let Ok(str) = str::from_utf8(&prog.stdout) { let mut output = String::with_capacity(str.len()); for line in stdout.lines() { From f0a27e3a30a78afbc3acf2ffd34021777c698910 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Fri, 12 Dec 2025 14:54:07 -0500 Subject: [PATCH 2/4] Split `report_linker_output` into its own function --- compiler/rustc_codegen_ssa/src/back/link.rs | 90 +++++++++++---------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 716eb31731d12..0e6ccd0496f57 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -59,7 +59,7 @@ use super::rpath::{self, RPathConfig}; use super::{apple, versioned_llvm_target}; use crate::base::needs_allocator_shim_for_linking; use crate::{ - CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file, + CodegenLintLevels, CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file }; pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { @@ -677,6 +677,51 @@ fn is_msvc_link_exe(sess: &Session) -> bool { && linker_path.to_str() == Some("link.exe") } +fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8], stderr: &[u8]) { + let escaped_stderr = escape_string(&stderr); + let mut escaped_stdout = escape_string(&stdout); + info!("linker stderr:\n{}", &escaped_stderr); + info!("linker stdout:\n{}", &escaped_stdout); + + // Hide some progress messages from link.exe that we don't care about. + // See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146 + if is_msvc_link_exe(sess) { + if let Ok(str) = str::from_utf8(&stdout) { + let mut output = String::with_capacity(str.len()); + for line in str.lines() { + if line.starts_with(" Creating library") + || line.starts_with("Generating code") + || line.starts_with("Finished generating code") + { + continue; + } else { + output += line; + output += "\r\n" + } + } + escaped_stdout = escape_string(output.trim().as_bytes()) + } + } + + let lint_msg = |msg| { + lint_level(sess, LINKER_MESSAGES, levels.linker_messages, None, |diag| { + LinkerOutput { inner: msg }.decorate_lint(diag) + }) + }; + + if !escaped_stderr.is_empty() { + // We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present. + let stderr = escaped_stderr + .strip_prefix("warning: ") + .unwrap_or(&escaped_stderr) + .replace(": warning: ", ": "); + lint_msg(format!("linker stderr: {stderr}")); + } + if !escaped_stdout.is_empty() { + lint_msg(format!("linker stdout: {}", escaped_stdout)) + } +} + /// Create a dynamic library or executable. /// /// This will invoke the system linker/cc to create the resulting file. This links to all upstream @@ -914,48 +959,7 @@ fn link_natively( sess.dcx().abort_if_errors(); } - let stderr = escape_string(&prog.stderr); - let mut stdout = escape_string(&prog.stdout); - info!("linker stderr:\n{}", &stderr); - info!("linker stdout:\n{}", &stdout); - - // Hide some progress messages from link.exe that we don't care about. - // See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146 - if is_msvc_link_exe(sess) { - if let Ok(str) = str::from_utf8(&prog.stdout) { - let mut output = String::with_capacity(str.len()); - for line in stdout.lines() { - if line.starts_with(" Creating library") - || line.starts_with("Generating code") - || line.starts_with("Finished generating code") - { - continue; - } - output += line; - output += "\r\n" - } - stdout = escape_string(output.trim().as_bytes()) - } - } - - let level = codegen_results.crate_info.lint_levels.linker_messages; - let lint = |msg| { - lint_level(sess, LINKER_MESSAGES, level, None, |diag| { - LinkerOutput { inner: msg }.decorate_lint(diag) - }) - }; - - if !prog.stderr.is_empty() { - // We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present. - let stderr = stderr - .strip_prefix("warning: ") - .unwrap_or(&stderr) - .replace(": warning: ", ": "); - lint(format!("linker stderr: {stderr}")); - } - if !stdout.is_empty() { - lint(format!("linker stdout: {}", stdout)) - } + report_linker_output(sess, codegen_results.crate_info.lint_levels, &prog.stdout, &prog.stderr); } Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; From 8ad1c88d1261a3c493e0b2473d008919f81aa178 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Fri, 12 Dec 2025 17:17:24 -0500 Subject: [PATCH 3/4] Split out linker-info from linker-messages - Hide common linker output behind `linker-info` - Add tests - Account for different capitalization on windows-gnu when removing "warning" prefix - Add some more comments - Add macOS deployment-target test - Ignore linker warnings from trying to statically link glibc I don't know what's going on in `nofile-limit.rs` but I want no part of it. --- compiler/rustc_codegen_ssa/src/back/link.rs | 129 +++++++++++++++--- compiler/rustc_codegen_ssa/src/lib.rs | 7 +- compiler/rustc_lint_defs/src/builtin.rs | 35 +++++ compiler/rustc_passes/messages.ftl | 2 +- compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_span/src/symbol.rs | 1 + .../macos-deployment-target-warning/foo.c | 1 + .../macos-deployment-target-warning/main.rs | 8 ++ .../macos-deployment-target-warning/rmake.rs | 29 ++++ .../warnings.txt | 11 ++ tests/ui/linking/macos-ignoring-duplicate.rs | 6 + .../linking/macos-ignoring-duplicate.stderr | 11 ++ tests/ui/linking/macos-search-path.rs | 6 + tests/ui/linking/macos-search-path.stderr | 11 ++ .../linking/windows-gnu-corrupt-drective.rs | 5 + .../windows-gnu-corrupt-drective.stderr | 12 ++ tests/ui/lint/linker-warning.stderr | 2 +- tests/ui/process/nofile-limit.rs | 3 + 18 files changed, 258 insertions(+), 25 deletions(-) create mode 100644 tests/run-make/macos-deployment-target-warning/foo.c create mode 100644 tests/run-make/macos-deployment-target-warning/main.rs create mode 100644 tests/run-make/macos-deployment-target-warning/rmake.rs create mode 100644 tests/run-make/macos-deployment-target-warning/warnings.txt create mode 100644 tests/ui/linking/macos-ignoring-duplicate.rs create mode 100644 tests/ui/linking/macos-ignoring-duplicate.stderr create mode 100644 tests/ui/linking/macos-search-path.rs create mode 100644 tests/ui/linking/macos-search-path.stderr create mode 100644 tests/ui/linking/windows-gnu-corrupt-drective.rs create mode 100644 tests/ui/linking/windows-gnu-corrupt-drective.stderr diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 0e6ccd0496f57..6db37fcdfe8a6 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -21,6 +21,7 @@ use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; use rustc_fs_util::{TempDirBuilder, fix_windows_verbatim_for_gcc, try_canonicalize}; use rustc_hir::attrs::NativeLibKind; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_lint_defs::builtin::LINKER_INFO; use rustc_macros::LintDiagnostic; use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file}; use rustc_metadata::{ @@ -59,7 +60,8 @@ use super::rpath::{self, RPathConfig}; use super::{apple, versioned_llvm_target}; use crate::base::needs_allocator_shim_for_linking; use crate::{ - CodegenLintLevels, CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file + CodegenLintLevels, CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, + looks_like_rust_object_file, }; pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { @@ -677,30 +679,99 @@ fn is_msvc_link_exe(sess: &Session) -> bool { && linker_path.to_str() == Some("link.exe") } +fn is_macos_ld(sess: &Session) -> bool { + let (_, flavor) = linker_and_flavor(sess); + sess.target.is_like_darwin && matches!(flavor, LinkerFlavor::Darwin(_, Lld::No)) +} + +fn is_windows_gnu_ld(sess: &Session) -> bool { + let (_, flavor) = linker_and_flavor(sess); + sess.target.is_like_windows + && !sess.target.is_like_msvc + && matches!(flavor, LinkerFlavor::Gnu(_, Lld::No)) +} + fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8], stderr: &[u8]) { - let escaped_stderr = escape_string(&stderr); + let mut escaped_stderr = escape_string(&stderr); let mut escaped_stdout = escape_string(&stdout); + let mut linker_info = String::new(); + info!("linker stderr:\n{}", &escaped_stderr); info!("linker stdout:\n{}", &escaped_stdout); - // Hide some progress messages from link.exe that we don't care about. - // See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146 - if is_msvc_link_exe(sess) { - if let Ok(str) = str::from_utf8(&stdout) { - let mut output = String::with_capacity(str.len()); + fn for_each(bytes: &[u8], mut f: impl FnMut(&str, &mut String)) -> String { + let mut output = String::new(); + if let Ok(str) = str::from_utf8(bytes) { + info!("line: {str}"); + output = String::with_capacity(str.len()); for line in str.lines() { - if line.starts_with(" Creating library") - || line.starts_with("Generating code") - || line.starts_with("Finished generating code") - { - continue; - } else { - output += line; - output += "\r\n" - } + f(line.trim(), &mut output); } - escaped_stdout = escape_string(output.trim().as_bytes()) } + escape_string(output.trim().as_bytes()) + } + + if is_msvc_link_exe(sess) { + escaped_stdout = for_each(&stdout, |line, output| { + // Hide some progress messages from link.exe that we don't care about. + // See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146 + if line.starts_with(" Creating library") + || line.starts_with("Generating code") + || line.starts_with("Finished generating code") + { + linker_info += line; + linker_info += "\r\n"; + } else { + *output += line; + *output += "\r\n" + } + }); + } else if is_macos_ld(sess) { + // 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") + }; + // FIXME: This is a real warning we would like to show, but it hits too many crates + // to want to turn it on immediately. + let search_path = |line: &str| { + line.starts_with("ld: warning: search path '") && line.ends_with("' not found") + }; + escaped_stderr = for_each(&stderr, |line, output| { + // This duplicate library warning is just not helpful at all. + if line.starts_with("ld: warning: ignoring duplicate libraries: ") + || deployment_mismatch(line) + || search_path(line) + { + linker_info += line; + linker_info += "\n"; + } else { + *output += line; + *output += "\n" + } + }); + } else if is_windows_gnu_ld(sess) { + let mut saw_exclude_symbol = false; + // See https://github.com/rust-lang/rust/issues/112368. + // FIXME: maybe check that binutils is older than 2.40 before downgrading this warning? + let exclude_symbols = |line: &str| { + line.starts_with("Warning: .drectve `-exclude-symbols:") + && line.ends_with("' unrecognized") + }; + escaped_stderr = for_each(&stderr, |line, output| { + if exclude_symbols(line) { + saw_exclude_symbol = true; + linker_info += line; + linker_info += "\n"; + } else if saw_exclude_symbol && line == "Warning: corrupt .drectve at end of def file" { + linker_info += line; + linker_info += "\n"; + } else { + *output += line; + *output += "\n" + } + }); } let lint_msg = |msg| { @@ -708,18 +779,29 @@ fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8] LinkerOutput { inner: msg }.decorate_lint(diag) }) }; + let lint_info = |msg| { + lint_level(sess, LINKER_INFO, levels.linker_info, None, |diag| { + LinkerOutput { inner: msg }.decorate_lint(diag) + }) + }; if !escaped_stderr.is_empty() { // We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present. - let stderr = escaped_stderr - .strip_prefix("warning: ") + escaped_stderr = + escaped_stderr.strip_prefix("warning: ").unwrap_or(&escaped_stderr).to_owned(); + // Windows GNU LD prints uppercase Warning + escaped_stderr = escaped_stderr + .strip_prefix("Warning: ") .unwrap_or(&escaped_stderr) .replace(": warning: ", ": "); - lint_msg(format!("linker stderr: {stderr}")); + lint_msg(format!("linker stderr: {escaped_stderr}")); } if !escaped_stdout.is_empty() { lint_msg(format!("linker stdout: {}", escaped_stdout)) } + if !linker_info.is_empty() { + lint_info(linker_info); + } } /// Create a dynamic library or executable. @@ -959,7 +1041,12 @@ fn link_natively( sess.dcx().abort_if_errors(); } - report_linker_output(sess, codegen_results.crate_info.lint_levels, &prog.stdout, &prog.stderr); + report_linker_output( + sess, + codegen_results.crate_info.lint_levels, + &prog.stdout, + &prog.stderr, + ); } Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 3ffc16d49ac15..150dac9253964 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -24,6 +24,7 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir::CRATE_HIR_ID; use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind}; use rustc_hir::def_id::CrateNum; +use rustc_lint_defs::builtin::LINKER_INFO; use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::WorkProduct; @@ -358,10 +359,14 @@ impl CodegenResults { #[derive(Copy, Clone, Debug, Encodable, Decodable)] pub struct CodegenLintLevels { linker_messages: LevelAndSource, + linker_info: LevelAndSource, } impl CodegenLintLevels { pub fn from_tcx(tcx: TyCtxt<'_>) -> Self { - Self { linker_messages: tcx.lint_level_at_node(LINKER_MESSAGES, CRATE_HIR_ID) } + Self { + linker_messages: tcx.lint_level_at_node(LINKER_MESSAGES, CRATE_HIR_ID), + linker_info: tcx.lint_level_at_node(LINKER_INFO, CRATE_HIR_ID), + } } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index ff108031badc1..7c027072b61f0 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -59,6 +59,7 @@ declare_lint_pass! { LARGE_ASSIGNMENTS, LATE_BOUND_LIFETIME_ARGUMENTS, LEGACY_DERIVE_HELPERS, + LINKER_INFO, LINKER_MESSAGES, LONG_RUNNING_CONST_EVAL, LOSSY_PROVENANCE_CASTS, @@ -4037,6 +4038,40 @@ declare_lint! { "warnings emitted at runtime by the target-specific linker program" } +declare_lint! { + /// The `linker_info` lint forwards warnings from the linker that are known to be informational-only. + /// + /// ### Example + /// + /// ```rust,ignore (needs CLI args, platform-specific) + /// #[warn(linker_info)] + /// fn main () {} + /// ``` + /// + /// On MacOS, using `-C link-arg=-lc` and the default linker, this will produce + /// + /// ```text + /// warning: linker stderr: ld: ignoring duplicate libraries: '-lc' + /// | + /// note: the lint level is defined here + /// --> ex.rs:1:9 + /// | + /// 1 | #![warn(linker_info)] + /// | ^^^^^^^^^^^^^^^ + /// ``` + /// + /// ### Explanation + /// + /// Many linkers are very "chatty" and print lots of information that is not necessarily + /// indicative of an issue. This output has been ignored for many years and is often not + /// actionable by developers. It is silenced unless the developer specifically requests for it + /// to be printed. See this tracking issue for more details: + /// . + pub LINKER_INFO, + Allow, + "linker warnings known to be informational-only and not indicative of a problem" +} + declare_lint! { /// The `named_arguments_used_positionally` lint detects cases where named arguments are only /// used positionally in format strings. This usage is valid but potentially very confusing. diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index f8ff46189c052..abd84942e94cf 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -552,7 +552,7 @@ passes_unused_empty_lints_note = attribute `{$name}` with an empty list has no effect passes_unused_linker_messages_note = - the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked + the `linker_messages` and `linker_info` lints can only be controlled at the root of a crate that needs to be linked passes_unused_multiple = multiple `{$name}` attributes diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8cf68b280850e..40d2e80dfa8eb 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1580,7 +1580,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } else if attr.has_any_name(&[sym::allow, sym::warn, sym::deny, sym::forbid, sym::expect]) && let Some(meta) = attr.meta_item_list() && meta.iter().any(|meta| { - meta.meta_item().map_or(false, |item| item.path == sym::linker_messages) + meta.meta_item().map_or(false, |item| { + item.path == sym::linker_messages || item.path == sym::linker_info + }) }) { if hir_id != CRATE_HIR_ID { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b0ef95d10ffa0..658d669ec653e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1361,6 +1361,7 @@ symbols! { link_section, linkage, linker, + linker_info, linker_messages, linkonce, linkonce_odr, diff --git a/tests/run-make/macos-deployment-target-warning/foo.c b/tests/run-make/macos-deployment-target-warning/foo.c new file mode 100644 index 0000000000000..85e6cd8c3909a --- /dev/null +++ b/tests/run-make/macos-deployment-target-warning/foo.c @@ -0,0 +1 @@ +void foo() {} diff --git a/tests/run-make/macos-deployment-target-warning/main.rs b/tests/run-make/macos-deployment-target-warning/main.rs new file mode 100644 index 0000000000000..2c3be92812e12 --- /dev/null +++ b/tests/run-make/macos-deployment-target-warning/main.rs @@ -0,0 +1,8 @@ +#![warn(linker_info, linker_messages)] +unsafe extern "C" { + safe fn foo(); +} + +fn main() { + foo(); +} diff --git a/tests/run-make/macos-deployment-target-warning/rmake.rs b/tests/run-make/macos-deployment-target-warning/rmake.rs new file mode 100644 index 0000000000000..e109b2adcc17a --- /dev/null +++ b/tests/run-make/macos-deployment-target-warning/rmake.rs @@ -0,0 +1,29 @@ +//@ only-apple +//! Tests that deployment target linker warnings are shown as `linker-info`, not `linker-messages` + +use run_make_support::external_deps::c_cxx_compiler::cc; +use run_make_support::external_deps::llvm::llvm_ar; +use run_make_support::{bare_rustc, diff}; + +fn main() { + let cwd = std::env::current_dir().unwrap().to_str().unwrap().to_owned(); + + 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(); + + let warnings = bare_rustc() + .arg("-L") + .arg(format!("native={cwd}")) + .arg("-lstatic=foo") + .link_arg("-mmacosx-version-min=11.2") + .input("main.rs") + .crate_type("bin") + .run() + .stderr_utf8(); + + diff() + .expected_file("warnings.txt") + .actual_text("(rustc -W linker-info)", &warnings) + .normalize(r"\(.*/rmake_out/", "(TEST_DIR/") + .run() +} diff --git a/tests/run-make/macos-deployment-target-warning/warnings.txt b/tests/run-make/macos-deployment-target-warning/warnings.txt new file mode 100644 index 0000000000000..ab08c6d9ae5b2 --- /dev/null +++ b/tests/run-make/macos-deployment-target-warning/warnings.txt @@ -0,0 +1,11 @@ +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) + + | +note: the lint level is defined here + --> main.rs:1:9 + | +1 | #![warn(linker_info, linker_messages)] + | ^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/linking/macos-ignoring-duplicate.rs b/tests/ui/linking/macos-ignoring-duplicate.rs new file mode 100644 index 0000000000000..0c9241c8ee195 --- /dev/null +++ b/tests/ui/linking/macos-ignoring-duplicate.rs @@ -0,0 +1,6 @@ +//@ only-apple +//@ compile-flags: -C link-arg=-lc -C link-arg=-lc +//@ build-fail +#![deny(linker_info)] +//~? ERROR ignoring duplicate libraries +fn main() {} diff --git a/tests/ui/linking/macos-ignoring-duplicate.stderr b/tests/ui/linking/macos-ignoring-duplicate.stderr new file mode 100644 index 0000000000000..9037e8f4e391b --- /dev/null +++ b/tests/ui/linking/macos-ignoring-duplicate.stderr @@ -0,0 +1,11 @@ +error: ld: warning: ignoring duplicate libraries: '-lc' + + | +note: the lint level is defined here + --> $DIR/macos-ignoring-duplicate.rs:4:9 + | +LL | #![deny(linker_info)] + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/linking/macos-search-path.rs b/tests/ui/linking/macos-search-path.rs new file mode 100644 index 0000000000000..6d3e420bcdf6d --- /dev/null +++ b/tests/ui/linking/macos-search-path.rs @@ -0,0 +1,6 @@ +//@ only-apple +//@ compile-flags: -C link-arg=-Wl,-L/no/such/file/or/directory +//@ build-fail +#![deny(linker_info)] +//~? ERROR search path +fn main() {} diff --git a/tests/ui/linking/macos-search-path.stderr b/tests/ui/linking/macos-search-path.stderr new file mode 100644 index 0000000000000..598036d0d403e --- /dev/null +++ b/tests/ui/linking/macos-search-path.stderr @@ -0,0 +1,11 @@ +error: ld: warning: search path '/no/such/file/or/directory' not found + + | +note: the lint level is defined here + --> $DIR/macos-search-path.rs:4:9 + | +LL | #![deny(linker_info)] + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/linking/windows-gnu-corrupt-drective.rs b/tests/ui/linking/windows-gnu-corrupt-drective.rs new file mode 100644 index 0000000000000..45151a380d262 --- /dev/null +++ b/tests/ui/linking/windows-gnu-corrupt-drective.rs @@ -0,0 +1,5 @@ +//@ only-windows-gnu +//@ build-fail +#![deny(linker_info)] +//~? ERROR Warning: .drectve +fn main() {} diff --git a/tests/ui/linking/windows-gnu-corrupt-drective.stderr b/tests/ui/linking/windows-gnu-corrupt-drective.stderr new file mode 100644 index 0000000000000..07e800ee836d5 --- /dev/null +++ b/tests/ui/linking/windows-gnu-corrupt-drective.stderr @@ -0,0 +1,12 @@ +error: Warning: .drectve `-exclude-symbols:_ZN28windows_gnu_corrupt_drective4main17h291ed884c1aada69E ' unrecognized + Warning: corrupt .drectve at end of def file + + | +note: the lint level is defined here + --> $DIR/windows-gnu-corrupt-drective.rs:3:9 + | +LL | #![deny(linker_info)] + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/linker-warning.stderr b/tests/ui/lint/linker-warning.stderr index ae5f6b3adece0..54994c48ea43a 100644 --- a/tests/ui/lint/linker-warning.stderr +++ b/tests/ui/lint/linker-warning.stderr @@ -20,7 +20,7 @@ warning: unused attribute LL | #![allow(linker_messages)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | - = note: the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked + = note: the `linker_messages` and `linker_info` lints can only be controlled at the root of a crate that needs to be linked warning: 2 warnings emitted diff --git a/tests/ui/process/nofile-limit.rs b/tests/ui/process/nofile-limit.rs index 64777b514256e..f5246856b80f2 100644 --- a/tests/ui/process/nofile-limit.rs +++ b/tests/ui/process/nofile-limit.rs @@ -11,6 +11,9 @@ #![feature(exit_status_error)] #![feature(rustc_private)] +// on aarch64, "Using 'getaddrinfo' in statically linked applications requires at runtime the shared +// libraries from the glibc version used for linking" +#![allow(linker_messages)] extern crate libc; use std::os::unix::process::CommandExt; From dc1d3bc40094ab74bcdaf5531be58f8eb22c2fab Mon Sep 17 00:00:00 2001 From: jyn Date: Fri, 12 Dec 2025 19:48:45 -0500 Subject: [PATCH 4/4] Set linker-messages to warn-by-default --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7c027072b61f0..a3303ac2fa37e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4034,7 +4034,7 @@ declare_lint! { /// and actionable warning of similar quality to our other diagnostics. See this tracking /// issue for more details: . pub LINKER_MESSAGES, - Allow, + Warn, "warnings emitted at runtime by the target-specific linker program" }