Skip to content
cross-compilers

Docker images · nothing runs on Windows

Build Windows apps on Linux.

windows-cross-compiler builds C, C++, Rust, and .NET for x64 and ARM64 Windows in a Linux container, and packages Windows App SDK (WinUI 3) apps as MSIX. Nothing runs on Windows and nothing is signed.

hello.cpp → x64 .exe
docker run --rm -v "$PWD:/workspace" \
  docker.io/shepherdjerred/windows-cross-compiler@sha256:6b35945b08c90de420111c415145487de5885b6e926c7cd6d4fe54d6d4380617 \
  x86_64-pc-windows-msvc-cl /EHsc hello.cpp /Fehello.exe

Base image on linux/amd64; the WinUI image needs an amd64 host.

Built on Linux, runs on your PC.

  • Compiles

    C, C++, Rust, C#

  • Links

    MSVC CRT, Windows SDK

  • Packages

    MSIX via stock tools

  • Targets

    x64 and ARM64 Windows

What it builds

The Windows toolchain, in a container

Everything you would otherwise need a Windows runner for, from a single docker run.

Quick start

Mount your project and build

Images are published by digest only — pull the digest recorded in images/<image>/DIGEST. Mount your sources at /workspace.

A C++ program

C++
docker run --rm -v "$PWD:/workspace" \
  docker.io/shepherdjerred/windows-cross-compiler@sha256:6b35945b08c90de420111c415145487de5885b6e926c7cd6d4fe54d6d4380617 \
  x86_64-pc-windows-msvc-cl /EHsc hello.cpp /Fehello.exe

A Rust crate

Rust
docker run --rm -v "$PWD:/workspace" \
  docker.io/shepherdjerred/windows-cross-compiler@sha256:6b35945b08c90de420111c415145487de5885b6e926c7cd6d4fe54d6d4380617 \
  cargo xwin build --release --target x86_64-pc-windows-msvc

A .NET project

.NET
docker run --rm -v "$PWD:/workspace" \
  docker.io/shepherdjerred/windows-cross-compiler@sha256:6b35945b08c90de420111c415145487de5885b6e926c7cd6d4fe54d6d4380617 \
  dotnet publish -c Release -r win-x64

A WinUI 3 app, packaged as MSIX

Directory.Build.targets — import the targets last
<Import Project="$(WindowsCrossTargets)" Condition="'$(WindowsCrossTargets)' != ''" />
WinUI
docker run --rm -v "$PWD:/workspace" \
  docker.io/shepherdjerred/windows-cross-compiler-winui@sha256:976070135674e22399d7384418fe975584de36fbdddceeefc09ecff3ddff2cef \
  dotnet build -c Release -r win-x64 -p:Platform=x64 \
    -p:GenerateAppxPackageOnBuild=true -p:AppxPackageDir=/workspace/AppPackages/

Toolchains

  • x86_64-pc-windows-msvc-cl
  • aarch64-pc-windows-msvc-cl
  • cargo xwin build --target <triple>
  • dotnet publish -r win-x64 | win-arm64
  • makensis (NSIS installers)

CMake projects can use the toolchain files under /opt/windows-cross/xwin/cmake/clang-cl/ .

How it works

Microsoft's own tools, wherever they run

Instead of reimplementing MSVC, the images assemble the CRT, SDK, and packaging tools Microsoft publishes, and run the Windows-only ones under Wine.

  1. The real CRT and SDK

    xwin downloads the MSVC CRT and Windows SDK into the image at build time; building the image accepts their license.

  2. clang-cl and lld

    An MSVC-compatible compiler driver that takes cl.exe arguments, with the target's headers and libraries already configured, plus CMake toolchain files.

  3. cargo xwin Rust

    Rust's Windows targets build against the in-image CRT and SDK, and makensis is available for NSIS installers.

  4. Stock WinUI tooling

    The .NET Framework XAML compiler (which also compiles XAML to XBF) and the SDK's makepri and makeappx run through generated Wine shims, driven by MSBuild targets you import last.

  5. Wine, patched where needed

    Six targeted Wine 11 patches keep makepri and makeappx working, and packaged resources are mapped from makepri dump output where the resource indexer API is unavailable.

Images

One image per workload

Pull docker.io/shepherdjerred/windows-cross-compiler by digest — or the Wine-based WinUI image for XAML and MSIX.

Image Digest Contents Hosts
windows-cross-compiler sha256:6b35945b08c9… full clang-cl + lld, MSVC CRT + Windows SDK, Rust + cargo-xwin, .NET SDK, NSIS linux/amd64
windows-cross-compiler-winui sha256:976070135674… full Base image plus Wine 11, .NET Framework 4.8, the XAML compiler, makepri, and makeappx linux/amd64

Digests live in images/<image>/DIGEST and are refreshed after each publish — check the full digest before you pull.

Known limitations

What to expect