# Makefile d'Ustagammon : toutes les opérations du projet passent par ici. # Chaque cible documentée par « ## » apparaît dans `make help`. SHELL := /bin/bash .DEFAULT_GOAL := help # Machine de développement modeste : jamais plus de deux tâches en parallèle. MAKEFLAGS += -j2 --no-print-directory BUILD_DIR := build # Outils lancés dans Docker (aucune installation sur le PC). SHELLCHECK_IMAGE := koalaman/shellcheck-alpine:v0.10.0 # Image construite ici : changer le numéro à chaque modification de docker/gherkin/. GHERKIN_IMAGE := ustagammon/gherkin:2 # GNU Backgammon de référence, compilé au commit figé par l'ADR 0005. 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 # Outils de l'application web (docker/web/) : TypeScript, Biome, Cucumber, # dependency-cruiser. Changer l'étiquette à chaque modification du Dockerfile. WEB_IMAGE := ustagammon/web:1 # 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 WASM_IMAGE WEB_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) DOCKER_WEB := docker run --rm --user "$$(id -u):$$(id -g)" -v "$(CURDIR):/src" -w /src $(WEB_IMAGE) .PHONY: help setup build engine engine-wasm web bench test lint deploy deploy-web clean reference-image reference help: ## Liste les commandes disponibles @echo "Ustagammon : commandes disponibles" @grep -E '^[a-zA-Z0-9_-]+:.*## ' $(MAKEFILE_LIST) \ | awk 'BEGIN { FS = ":.*## " } { printf " make %-16s %s\n", $$1, $$2 }' setup: ## Installe la chaîne d'outils (images Docker) ; sans effet si déjà fait @command -v docker >/dev/null || { echo "Docker est requis : sudo apt install docker.io"; exit 1; } @docker image inspect $(SHELLCHECK_IMAGE) >/dev/null 2>&1 \ || docker pull $(SHELLCHECK_IMAGE) @docker image inspect $(GHERKIN_IMAGE) >/dev/null 2>&1 \ || docker build -q -t $(GHERKIN_IMAGE) docker/gherkin @$(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) @docker image inspect $(WEB_IMAGE) >/dev/null 2>&1 \ || docker build -t $(WEB_IMAGE) docker/web @echo "Chaîne d'outils prête." build: engine-wasm web ## Compile le moteur (si nécessaire) puis l'application engine: ## Compile le moteur, ses données et build/engine-cli (dans Docker) @docker image inspect $(BUILD_C_IMAGE) >/dev/null 2>&1 \ || { 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 # L'application est recompilée entièrement (quelques secondes) : build/web/ # ne garde ainsi aucun fichier dont la source a disparu. Le package.json # indique à Node que les .js produits sont des modules ES. web: ## Compile l'application TypeScript (app/) dans build/web/ (dans Docker) @docker image inspect $(WEB_IMAGE) >/dev/null 2>&1 \ || { echo "Outils web absents : lancer d'abord make setup"; exit 1; } @rm -rf $(BUILD_DIR)/web @$(DOCKER_WEB) tsc -p app/tsconfig.json @cp app/package.json $(BUILD_DIR)/web/package.json 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 lint: ## Vérifie le style et les erreurs courantes @tests/lint.sh 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/ avec le serveur HTTP de # Python (types MIME corrects, dont application/wasm). Les deux dossiers sont # montés en lecture seule puis copiés dans le conteneur au démarrage : relancer # après une modification. # 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:/web:ro" -v "$(CURDIR)/build/wasm:/wasm:ro" $(BUILD_C_IMAGE) \ sh -c 'cp -r /web /tmp/site && cp -r /wasm /tmp/site/wasm \ && exec python3 -m http.server 8080 --directory /tmp/site' clean: ## Supprime les artefacts de build (garde les images Docker) rm -rf $(BUILD_DIR) reference-image: ## Construit l'image Docker du gnubg de référence (cache Docker : rapide si à jour) docker build -t $(REFERENCE_IMAGE) docker/gnubg-reference @echo "Image $(REFERENCE_IMAGE) prête." reference: reference-image ## Régénère tests/reference/results/ avec le gnubg de référence rm -rf tests/reference/results docker run --rm --user "$$(id -u):$$(id -g)" -e HOME=/tmp \ -v "$(CURDIR)/tests/reference:/reference" $(REFERENCE_IMAGE) \ gnubg --tty --quiet --no-rc --python=/reference/generate.py