Skip to content

Commit 5815930

Browse files
committed
Add Skia WebAssembly WebGL build
Build a wasm32 static Skia library with Emscripten and WebGL enabled. Publish and fetch the wasm artifact, and resolve it through the CMake modules without requiring native zlib or libpng prebuilts.
1 parent b3fe235 commit 5815930

11 files changed

Lines changed: 186 additions & 8 deletions

File tree

.github/workflows/build-skia.yml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ on:
2424

2525
env:
2626
ANDROID_NDK_VERSION: 28.2.13676358
27+
EMSCRIPTEN_VERSION: 2.0.6
2728
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
2829
GITHUB_TOKEN: ${{ github.token }}
2930
SKIA_DIAGNOSTICS_ARCHIVE: skia-build-diagnostics-158dc9d7.tar.gz
@@ -338,6 +339,83 @@ jobs:
338339
name: skia-diagnostics-android-arm64-v8a
339340
path: skia/dist/diagnostics
340341

342+
build-wasm:
343+
name: Build wasm/wasm32
344+
needs: prepare-skia-sources
345+
runs-on: ubuntu-24.04
346+
347+
steps:
348+
- name: Checkout source code
349+
uses: actions/checkout@v6
350+
351+
- name: Restore ccache
352+
uses: actions/cache@v5
353+
with:
354+
path: .cache/ccache/skia-wasm-wasm32
355+
key: skia-ccache-${{ runner.os }}-wasm-wasm32-${{ hashFiles('skia/manifest.json', 'skia/scripts/**') }}
356+
restore-keys: |
357+
skia-ccache-${{ runner.os }}-wasm-wasm32-
358+
359+
- name: Install build tools
360+
run: sudo apt-get update && sudo apt-get install -y ccache ninja-build rsync
361+
362+
- name: Setup Emscripten
363+
uses: mymindstorm/setup-emsdk@v14
364+
with:
365+
version: ${{ env.EMSCRIPTEN_VERSION }}
366+
367+
- name: Restore Skia source archive
368+
uses: actions/cache@v5
369+
with:
370+
path: skia/.source-cache
371+
key: ${{ needs.prepare-skia-sources.outputs.cache-key }}
372+
enableCrossOsArchive: true
373+
374+
- name: Extract Skia source archive
375+
run: |
376+
test -f skia/.source-cache/skia-source.tar
377+
tar -C skia -xf skia/.source-cache/skia-source.tar
378+
379+
- name: Fetch native depot_tools
380+
working-directory: skia
381+
run: ./scripts/fetch-source.sh depot_tools
382+
383+
- name: Build static library
384+
working-directory: skia
385+
env:
386+
CCACHE_DIR: ${{ github.workspace }}/.cache/ccache/skia-wasm-wasm32
387+
SKIA_SKIP_DEPS_SYNC: 1
388+
run: ./scripts/build-wasm32.sh
389+
390+
- name: Print build summary on failure
391+
if: failure()
392+
run: |
393+
find skia/dist/diagnostics -type f -name 'build-summary.json' -print -exec cat {} \; || true
394+
395+
- name: Verify artifacts
396+
run: |
397+
test -f skia/dist/libskia-wasm32.a
398+
test -f skia/dist/build_config_manifest-wasm-wasm32.md
399+
grep -Eq 'target_cpu[[:space:]]*=[[:space:]]*"wasm"' skia/dist/build_config_manifest-wasm-wasm32.md
400+
grep -Eq 'skia_use_webgl[[:space:]]*=[[:space:]]*true' skia/dist/build_config_manifest-wasm-wasm32.md
401+
grep -Eq 'skia_gl_standard[[:space:]]*=[[:space:]]*"webgl"' skia/dist/build_config_manifest-wasm-wasm32.md
402+
! find skia/dist -maxdepth 1 -name '*.so' | grep -q .
403+
404+
- name: Upload artifact
405+
uses: actions/upload-artifact@v7
406+
with:
407+
name: skia-wasm-wasm32
408+
path: |
409+
skia/dist/libskia-wasm32.a
410+
skia/dist/build_config_manifest-wasm-wasm32.md
411+
412+
- name: Upload diagnostics
413+
if: always()
414+
uses: actions/upload-artifact@v7
415+
with:
416+
name: skia-diagnostics-wasm-wasm32
417+
path: skia/dist/diagnostics
418+
341419
build-apple:
342420
name: Build ${{ matrix.platform_arch }}
343421
runs-on: macos-15
@@ -581,6 +659,7 @@ jobs:
581659
needs:
582660
- build-linux
583661
- build-android
662+
- build-wasm
584663
- build-apple
585664
- package-ios
586665
- build-windows

