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

`+

// See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146

`

``

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;

`