From d98e2a32d574f2933356e5d87ad26d5efed0f8b7 Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Tue, 16 Jun 2026 23:46:33 -0400 Subject: [PATCH 1/2] Moved examples/wasm to wasm/ --- examples/wasm/BUILD.bazel | 77 ------------------ wasm/BUILD.bazel | 78 ++++++++++++++++++- .../wasm => wasm}/calc_dd_table_pbn_test.cpp | 0 .../tests/test_wasm_examples_system.py | 0 4 files changed, 77 insertions(+), 78 deletions(-) delete mode 100644 examples/wasm/BUILD.bazel rename {examples/wasm => wasm}/calc_dd_table_pbn_test.cpp (100%) rename {examples/wasm => wasm}/tests/test_wasm_examples_system.py (100%) diff --git a/examples/wasm/BUILD.bazel b/examples/wasm/BUILD.bazel deleted file mode 100644 index b9d78014..00000000 --- a/examples/wasm/BUILD.bazel +++ /dev/null @@ -1,77 +0,0 @@ -load("@rules_cc//cc:defs.bzl", "cc_test") -load("@emsdk//emscripten_toolchain:wasm_rules.bzl", "wasm_cc_binary") -load("@rules_python//python:defs.bzl", "py_test") -load("//:CPPVARIABLES.bzl", "DDS_CPPOPTS", "DDS_LOCAL_DEFINES") - -wasm_cc_binary( - name = "solve_board_wasm", - cc_target = "//examples:solve_board", - outputs = [ - "solve_board.js", - "solve_board.wasm", - ], -) - -wasm_cc_binary( - name = "analyse_play_bin_wasm", - cc_target = "//examples:AnalysePlayBin", - outputs = [ - "AnalysePlayBin.js", - "AnalysePlayBin.wasm", - ], -) - -wasm_cc_binary( - name = "calc_dd_table_pbn_wasm", - cc_target = "//examples:calc_dd_table_pbn", - outputs = [ - "calc_dd_table_pbn.js", - "calc_dd_table_pbn.wasm", - ], -) - -filegroup( - name = "all_examples_wasm", - srcs = [ - ":analyse_play_bin_wasm", - ":calc_dd_table_pbn_wasm", - ":solve_board_wasm", - ], - visibility = ["//visibility:public"], -) - -cc_test( - name = "calc_dd_table_pbn_test", - size = "small", - srcs = ["calc_dd_table_pbn_test.cpp"], - copts = DDS_CPPOPTS, - local_defines = DDS_LOCAL_DEFINES, - deps = [ - "//examples:hands", - "//library/src:dds", - "//library/src/api:api_definitions", - "@googletest//:gtest_main", - ], -) - -py_test( - name = "wasm_examples_system_test", - size = "small", - timeout = "short", - main = "tests/test_wasm_examples_system.py", - srcs = ["tests/test_wasm_examples_system.py"], - data = [":calc_dd_table_pbn_wasm"], -) - -test_suite( - name = "all", - tests = [ - ":calc_dd_table_pbn_test", - ":wasm_examples_system_test", - ], -) - -test_suite( - name = "wasm_system_tests", - tests = [":wasm_examples_system_test"], -) diff --git a/wasm/BUILD.bazel b/wasm/BUILD.bazel index 9bb72912..b9d78014 100644 --- a/wasm/BUILD.bazel +++ b/wasm/BUILD.bazel @@ -1 +1,77 @@ -# WASM helpers live in //:wasm_compat.bzl (no build targets in this package). +load("@rules_cc//cc:defs.bzl", "cc_test") +load("@emsdk//emscripten_toolchain:wasm_rules.bzl", "wasm_cc_binary") +load("@rules_python//python:defs.bzl", "py_test") +load("//:CPPVARIABLES.bzl", "DDS_CPPOPTS", "DDS_LOCAL_DEFINES") + +wasm_cc_binary( + name = "solve_board_wasm", + cc_target = "//examples:solve_board", + outputs = [ + "solve_board.js", + "solve_board.wasm", + ], +) + +wasm_cc_binary( + name = "analyse_play_bin_wasm", + cc_target = "//examples:AnalysePlayBin", + outputs = [ + "AnalysePlayBin.js", + "AnalysePlayBin.wasm", + ], +) + +wasm_cc_binary( + name = "calc_dd_table_pbn_wasm", + cc_target = "//examples:calc_dd_table_pbn", + outputs = [ + "calc_dd_table_pbn.js", + "calc_dd_table_pbn.wasm", + ], +) + +filegroup( + name = "all_examples_wasm", + srcs = [ + ":analyse_play_bin_wasm", + ":calc_dd_table_pbn_wasm", + ":solve_board_wasm", + ], + visibility = ["//visibility:public"], +) + +cc_test( + name = "calc_dd_table_pbn_test", + size = "small", + srcs = ["calc_dd_table_pbn_test.cpp"], + copts = DDS_CPPOPTS, + local_defines = DDS_LOCAL_DEFINES, + deps = [ + "//examples:hands", + "//library/src:dds", + "//library/src/api:api_definitions", + "@googletest//:gtest_main", + ], +) + +py_test( + name = "wasm_examples_system_test", + size = "small", + timeout = "short", + main = "tests/test_wasm_examples_system.py", + srcs = ["tests/test_wasm_examples_system.py"], + data = [":calc_dd_table_pbn_wasm"], +) + +test_suite( + name = "all", + tests = [ + ":calc_dd_table_pbn_test", + ":wasm_examples_system_test", + ], +) + +test_suite( + name = "wasm_system_tests", + tests = [":wasm_examples_system_test"], +) diff --git a/examples/wasm/calc_dd_table_pbn_test.cpp b/wasm/calc_dd_table_pbn_test.cpp similarity index 100% rename from examples/wasm/calc_dd_table_pbn_test.cpp rename to wasm/calc_dd_table_pbn_test.cpp diff --git a/examples/wasm/tests/test_wasm_examples_system.py b/wasm/tests/test_wasm_examples_system.py similarity index 100% rename from examples/wasm/tests/test_wasm_examples_system.py rename to wasm/tests/test_wasm_examples_system.py From 395a0b7357accc458e286e04deb1629fad86accd Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Tue, 16 Jun 2026 23:46:46 -0400 Subject: [PATCH 2/2] Moved examples/wasm to wasm/ --- .github/workflows/ci_wasm.yml | 6 +++--- MODULE.bazel | 2 +- MODULE.bazel.lock | 2 +- docs/wasm_build.md | 18 +++++++++--------- examples/BUILD.bazel | 17 ++++++++++------- wasm/tests/test_wasm_examples_system.py | 2 +- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci_wasm.yml b/.github/workflows/ci_wasm.yml index 8e5bf543..598251ee 100644 --- a/.github/workflows/ci_wasm.yml +++ b/.github/workflows/ci_wasm.yml @@ -22,14 +22,14 @@ jobs: # 3️⃣ Unit tests and WASM builds (hermetic emsdk toolchain downloaded by Bazel) - name: Test web helpers, system tests, e2e, and CalcDDtablePBN - run: bazel test --verbose_failures //web:web_tests //web:web_system_tests //examples/wasm:all + run: bazel test --verbose_failures //web:web_tests //web:web_system_tests //wasm:all - name: Build WASM targets - run: bazel build --verbose_failures //examples/wasm:all_examples_wasm + run: bazel build --verbose_failures //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/wasm/solve_board.js + run: node bazel-bin/wasm/solve_board.js # 5️⃣ Upload test logs - name: Upload test logs - WASM diff --git a/MODULE.bazel b/MODULE.bazel index e9766b27..a7897c13 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -9,7 +9,7 @@ bazel_dep(name = "googletest", version = "1.17.0.bcr.2") bazel_dep(name = "pybind11_bazel", version = "3.0.1") bazel_dep(name = "rules_python", version = "2.0.1") bazel_dep(name = "toolchains_llvm", version = "1.7.0") -# WASM builds (//examples/wasm:*, //web:dds_mvp_wasm). If you bump this version, +# WASM builds (//wasm:*, //web:dds_mvp_wasm). If you bump this version, # rebuild and run web/update_wasm.sh; see docs/wasm_build.md and patch_mvp_wasm.py. bazel_dep(name = "emsdk", version = "5.0.7") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c9c77ee2..800cc995 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -260,7 +260,7 @@ }, "@@emsdk+//:emscripten_deps.bzl%emscripten_deps": { "general": { - "bzlTransitiveDigest": "reX42Ca3PEP5mFXph0pqMqqqwHJbvykl5X4FHfXD6qg=", + "bzlTransitiveDigest": "Dt5IF0PG0xjU5iMLeU6FQ1/xWvBqUgUognNk3r5pJXY=", "usagesDigest": "lqS0hMGr6MqmX63BGZOskMFcqzqO53K0UlYFxuE3QSU=", "recordedInputs": [ "REPO_MAPPING:bazel_features+,bazel_features_globals bazel_features++version_extension+bazel_features_globals", diff --git a/docs/wasm_build.md b/docs/wasm_build.md index 2e973f47..561192fa 100644 --- a/docs/wasm_build.md +++ b/docs/wasm_build.md @@ -26,7 +26,7 @@ WASM targets use `wasm_cc_binary`, which applies an Emscripten **platform transi ### Build all WASM examples ```bash -bazel build //examples/wasm:all_examples_wasm +bazel build //wasm:all_examples_wasm ``` The alias `//examples:all_examples_wasm` points at the same filegroup. @@ -34,12 +34,12 @@ The alias `//examples:all_examples_wasm` points at the same filegroup. ### Build a specific example ```bash -bazel build //examples/wasm:solve_board_wasm +bazel build //wasm:solve_board_wasm ``` ### Output files -Outputs are under `bazel-bin/examples/wasm/`: +Outputs are under `bazel-bin/wasm/`: - `solve_board.js` / `solve_board.wasm` - `AnalysePlayBin.js` / `AnalysePlayBin.wasm` @@ -47,7 +47,7 @@ Outputs are under `bazel-bin/examples/wasm/`: ## Available WASM targets -Rules in `examples/wasm/BUILD.bazel` wrap native examples in `examples/`: +Rules in `wasm/BUILD.bazel` wrap native examples in `examples/`: - `solve_board_wasm` — solves a single board - `analyse_play_bin_wasm` — analyze play from binary format @@ -66,7 +66,7 @@ Native builds (`bazel build //...`, `bazel test //library/tests/...`, Python bin ### Node.js ```bash -node bazel-bin/examples/wasm/solve_board.js +node bazel-bin/wasm/solve_board.js ``` ### Web browser (DDS MVP) @@ -89,7 +89,7 @@ The MVP loads wasm from `dds_mvp_wasm_bin.js` (base64, no network fetch), so `fi ./web/clean_wasm.sh # web artifacts only ``` -For other experiments, copy built `.js` / `.wasm` files from `bazel-bin/examples/wasm/` to any static file server. +For other experiments, copy built `.js` / `.wasm` files from `bazel-bin/wasm/` to any static file server. ## Compilation flags @@ -114,7 +114,7 @@ build:macos --cxxopt=-std=c++20 build:linux --cxxopt=-std=c++20 ``` -There is no separate `build:wasm` profile in `.bazelrc`; WASM builds are selected by targeting `//examples/wasm:*`. +There is no separate `build:wasm` profile in `.bazelrc`; WASM builds are selected by targeting `//wasm:*`. ## Tests @@ -122,14 +122,14 @@ Unit and system tests (Node.js required for system tests; skipped if `node` is n ```bash bazel test //web:web_tests //web:web_system_tests //web:web_e2e_tests -bazel test //examples/wasm:all +bazel test //wasm:all ``` `bazel test //...` skips targets tagged `e2e` by default (see `.bazelrc`). Run Playwright tests explicitly, e.g. `bazel test //web:web_e2e_tests` or `bazel test --test_tag_filters=e2e //web:dds_mvp_e2e_test`. To run all tests, including the Playwright tests: `bazel test --test_tag_filters= /...` - **`//web:dds_mvp_wasm_system_test`** — builds `//web:dds_mvp_wasm`, runs `patch_mvp_wasm` / `gen_wasm_bin_js` / `verify_wasm_js`, then calls `dds_mvp_calc_table` via Node (`web/tests/dds_mvp_wasm_node.mjs`). - **`//web:dds_mvp_e2e_test`** — Playwright tests for `dds_mvp.html` over `file://` and HTTP (part-score deal table, validation error). Requires Node, network (Chromium download on first run), and `tags = ["no-sandbox"]`. -- **`//examples/wasm:wasm_examples_system_test`** — runs `calc_dd_table_pbn.js` under Node and checks for `OK` on all three example hands. +- **`//wasm:wasm_examples_system_test`** — runs `calc_dd_table_pbn.js` under Node and checks for `OK` on all three example hands. The MVP link flags include `-sENVIRONMENT=web,node` so the same `.js` / `.wasm` artifacts work in the browser and in Node system tests. diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel index e425c145..6321836e 100644 --- a/examples/BUILD.bazel +++ b/examples/BUILD.bazel @@ -19,7 +19,7 @@ EXAMPLES_LOCAL_DEFINES = DDS_LOCAL_DEFINES + select({ "//conditions:default": [], }) -# Emscripten link flags for examples built as WASM (see //examples/wasm). +# Emscripten link flags for examples built as WASM (see //wasm). EXAMPLES_LINKOPTS_WASM = select({ "//:build_wasm": WASM_LINKOPTS, "//conditions:default": [], @@ -33,7 +33,10 @@ cc_library( includes = ["."], copts = EXAMPLES_CPPOPTS, local_defines = EXAMPLES_LOCAL_DEFINES, - visibility = ["//examples:__subpackages__"], + visibility = [ + "//examples:__subpackages__", + "//wasm:__pkg__", + ], deps = [ "//library/src:dds", "//library/src/api:api_definitions", @@ -73,7 +76,7 @@ cc_binary( copts = EXAMPLES_CPPOPTS, linkopts = DDS_LINKOPTS + EXAMPLES_LINKOPTS_WASM, local_defines = EXAMPLES_LOCAL_DEFINES, - visibility = ["//examples/wasm:__pkg__"], + visibility = ["//wasm:__pkg__"], deps = [ ":hands", "//library/src:dds", @@ -139,7 +142,7 @@ cc_binary( copts = EXAMPLES_CPPOPTS, linkopts = DDS_LINKOPTS + EXAMPLES_LINKOPTS_WASM, local_defines = EXAMPLES_LOCAL_DEFINES, - visibility = ["//examples/wasm:__pkg__"], + visibility = ["//wasm:__pkg__"], deps = [ ":hands", "//library/src:dds", @@ -205,7 +208,7 @@ cc_binary( copts = EXAMPLES_CPPOPTS, linkopts = DDS_LINKOPTS + EXAMPLES_LINKOPTS_WASM, local_defines = EXAMPLES_LOCAL_DEFINES, - visibility = ["//examples/wasm:__pkg__"], + visibility = ["//wasm:__pkg__"], deps = [ ":hands", "//library/src:dds", @@ -275,8 +278,8 @@ filegroup( ], ) -# Backward-compatible alias; prefer //examples/wasm:all_examples_wasm. +# Backward-compatible alias; prefer //wasm:all_examples_wasm. alias( name = "all_examples_wasm", - actual = "//examples/wasm:all_examples_wasm", + actual = "//wasm:all_examples_wasm", ) diff --git a/wasm/tests/test_wasm_examples_system.py b/wasm/tests/test_wasm_examples_system.py index c16fc794..bfd4634b 100644 --- a/wasm/tests/test_wasm_examples_system.py +++ b/wasm/tests/test_wasm_examples_system.py @@ -26,7 +26,7 @@ def rlocation(relpath: str) -> Path: @unittest.skipUnless(shutil.which("node"), "node not found") class WasmExamplesSystemTest(unittest.TestCase): def test_calc_dd_table_pbn_wasm(self) -> None: - js = rlocation("examples/wasm/calc_dd_table_pbn.js") + js = rlocation("wasm/calc_dd_table_pbn.js") proc = subprocess.run( ["node", str(js)], capture_output=True,