Code change:
A localized (e.g. German) MSVC can produce non-UTF-8 output, which can become almost unreadable in the way it's currently forwarded to the user. This can be seen in an (otherwise unrelated) issue comment: Note especially this line: That output might be a lot longer for multiple LNK errors (one line per error, but the lines are not properly separated in the output, because they are converted to ) and become really hard to read. If possible, the output should be converted to Unicode in this case. (previously reported as ) NOTE from Please install Visual Studio English Language Pack side by side with your favorite language pack for UI
I’m surprised we try to interpret any output in Windows as UTF-8 as opposed to UTF-16, like we should.
I suspect that the MSVC compiler's raw output is encoded as Windows-1252 or Windows-1250 (for German) depending on the current console code page and not as UTF-16. Does solve the encoding problem?
No, neither in nor in (usually I'm working with the latter). It prints but the encoding problems persist.
Is it just MSVC which is localized, or is your system codepage itself different? If we know that a certain program's output is the system codepage we could use with to convert it. Perhaps we could check whether the output is UTF-8, and attempt to do the codepage conversion if it isn't.
I am using a German localized Windows. How can I find out the system codepage? The default CP for console windows is "850 (OEM - Multilingual Lateinisch I)".
You can call  with or .
That returns codepage numbers 1252 for and 850 for .
In which case the output from the linker appears to be , so now someone just has to add code to rustc which detects when the linker output isn't utf-8 on windows and use with instead.
I ran into this problem as well (also on a German Windows 10). As a workaround it helps if you go to in Win 10 to Settings -Region and Language -Language and add English as a language and make it default ( you may have to log out and back in again). After that, programs like should output using a locale that works with rust as it is right now. It would still be great if this could be fixed in rust :)
Just saw another instance of this in , except with ) (a common encoding in China), where got printed instead of the desired .
Using nightly 2019-07-04, we can confirm that this issue is fixed. (I'm using Chinese version of Visual Studio).
For me, it still does not work even with nightly build (1.38 x86_64-pc-windows-msvc, Russian version of VS). I try to compile a Hello world project in Intellij Idea but always get the exception:
Could you execute and see what that outputs?
That's a little strange. Could you open "x64 Native Tools Command Prompt for Visual Studio 2019" from start menu, and execute the following command: And see whether the output is English? If the output's still not in English, would you mind open "Visual Studio Installer" from start menu, choose "Modify" for the corresponding Visual Studio edition, and in the Language packs tab, install the English language pack. And try the instructions above again?
thanks! The hint about installing the English language pack has made the previous error disappear. But now I have another message while running in Idea: I haven't changed the path to the std library, it's looks like
Yes, this is the same error as before, it's because you didn't install windows sdk. Choose the newest one in the visual studio installer too.
thank you again. Now it's compiling and running. I'm happy ;) Just out of curiosity: was I supposed to know in advance that I would need an English lang pack and a Windows SDK when installing Visual Studio?
Please feel free to point out places where Rust tells you to install Visual Studio but does not tell you to install the Windows SDK, so that we can fix those places. It might still be worth implementing the text encoding version of the fix for people who don't have the English language pack, though I really wish we could just get unicode output out of VS without having to specify a language.
sorry, seems I was a bit inattentive. Now I double-checked: after starting rustup- the screen info says, I should assure that I have Windows SDK installed. So my fault, nothing to fix there :) Thanks.
This is not a fix anymore.
refer to
Please make sure you have installed Visual Studio English Language Pack side by side with your favorite language pack for UI for this to work.
I'm not sure this problem is really fixed. The PR that closed this kinda works around the issue because English is usually ASCII which is the same in UTF-8. However, as noted above, this relies on the Visual Studio English language pack being installed which it isn't always. And that there's no non-ascii output (e.g. file paths, etc). The suggestion to use with seems like a better fix, imho.

Related discussion:
text: } } <ins> #[cfg(not(windows))] fn escape_linker_output(s: &[u8], _flavour: LinkerFlavor) -> String { escape_string(s) } /// If the output of the msvc linker is not UTF-8 and the host is Windows, /// then try to convert the string from the OEM encoding. #[cfg(windows)] fn escape_linker_output(s: &[u8], flavour: LinkerFlavor) -> String { // This only applies to the actual MSVC linker. if flavour != LinkerFlavor::Msvc(Lld::No) { return escape_string(s); } match str::from_utf8(s) { Ok(s) => return s.to_owned(), Err(_) => match win::locale_byte_str_to_string(s, win::oem_code_page()) { Some(s) => s, // The string is not UTF-8 and isn't valid for the OEM code page None => format!("Non-UTF-8 output: {}", s.escape_ascii()), }, } } /// Wrappers around the Windows API. #[cfg(windows)] mod win { use windows::Win32::Globalization::{ GetLocaleInfoEx, MultiByteToWideChar, CP_OEMCP, LOCALE_IUSEUTF8LEGACYOEMCP, LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_RETURN_NUMBER, MB_ERR_INVALID_CHARS, }; /// Get the Windows system OEM code page. This is most notably the code page /// used for link.exe's output. pub fn oem_code_page() -> u32 { unsafe { let mut cp: u32 = 0; // We're using the `LOCALE_RETURN_NUMBER` flag to return a u32. // But the API requires us to pass the data as though it's a [u16] string. let len = std::mem::size_of::<u32>() / std::mem::size_of::<u16>(); let data = std::slice::from_raw_parts_mut(&mut cp as *mut u32 as *mut u16, len); let len_written = GetLocaleInfoEx( LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_IUSEUTF8LEGACYOEMCP | LOCALE_RETURN_NUMBER, Some(data), ); if len_written as usize == len { cp } else { CP_OEMCP } } } /// Try to convert a multi-byte string to a UTF-8 string using the given code page /// The string does not need to be null terminated. /// /// This is implemented as a wrapper around `MultiByteToWideChar`. /// See <https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar> /// /// It will fail if the multi-byte string is longer than `i32::MAX` or if it contains /// any invalid bytes for the expected encoding. pub fn locale_byte_str_to_string(s: &[u8], code_page: u32) -> Option<String> { // `MultiByteToWideChar` requires a length to be a "positive integer". if s.len() > isize::MAX as usize { return None; } // Error if the string is not valid for the expected code page. let flags = MB_ERR_INVALID_CHARS; // Call MultiByteToWideChar twice. // First to calculate the length then to convert the string. let mut len = unsafe { MultiByteToWideChar(code_page, flags, s, None) }; if len > 0 { let mut utf16 = vec![0; len as usize]; len = unsafe { MultiByteToWideChar(code_page, flags, s, Some(&mut utf16)) }; if len > 0 { return utf16.get(..len as usize).map(String::from_utf16_lossy); } } None } } </ins> fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) { // On macOS the runtimes are distributed as dylibs which should be linked to // both executables and dynamic shared objects. Everywhere else the runtimes