From d4aa3e6f4f68570d79f1aa8158d80c9edb26ce5a Mon Sep 17 00:00:00 2001 From: Oli Larkin Date: Mon, 15 Jun 2026 00:51:46 +0200 Subject: [PATCH 1/2] Support Skia M149: bump LLVM to 20, rename wasm static libs - Bump CI LLVM to 20.1.0; M149's bundled MSVC STL requires Clang 20+ - M149's wasm toolchain emits lib.wasm.a; pass bare GN target names to ninja and rename outputs back to lib.a on copy for downstream compatibility --- .github/workflows/build-skia.yml | 4 ++-- build-skia.py | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-skia.yml b/.github/workflows/build-skia.yml index 00fbc21..ae7ca85 100644 --- a/.github/workflows/build-skia.yml +++ b/.github/workflows/build-skia.yml @@ -194,14 +194,14 @@ jobs: if: steps.check.outputs.should_build == 'true' && runner.os != 'macOS' && matrix.os != 'windows-11-arm' uses: KyleMayes/install-llvm-action@v2 with: - version: "19.1.0" + version: "20.1.0" env: true - name: Install LLVM and Clang (Windows ARM64) if: steps.check.outputs.should_build == 'true' && matrix.os == 'windows-11-arm' shell: pwsh run: | - $llvmUrl = "https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.0/LLVM-19.1.0-woa64.exe" + $llvmUrl = "https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.0/LLVM-20.1.0-woa64.exe" $installerPath = "$env:TEMP\llvm-installer.exe" Write-Host "Downloading LLVM installer..." Invoke-WebRequest -Uri $llvmUrl -OutFile $installerPath diff --git a/build-skia.py b/build-skia.py index 1c02804..c4a9468 100755 --- a/build-skia.py +++ b/build-skia.py @@ -449,7 +449,7 @@ def validate_archs(self): "visionos": ["arm64"], "win": ["x64", "arm64", "Win32"], "linux": ["x64", "arm64"], - "wasm": ["wasm32"] + "wasm": ["wasm32"], } for arch in self.archs: if arch not in valid_archs[self.platform]: @@ -620,6 +620,10 @@ def build_skia(self, arch: str): # On Windows, ninja expects targets without the .lib extension if self.platform == "win": libs_to_build = [lib[:-4] if lib.endswith('.lib') else lib for lib in libs_to_build] + # On wasm, M149+ outputs lib.wasm.a (when is_canvaskit=false), + # so pass bare GN target names to ninja and rename at move_libs time. + elif self.platform == "wasm": + libs_to_build = [lib[3:-2] if lib.startswith('lib') and lib.endswith('.a') else lib for lib in libs_to_build] # Construct the ninja command with all library targets ninja_command = ["ninja", "-C", str(output_dir)] + libs_to_build @@ -659,7 +663,11 @@ def move_libs(self, arch: str): # Copy the libraries for lib in LIBS[self.platform]: - src_file = src_dir / lib + # M149+ wasm toolchain emits lib.wasm.a; copy to lib.a for compatibility. + if self.platform == "wasm" and lib.endswith('.a'): + src_file = src_dir / f"{lib[:-2]}.wasm.a" + else: + src_file = src_dir / lib dest_file = dest_dir / lib if src_file.exists(): shutil.copy2(str(src_file), str(dest_file)) From dd3da7ca2a440672da649aa6bfc96aa0f22583d8 Mon Sep 17 00:00:00 2001 From: Dan Raffel Date: Mon, 15 Jun 2026 00:51:58 +0200 Subject: [PATCH 2/2] Patch m149 D3D release build Ungate GrD3DBackendFormatData::equal so Direct3D Release builds compile on M149, where the base class declares equal() as unconditionally pure virtual. --- build-skia.py | 4 +++ patches/fix_m149_d3d_backend_surface.patch | 36 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 patches/fix_m149_d3d_backend_surface.patch diff --git a/build-skia.py b/build-skia.py index c4a9468..b39ef96 100755 --- a/build-skia.py +++ b/build-skia.py @@ -223,6 +223,10 @@ def colored_print(message, color): "win": """ skia_use_dawn = true + # Keep Direct3D enabled. M149 makes GrBackendFormatData::equal unconditionally + # pure virtual while GrD3DBackendFormatData's override is gated by GPU_TEST_UTILS, + # leaving the subclass abstract in Release builds. patches/fix_m149_d3d_backend_surface.patch + # ungates the override so D3D Release builds compile. Re-enable plain once Skia fixes upstream. skia_use_direct3d = true is_trivial_abi = false """, diff --git a/patches/fix_m149_d3d_backend_surface.patch b/patches/fix_m149_d3d_backend_surface.patch new file mode 100644 index 0000000..a08b383 --- /dev/null +++ b/patches/fix_m149_d3d_backend_surface.patch @@ -0,0 +1,36 @@ +diff --git a/src/gpu/ganesh/d3d/GrD3DBackendSurface.cpp b/src/gpu/ganesh/d3d/GrD3DBackendSurface.cpp +index 8d20c4fbda..e4d94b0c76 100644 +--- a/src/gpu/ganesh/d3d/GrD3DBackendSurface.cpp ++++ b/src/gpu/ganesh/d3d/GrD3DBackendSurface.cpp +@@ -39,7 +39,6 @@ private: + + GrColorFormatDesc desc() const override { return GrDxgiFormatDesc(fFormat); } + +-#if defined(GPU_TEST_UTILS) + bool equal(const GrBackendFormatData* that) const override { + SkASSERT(!that || that->type() == GrBackendApi::kDirect3D); + if (auto otherD3D = static_cast(that)) { +@@ -47,7 +46,6 @@ private: + } + return false; + } +-#endif + + std::string toString() const override { + #if defined(SK_DEBUG) || defined(GPU_TEST_UTILS) +@@ -114,6 +112,7 @@ private: + + bool isProtected() const override { return false; } + ++#if defined(GPU_TEST_UTILS) + bool equal(const GrBackendTextureData* that) const override { + SkASSERT(!that || that->type() == GrBackendApi::kDirect3D); + #if defined(GPU_TEST_UTILS) +@@ -123,6 +122,7 @@ private: + #endif + return false; + } ++#endif + + bool isSameTexture(const GrBackendTextureData* that) const override { + SkASSERT(!that || that->type() == GrBackendApi::kDirect3D);