mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Treat MSVC "performing full link" message as informational
When the MSVC incremental linker finds a .ilk file for incremental linking but its associated .exe file is missing, this message is printed to stdout in 1 line: LINK : ...\foo.exe not found or not build by the last incremental link; performing full link However, if both the .ilk and .exe files are missing (for a clean build), the message isn't printed and it still does a full link. So, the presence of the message doesn't affect the result of the build.
This commit is contained in:
@@ -759,10 +759,15 @@ fn for_each(bytes: &[u8], mut f: impl FnMut(&str, &mut String)) -> String {
|
||||
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
|
||||
// When incremental linking is enabled and an .ilk exists, but its associated .exe is
|
||||
// missing, link.exe prints the path of the missing .exe followed by:
|
||||
let ilk_but_no_exe =
|
||||
"not found or not built by the last incremental link; performing full link";
|
||||
let trimmed = line.trim_start();
|
||||
if trimmed.starts_with("Creating library")
|
||||
|| trimmed.starts_with("Generating code")
|
||||
|| trimmed.starts_with("Finished generating code")
|
||||
|| trimmed.ends_with(ilk_but_no_exe)
|
||||
{
|
||||
linker_info += line;
|
||||
linker_info += "\r\n";
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
fn main() {}
|
||||
@@ -0,0 +1,47 @@
|
||||
//@ only-msvc
|
||||
//! Tests that the MSVC incremental linker's "performing full link" message is classified as
|
||||
//! `linker_info`, not `linker_messages`.
|
||||
//!
|
||||
//! The MSVC incremental linker prints this message to stdout when it finds a `.ilk` file for
|
||||
//! incremental linking but its associated `.exe` file is missing:
|
||||
//!
|
||||
//! ```
|
||||
//! LINK : ...\main.exe not found or not built by the last incremental link; performing full link
|
||||
//! ```
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::bare_rustc;
|
||||
|
||||
fn incremental_rustc() -> run_make_support::Rustc {
|
||||
let mut r = bare_rustc();
|
||||
r.input("main.rs")
|
||||
// Overrides `rust.lld=true` on CI.
|
||||
.arg("-Clinker=link.exe")
|
||||
.arg("-Clinker-flavor=msvc")
|
||||
// Without this, Rust passes /OPT:REF to link.exe, which
|
||||
// disables incremental linking entirely and suppresses the message.
|
||||
.arg("-Clink-dead-code")
|
||||
// /DEBUG is required: it implies /INCREMENTAL, which is what makes
|
||||
// link.exe create the .ilk file and later emit the message.
|
||||
.arg("-Cdebuginfo=2");
|
||||
r
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// First link: produces main.exe and main.ilk.
|
||||
incremental_rustc().run();
|
||||
|
||||
// Delete the .exe but leave the .ilk.
|
||||
fs::remove_file("main.exe").unwrap();
|
||||
|
||||
// Second link: link.exe finds the .ilk but not the .exe and emits the
|
||||
// "performing full link" message on stdout.
|
||||
let output = incremental_rustc()
|
||||
.arg("-Dlinker_messages") // Fail if the message is misclassified.
|
||||
.arg("-Wlinker_info")
|
||||
.run();
|
||||
|
||||
// Verify the message was actually emitted and routed to linker_info.
|
||||
output.assert_stderr_contains("performing full link");
|
||||
}
|
||||
Reference in New Issue
Block a user