Skip to main content

WebAssembly Build Guide

This guide shows you how to build MNE-CPP for WebAssembly (Wasm). MNE-CPP uses multi-threaded Wasm by default and provides a build script that handles Emscripten setup, CMake configuration, and compilation.

Prerequisites​

Qt 6 for WebAssembly​

You need a Qt 6 installation that includes the WebAssembly (multi-threaded) target. Install it via the Qt Online Installer — select both a desktop target (e.g. Desktop gcc 64-bit on Linux or macOS on Mac) and the WebAssembly (multi-threaded) target. CI currently uses Qt 6.10.2.

A desktop (host) Qt is required alongside the Wasm Qt because Qt's cross-compilation needs a host toolchain to build code generators and other tools.

Emscripten SDK​

The build script can automatically download and set up the Emscripten SDK for you. If you prefer to install it manually, see emscripten.org. CI currently uses emsdk 4.0.7.

System Dependencies​

On Linux, install the following packages:

sudo apt-get install build-essential libgl1-mesa-dev ninja-build

On macOS, install Ninja:

brew install ninja

CMake​

CMake 3.15 or higher is required.

Build with the Provided Script​

MNE-CPP provides a Wasm build script at scripts/wasm/wasm.sh. From the repository root:

# Set Qt6_DIR to the folder containing wasm_multithread/ and your host Qt (gcc_64/ or macos/)
export Qt6_DIR=$HOME/Qt/6.10.2

./scripts/wasm/wasm.sh

The script will:

  1. Clone and activate the Emscripten SDK (version 4.0.7 by default)
  2. Auto-detect the host Qt path from Qt6_DIR
  3. Run qt-cmake with -DWASM=ON
  4. Build MNE-CPP for WebAssembly

Build output is placed in out/wasm/.

Script Options​

OptionDescription
--emsdk <version>, -eSet the Emscripten version (default: 4.0.7)
--qt <path>, -qSet the Qt installation path manually
--qt-host <path>Set the host Qt path for cross-compilation
--no-logSkip writing build_info.txt
--help, -hShow help

Example with explicit paths:

./scripts/wasm/wasm.sh --emsdk 4.0.7 --qt $HOME/Qt/6.10.2 --qt-host $HOME/Qt/6.10.2/gcc_64

Build Manually​

If you prefer to run the steps yourself:

# 1. Set up Emscripten
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 4.0.7
./emsdk activate 4.0.7
source ./emsdk_env.sh
cd ..

# 2. Configure and build
$HOME/Qt/6.10.2/wasm_multithread/bin/qt-cmake \
-DQT_HOST_PATH=$HOME/Qt/6.10.2/gcc_64 \
-DCMAKE_BUILD_TYPE=Release \
-DWASM=ON \
-S src \
-B build/wasm

cmake --build build/wasm --parallel $(nproc)

Adjust QT_HOST_PATH to gcc_64 (Linux) or macos (macOS) as appropriate.

Run an Application​

Navigate to the build output directory and start a local web server:

cd out/wasm/apps
python3 -m http.server

Open a Chromium-based browser or Firefox and visit:

http://localhost:8000/mne_analyze.html
Cross-Origin Headers

Multi-threaded Wasm requires the server to send the Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp headers. Without these headers, SharedArrayBuffer is unavailable and the application will hang silently in Chrome and Safari (Edge is more permissive).

Automatic fix (recommended): Run the post-build script to inject a COI service worker that adds these headers client-side — this works on any static host including GitHub Pages:

./scripts/wasm/wasm_postbuild.sh out/wasm/apps

The wasm.sh build script runs this automatically. If you build manually with CMake, run the command above after cmake --build.

Alternative for local testing: Use a server that sends COOP/COEP headers, e.g.:

npx coi-serviceworker-server out/wasm/apps

See the Qt for WebAssembly documentation for details.

Live Demo​

Live Wasm builds are available at:

Notes​

  • Chromium-based browsers and Firefox provide the best compatibility.
  • Qt3D / QOpenGLWidget is not supported in WebAssembly builds (-DNO_OPENGL is implied by -DWASM=ON).
  • The Wasm build always uses static linking (BUILD_SHARED_LIBS=OFF).

References​