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.
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.
-
C & C++
clang-cl with cl.exe arguments, MSVC CRT and Windows SDK headers and libraries already configured.
-
Rust
cargo xwin builds both Windows targets against the CRT and SDK already in the image.
-
.NET
EnableWindowsTargeting is set, so net*-windows projects restore and publish for win-x64 and win-arm64.
-
WinUI 3 & MSIX
Windows App SDK apps compile XAML and package as MSIX in the Wine-based image.
-
x64 & ARM64
Both Windows architectures from one image: x86_64 and aarch64 targets for C, Rust, and .NET.
-
CMake toolchains
Toolchain files for clang-cl builds live under /opt/windows-cross/xwin/cmake/clang-cl/.
-
Pinned by digest
Images are published by digest only, recorded in images/<image>/DIGEST, so CI pulls exact bits.
-
Stock SDK tools
Microsoft's XAML compiler, makepri, and makeappx run unmodified under Wine through generated shims.
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
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
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
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
<Import Project="$(WindowsCrossTargets)" Condition="'$(WindowsCrossTargets)' != ''" /> 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.
-
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.
-
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.
-
cargo xwin Rust
Rust's Windows targets build against the in-image CRT and SDK, and makensis is available for NSIS installers.
-
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.
-
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
-
Packages are unsigned
The SDK's signtool needs the x64 MFC runtime, which Wine lacks, so a build that enables signing fails with an explicit error. Sign on Windows.
-
The WinUI image needs an amd64 host
Building it runs 32-bit Wine code, which Docker's Rosetta emulation on Apple silicon cannot execute.
-
Manifest string patterns unenforced
MSXML accepts AppX manifest schema constructs that libxml2 rejects. A compatibility patch normalizes them, so makeappx does not enforce those string patterns here.
-
APPX2101 warning for makepri
.NET on Linux cannot read version resources from native executables, so the manifest's build metadata omits the MakePri version.