Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,3 @@ build:tsan --linkopt=-fsanitize=thread
build:tsan --strip=never
build:tsan --features=dbg
build:tsan --compilation_mode=dbg

# WebAssembly (WASM) configuration
# Usage: bazel build --config=wasm //...
# Compiles using the hermetic emsdk toolchain downloaded automatically by Bazel.
build:wasm --platforms=@emsdk//:platform_wasm
build:wasm --cpu=wasm
build:wasm --cxxopt=-std=c++20
build:wasm --host_cxxopt=-std=c++20
build:wasm --compilation_mode=opt
5 changes: 3 additions & 2 deletions .github/workflows/ci_wasm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ jobs:

# 3️⃣ Build WASM targets (hermetic emsdk toolchain downloaded by Bazel)
- name: Build WASM targets
run: bazel build --config=wasm --verbose_failures //examples:all_examples_wasm
run: bazel build --verbose_failures //examples/wasm:all_examples_wasm

# 4️⃣ Smoke test: run solve_board under Node.js — pass if it does not crash
- name: Smoke test solve_board_wasm
run: node bazel-bin/examples/solve_board.js
run: node bazel-bin/examples/wasm/solve_board.js
git push -u origin wasm-refactor
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks strange.

3 changes: 1 addition & 2 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ config_setting(
define_values = {"asan": "true"},
)

