diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 069fb9a..cdb468c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,3 +92,81 @@ jobs: ${{ runner.os }}-cargo-min- - name: Build default feature set run: cargo build --workspace + + build-wasm: + name: Build WebAssembly (Emscripten) + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-emscripten + + - name: Install Emscripten + uses: mymindstorm/setup-emsdk@v14 + with: + # Pin to 3.1.x: Skia's pre-built wasm binaries use emscripten-style + # exception handling (invoke_* wrappers). Emscripten 4.x defaults to + # wasm-native exceptions (-fwasm-exceptions) which is incompatible. + version: '3.1.74' + actions-cache-folder: 'emsdk-cache' + + - name: Cache cargo registry + git + build + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-wasm-emsdk3.1.74-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-wasm-emsdk3.1.74- + + - name: Build xtask + run: cargo build -p xtask + + - name: Build WASM with xtask + run: cargo xtask emscripten --features skia-wasm --emsdk $EMSDK + + - name: Prepare deployment artifacts + run: | + mkdir -p deploy + cp examples/web/index.html deploy/ + cp examples/web/dist/emscripten.js deploy/ + cp examples/web/dist/emscripten.wasm deploy/ + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: deploy + + deploy: + name: Deploy to GitHub Pages + runs-on: ubuntu-latest + needs: [test, minimal, build-wasm] + # Only deploy on push to main (not on PRs) + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + + # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. + # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. + concurrency: + group: "pages" + cancel-in-progress: false + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 64ee131..f8d7e2d 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -118,7 +118,9 @@ fn build_emscripten( // Check emsdk exists let emsdk_path = get_emsdk_path(emsdk_override)?; - // Set EMCC_CFLAGS + // Set EMCC_CFLAGS (applies to every emcc invocation: compile + link). + // SUPPORT_LONGJMP must be set explicitly — the emscripten default does + // not propagate when emcc is invoked as a linker through rustc's driver. let emcc_cflags = [ "--no-entry", "-sASSERTIONS=1", @@ -127,6 +129,7 @@ fn build_emscripten( "-sENVIRONMENT=web", "-sERROR_ON_UNDEFINED_SYMBOLS=0", "-sMAX_WEBGL_VERSION=2", + "-sSUPPORT_LONGJMP=emscripten", ] .join(" "); @@ -135,6 +138,7 @@ fn build_emscripten( "-C link-args=-sEXPORTED_FUNCTIONS=['_sk_load_pdf','_sk_get_page_count','_sk_render_page','_sk_free_pdf','_malloc','_free']", "-C link-args=-sEXPORTED_RUNTIME_METHODS=['cwrap','HEAPU8']", "-C link-args=-sSTANDALONE_WASM=0", + "-C link-args=-sSUPPORT_LONGJMP=emscripten", ] .join(" "); @@ -173,7 +177,10 @@ fn build_emscripten( .arg("cargo") .args(&cargo_args) .env("EMCC_CFLAGS", emcc_cflags) - .env("RUSTFLAGS", rustflags) + .env( + "CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUSTFLAGS", + rustflags, + ) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .status()