windows: docker + hcloud build scripts for cross-compile
Two parallel paths to build wzp-desktop.exe for x86_64-pc-windows-msvc:
scripts/Dockerfile.windows-builder
Debian 12 base, matches scripts/Dockerfile.android-builder's layout:
- apt: build-essential, cmake, ninja-build, llvm, clang, lld, nasm,
libssl-dev, node 20 LTS
- rust stable + x86_64-pc-windows-msvc target
- cargo-xwin pre-installed
- Pre-warmed ~/.cache/cargo-xwin layer: creates a throwaway cargo
project and runs `cargo xwin build` once during image build so the
MSVC CRT + Windows SDK (~1.5 GB) is baked into an image layer.
Saves ~4 minutes off every cold cross-compile run.
- Builder user uid 1000 to match existing bind-mount perms on
SepehrHomeserverdk.
scripts/build-windows-docker.sh
Same pattern as scripts/build-tauri-android.sh but for Windows:
- Fires a remote build on SepehrHomeserverdk via ssh + heredoc
- Mounts the shared cargo-registry + cargo-git cache + a
target-windows dir (separate from the android target cache so
different triples don't stomp each other)
- Runs npm install + npm run build for the frontend dist, then
cargo xwin build --release --target x86_64-pc-windows-msvc
--bin wzp-desktop inside the container
- Uploads the resulting .exe to rustypaste (via the .env token on
the remote, same as android script) and fires ntfy.sh/wzp
notifications at start + completion
- scp's the .exe back to target/windows-exe/wzp-desktop.exe locally
- --image-build flag triggers a fire-and-forget `docker build` of
the Dockerfile.windows-builder on the remote (used once after the
Dockerfile changes). The image is already built at the moment of
this commit — sha256:f3895cb2fde7
scripts/build-windows-cloud.sh
Kept as an alternative cross-compile path using a fresh Hetzner VM
(cx33, 8 vCPU, 8 GB — bumped from cx23 after the smaller size OOM'd
mid-rustc). The docker-on-SepehrHomeserverdk path is now the
preferred fast path because the image has a pre-warmed xwin cache
and a persistent cargo target volume, making warm builds ~3 minutes
vs the cloud path's ~20 minutes cold each run. The cloud script
stays around for when we want a truly isolated environment.
Both scripts notify via ntfy.sh/wzp and upload to paste.dk.manko.yoga
so the user can pick up the artefact + see status without polling.
This commit is contained in:
92
scripts/Dockerfile.windows-builder
Normal file
92
scripts/Dockerfile.windows-builder
Normal file
@@ -0,0 +1,92 @@
|
||||
# =============================================================================
|
||||
# WZ Phone — Windows (x86_64-pc-windows-msvc) cross-compile image
|
||||
#
|
||||
# Cross-compiles the Tauri desktop binary for Windows from a Linux host via
|
||||
# `cargo xwin`, which auto-downloads the Microsoft CRT + Windows SDK at build
|
||||
# time. This image pre-warms that cache so the cross-compile is as close as
|
||||
# possible to a native Linux build on rebuild (~3 min warm vs ~20 min cold).
|
||||
#
|
||||
# Build:
|
||||
# docker build -t wzp-windows-builder -f Dockerfile.windows-builder .
|
||||
#
|
||||
# Run: driven by scripts/build-windows-docker.sh (see that file).
|
||||
# =============================================================================
|
||||
FROM debian:bookworm
|
||||
|
||||
ARG RUST_TARGET=x86_64-pc-windows-msvc
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# ── System packages ──────────────────────────────────────────────────────────
|
||||
# - build-essential + pkg-config + libssl-dev: baseline cargo build toolchain
|
||||
# - cmake + ninja-build: audiopus_sys (libopus) uses cmake and expects Ninja
|
||||
# as the generator for the windows target; without ninja-build the cmake
|
||||
# build fails with "CMake was unable to find a build program corresponding
|
||||
# to Ninja" partway through.
|
||||
# - llvm + clang + lld: cargo-xwin uses clang + lld-link for PE/COFF output.
|
||||
# - nasm: ring / rustls assembly for Windows needs NASM on non-Windows hosts.
|
||||
# - curl, git, ca-certificates, unzip: obvious plumbing.
|
||||
# - xz-utils: some Microsoft installer archives are xz-compressed.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
cmake \
|
||||
ninja-build \
|
||||
curl \
|
||||
git \
|
||||
pkg-config \
|
||||
libssl-dev \
|
||||
ca-certificates \
|
||||
llvm \
|
||||
clang \
|
||||
lld \
|
||||
nasm \
|
||||
unzip \
|
||||
xz-utils \
|
||||
file \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ── Node.js 20 LTS (required by Tauri for frontend build) ────────────────────
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& node --version \
|
||||
&& npm --version
|
||||
|
||||
# ── Builder user (1000:1000) — matches host bind-mount UID for the cache
|
||||
# volumes so cargo-registry / target survive across runs without perms
|
||||
# gymnastics.
|
||||
RUN groupadd -g 1000 builder \
|
||||
&& useradd -m -u 1000 -g 1000 -s /bin/bash builder
|
||||
|
||||
USER builder
|
||||
WORKDIR /home/builder
|
||||
|
||||
# ── Rust toolchain + Windows target + cargo-xwin ────────────────────────────
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
||||
| sh -s -- -y --default-toolchain stable \
|
||||
&& . $HOME/.cargo/env \
|
||||
&& rustup target add ${RUST_TARGET} \
|
||||
&& cargo install cargo-xwin --locked
|
||||
|
||||
ENV PATH="/home/builder/.cargo/bin:$PATH" \
|
||||
XWIN_ACCEPT_LICENSE=1 \
|
||||
RUST_TARGET_WIN=${RUST_TARGET}
|
||||
|
||||
# ── Pre-warm the xwin cache ─────────────────────────────────────────────────
|
||||
# cargo-xwin downloads the Microsoft CRT + Windows SDK (~1.5-2 GB) into
|
||||
# ~/.cache/cargo-xwin the first time it runs. Baking that into an image
|
||||
# layer saves ~4 minutes off every subsequent cold run.
|
||||
#
|
||||
# We do this by creating a throwaway Rust project, building it with
|
||||
# cargo-xwin against the Windows target, then deleting the project but
|
||||
# keeping the xwin cache.
|
||||
RUN set -eux; \
|
||||
mkdir -p /tmp/xwin-warmup && cd /tmp/xwin-warmup && \
|
||||
. $HOME/.cargo/env && \
|
||||
cargo new --bin xwin-warmup --quiet && \
|
||||
cd xwin-warmup && \
|
||||
cargo xwin build --release --target ${RUST_TARGET} 2>&1 | tail -5 && \
|
||||
cd / && rm -rf /tmp/xwin-warmup && \
|
||||
du -sh $HOME/.cache/cargo-xwin
|
||||
|
||||
WORKDIR /build/source
|
||||
Reference in New Issue
Block a user