# Cross-Compiling Windows Binaries on Linux This document describes how to build `zenserver.exe` and `zen.exe` for Windows from a Linux host using clang-cl, lld-link, and the Windows SDK fetched via [xwin](https://github.com/Jake-Shadle/xwin). ## Prerequisites - **LLVM/Clang 17+** with the following tools (typically in `/usr/lib/llvm-/bin/`): - `clang` (used as `clang-cl` via `--driver-mode=cl`) - `lld-link` - `llvm-lib` - `llvm-rc` - `llvm-ml` - `llvm-mt` On Ubuntu/Debian: ```bash sudo apt install clang-18 lld-18 llvm-18 ``` - **xmake** (build system) — see [xmake.io](https://xmake.io) for installation. ## Step 1: Fetch the Windows SDK Run the provided script to download the Windows SDK and MSVC CRT headers/libs: ```bash ./scripts/win_cross/get_win_sdk.sh ``` This downloads the SDK to `~/.xwin-sdk` by default. Override the location with an argument or the `$XWIN_SDK_DIR` environment variable: ```bash ./scripts/win_cross/get_win_sdk.sh /path/to/sdk ``` The script also creates: - Tool wrapper scripts (clang-cl, lld-link, llvm-lib, etc.) in the SDK `bin/` directory - An MSVC-compatible directory layout that xmake's built-in clang-cl toolchain can discover - Debug CRT lib symlinks so cmake package builds succeed ## Step 2: Configure and Build ```bash xmake config -y -p windows -a x64 \ --toolchain=clang-cl \ --sdk=$HOME/.xwin-sdk \ --mrc=$HOME/.xwin-sdk/bin/x64/rc.exe \ -m release \ --zensentry=n \ --zenmimalloc=n xmake ``` ### Notes - **`--sdk` must use an absolute path** — `$HOME/.xwin-sdk` works, but `~/.xwin-sdk` does not (xmake doesn't expand `~`). - **`--mrc`** points to the resource compiler wrapper. Without it, xmake can't auto-detect `llvm-rc` (it doesn't support `--version`). - **`--zensentry=no`** is recommended — crashpad (used by sentry-native) is difficult to cross-compile. - **`--zenmimalloc=no`** is recommended initially to reduce the package surface. - **LTO is automatically disabled** for cross-compilation builds. ## Step 3: Verify ```bash file build/windows/x64/release/zenserver.exe # PE32+ executable (console) x86-64, for MS Windows, 12 sections file build/windows/x64/release/zen.exe # PE32+ executable (console) x86-64, for MS Windows, 12 sections ``` ## Running with Wine (optional) The resulting binaries can be run under Wine for testing: ```bash wine build/windows/x64/release/zenserver.exe --help ``` ## Troubleshooting ### Library not found (case sensitivity) The Windows SDK ships headers and libs with specific casing (e.g. `DbgHelp.h`, `ws2_32.lib`). Linux filesystems are case-sensitive, so `#include ` won't find `DbgHelp.h`. The codebase uses lowercase includes where possible. If you encounter a missing header/lib, check the actual casing in the SDK directory. ### `add_ldflags(...) is ignored` xmake's auto flag checker may reject MSVC linker flags when using clang-cl. Add `{force = true}` to the `add_ldflags()` call. ### Stale build state If you hit unexpected errors after changing toolchain settings, clean everything: ```bash rm -rf .xmake build ~/.xmake ``` Then reconfigure and rebuild.