-
-
Notifications
You must be signed in to change notification settings - Fork 15.4k
codegen: classify localized MSVC linker progress as linker_info #160445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
rust-bors
merged 1 commit into
rust-lang:main
from
rabindra789:fix/msvc-localized-linker-output
Aug 8, 2026
+119
−13
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
tests/run-make/msvc-localized-linker-output/fake-linker.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| fn main() { | ||
| // Simulate a localized (e.g. Japanese) `link.exe`, as printed when the | ||
| // English language pack is not installed and `VSLANG=1033` has no effect. | ||
| // This is "Creating library foo.dll.lib and object foo.dll.exp" in Japanese. | ||
| println!("ライブラリ foo.dll.lib とオブジェクト foo.dll.exp を作成中"); | ||
| // A file name containing an `LNK####`-looking fragment must not be | ||
| // mistaken for a diagnostic, which is why the matcher requires the | ||
| // structured `LINK : warning LNK####:` form. | ||
| println!("LNK2001.lib: progress message, not a diagnostic"); | ||
| for arg in std::env::args() { | ||
| if arg == "run_make_lnk" { | ||
| // Real diagnostics are structured as `LINK : warning LNK####:`. | ||
| println!("LINK : warning LNK2001: unresolved external symbol foo"); | ||
| // The one code-bearing informational line has no `LINK : ` prefix | ||
| // and keeps the exception that classifies it as `linker_info`. | ||
| println!( | ||
| "LNK6004: 'foo.exe' not found or not built by the last incremental link; \ | ||
| performing full link" | ||
| ); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fn main() {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| //@ only-msvc | ||
| //@ ignore-cross-compile (need to run the fake link.exe on the host) | ||
|
|
||
| //! Tests that localized (non-English) MSVC `link.exe` progress messages are | ||
| //! classified as `linker_info`, not `linker_messages`. | ||
| //! | ||
| //! `link.exe` is hardcoded by rustc to run with `VSLANG=1033`, which only works | ||
| //! when an English language pack is installed. Without it, messages like | ||
| //! "Creating library ..." are printed in another language, and the English | ||
| //! string matching that used to detect them fails. Since all real diagnostics | ||
| //! carry a locale-independent `LNK####` code, printed in the structured | ||
| //! `LINK : warning LNK####:` form, any line without one is informational, no | ||
| //! matter the language it was printed in. | ||
|
|
||
| use run_make_support::{bare_rustc, rustc, target}; | ||
|
|
||
| fn main() { | ||
| // rustc prepends the sysroot's tools bin directory to the linker's `PATH`, | ||
| // which bare names like `link.exe` are resolved against. Put the fake | ||
| // `link.exe` there so it wins over the real linker; `-L` below keeps std | ||
| // available from the real sysroot. | ||
| let fake_sysroot = std::env::current_dir().unwrap().join("fake-sysroot"); | ||
| let tools_bin = fake_sysroot.join(format!("lib/rustlib/{}/bin", target())); | ||
| std::fs::create_dir_all(&tools_bin).unwrap(); | ||
| rustc().arg("fake-linker.rs").output(tools_bin.join("link.exe")).run(); | ||
|
|
||
| let real_libdir = rustc().print("target-libdir").run().stdout_utf8(); | ||
| let real_libdir = real_libdir.trim(); | ||
|
|
||
| let fake_link = |extra: &[&str]| { | ||
| let mut r = bare_rustc(); | ||
| r.input("main.rs") | ||
| .output("main") | ||
| .arg(format!("--sysroot={}", fake_sysroot.display())) | ||
| .arg(format!("-L{real_libdir}")) | ||
| // Matched by name against the linker's `PATH`, so the fake in the | ||
| // tools bin directory is used instead of the real VS linker. | ||
| .arg("-Clinker=link.exe") | ||
| // Overrides `rust.lld=true` on CI. | ||
| .arg("-Clinker-flavor=msvc"); | ||
| for a in extra { | ||
| r.arg(a); | ||
| } | ||
| r | ||
| }; | ||
|
|
||
| // The localized progress line must not warn by default. | ||
| fake_link(&[]) | ||
| .run() | ||
| .assert_stderr_not_contains("linker stdout") | ||
| .assert_stderr_not_contains("ライブラリ foo.dll.lib とオブジェクト foo.dll.exp を作成中"); | ||
|
|
||
| // It is still visible through `linker_info`, and must not be misclassified | ||
| // as `linker_messages`. | ||
| fake_link(&["-Wlinker_info", "-Dlinker_messages"]) // Fail if the message is misclassified. | ||
| .run() | ||
| .assert_stderr_contains("ライブラリ foo.dll.lib とオブジェクト foo.dll.exp を作成中"); | ||
|
|
||
| // Real diagnostics keep their `LNK####` code and still warn. | ||
| fake_link(&["-Clink-arg=run_make_lnk"]) | ||
| .run() | ||
| .assert_stderr_contains( | ||
| "warning: linker stdout: LINK : warning LNK2001: unresolved external symbol foo", | ||
| ) | ||
| // The informational LNK6004 line stays hidden. | ||
| .assert_stderr_not_contains("LNK6004"); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.