Rust on Windows with clang (LLVM) or gcc

I read this which discusses need to build C/C++ dependencies.

I gather that general development requires some external dependencies that require the additional tools, however, to establish a reference point, can pure rust code be written and built without llvm/gnu/msvc tools?

Can LLVM e.g. mingw be used on windows with Rust?

Is information up to date? I.e. Perhaps now, rust has more stand-alone crates that don't require these other language tools?

One of my goals is to get away from visual studio / msvc licensing requirements. If you read the VS/msvc licenses carefully, users are expected to use Visual Studio unless simply building open source dependencies. So that's another reason that knowing why rust needs these tools is helpful. But for C/C++ development in general, I plan to use mingw, with llvm preferred but gcc also OK.

Thank You

If you want to develop on Windows, but without the Microsoft toolchains, I think your best bet is to use WSL.

I program with Rust on windows using the x86_64-pc-windows-gnu target.

It's pretty easy and you don't need msvc.
You just need:

then install the rights tools:
pacman -S mingw-w64-ucrt-x86_64-gcc
add C:\msys64\ucrt64\bin to your path

Then it works perfectly (for me).

Thank you but I don't think that option supports use of the Windows API.

Thank you for information!

Apparently, llvm is a lower Tier? Interesting information:
[Rustup packages availability on x86_64-pc-windows-gnu]
[Rustup packages availability on x86_64-pc-windows-gnullvm]

This concurs with use of gcc. Does ...windows-gnullvm... correspond to clang?

clang itself is a compiler frontend (for C/C++ language), it is not an ABI specifier, so it is ambiguous when we talk about ABIs. e.g., there's clang-cl which uses the msvc ABI (and can be used with Visual Studio), and there's also clang from the msys2/mingw project, which uses the gnu ABI.

the rust target triplet -windows-gnullvm is similar to -windows-gnu, in that it uses the gnu ABI. the difference is it links against the "modern" ucrt as the C runtime (as opposed to the very old msvcrt), and it uses various LLVM tools/libraries instead of GCC/Binutils.

as of now, this target is still "tier2 without host tools", meaning it can only be cross-compiled.

for Windows target, although it is doable in theory, I strongly discourage cross-compilation. IMO, the preferred toolchain should be the -windows-msvc triplets, but if you don't want -windows-msvc, the alternative -windows-gnu is very good too.

for "pure" rust programs, the experience is mostly the same. even the official windows-rs crate by microsoft supports both targets equally.

the most significant difference between the two, IMO, is when you need some ffi libraries:

  • when using -msvc, the vcpkg tool is very handy and "just works" most of the time.
  • when using -gnu, the best option is usually pacman (and probably integration with pkg-config) of the msys2/mingw project.
  • or in both cases, you can always build from source, if you don't like "package managers".
1 Like

gnu ABI .. links against the "modern" ucrt

gnu and clang (not clang-cl) have different ABIs?

...LVM tools/libraries

Such as lld, clang-tidy, clang-format ?

when using -msvc, the vcpkg tool is very handy and "just works" most of the time.

The problem for me is the Microsoft license

Thanks kindly for all the information including the great details about vcpkg vs pacman.

for the msys2/mingw project, gcc and clang have the same ABI, and it is called the GNU ABI. if you didn't already, you can read the chapter about Windows of the rustup book.

lld maybe, clang-tidy/clang-format no.

clang-tidy and clang-format are frontend tools based on libclang, which is a language frontend for the C/C++ family. rust only uses the llvm backends.

I don't know the exact details, but the llvm tools that I can think of probably include various "sanitizers" (such as ASan, UBSan), performance profilers, etc.

So gnullvm uses the ucrt? The ucrt is what I'm interested in. I prefer not to use an obsolete c lib. To confirm, currently, the standard gnu toolset for use with Rust on Windows, x86_64-pc-windows-gnu, uses the old msvcrt?

Do Rust crates lessen the importance of the particular crt because they (standard Rust crates) reduce much of the need for use of crt functions?

Thank You!

unfortunately, last time I checked (about half a year ago), it was the case, and I'm pretty sure it still is true as of now. although the msys2 project announced the change of the default environment to ucrt a long time ago.

yes, to some extent. "pure" rust code typically uses rust's standard library, most of them doesn't need direct interface with crt. and rust's standard library is fairly well designed and portable across various operating systems.

but at the end of the day, rust's standard library itself is built on top of libc, which can be thought of as rust bindings to (a subset of) the crt. and for -windows-gnu targets, that crt is (unfortunately) the legacy mscvrt.

but that should be considered an implementation detail, and I believe the rust standard library has been carefully written to work around the legacy stuff, and re-implemented many crt features when neccessary (e.g. it is known to be bad or broken ). so it is not a concern in practice.

...unfortunately, last time I checked (about half a year ago), it was the case,

Yes, this links from mingw-w64 site and the readme is explicit that it uses msvcrt.

rust's standard library itself is built on top of libc

Makes sense. Although perhaps some is replaced by pure Rust, e.g. memcpy() strcpy(), the list is quite long, I know. The goal of a safe language system is to gradually become free of all unsafe language code and libs, so I imagine the plan is for Rust to eventually be independent of all C/C++ libraries. Although, as I see that you mentioned, Rust's wrappers could use them more safely until full rewrite, e.g. bounds checks before calls into libc. Logical.

This uses ucrt but if Rust standard crate(s) builds on msvcrt, then perhaps compatibility issue? I.e. Given what we've discussed here, it's best to avoid a toolchain that uses ucrt?

I'll look into Msys2 a bit more. This is all very helpful. I'm not overly concerned about msvcrt for Rust but I like to learn about the various options in general.

Based on the posts here, the default toolchain with CLion, mingw gnu, is probably ideal, true?

I'm also considering Linux because I'm interested in Linux (my code base was ported from Linux to Windows) and from what I am learning, Linux appears not to have the crt and ABI differences between clang and gcc as Windows does.

I don't know for sure, I have not used the llvm-mingw toolchain myself.

based on the discussion in #72241 and this document, my understanding is that, it is possible to use make a native rust toolchain work with llvm-mingw, but it is not supported by rustup, you need to do quite a lot of work yourself (bootstrapping??). however, use it for cross compilation is fine.

I don't use CLion, but IMO it probably is. the thing is, if you are targeting Windows while not wanting msvc, mingw is the only viable alternative (that is native on Windows). due to the way libc works on Windows, you cannot mix different runtimes (e.g. msvcrt and ucrt, forget about those vcredist).

although ucrt might be a better implementation, it's relative new to the mingw ecosystem. unless you are are absolutely certain every piece of code is written directly using libc (without third party dependencies), I would argue msvcrt has a better choice to work, purely from a compatibility perspective.

and personally, I generally prefer the "default" provision if it "just works". I don't like to dig into the "customizable" rabbit hole, unless there's an absolute need for it.

the difference is not in the C compilers per se (clang vs gcc), it is the C runtimes (a.k.a. libc, which determine the "env" or "abi" part of the target triple). on Windows, we have -msvc vs -gnu (vs -gnullvm); on Linux, we have mainly -gnu vs -musl, (there are many other environments too, mostly for specific hardware or embedded systems, such as -androideabi, -uclibc, etc.).

but again, unless you are targeting a very specific platform, the default works just fine, which is most likely either x86_64-unknown-linux-gnu or aarch64-unknown-linux-gnu for linux based PC and servers these days.