Use lld by default on Windows to mitigate Microsoft C++ Build Tools licencing issues

Rust needs a platform-specific linker to produce executables. On Windows the default is Microsoft C++ Built Tools, which is a standalone MSVC toolchain without requiring a full Visual Studio installation.

Nonetheless it may still be regarded a part of Visual Studio, which is a proprietary product. Visual Studio is free under Community licence but almost all companies would have to pay for Pro or Enterprise licences.

The licencing situation of Microsoft C++ Build Tools has long been murky (just search "Microsoft C++ Build Tools licence" and all the results are people asking whether they are allowed to use it without VS licence).

Today Microsoft added a Rust topic to their VSCode docs, which states (emphasis added)


On Windows, you will need to also install Microsoft C++ Build Tools in order to get the C/C++ linker link.exe . Be sure to select the Desktop Development with C++ when running the Visual Studio installer.

Note : You can use the C++ toolset from Visual Studio Build Tools along with Visual Studio Code to compile, build, and verify any codebase as long as you also have a valid Visual Studio license (either Community, Pro, or Enterprise).

The implication here is clear: you must have a VS licence to use link.exe. For individuals this doesn't matter much as Community licence is free, but for companies it means the Rust default could set them up for a licence violation.

As such, Rust should change the default linker to lld on Windows ASAP. lld has been production quality for many years and this will also simplify the Rust installation experience on Windows as rustup could install rust-lld by default, no longer requiring users to install Microsoft C++ Build Tools separately (which we can't distribute)


Note that the VS2022 Community EULA states

If you are an enterprise, your employees and contractors may not use the software to develop or test your applications, except for: (i) open source; (ii) Visual Studio extensions; (iii) device drivers for the Windows operating system; (iv) SQL Server development; and, (v) education purposes as permitted above.


This is currently blocked on at least

Note that there is currently work being done to allow using rust-lld on linux with stable rustc: Implement `-Zgcc-ld=lld` stabilization MCP by lqd · Pull Request #96401 · rust-lang/rust · GitHub This does not switch the default though.


Using lld is not sufficient on its own, even if it is possible.

We would also need a replacement for, amongst other things, the C runtime startup/shutdown code, a variety of utility functions (memcpy, memcmp, etc) and C++ exception handling (currently rust/llvm hardcodes a dependency on _CxxThrowException and __CxxFrameHandler3 for msvc targets).

A future alternative would be the new pc-windows-gnullvm targets but this is not yet available and would start as tier 3.

It's also possible that the VC runtime (which provides many of these things) may be made open source in the same way that the Microsoft C++ Standard Library has (Apache License v2.0 with LLVM Exception). In which case we wouldn't need Visual Studio for that.


the C runtime startup/shutdown code, a variety of utility functions ( memcpy , memcmp , etc)

I thought these are from LLVM's compiler-rt?

hardcodes a dependency on _CxxThrowException and __CxxFrameHandler3

I'm not familiar with these ones. Are they not just symbols dynamically linked at runtime? In which case it's irrelevant to any Microsoft licences

Perhaps! If so, that would need to be shipped with Rust and linked in automatically when using lld as the linker.

These are provided by either the static libvcruntime.lib or the dynamic vcruntime140.dll. The dynamic version is not shipped with the OS so even that requires Visual Studio.

We don't use compiler-rt AFAIK. We use the ones from the native toolchain and have unoptimized fallbacks written in rust in the compiler_builtins crate for when you don't use an OS at all.

The pc-windows-gnu targets work fine, right? mingw just uses a different format import libraries afaik so if you try to use a dll or staticlib not shipped with windows you have to compile it for mingw.

Sure, it's... fine. It is however a bit old (uses the 90's era msvcrt.dll) and likes to do weird stuff (like emulating TLS instead of using native).