Skip to content

Instantly share code, notes, and snippets.

@kennykerr
Last active July 1, 2026 13:53
Show Gist options
  • Select an option

  • Save kennykerr/52af2613fbe936cfce123a41399003bd to your computer and use it in GitHub Desktop.

Select an option

Save kennykerr/52af2613fbe936cfce123a41399003bd to your computer and use it in GitHub Desktop.
Rust on Windows wishlist

Rust on Windows wishlist

Rust-on-Windows wishlist

Everything below is grounded in a real upstream issue or a workaround currently living in the microsoft/windows-rs repo.

rustfmt

  1. cargo fmt fails on large workspaces (Windows command-line limit). cargo fmt --all dies with The 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.

Cargo

  1. Allow . in cdylib/crate names. Can't produce Microsoft.Sample.dll directly; renaming post-build leaves symbols referring to the old name. Dotted names are common/required for Windows DLLs. -> rust-lang/cargo#15735 (open).

  2. Reliable way to get the target dir from a build script (e.g. a CARGO_TARGET_DIR env var). Needed by codegen/import-lib build scripts; precedent exists (cargo doc). -> rust-lang/cargo#9661 (open).

  3. 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.toml depends on csharp_component). Because a cdylib has no linkable Rust target, Cargo prints the unhelpful warning: the package csharp_component provides 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 a bin/cdylib artifact 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).

rustc / lints

  1. From<PrivateType> for PublicExternalType silently suppresses dead_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).

Linking (Windows MSVC)

  1. Windows MSVC is stuck on the old link.exe while other targets moved to a much faster linker. Rust switched x86_64-unknown-linux-gnu to 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 to link.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, and wild (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-msvc targets. 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/.

Build performance on Windows (dramatically slower than Linux)

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.

  1. Filesystem operations are slow and have hostile semantics - and this hits build time directly, not just std::fs calls. 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 - Path comparison 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)".
  2. 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 than fork+exec / posix_spawn and 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 the windows-threading crate, which dispatches closures through the Win32 thread pool (TrySubmitThreadpoolCallback) and reuses worker threads instead of spawning a fresh OS thread per call - dramatically cheaper than std::thread. A thread-pool- backed default in std, and lower per-process spawn overhead in cargo/rustc on Windows, would help everyone.

  3. 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 ~/.cargo from 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment