Moteur en WebAssembly : make engine-wasm et suite de contrat

Le moteur et engine-cli sont compilés avec Emscripten (image figée
emscripten/emsdk:3.1.64), en C générique, sans threads ; les données
de build/data/ sont incluses dans engine.data. Le JavaScript appelle
engine_init une fois puis main pour chaque commande : la sortie est le
JSON d'engine-cli, sans code de mise en forme dupliqué.

tests/test_wasm_reference.sh rejoue les 32 positions de référence sous
Node avec le même comparateur (option --cli) et la même tolérance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Pierre MARTIN
2026-11-02 19:07:01 +01:00
co-authored by Claude Opus 5.5
parent 850de27e90
commit b0030521d8
9 changed files with 265 additions and 9 deletions
+31 -2
View File
@@ -18,14 +18,19 @@ REFERENCE_IMAGE := ustagammon/gnubg-reference:14b6798
# Chaîne de compilation C (docker/build-c/Dockerfile) : changer l'étiquette
# à chaque modification du Dockerfile, pour que make setup la reconstruise.
BUILD_C_IMAGE := ustagammon/build-c:2
# Emscripten (compilation WebAssembly ; contient aussi Node et Python 3).
WASM_IMAGE := emscripten/emsdk:3.1.64
# Port de la page de test servie sur le réseau local (make deploy-web).
WEB_PORT := 8080
export SHELLCHECK_IMAGE GHERKIN_IMAGE BUILD_C_IMAGE
export SHELLCHECK_IMAGE GHERKIN_IMAGE BUILD_C_IMAGE WASM_IMAGE
# Lance une commande dans la chaîne C, sous l'utilisateur courant pour que
# build/ lui appartienne.
DOCKER_C := docker run --rm --user "$$(id -u):$$(id -g)" -v "$(CURDIR):/src" -w /src $(BUILD_C_IMAGE)
DOCKER_WASM := docker run --rm --user "$$(id -u):$$(id -g)" -e HOME=/tmp -v "$(CURDIR):/src" -w /src $(WASM_IMAGE)
.PHONY: help setup build engine test lint deploy clean reference-image reference
.PHONY: help setup build engine engine-wasm bench test lint deploy deploy-web clean reference-image reference
help: ## Liste les commandes disponibles
@echo "Ustagammon : commandes disponibles"
@@ -41,6 +46,8 @@ setup: ## Installe la chaîne d'outils (images Docker) ; sans effet si déjà fa
@$(MAKE) reference-image
@docker image inspect $(BUILD_C_IMAGE) >/dev/null 2>&1 \
|| docker build -t $(BUILD_C_IMAGE) docker/build-c
@docker image inspect $(WASM_IMAGE) >/dev/null 2>&1 \
|| docker pull $(WASM_IMAGE)
@echo "Chaîne d'outils prête."
build: engine ## Compile le moteur (si nécessaire) puis l'application
@@ -50,6 +57,14 @@ engine: ## Compile le moteur, ses données et build/engine-cli (dans Docker)
|| { echo "Chaîne C absente : lancer d'abord make setup"; exit 1; }
@$(DOCKER_C) make -f engine/engine.mk -j2 --no-print-directory
engine-wasm: engine ## Compile le moteur en WebAssembly dans build/wasm/ (dans Docker)
@docker image inspect $(WASM_IMAGE) >/dev/null 2>&1 \
|| { echo "Emscripten absent : lancer d'abord make setup"; exit 1; }
@$(DOCKER_WASM) make -f engine-wasm/wasm.mk -j2 --no-print-directory
bench: engine-wasm ## Mesure le moteur WebAssembly sous Node, sur ce PC (rapport texte)
@$(DOCKER_WASM) node engine-wasm/bench.mjs
test: ## Lance tous les tests
@tests/run.sh
@@ -58,8 +73,22 @@ lint: ## Vérifie le style et les erreurs courantes
deploy: ## Installe l'application sur le téléphone (pas encore disponible)
@echo "Pas encore disponible : le socle (PWA ou Android) sera choisi à la fin de l'étape 0."
@echo "Page de test du moteur WebAssembly : make deploy-web"
@exit 1
# Sert web/ à la racine et build/wasm/ sous /wasm/, en lecture seule, avec le
# serveur HTTP de Python (types MIME corrects, dont application/wasm).
# L'adresse affichée est celle du PC sur l'interface de sa route par défaut,
# c'est-à-dire sur le réseau local (Wi-Fi ou câble).
deploy-web: engine-wasm ## Sert la page de test WebAssembly sur le réseau local (Ctrl+C pour arrêter)
@ip="$$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{ for (i = 1; i < NF; i++) if ($$i == "src") print $$(i + 1) }')"; \
echo "Page de test : http://$${ip:-ADRESSE-DU-PC}:$(WEB_PORT)/"; \
echo "Page de mesure : http://$${ip:-ADRESSE-DU-PC}:$(WEB_PORT)/bench.html"; \
echo "À ouvrir depuis le téléphone, sur le même Wi-Fi. Ctrl+C pour arrêter."
@docker run --rm --init -p $(WEB_PORT):8080 \
-v "$(CURDIR)/web:/site:ro" -v "$(CURDIR)/build/wasm:/site/wasm:ro" \
$(BUILD_C_IMAGE) python3 -m http.server 8080 --directory /site
clean: ## Supprime les artefacts de build (garde les images Docker)
rm -rf $(BUILD_DIR)