#windows #cross-compilation

bin+lib xwin

Allows downloading and repacking the MSVC CRT and Windows SDK for cross compilation

28 releases

0.3.1 Sep 12, 2023
0.2.15 Sep 11, 2023
0.2.14 Jun 20, 2023
0.2.12 Mar 31, 2023
0.1.5 Nov 25, 2021

#44 in Development tools

Download history 2923/week @ 2023-06-06 2512/week @ 2023-06-13 2247/week @ 2023-06-20 2717/week @ 2023-06-27 2450/week @ 2023-07-04 3486/week @ 2023-07-11 3966/week @ 2023-07-18 3352/week @ 2023-07-25 3882/week @ 2023-08-01 3706/week @ 2023-08-08 3253/week @ 2023-08-15 3517/week @ 2023-08-22 3850/week @ 2023-08-29 3957/week @ 2023-09-05 3573/week @ 2023-09-12 3011/week @ 2023-09-19

14,998 downloads per month
Used in 3 crates (2 directly)

Apache-2.0 OR MIT

2.5K SLoC


A utility for downloading and packaging the Microsoft CRT headers and libraries, and Windows SDK headers and libraries needed for compiling and linking programs targeting Windows.

Crates.io Docs dependency status Build status


The goal of this project is to create a root directory for both the CRT and Windows SDK that each contain all of the necessary includes and libraries needed for an application to compile and link from a non-Windows platform, using a native cross compiling toolchain like clang/LLVM. This includes adding symlinks to correct numerous casing issues in the Windows SDK so that the files generated by this program can function on a case-sensitive file system.

See this blog post for an in depth walk-through of how xwin can be used.


From source

cargo install xwin --locked


xwin provides two feature toggles used to decide which TLS implementation to use

  • rustls (default) - Uses rustls for TLS
  • native-tls - Uses native-tls for TLS. Note that on platforms where OpenSSL is used it is always built from source.

From tarball

You can download a prebuilt binary from the Releases.

  • x86_64-unknown-linux-musl
  • x86_64-apple-darwin
  • aarch64-apple-darwin


  • --accept-license - Doesn't display the prompt to accept the license. You can also set the XWIN_ACCEPT_LICENSE=1 environment variable
  • --arch <arch> - The architectures to include [default: x86_64] [possible values: x86, x86_64, aarch, aarch64]. Note that I haven't fully tested aarch/64 nor x86 so there might be issues with them, please file an issue if you encounter problems with them.
  • --cache-dir <cache-dir> - Specifies the cache directory used to persist downloaded items to disk. Defaults to ./.xwin-cache if not specified.
  • -L, --log-level <level> - The log level for messages, only log messages at or above the level will be emitted [default: info] [possible values: off, error, warn, info, debug, trace].
  • --variant <variant>... - The variants to include [default: desktop] [possible values: desktop, onecore, spectre]. Note that I haven't fully tested any variant except desktop, please file an issue if you try to use one of the others and run into issues. Note that there is another store variant that hasn't even been implemented due to it being weird and me not having a real project targeting it.
  • --channel <channel> - The product channel to use [default: release]
  • --manifest-version <version> - The manifest version to retrieve [default: 16].
  • --manifest - Specifies a top level manifest to use, rather than downloading it from Microsoft. This can be used to ensure the output is reproducible.
  • https_proxy - Environment variable that specifies the HTTPS proxy to use.

xwin download

This downloads the top level manifest and any vsix, msi, or cab files that are needed that aren't already in the download cache.

xwin unpack

Decompresses all of the downloaded package contents to disk. download is run automatically.

xwin splat

Fixes the packages to prune unneeded files and adds symlinks to address file casing issues and then spalts the final artifacts into directories. This is the main command you will want to run as it also downloads and unpacks automatically, providing the desired headers at the path specified to --output (./.xwin-cache/splat).

  • --copy - Copies files from the unpack directory to the splat directory instead of moving them, which preserves the original unpack directories but increases overall execution time and disk usage.
  • --disable-symlinks - By default, symlinks are added to both the CRT and WindowsSDK to address casing issues in general usage. For example, if you are compiling C/C++ code that does #include <windows.h>, it will break on a case-sensitive file system, as the actual path in the WindowsSDK is Windows.h. This also applies even if the C/C++ you are compiling uses correct casing for all CRT/SDK includes, as the internal headers also use incorrect casing in most cases
  • --include-debug-libs - The MSVCRT includes (non-redistributable) debug versions of the various libs that are generally uninteresting to keep for most usage
  • --include-debug-symbols - The MSVCRT includes PDB (debug symbols) files for several of the libraries that are generally uninteresting to keep for most usage
  • --preserve-ms-arch-notation - By default, we convert the MS specific x64, arm, and arm64 target architectures to the more canonical x86_64, aarch, and aarch64 of LLVM etc when creating directories/names. Passing this flag will preserve the MS names for those targets
  • --output - The root output directory. Defaults to ./.xwin-cache/splat if not specified

This moves all of the unpacked files which aren't pruned to their canonical locations under a root directory, for example here is what an x86_64 Desktop splat looks like. unpack is run automatically as needed.

├── crt
│  ├── include
│  │  ├── cliext
│  │  ├── CodeAnalysis
│  │  ├── cvt
│  │  ├── experimental
│  │  ├── Manifest
│  │  └── msclr
│  │     └── com
│  └── lib
│     └── x86_64
└── sdk
   ├── include
   │  ├── cppwinrt
   │  │  └── winrt
   │  │     └── impl
   │  ├── shared
   │  │  ├── ndis
   │  │  └── netcx
   │  │     └── shared
   │  │        └── net
   │  │           └── wifi
   │  ├── ucrt
   │  │  └── sys
   │  ├── um
   │  │  ├── alljoyn_c
   │  │  ├── gl
   │  │  ├── qcc
   │  │  │  └── windows
   │  │  └── winsqlite
   │  └── winrt
   │     └── wrl
   │        └── wrappers
   └── lib
      ├── ucrt
      │  └── x86_64
      └── um
         └── x86_64


xwin.dockerfile is an example Dockerfile that can be used a container image capable of building and testing Rust crates targeting x86_64-pc-windows-msvc.


Special thanks to https://github.com/mstorsjo/msvc-wine for the inspiration and @mdsteele for publishing several Rust crates around msi/cab files that were needed in this project


This contribution is dual licensed under EITHER OF

at your option.


~619K SLoC