From 48d2bd4f65fb29841303e68ae7d62765a6e658e1 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Fri, 10 Apr 2026 12:55:48 +0400 Subject: [PATCH] fix(windows): bake SSE patch into docker image instead of runtime --- scripts/Dockerfile.windows-builder | 24 +++++++++++++++ scripts/build-windows-docker.sh | 47 ++---------------------------- 2 files changed, 27 insertions(+), 44 deletions(-) diff --git a/scripts/Dockerfile.windows-builder b/scripts/Dockerfile.windows-builder index 2b68423..30565d4 100644 --- a/scripts/Dockerfile.windows-builder +++ b/scripts/Dockerfile.windows-builder @@ -89,4 +89,28 @@ RUN set -eux; \ cd / && rm -rf /tmp/xwin-warmup && \ du -sh $HOME/.cache/cargo-xwin +# ── Patch the cargo-xwin clang-cl toolchain to add SSE4.1 / SSSE3 ───────── +# libopus (via audiopus_sys) uses per-file COMPILE_FLAGS "-msse4.1" on +# its opus/silk/x86/*_sse4_1.c sources, but clang-cl silently drops the +# bare -m flags (it expects /clang:-m… instead). The per-file +# intrinsics functions then fail to compile because the surrounding +# function isn't marked with the target feature. We fix this by +# inserting /clang:-msse4.1 / /clang:-mssse3 directly into the +# COMPILE_FLAGS list in the cargo-xwin-generated cmake toolchain so +# EVERY C file in every cmake-driven subbuild gets the feature flags. +# All x86_64 Windows CPUs shipped since 2008 have these, safe on target. +# +# We do the patch inside the image (not at container run time) so +# (a) it persists across container restarts without bash/awk/sed +# escaping games inside docker-bash-c, and (b) it becomes part of +# the shared image layer cache. +RUN set -eux; \ + TOOLCHAIN=$HOME/.cache/cargo-xwin/cmake/clang-cl/x86_64-pc-windows-msvc-toolchain.cmake; \ + test -f "$TOOLCHAIN"; \ + grep -q WZP_SSE_PATCH "$TOOLCHAIN" || \ + awk '/\/imsvc .*\/winrt\)/ {sub(/\)/, "", $0); print $0; print " /clang:-msse4.1"; print " /clang:-mssse3"; print " /clang:-msse3"; print " /clang:-msse2"; print " # WZP_SSE_PATCH"; print " )"; next} {print}' "$TOOLCHAIN" > "$TOOLCHAIN.new" && \ + mv "$TOOLCHAIN.new" "$TOOLCHAIN"; \ + echo "=== Patched toolchain ==="; \ + grep -A 15 "set(COMPILE_FLAGS" "$TOOLCHAIN" | head -20 + WORKDIR /build/source diff --git a/scripts/build-windows-docker.sh b/scripts/build-windows-docker.sh index a208ea1..fb9a9a6 100755 --- a/scripts/build-windows-docker.sh +++ b/scripts/build-windows-docker.sh @@ -173,50 +173,9 @@ docker run --rm \ bash -c ' set -euo pipefail -# libopus (audiopus_sys) ships per-file SSE4.1 / SSSE3 C sources under -# opus/silk/x86/ that assume the compiler sets `-msse4.1` / `-mssse3` -# as per-file CMake COMPILE_FLAGS. With clang-cl those bare -m flags -# are silently ignored (clang-cl expects /clang:-msse4.1), so the -# intrinsics functions in those files fail to compile with: -# "error: always_inline function _mm_cvtepi16_epi32 requires target -# feature sse4.1, but would be inlined into a function that is -# compiled without support for sse4.1" -# -# env-var CFLAGS do NOT help here: cargo-xwin ships its own CMake -# toolchain file (~/.cache/cargo-xwin/cmake/clang-cl/x86_64-pc-windows-msvc-toolchain.cmake) -# which hardcodes COMPILE_FLAGS and FORCE-overrides CMAKE_C_FLAGS, -# so anything we export via CFLAGS_$TARGET gets dropped. The only -# place that actually reaches every C compilation inside the opus -# cmake build is the toolchain file itself. Patch it in place with -# a one-shot sed: append four /clang:-m* flags immediately before -# the closing paren of the COMPILE_FLAGS setter. Idempotent across -# runs — if the file already contains the sentinel line we skip. -TOOLCHAIN_FILE=/home/builder/.cache/cargo-xwin/cmake/clang-cl/x86_64-pc-windows-msvc-toolchain.cmake -echo ">>> Patching cargo-xwin toolchain for SSE4.1 / SSSE3 intrinsics" -if grep -q WZP_SSE_PATCH "$TOOLCHAIN_FILE"; then - echo " (already patched, skipping)" -else - # The cleanest way to add flags is to append a pure-CMake block to - # the end of the toolchain file. Both CMAKE_C_FLAGS and - # CMAKE_CXX_FLAGS were already FORCE-set earlier in the toolchain; - # we override them again with the same content plus our SSE flags. - # This runs AFTER the original set(... FORCE) and the CMAKE_ARGS - # from the cmake-rs invocation, so it wins. - cat >> "$TOOLCHAIN_FILE" <>> Toolchain tail after patch:" -tail -15 "$TOOLCHAIN_FILE" +# (SSE4.1 / SSSE3 toolchain patch for libopus is baked into the image +# during the xwin pre-warm — see Dockerfile.windows-builder. No runtime +# patching needed.) cd /build/source/desktop