fix(windows): bake SSE patch into docker image instead of runtime
This commit is contained in:
@@ -89,4 +89,28 @@ RUN set -eux; \
|
|||||||
cd / && rm -rf /tmp/xwin-warmup && \
|
cd / && rm -rf /tmp/xwin-warmup && \
|
||||||
du -sh $HOME/.cache/cargo-xwin
|
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
|
WORKDIR /build/source
|
||||||
|
|||||||
@@ -173,50 +173,9 @@ docker run --rm \
|
|||||||
bash -c '
|
bash -c '
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# libopus (audiopus_sys) ships per-file SSE4.1 / SSSE3 C sources under
|
# (SSE4.1 / SSSE3 toolchain patch for libopus is baked into the image
|
||||||
# opus/silk/x86/ that assume the compiler sets `-msse4.1` / `-mssse3`
|
# during the xwin pre-warm — see Dockerfile.windows-builder. No runtime
|
||||||
# as per-file CMake COMPILE_FLAGS. With clang-cl those bare -m flags
|
# patching needed.)
|
||||||
# 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" <<CMAKE_PATCH_EOF
|
|
||||||
|
|
||||||
# ── WZP_SSE_PATCH ─────────────────────────────────────────────────────────
|
|
||||||
# libopus (audiopus_sys) has per-file COMPILE_FLAGS "-msse4.1" on its
|
|
||||||
# sse4_1.c sources, which clang-cl silently drops (expects /clang:-m…).
|
|
||||||
# Force-add the flags globally so every C file in the opus cmake subbuild
|
|
||||||
# compiles with the intrinsics target features enabled. All x86_64
|
|
||||||
# Windows CPUs shipped since 2008 support these, so enabling them
|
|
||||||
# globally on this target is safe.
|
|
||||||
set(CMAKE_C_FLAGS "\${CMAKE_C_FLAGS} /clang:-msse4.1 /clang:-mssse3 /clang:-msse3 /clang:-msse2" CACHE STRING "" FORCE)
|
|
||||||
set(CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} /clang:-msse4.1 /clang:-mssse3 /clang:-msse3 /clang:-msse2" CACHE STRING "" FORCE)
|
|
||||||
CMAKE_PATCH_EOF
|
|
||||||
fi
|
|
||||||
echo ">>> Toolchain tail after patch:"
|
|
||||||
tail -15 "$TOOLCHAIN_FILE"
|
|
||||||
|
|
||||||
cd /build/source/desktop
|
cd /build/source/desktop
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user