From 491a344f239bc7f6fb9a4f0a9a0d3cefa72645a3 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Sun, 19 Jul 2026 23:18:57 +0200 Subject: [PATCH] =?UTF-8?q?fix(client/windows):=20repair=20the=20v0.15.0?= =?UTF-8?q?=20MSIX=20build=20=E2=80=94=20ARM64=20feature=20leak=20+=20ille?= =?UTF-8?q?gal=20XML=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both MSIX matrix jobs failed at the v0.15.0 tag, for two unrelated reasons, both introduced by this release. 0.13.0 and 0.14.0 shipped both packages; 0.15.0 shipped neither. ARM64 failed to BUILD. The PyroWave Windows un-gating (1ef0229b) moved `pyrowave-sys` in pf-client-core out of `cfg(target_os = "linux")` into a general optional dependency that pf-client-core's own `default = ["pyrowave"]` turns on. The ARM64 leg builds `--no-default-features` precisely to skip it, but that only disables defaults for the two packages named with `-p` — every internal edge kept inheriting them: clients/windows -> pf-client-core, clients/session -> pf-client-core, clients/session -> pf-presenter, and pf-presenter's own `default = ["pyrowave"]` -> pf-client-core. So the vendored Granite C++ compiled on ARM64 and stopped where it always does: muglm.cpp reaching for _MM_TRANSPOSE4_PS/_mm_storeu_ps, then `simd.hpp:103 #error "Implement me."`. Those three internal edges now pass `default-features = false`; the feature is enabled only through an explicit chain (clients/session's `pyrowave` -> pf-client-core/pyrowave + pf-presenter/pyrowave, and pf-presenter's `pyrowave` -> pf-client-core/pyrowave), so `--no-default-features` finally means what it says. Verified by feature resolution rather than assertion — `cargo tree -i pyrowave-sys`: aarch64-pc-windows-msvc, --no-default-features -> not in the graph (was: present) x86_64-pc-windows-msvc, default features -> present x86_64-unknown-linux-gnu, default features -> present PyroWave is NOT dropped from the Windows client. Decode has always run in the spawned punktfunk-session binary, whose own default keeps the feature on, and unification turns it back on for the shared pf-client-core wherever that binary is in the build (x64, Linux). The shell only ever offered "pyrowave" as a codec preference string — it holds no decoder and never called one, so linking the C++ into it was dead weight even on x64. x64 built fine and failed at PACKAGING: `makepri new` rejected the manifest with PRI191 "Appx manifest not found or is invalid" / malformed comment syntax. The console tile added in 2508b720 documented its flag inside an XML comment, and XML forbids `--` anywhere in a comment body, so the literal flag spelling made the whole manifest unparseable. Reworded, with a note to keep the next person from reintroducing it. Confirmed by parsing both revisions after template substitution: the tagged manifest fails at line 63 col 9, this one parses. Co-Authored-By: Claude Opus 4.8 --- clients/session/Cargo.toml | 8 ++++++-- clients/windows/Cargo.toml | 12 +++++++++++- clients/windows/packaging/AppxManifest.xml | 11 ++++++++--- crates/pf-presenter/Cargo.toml | 6 +++++- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/clients/session/Cargo.toml b/clients/session/Cargo.toml index e57559ef..c4cc7ec2 100644 --- a/clients/session/Cargo.toml +++ b/clients/session/Cargo.toml @@ -27,9 +27,13 @@ ui = ["dep:pf-console-ui", "dep:serde_json"] # Same Linux+Windows gating as the rest of the client stack; elsewhere this is a stub # binary. [target.'cfg(any(target_os = "linux", windows))'.dependencies] -pf-presenter = { path = "../../crates/pf-presenter" } +# `default-features = false` on both: THIS crate's `pyrowave` feature (above) is the single +# switch that turns the wavelet codec on, and it enables it explicitly on each. Inheriting their +# defaults instead would make `--no-default-features` a lie — the Windows ARM64 leg builds that +# way precisely to skip the vendored PyroWave C++, which has no ARM64 SIMD path. +pf-presenter = { path = "../../crates/pf-presenter", default-features = false } pf-console-ui = { path = "../../crates/pf-console-ui", optional = true } -pf-client-core = { path = "../../crates/pf-client-core" } +pf-client-core = { path = "../../crates/pf-client-core", default-features = false } punktfunk-core = { path = "../../crates/punktfunk-core", features = ["quic"] } # The fake-library dev hook (`PUNKTFUNK_FAKE_LIBRARY`, browse mode) parses GameEntry JSON. serde_json = { version = "1", optional = true } diff --git a/clients/windows/Cargo.toml b/clients/windows/Cargo.toml index af6d3960..0114c7a4 100644 --- a/clients/windows/Cargo.toml +++ b/clients/windows/Cargo.toml @@ -29,7 +29,17 @@ punktfunk-core = { path = "../../crates/punktfunk-core", features = ["quic"] } # The shared client service layer: the trust/settings stores (ONE `Settings` struct for the # shell and the spawned session binary — src/trust.rs re-exports it) and the game-library # data model (fetch + art pipeline) behind the library page. -pf-client-core = { path = "../../crates/pf-client-core" } +# +# `default-features = false` drops pf-client-core's default `pyrowave`, which would otherwise +# build the vendored PyroWave C++ INTO THE SHELL — dead weight here (the shell never decodes; +# it only offers "pyrowave" as a codec preference string the session binary acts on) and fatal +# on ARM64, where Granite's math falls back to x86 SSE intrinsics and stops at +# `simd.hpp: #error "Implement me."`. This does NOT drop PyroWave from the Windows client: +# decode lives in the spawned punktfunk-session binary, whose own default enables the feature, +# and cargo's feature unification turns it back on for the shared pf-client-core whenever that +# binary is in the same build (x64). On the ARM64 leg both are built --no-default-features, so +# nothing enables it and the C++ is never compiled. +pf-client-core = { path = "../../crates/pf-client-core", default-features = false } # WinUI 3 UI via windows-reactor (a declarative React-like framework backed by WinUI). Its # `build.rs` downloads the Windows App SDK NuGets and stages the bootstrap DLL + resources.pri diff --git a/clients/windows/packaging/AppxManifest.xml b/clients/windows/packaging/AppxManifest.xml index dc1c9de7..a713bf56 100644 --- a/clients/windows/packaging/AppxManifest.xml +++ b/clients/windows/packaging/AppxManifest.xml @@ -59,9 +59,14 @@ diff --git a/crates/pf-presenter/Cargo.toml b/crates/pf-presenter/Cargo.toml index 7c2e3ad3..a98156c6 100644 --- a/crates/pf-presenter/Cargo.toml +++ b/crates/pf-presenter/Cargo.toml @@ -11,7 +11,11 @@ repository.workspace = true # Same Linux+Windows gating as the rest of the client stack (dmabuf import is the one # Linux-only module — see lib.rs). [target.'cfg(any(target_os = "linux", windows))'.dependencies] -pf-client-core = { path = "../pf-client-core" } +# `default-features = false`: the PyroWave decode backend is turned on through THIS crate's own +# `pyrowave` feature (which re-exports it below), never by inheriting the dependency's default. +# Otherwise a consumer that deliberately builds us without `pyrowave` still drags the vendored +# C++ in — fatal on Windows ARM64, where Granite has no SIMD path. +pf-client-core = { path = "../pf-client-core", default-features = false } # AVVkFrame access (Vulkan Video frames: live sync state under the frames lock). pf-ffvk = { path = "../pf-ffvk" } punktfunk-core = { path = "../punktfunk-core", features = ["quic"] }