# WebAssembly (WASM) build configuration
# Usage: bazel build --config=wasm //...
# Matches cc_* targets built under the wasm_cc_binary platform transition (cpu=wasm).
config_setting(
name = "build_wasm",
values = {"cpu": "wasm"},
Expand Down
134 changes: 54 additions & 80 deletions docs/wasm_build.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WebAssembly (WASM) Build Guide

This document explains how to build the DDS library and examples for WebAssembly using Bazel.
This document explains how to build DDS examples for WebAssembly using Bazel.

## Prerequisites

Expand All @@ -9,128 +9,102 @@ This document explains how to build the DDS library and examples for WebAssembly
Bazel 7.x or later is required. Install using your package manager or download from:
https://bazel.build/install

The Emscripten SDK (emsdk) does NOT need to be manually installed. Bazel will automatically download, configure, and cache the appropriate hermetic Emscripten toolchain for your host platform as part of the build process.
The Emscripten SDK (emsdk) does NOT need to be manually installed. Bazel downloads and caches a hermetic Emscripten toolchain when you build a `wasm_cc_binary` target.

## Building WASM Examples

### Build All Examples
WASM targets use `wasm_cc_binary`, which applies an Emscripten **platform transition** to the underlying `cc_binary`. You do **not** need `--config=wasm` or any other `.bazelrc` profile.

```bash
cd /workspaces/dds
bazel build //examples:all_examples_wasm
```

### Build Specific Example
### Build all WASM examples

```bash
bazel build //examples:solve_board_wasm
```

### Output Files

the output files will be located in:
```
bazel-bin/examples/
bazel build //examples/wasm:all_examples_wasm
```

Depending on the target, you'll get:
- `target.js` - JavaScript bindings
- `target.wasm` - WebAssembly binary
The alias `//examples:all_examples_wasm` points at the same filegroup.

### Build a specific example

## Available WASM Targets

The following example targets are available for WASM builds:
```bash
bazel build //examples/wasm:solve_board_wasm
```

### Implemented Examples
- `solve_board` - Solves a single board (produces .js and .wasm)
### Output files

- `analyse_play_bin` - Analyze play from binary format
Outputs are under `bazel-bin/examples/wasm/`:

- `solve_board.js` / `solve_board.wasm`
- `AnalysePlayBin.js` / `AnalysePlayBin.wasm`

## WASM Build Configuration
## Available WASM targets

The WASM build is configured through:
Rules in `examples/wasm/BUILD.bazel` wrap native examples in `examples/`:

1. **BUILD.bazel** - Defines the WASM config_setting:
```python
config_setting(
name = "build_wasm",
values = {"cpu": "wasm"},
)
```
- `solve_board_wasm` — solves a single board
- `analyse_play_bin_wasm` — analyze play from binary format

2. **CPPVARIABLES.bzl** - Specifies WASM-specific compiler flags:
- Optimization: `-O3 -flto`
- Exceptions: `-fexceptions`
- Define: `-D__WASM__`
## How it works

3. **.bazelrc** - Contains the `wasm` profile:
```
build:wasm --platforms=@emsdk//:platform_wasm
build:wasm --cpu=wasm
build:wasm --cxxopt=-std=c++20
build:wasm --host_cxxopt=-std=c++20
build:wasm --compilation_mode=opt
```
1. **`wasm_cc_binary`** (from `@emsdk`) transitions its `cc_target` to `@emsdk//:platform_wasm` and sets `--cpu=wasm`.
2. **`//:build_wasm`** in the root `BUILD.bazel` matches that CPU for `select()` in `CPPVARIABLES.bzl` and example link flags.
3. **`wasm_compat.bzl`** — shared Emscripten link flags (`WASM_LINKOPTS`) on the WASM-capable `cc_binary` targets.

## Running WASM Examples
Native builds (`bazel build //...`, `bazel test //library/tests/...`, Python bindings) are unchanged and use the host LLVM toolchain.

After building, you can run the examples:
## Running WASM examples

### Node.js (requires Node.js installed)
### Node.js

```bash
node bazel-bin/examples/solve_board.js
node bazel-bin/examples/wasm/solve_board.js
```

### Web Browser (TODO)

For HTML targets, open the generated HTML file in a web browser:
```bash
# Copy the output files to a web-accessible location
cp bazel-bin/examples/solve_board.* /path/to/webserver/

# Then open in browser at http://localhost:8000/solve_board.html
```
### Web browser (not yet supported)

## Compilation Flags
There is no checked-in HTML runner yet. To experiment manually, copy the built `.js` and `.wasm` files from `bazel-bin/examples/wasm/` to a static file server and load the `.js` from a page that provides the Emscripten `Module` hooks.

The WASM build uses the following key flags:
## Compilation flags

| Flag | Purpose |
|------|---------|
| `-O3` | Aggressive optimization |
| `-flto` | Link-time optimization |
| `-fexceptions` | Enable C++ exceptions |
| `-D__WASM__` | Defines `__WASM__` preprocessor constant |
| `-D__WASM__` | Preprocessor constant for WASM builds |
| `-sWASM=1` | Emscripten WASM output (link flag) |
| `-sALLOW_MEMORY_GROWTH=1` | Allow heap growth at runtime |
| `-sINITIAL_MEMORY=268435456` | Configure 256MB initial memory |
| `-sINITIAL_MEMORY=268435456` | 256MB initial memory |

## C++ standard

## C++ Standard
WASM example binaries are built as C++20. The Emscripten toolchain (via `wasm_cc_binary`) compiles the transitioned `cc_target`; project flags for that configuration come from `CPPVARIABLES.bzl` when `//:build_wasm` matches (`--cpu=wasm` set by the transition).

Comment on lines +78 to +81
Host-side Bazel actions still use the normal platform flags in `.bazelrc`:

The WASM build uses C++20 as specified in `.bazelrc`:
```
build:wasm --cxxopt=-std=c++20
build:macos --cxxopt=-std=c++20
build:linux --cxxopt=-std=c++20
```

## Related Documentation
There is no separate `build:wasm` profile in `.bazelrc`; WASM builds are selected by targeting `//examples/wasm:*`.

- [Emscripten Documentation](https://emscripten.org/docs/)
- [Bazel Build System](https://bazel.build/docs)
- [DDS C++ API](c++_interface.md)
- [Build System Overview](BUILD_SYSTEM.md)
## Development notes

## Next Steps
- The `__WASM__` preprocessor constant is defined for WASM builds (`CPPVARIABLES.bzl`). It was added to work around platform-specific code paths; revisit whether it can be narrowed or removed as WASM support matures.
- Some threading and platform-specific features are disabled or stubbed when `__WASM__` is set.
- A reusable `cc_library` WASM artifact (not only example binaries) is not yet provided; today only `wasm_cc_binary` example targets are wired up.
- Browser/HTML packaging (`.html` shell, assets) is not yet documented or automated; Node.js is the supported smoke-test runner for now.

## Next steps

To integrate WASM builds into CI/CD:
1. See `.github/workflows/ci_linux.yml` and `.github/workflows/ci_macos.yml`
2. Store WASM artifacts for download/release

## Development Notes
1. See `.github/workflows/ci_wasm.yml`
2. Store WASM artifacts (`*.js`, `*.wasm`) for download or release as needed

## Related documentation

- The `__WASM__` preprocessor constant is added initially to bypass error, need to check again whether we can remove
- Some threading and platform-specific features are disabled for WASM
- The build flow for a reusable library wasm
- A good HTML example
- [Emscripten Documentation](https://emscripten.org/docs/)
- [Bazel Build System](https://bazel.build/docs)
- [DDS C++ API](c++_interface.md)
- [Build System Overview](BUILD_SYSTEM.md)
Loading
Loading