Skip to content

Commit fbc52c9

Browse files
Rollup merge of rust-lang#156291 - kupiakos:msvc-link-info, r=jyn514,mati865
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: ```text 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. See rust-lang#156209 for further context. r? @mati865 cc @jyn514
2 parents ffe32f0 + 39c766e commit fbc52c9

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,10 +754,15 @@ fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8]
754754
escaped_stdout = for_each(&stdout, |line, output| {
755755
// Hide some progress messages from link.exe that we don't care about.
756756
// See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146
757+
// When incremental linking is enabled and an .ilk exists, but its associated .exe is
758+
// missing, link.exe prints the path of the missing .exe followed by:
759+
let ilk_but_no_exe =
760+
"not found or not built by the last incremental link; performing full link";
757761
let trimmed = line.trim_start();
758762
if trimmed.starts_with("Creating library")
759763
|| trimmed.starts_with("Generating code")
760764
|| trimmed.starts_with("Finished generating code")
765+
|| trimmed.ends_with(ilk_but_no_exe)
761766
{
762767
linker_info += line;
763768
linker_info += "\r\n";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//@ only-msvc
2+
//! Tests that the MSVC incremental linker's "performing full link" message is classified as
3+
//! `linker_info`, not `linker_messages`.
4+
//!
5+
//! The MSVC incremental linker prints this message to stdout when it finds a `.ilk` file for
6+
//! incremental linking but its associated `.exe` file is missing:
7+
//!
8+
//! ```
9+
//! LINK : ...\main.exe not found or not built by the last incremental link; performing full link
10+
//! ```
11+
12+
use std::fs;
13+
14+
use run_make_support::bare_rustc;
15+
16+
fn incremental_rustc() -> run_make_support::Rustc {
17+
let mut r = bare_rustc();
18+
r.input("main.rs")
19+
// Overrides `rust.lld=true` on CI.
20+
.arg("-Clinker=link.exe")
21+
.arg("-Clinker-flavor=msvc")
22+
// Without this, Rust passes /OPT:REF to link.exe, which
23+
// disables incremental linking entirely and suppresses the message.
24+
.arg("-Clink-dead-code")
25+
// /DEBUG is required: it implies /INCREMENTAL, which is what makes
26+
// link.exe create the .ilk file and later emit the message.
27+
.arg("-Cdebuginfo=2");
28+
r
29+
}
30+
31+
fn main() {
32+
// First link: produces main.exe and main.ilk.
33+
incremental_rustc().run();
34+
35+
// Delete the .exe but leave the .ilk.
36+
fs::remove_file("main.exe").unwrap();
37+
38+
// Second link: link.exe finds the .ilk but not the .exe and emits the
39+
// "performing full link" message on stdout.
40+
let output = incremental_rustc()
41+
.arg("-Dlinker_messages") // Fail if the message is misclassified.
42+
.arg("-Wlinker_info")
43+
.run();
44+
45+
// Verify the message was actually emitted and routed to linker_info.
46+
output.assert_stderr_contains("performing full link");
47+
}

0 commit comments

Comments
 (0)