Rust Toolchain Platform/Target Questions

context

I wanted to install the Rust toolchain on a Windows 10 machine. Since I was already using gcc and clang from MSYS2's UCRT64 environment, when I saw Rust might need MSVC as a prerequisite, I wondered whether I could just use the already installed gcc.

Then I found a post saying this is because Rust needs a linker. So instead of installing the x86_64-pc-windows-msvc toolchain, I installed the x86_64-pc-windows-gnu toolchain hoping just to use the GNU linker. And so far, it seems my code compiles and runs with no problem.

Then I found that the x86_64-pc-windows-gnu toolchain itself included the ld.exe in the bin folder, which should be the GNU linker(?). So I tried to remove my gcc and clang from the environment, and my Rust code still compiled and ran normally.

update

  • On my local machine, I removed the GNU toolchain from MSYS2 UCRT64 environment from the disk and Rust still works.
  • On the Windows Sandbox on my local machine, I installed Rust x86_64-pc-windows-gnu toolchain using rustup-init with nothing additional installed. Code still compiles and runs

question

So why doesn't Rust use the x86_64-pc-windows-gnu toolchain for Windows by default? Because it seems that by using the x86_64-pc-windows-gnu toolchain, you don't need to install any extra thing, which is simpler.

Is it because there are certain drawbacks or limitations when using the x86_64-pc-windows-gnu toolchain? But so far, my code compiles and runs with no problem. Is it because my code is very simple?

You are contradicting yourself here a little. You said you installed the GNU toolchain above. I highly doubt Windows ships the GNU toolchain out of the box (could be wrong though). I think it is very unlikely you'll find a Windows with MinGW but not MSVC installed.

Here a snippet from a great answer from a previous question:

1 Like

Thanks for replying. Yes I installed the GNU toolchain beforehand, but I removed them from the environment later. I cannot access gcc or ld from my PowerShell environment.

But there is a possibility that Rust can cache the location of the linker. I will try to remove them from the disk later totally.

I tried cargo build -vv, but it didn't give linker information. When switching to the x86_64-pc-windows-msvc toolchain, cargo build will give an error of "linker link.exe not found" because I didn't install MSVC.

Out of interest I went down the rabbit hole and tried to find out how rustc finds the right linker. Didn't make it that far :sweat_smile:. I think rustc takes the information what default linker to use from the target specification json . I ran rustc +nightly -Z unstable-options --target=x86_64-pc-windows-gnu --print target-spec-json according to the rustc book to find out the target specification. The json says the linker is supposed to be x86_64-w64-mingw32-gcc. The source for the target specification is here: rust/x86_64_pc_windows_gnu.rs at c8e6a9e8b6251bbc8276cb78cabe1998deecbed7 · rust-lang/rust · GitHub.

Thanks for your time. I got some updated test results:

  • On my local machine, I removed the GNU toolchain from MSYS2 UCRT64 environment and Rust still works.
  • On the Windows Sandbox on my local machine, I installed Rust x86_64-pc-windows-gnu toolchain using rustup-init with nothing additional installed. Code still compiles and runs :eyes:

So I guess the x86_64-pc-windows-gnu toolchain indeed works out of the box on Windows 10 or higher(?).

I believe x86_64-pc-windows-gnu ships with all parts of MinGW necessary for compiling.

2 Likes

Yeah it's consistent with my test results.

But then why doesn't Rust use x86_64-pc-windows-gnu by default? Shouldn't it be simpler for newcomers?

As @jofas pointed out, MinGW doesn't support import libraries created by MSVC and many import libraries shipped with MinGW are outdated or straight up incorrect. This means that you can't use many libraries when using MinGW, but you can't easily figure out which ones. This is a much worse experience than having to install the visual studio build tools once at the start when prompted by rustup.

2 Likes

It would be easier for newcomer who only just want to port code from GNU/Linux to Windows.

The assumption (which is IMNSHO) is that if you want to use rust in Windows then you are, probably, Windows developer and want to use other Windows SDKs and tools.

x86_64-pc-windows-gnu is awful for that, it doesn't play well with anything but itself. It's entirely unsuitable to use for Windows-native development.

1 Like

I agree with some points.

Mingw lags in supporting recent windows sdk features. This happened with DirectX, gdiplus and recently with webview. The linker is also slower. Visual studio also offers better a better C/C++ debugging experience. However mingw catches up quite quickly. The mingw package management (provided via pacman) is also great and beats any other mean of installing native packages on windows. The install size of msys2/mingw is less than 200mb, while the msvc toolchain (without the IDE) requires a few gigs. Until recently the msvc toolchain lagged in its support of more recent C standards, while with GCC you would always get support for the latest standard. I don’t blame the gcc devs for following their own abi and not bending backwards to use the msvc abi which is closed.

Zig for example defaults to using the gnu abi (via its own toolchain) on windows.
Several production apps use mingw gnu toolchain such as git for windows, krita, kdenlive and most gtk apps running on windows.

I think it's mainly a licensing issue, rustup cannot automatically install MSVC for you due to its license. The installation is not exactly difficult.

But presumably, if you're using a Windows machine to compile rust code, you will either:

  • build and run multiplatform code (in which case the toolchain shouldn't matter, rust should be able to build everything from scratch for you), or,
  • build and run Windows-specific code (i.e. using winapi) and link against Windows specific dlls, which are built for the MSVC ABI.

Assuming these two groups capture the majority of rust users on Windows, the choice is pretty clear - msvc toolchain handles both cases but gnu does not.

The only case I can think of where you would need x86_64-pc-windows-gnu is if you're using a crate which builds a C library, and that C library needs Msys2 in order to build. After all, that's basically the entire purpose of Msys2 - some C libraries have incredible complex builds, using huge Make files and linux-specific tooling, which would be very difficult, if not impossible, to recreate in a way compatible with Windows. Having built many programs with Msys/Msys2 myself, I can say these cases are becoming exceedingly rare, perhaps due to proliferation of better build systems than e.g. Make which let you make fewer assumptions about your environment.

2 Likes

Um. From rustup 1.25.0 release notes: One of the biggest changes in 1.25.0 is the new offer on Windows installs to auto-install the Visual Studio 2022 compilers which should simplify the process of getting started for people not used to developing on Windows with the MSVC-compatible toolchains.

I'm not sure why it took so many years to actually do that, but it does that now.