Jake-Shadle / xwin

A utility for downloading and packaging the Microsoft CRT & Windows SDK headers and libraries needed for compiling and linking programs targeting Windows.
Apache License 2.0
390 stars 40 forks source link
cross-compilation msvc msvcrt rust windows windows-sdk
# `xwin` **A utility for downloading and packaging the [Microsoft CRT](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?redirectedfrom=MSDN&view=msvc-160) headers and libraries, and [Windows SDK](https://en.wikipedia.org/wiki/Microsoft_Windows_SDK) headers and libraries needed for compiling and linking programs targeting Windows.** [![Crates.io](https://img.shields.io/crates/v/xwin.svg)](https://crates.io/crates/xwin) [![Docs](https://docs.rs/xwin/badge.svg)](https://docs.rs/xwin) [![dependency status](https://deps.rs/repo/github/Jake-Shadle/xwin/status.svg)](https://deps.rs/repo/github/Jake-Shadle/xwin) [![Build status](https://github.com/Jake-Shadle/xwin/workflows/CI/badge.svg)](https://github.com/Jake-Shadle/xwin/actions)

Introduction

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.

Installation

From source

cargo install xwin --locked

Features

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

From tarball

You can download a prebuilt binary from the Releases.

Usage

Common

Env vars

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).

Splat options

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.

.xwin-cache/splat
├── 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 minimize

This is an advanced command that performs a splat before performing a build on a cargo manifest using strace to capture all of the headers and libraries that are used throughout the build and dumping them to a map. This command can also output the final splat to disk, or the map file can be used with splat to only splat the files and symlinks described in it.

Note that currently the build is always done with the /vctoolsdir and /winsdkdir options, so it is expected these are the same options used when compiling C/C++ code in your normal environment. If that is not the case please open an issue.

At the end of the command, a printout of the amount and size of the original versus minimized files is done, eg.

  crt headers: 73(2.6MiB) / 384(18.4MiB) => 14.00%
  crt libs: 5(28.0MiB) / 26(81.1MiB) => 34.58%
  sdk headers: 180(9.6MiB) / 4435(304.7MiB) => 3.15%
  sdk libs: 29(69.8MiB) / 456(169.9MiB) => 41.06%

Requirements

Minimize options

Note all of the splat options also apply to minimize.

Map file

As noted in minimize, there are many restrictions on it to make my life easier, but that make it unsuitable for those who don't use cargo/rust. It's possible for others to come up with their own versions of minimize that can output the same format that splat understands to still get the benefits of xwin without cargo/rust.

The format is extremely simple

├── crt
│  ├── headers
│  │  ├── filter - Array of relative paths to keep
│  │  └── symlinks
│  │     └── <path> - The same path as one of the filters
│  │        └── <names> - Array of symlinks to create in the same directory as the parent path
│  ├── libs *
└── sdk *

Example

See docs/example-map.toml for a real world example.

Container

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.

Thanks

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

License

This contribution is dual licensed under EITHER OF

at your option.