.github/workflows/release-skia.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,4 @@ jobs:
122122
gh release create "${TAG_NAME}" "${release_files[@]}" \
123123
--verify-tag \
124124
--title "Skia ${SKIA_VERSION} static libraries" \
125-
--notes "Static Skia ${SKIA_VERSION} libraries for TotalCross, including Android arm64-v8a with NDK ${ANDROID_NDK_VERSION:-28.2.13676358}, iOS device/simulator arm64 artifacts, and a separate diagnostics archive with full GN/Ninja logs."
125+
--notes "Static Skia ${SKIA_VERSION} libraries for TotalCross, including WebAssembly/WebGL wasm32, Android arm64-v8a with NDK ${ANDROID_NDK_VERSION:-28.2.13676358}, iOS device/simulator arm64 artifacts, and a separate diagnostics archive with full GN/Ninja logs."

skia/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ describes the GitHub Release assets consumed by TotalCross.
1010

1111
```bash
1212
./fetch.sh --platform linux --arch x86_64 --install-dev
13+
./fetch.sh --platform wasm --arch wasm32 --install-dev
1314
./fetch.sh --platform macos --arch arm64 --install-dev
1415
./fetch.sh --platform android --arch arm64-v8a
1516
./fetch.sh --platform ios --arch arm64 --install-dev
@@ -27,6 +28,7 @@ in `artifacts.json`. Override it with `--base-url`, `--github-repo`,
2728
./scripts/build-linux-x86_64.sh
2829
./scripts/build-linux-aarch64.sh
2930
./scripts/build-linux-armv7l.sh
31+
./scripts/build-wasm32.sh
3032
./scripts/build-android-arm64.sh
3133
./scripts/build-ios-arm64.sh
3234
./scripts/build-ios-simulator-arm64.sh

skia/artifacts.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"libskia-linux-x86_64.a",
1818
"libskia-linux-aarch64.a",
1919
"libskia-linux-armv7l.a",
20+
"libskia-wasm32.a",
2021
"libskia-android-arm64-v8a.a",
2122
"libskia-macos-arm64.a",
2223
"libskia-ios-arm64.a",
@@ -28,6 +29,7 @@
2829
"build_config_manifest-linux-x86_64.md",
2930
"build_config_manifest-linux-aarch64.md",
3031
"build_config_manifest-linux-armv7l.md",
32+
"build_config_manifest-wasm-wasm32.md",
3133
"build_config_manifest-android-arm64-v8a.md",
3234
"build_config_manifest-macos-arm64.md",
3335
"build_config_manifest-ios-arm64.md",
@@ -63,6 +65,10 @@
6365
"artifact_name": "libskia-linux-armv7l.a",
6466
"target_path": "local/out/Release/linux/armv7l/libskia.a"
6567
},
68+
"wasm-wasm32": {
69+
"artifact_name": "libskia-wasm32.a",
70+
"target_path": "local/out/Release/wasm/wasm32/libskia.a"
71+
},
6672
"android-arm64-v8a": {
6773
"artifact_name": "libskia-android-arm64-v8a.a",
6874
"target_path": "local/out/Release/android/arm64-v8a/libskia.a"
@@ -106,6 +112,10 @@
106112
"artifact_name": "build_config_manifest-linux-armv7l.md",
107113
"target_path": "local/out/Release/linux/armv7l/build_config_manifest.md"
108114
},
115+
"wasm-wasm32": {
116+
"artifact_name": "build_config_manifest-wasm-wasm32.md",
117+
"target_path": "local/out/Release/wasm/wasm32/build_config_manifest.md"
118+
},
109119
"android-arm64-v8a": {
110120
"artifact_name": "build_config_manifest-android-arm64-v8a.md",
111121
"target_path": "local/out/Release/android/arm64-v8a/build_config_manifest.md"

skia/cmake/AutoFetchSkia.cmake

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ function(tcvm_auto_fetch_skia)
9292
return()
9393
endif()
9494

95-
tcvm_auto_fetch_skia_dependencies()
96-
9795
find_program(TCVM_BASH_EXECUTABLE bash)
9896
if(NOT TCVM_BASH_EXECUTABLE)
9997
message(FATAL_ERROR "Unable to auto-fetch Skia because 'bash' was not found")
@@ -156,6 +154,11 @@ function(tcvm_auto_fetch_skia)
156154

157155
set(TCVM_FETCH_INSTALL_DEV ON)
158156
set(TCVM_SKIA_ARTIFACT "${TCVM_SKIA_DIR}/out/Release/macos/${TCVM_FETCH_ARCH}/libskia.a")
157+
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
158+
set(TCVM_FETCH_PLATFORM "wasm")
159+
set(TCVM_FETCH_ARCH "wasm32")
160+
set(TCVM_FETCH_INSTALL_DEV ON)
161+
set(TCVM_SKIA_ARTIFACT "${TCVM_SKIA_DIR}/out/Release/wasm/wasm32/libskia.a")
159162
elseif(UNIX AND (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
160163
set(TCVM_FETCH_PLATFORM "linux")
161164
set(TCVM_FETCH_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
@@ -193,6 +196,10 @@ function(tcvm_auto_fetch_skia)
193196
return()
194197
endif()
195198

199+
if(NOT TCVM_FETCH_PLATFORM STREQUAL "wasm")
200+
tcvm_auto_fetch_skia_dependencies()
201+
endif()
202+
196203
if(TCVM_FETCH_INSTALL_DEV)
197204
if(NOT EXISTS "${TCVM_SKIA_DIR}/include/core/SkCanvas.h" OR NOT EXISTS "${TCVM_SKIA_DIR}/src/gpu/gl/GrGLDefines.h")
198205
set(TCVM_FETCH_NEEDED ON)

skia/cmake/FindSkia.cmake

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ elseif(APPLE)
6969
elseif(SKIA_ARCH STREQUAL "aarch64")
7070
set(SKIA_ARCH "arm64")
7171
endif()
72+
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
73+
set(SKIA_PLATFORM "wasm")
74+
set(SKIA_ARCH "wasm32")
7275
elseif(UNIX AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
7376
set(SKIA_PLATFORM "linux")
7477
set(SKIA_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
@@ -203,13 +206,17 @@ find_package_handle_standard_args(Skia
203206
)
204207

205208
if(Skia_FOUND AND NOT TARGET Skia::Skia)
206-
find_package(ZLIB REQUIRED MODULE)
207-
find_package(PNG REQUIRED MODULE)
209+
set(SKIA_INTERFACE_LIBRARIES "")
210+
if(NOT SKIA_PLATFORM STREQUAL "wasm")
211+
find_package(ZLIB REQUIRED MODULE)
212+
find_package(PNG REQUIRED MODULE)
213+
set(SKIA_INTERFACE_LIBRARIES "PNG::PNG;ZLIB::ZLIB")
214+
endif()
208215

209216
add_library(Skia::Skia UNKNOWN IMPORTED)
210217
set_target_properties(Skia::Skia PROPERTIES
211218
IMPORTED_LOCATION "${SKIA_LIBRARY}"
212219
INTERFACE_INCLUDE_DIRECTORIES "${SKIA_INCLUDE_DIRS}"
213-
INTERFACE_LINK_LIBRARIES "PNG::PNG;ZLIB::ZLIB"
220+
INTERFACE_LINK_LIBRARIES "${SKIA_INTERFACE_LIBRARIES}"
214221
)
215222
endif()

skia/fetch.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ an artifact base URL or a GitHub Release.
2222
2323
Options:
2424
--platform <name> Target platform: ios, ios-simulator, macos, linux,
25-
android, windows.
25+
wasm, android, windows.
2626
--arch <name> Target arch/ABI: arm64, x86, x64, x86_64, aarch64,
27-
armv7l, arm64-v8a.
27+
armv7l, wasm32, arm64-v8a.
2828
--source <path|url> Install from a specific local file or URL.
2929
--base-url <url> Base URL used with the manifest artifact_name.
3030
--github-repo <r> GitHub repo in owner/name format.
@@ -194,6 +194,7 @@ normalize_platform() {
194194
ios-simulator|iphonesimulator) echo "ios-simulator" ;;
195195
Darwin|darwin|macos|mac|osx) echo "macos" ;;
196196
Linux|linux) echo "linux" ;;
197+
wasm|wasm32|Emscripten|emscripten) echo "wasm" ;;
197198
Android|android) echo "android" ;;
198199
Windows|windows|mingw*|MINGW*|msys*|MSYS*) echo "windows" ;;
199200
*) die "unsupported platform: $1" ;;
@@ -208,6 +209,7 @@ normalize_arch() {
208209
x64) echo "x64" ;;
209210
x86|i386|i686) echo "x86" ;;
210211
armv7l|armv7) echo "armv7l" ;;
212+
wasm|wasm32) echo "wasm32" ;;
211213
arm64-v8a) echo "arm64-v8a" ;;
212214
*) die "unsupported architecture/ABI: $1" ;;
213215
esac

skia/manifest.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"libskia-linux-x86_64.a",
1818
"libskia-linux-aarch64.a",
1919
"libskia-linux-armv7l.a",
20+
"libskia-wasm32.a",
2021
"libskia-android-arm64-v8a.a",
2122
"libskia-macos-arm64.a",
2223
"libskia-ios-arm64.a",
@@ -28,6 +29,7 @@
2829
"build_config_manifest-linux-x86_64.md",
2930
"build_config_manifest-linux-aarch64.md",
3031
"build_config_manifest-linux-armv7l.md",
32+
"build_config_manifest-wasm-wasm32.md",
3133
"build_config_manifest-android-arm64-v8a.md",
3234
"build_config_manifest-macos-arm64.md",
3335
"build_config_manifest-ios-arm64.md",

skia/manifest.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ artifact:
1818
- libskia-linux-x86_64.a
1919
- libskia-linux-aarch64.a
2020
- libskia-linux-armv7l.a
21+
- libskia-wasm32.a
2122
- libskia-android-arm64-v8a.a
2223
- libskia-macos-arm64.a
2324
- libskia-ios-arm64.a

skia/scripts/build-wasm32.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
6+
source "$SCRIPT_DIR/common.sh"
7+
8+
build_skia_wasm32

0 commit comments

Comments
 (0)