The previous sed-based patch didn't stick in the docker-bash-c
heredoc (bash single-quoting made the newline escaping fragile).
Switch to a much simpler approach: just 'cat >>' a pure-CMake block
to the end of the cargo-xwin toolchain file. The block does:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /clang:-msse4.1 ..." CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /clang:-msse4.1 ..." CACHE STRING "" FORCE)
Running AFTER the toolchain's own FORCE-set and AFTER cmake-rs's
-DCMAKE_C_FLAGS= command-line override, it unconditionally wins. No
sed, no awk, no python, no newline escaping — just CMake reading the
toolchain file like it normally does.
Idempotent via the WZP_SSE_PATCH sentinel grep in the comment block.
The CFLAGS_x86_64_pc_windows_msvc env-var approach from 990b6f1 did
nothing — cargo-xwin ships its own clang-cl cmake toolchain file at
~/.cache/cargo-xwin/cmake/clang-cl/x86_64-pc-windows-msvc-toolchain.cmake
which hardcodes COMPILE_FLAGS and FORCE-overrides CMAKE_C_FLAGS. Any
env-var CFLAGS gets dropped before opus's cmake build sees it.
The only place that actually makes it into every C file compilation
in the libopus subbuild is the toolchain file itself. Patch it in
place with an idempotent sed that appends
/clang:-msse4.1
/clang:-mssse3
/clang:-msse3
/clang:-msse2
right before the closing paren of the COMPILE_FLAGS setter. The patch
is marked with a WZP_SSE_PATCH comment so re-runs skip it.
Confirmed the error message matches with/without the env var — same
20 clang errors from NSQ_del_dec_sse4_1.c / NSQ_sse4_1.c before and
after 990b6f1, which is how we ruled out the env-var path.
libopus ships per-file SSE4.1 / SSSE3 C sources (opus/silk/x86/NSQ_del_dec_sse4_1.c
etc.) that assume the compiler picks up `-msse4.1` / `-mssse3` as per-file
CMake COMPILE_FLAGS. With clang-cl those bare -m flags are silently dropped,
so _mm_cvtepi16_epi32 + friends fail compile with 'always_inline function
requires target feature sse4.1, but would be inlined into a function that
is compiled without support for sse4.1'.
Workaround: set CFLAGS_x86_64_pc_windows_msvc + CXXFLAGS_x86_64_pc_windows_msvc
to `/clang:-msse4.1 /clang:-mssse3 /clang:-msse3 /clang:-msse2` before running
cargo xwin build. Every x86_64 Windows CPU shipped since 2008 has these
instruction sets so globally enabling them on this target is safe.
Also bump the tail -30 on cargo xwin output to tail -50 so the actual
compiler errors (not just the cmake wrapper panic) make it into the
ntfy / remote log file next time.
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.