Rust on Windows wishlist
Everything below is grounded in a real upstream issue or a workaround currently living in the microsoft/windows-rs repo.
cargo fmtfails on large workspaces (Windows command-line limit).cargo fmt --alldies withThe filename or extension is too long. (os error 206)- rustfmt/cargo builds one giant argument list that blows past the Windows ~32K command-line limit. Should use a response file / batch invocations on Windows. -> rust-lang/rustfmt#6934 (open; related #5975). Verified: reproduces on the windows-rs repo today.
-
Allow
.incdylib/crate names. Can't produceMicrosoft.Sample.dlldirectly; renaming post-build leaves symbols referring to the old name. Dotted names are common/required for Windows DLLs. -> rust-lang/cargo#15735 (open). -
Reliable way to get the target dir from a build script (e.g. a
CARGO_TARGET_DIRenv var). Needed by codegen/import-lib build scripts; precedent exists (cargo doc). -> rust-lang/cargo#9661 (open). -
A crate that produces a DLL (
cdylib/bin) can't be a real dependency, so build ordering is unreliable and emits a bogus warning. To make a DLL build before the crate that needs it at runtime, we currently declare it as a normal dependency purely for ordering (e.g.crates/samples/csharp/client/Cargo.tomldepends oncsharp_component). Because acdylibhas no linkable Rust target, Cargo prints the unhelpfulwarning: the packagecsharp_componentprovides no linkable target(windows-rs CI run 28479315077, job 84411708172), and the ordering itself isn't guaranteed. Artifact dependencies (RFC 3028 /bindeps) are the intended fix but are still unstable. Stabilizing them - a crate depending on abin/cdylibartifact with guaranteed build order and no spurious warning - would help anyone shipping DLLs from Rust (COM/WinRT components, C# interop, plugins). -> rust-lang/cargo#9096 (artifact deps tracking, open); rust-lang/cargo#7825 (the "no linkable target" warning, open).
From<PrivateType> for PublicExternalTypesilently suppressesdead_code. A single such impl disables dead-code warnings for all methods on the type, hiding real dead code in generated bindings. -> rust-lang/rust#157961 (open).
-
Windows MSVC is stuck on the old
link.exewhile other targets moved to a much faster linker. Rust switchedx86_64-unknown-linux-gnuto LLD by default (nightly May 2024, stabilized in 1.90.0, Sept 2025), citing linking as up to half of compile time and ~7x faster incremental links. Windows MSVC got none of this and still defaults tolink.exe, a major reason large MSVC builds are slow (rust-lang/rust#145864: rustc final stages ~21 min for a large program on MSVC).The state of the art shows how much headroom exists: on Linux, linking can run essentially at disk-I/O speed.
mold(Rui Ueyama) proved this with a modern multithreaded design, andwild(David Lattimore) is a newer linker written in Rust pursuing the same speed plus incremental linking. Windows has no comparable fast COFF/PDB linker.Highest-value asks for DevDiv:
- Make a fast linker (
lld-link/rust-lld) the default - or at least a well-supported, documented option - for the*-pc-windows-msvctargets. This has been requested since 2020 (rust-lang/rust#71520, still open) but has stalled. - Revive the parallel linker + PDB-generator effort. The building blocks exist and are actively maintained (github.com/microsoft/pdb-rs - Rust crates for reading/writing PDB/MSF/MSFZ), but the parallel-linker side appears to have stalled. A fast, parallel, MSVC-compatible linker + PDB writer would benefit all of Rust on Windows, not just windows-rs.
Blog refs: blog.rust-lang.org/2024/05/17/enabling-rust-lld-on-linux/ and blog.rust-lang.org/2025/09/01/rust-lld-on-1.90.0-stable/.
- Make a fast linker (
The biggest day-to-day pain point: the same Rust workspace builds far faster on Linux than on Windows, and the gap is dominated by OS-level costs - filesystem, process/thread creation, and Defender - not by rustc/LLVM codegen. A Rust build is I/O- and process-heavy by design: thousands of small file reads, writes, stats, and deletions, plus a separate process per crate and per build script. Every one of those operations is more expensive on Windows, and the cost compounds across a large workspace. These are largely Windows/NTFS/Defender issues rather than pure DevDiv, but they throttle Rust on Windows every day and are worth raising jointly.
-
Filesystem operations are slow and have hostile semantics - and this hits build time directly, not just
std::fscalls. Every crate compiled writes/reads/stats/ deletes many small files (rlibs, object files, incremental fingerprints, dep-info). NTFS plus Defender plus the Search indexer make each operation far slower than the Linux equivalent, and the cost multiplies across a workspace. On top of the raw slowness, Windows can't delete/replace a file while a handle is open, and scanners routinely hold handles on freshly written outputs, producing "Access is denied", "used by another process", and "cannot open file" errors plus retry loops. Evidence:- rust-lang/rust#127883 - tracking issue: high failure rates on Windows MSVC CI from filesystem errors (~15% of builds); explicitly does NOT affect the GNU builders. Bootstrap had to add retry/mitigation for deleting executables held open by rustc, the MSVC linker, and cargo.
- rust-lang/rust#154521 -
Pathcomparison is "obscenely slow" (64% of one real program's runtime). - rust-lang/rust#127606 - file truncation (
std::fs::write) is slow on Windows. - rust-lang/rust#148257 / #151181 - flaky "failed to remove temporary directory" and incremental "Access is denied (os error 5)".
-
Process and thread creation are far more expensive than on Linux - and a cargo build spawns a lot of both. cargo runs a separate process per crate and per build script, and rustc spawns threads for its parallel front-end and codegen units. Windows
CreateProcess/thread creation is much heavier thanfork+exec/posix_spawnand thread spawn on Linux, so this overhead alone widens the gap on every build. Not directly a DevDiv fix, but they could take a cue from thewindows-threadingcrate, which dispatches closures through the Win32 thread pool (TrySubmitThreadpoolCallback) and reuses worker threads instead of spawning a fresh OS thread per call - dramatically cheaper thanstd::thread. A thread-pool- backed default in std, and lower per-process spawn overhead in cargo/rustc on Windows, would help everyone. -
Windows Defender both slows builds and blocks developers. Real-time scanning holds handles on and re-scans every build artifact (feeding into item 7's slowness and flakiness), and it also false-flags rustc-built dylibs - even the shipped
std-*.dll- as trojans (rust-lang/rust#137443, #93187, #88297). Today the only mitigation is excluding the workspace and~/.cargofrom Defender (windows-rs#4053), which noticeably speeds builds. DevDiv coordinating with the Defender team on toolchain-aware scanning / an allow path for Rust output would remove a recurring, high-friction papercut.