Auto merge of #119286 - jyn514:linker-output, r=bjorn3 · rust-lang/rust@f7cc13a (original) (raw)
`@@ -15,12 +15,14 @@ use rustc_ast::CRATE_NODE_ID;
`
15
15
`use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
`
16
16
`use rustc_data_structures::memmap::Mmap;
`
17
17
`use rustc_data_structures::temp_dir::MaybeTempDir;
`
18
``
`-
use rustc_errors::DiagCtxtHandle;
`
``
18
`+
use rustc_errors::{DiagCtxtHandle, LintDiagnostic};
`
19
19
`use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
`
20
20
`use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
`
``
21
`+
use rustc_macros::LintDiagnostic;
`
21
22
`use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
`
22
23
`use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
`
23
24
`use rustc_middle::bug;
`
``
25
`+
use rustc_middle::lint::lint_level;
`
24
26
`use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
`
25
27
`use rustc_middle::middle::dependency_format::Linkage;
`
26
28
`use rustc_middle::middle::exported_symbols::SymbolExportKind;
`
`@@ -29,6 +31,7 @@ use rustc_session::config::{
`
29
31
`OutputType, PrintKind, SplitDwarfKind, Strip,
`
30
32
`};
`
31
33
`use rustc_session::cstore::DllImport;
`
``
34
`+
use rustc_session::lint::builtin::LINKER_MESSAGES;
`
32
35
`use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
`
33
36
`use rustc_session::search_paths::PathKind;
`
34
37
`use rustc_session::utils::NativeLibKind;
`
`@@ -749,6 +752,14 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out
`
749
752
`}
`
750
753
`}
`
751
754
``
``
755
`+
#[derive(LintDiagnostic)]
`
``
756
`+
#[diag(codegen_ssa_linker_output)]
`
``
757
`+
/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
`
``
758
`+
/// end up with inconsistent languages within the same diagnostic.
`
``
759
`+
struct LinkerOutput {
`
``
760
`+
inner: String,
`
``
761
`+
}
`
``
762
+
752
763
`/// Create a dynamic library or executable.
`
753
764
`///
`
754
765
`/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
`
`@@ -981,6 +992,11 @@ fn link_natively(
`
981
992
``
982
993
`match prog {
`
983
994
`Ok(prog) => {
`
``
995
`+
let is_msvc_link_exe = sess.target.is_like_msvc
`
``
996
`+
&& flavor == LinkerFlavor::Msvc(Lld::No)
`
``
997
`+
// Match exactly "link.exe"
`
``
998
`+
&& linker_path.to_str() == Some("link.exe");
`
``
999
+
984
1000
`if !prog.status.success() {
`
985
1001
`let mut output = prog.stderr.clone();
`
986
1002
` output.extend_from_slice(&prog.stdout);
`
`@@ -997,16 +1013,9 @@ fn link_natively(
`
997
1013
`// is not a Microsoft LNK error then suggest a way to fix or
`
998
1014
`// install the Visual Studio build tools.
`
999
1015
`if let Some(code) = prog.status.code() {
`
1000
``
`-
if sess.target.is_like_msvc
`
1001
``
`-
&& flavor == LinkerFlavor::Msvc(Lld::No)
`
1002
``
`-
// Respect the command line override
`
1003
``
`-
&& sess.opts.cg.linker.is_none()
`
1004
``
`-
// Match exactly "link.exe"
`
1005
``
`-
&& linker_path.to_str() == Some("link.exe")
`
1006
``
`` -
// All Microsoft link.exe
linking error codes are
``
1007
``
`-
// four digit numbers in the range 1000 to 9999 inclusive
`
1008
``
`-
&& (code < 1000 || code > 9999)
`
1009
``
`-
{
`
``
1016
`` +
// All Microsoft link.exe
linking ror codes are
``
``
1017
`+
// four digit numbers in the range 1000 to 9999 inclusive
`
``
1018
`+
if is_msvc_link_exe && (code < 1000 || code > 9999) {
`
1010
1019
`let is_vs_installed = windows_registry::find_vs_version().is_ok();
`
1011
1020
`let has_linker =
`
1012
1021
` windows_registry::find_tool(&sess.target.arch, "link.exe").is_some();
`
`@@ -1028,8 +1037,49 @@ fn link_natively(
`
1028
1037
``
1029
1038
` sess.dcx().abort_if_errors();
`
1030
1039
`}
`
1031
``
`-
info!("linker stderr:\n{}", escape_string(&prog.stderr));
`
1032
``
`-
info!("linker stdout:\n{}", escape_string(&prog.stdout));
`
``
1040
+
``
1041
`+
let stderr = escape_string(&prog.stderr);
`
``
1042
`+
let mut stdout = escape_string(&prog.stdout);
`
``
1043
`+
info!("linker stderr:\n{}", &stderr);
`
``
1044
`+
info!("linker stdout:\n{}", &stdout);
`
``
1045
+
``
1046
`+
// Hide some progress messages from link.exe that we don't care about.
`
``
1047
`+
`
``
1048
`+
if is_msvc_link_exe {
`
``
1049
`+
if let Ok(str) = str::from_utf8(&prog.stdout) {
`
``
1050
`+
let mut output = String::with_capacity(str.len());
`
``
1051
`+
for line in stdout.lines() {
`
``
1052
`+
if line.starts_with(" Creating library")
`
``
1053
`+
|| line.starts_with("Generating code")
`
``
1054
`+
|| line.starts_with("Finished generating code")
`
``
1055
`+
{
`
``
1056
`+
continue;
`
``
1057
`+
}
`
``
1058
`+
output += line;
`
``
1059
`+
output += "\r\n"
`
``
1060
`+
}
`
``
1061
`+
stdout = escape_string(output.trim().as_bytes())
`
``
1062
`+
}
`
``
1063
`+
}
`
``
1064
+
``
1065
`+
let (level, src) = codegen_results.crate_info.lint_levels.linker_messages;
`
``
1066
`+
let lint = |msg| {
`
``
1067
`+
lint_level(sess, LINKER_MESSAGES, level, src, None, |diag| {
`
``
1068
`+
LinkerOutput { inner: msg }.decorate_lint(diag)
`
``
1069
`+
})
`
``
1070
`+
};
`
``
1071
+
``
1072
`+
if !prog.stderr.is_empty() {
`
``
1073
`` +
// We already print warning:
at the start of the diagnostic. Remove it from the linker output if present.
``
``
1074
`+
let stderr = stderr
`
``
1075
`+
.strip_prefix("warning: ")
`
``
1076
`+
.unwrap_or(&stderr)
`
``
1077
`+
.replace(": warning: ", ": ");
`
``
1078
`+
lint(format!("linker stderr: {stderr}"));
`
``
1079
`+
}
`
``
1080
`+
if !stdout.is_empty() {
`
``
1081
`+
lint(format!("linker stdout: {}", stdout))
`
``
1082
`+
}
`
1033
1083
`}
`
1034
1084
`Err(e) => {
`
1035
1085
`let linker_not_found = e.kind() == io::ErrorKind::NotFound;
`