Files
Ustagammon/Makefile
T

134 lines
6.5 KiB
Makefile

# 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
# Port de la page de test servie sur le réseau local (make deploy-web).
WEB_PORT := 8080
# Serveur statique de production (deploy/Dockerfile) : même version ici.
CADDY_IMAGE := caddy:2.8.4-alpine
export SHELLCHECK_IMAGE GHERKIN_IMAGE BUILD_C_IMAGE WASM_IMAGE CADDY_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 engine-wasm bench test lint deploy deploy-web site package deploy-prod 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 $(CADDY_IMAGE) >/dev/null 2>&1 \
|| docker pull $(CADDY_IMAGE)
@echo "Chaîne d'outils prête."
build: engine ## 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
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'
# Le site tel qu'il sera publié : web/ à la racine, le moteur sous wasm/, et
# version.json (commit déployé). Reconstruit entièrement à chaque appel.
site: engine-wasm ## Assemble le site publié dans build/site/
rm -rf $(BUILD_DIR)/site
mkdir -p $(BUILD_DIR)/site/wasm
cp -r web/. $(BUILD_DIR)/site/
cp $(BUILD_DIR)/wasm/engine.mjs $(BUILD_DIR)/wasm/engine.wasm $(BUILD_DIR)/wasm/engine.data \
$(BUILD_DIR)/wasm/positions.json $(BUILD_DIR)/site/wasm/
printf '{"commit": "%s", "dirty": %s}\n' "$$(git rev-parse HEAD)" \
"$$(git diff --quiet HEAD && echo false || echo true)" > $(BUILD_DIR)/site/version.json
# L'archive envoyée à CapRover : captain-definition, Dockerfile, Caddyfile et
# le site. CapRover construit l'image (une simple copie) sur le serveur.
package: site ## Prépare l'archive de déploiement build/ustagammon.tar
rm -rf $(BUILD_DIR)/deploy
cp -r deploy $(BUILD_DIR)/deploy
cp -r $(BUILD_DIR)/site $(BUILD_DIR)/deploy/site
tar -cf $(BUILD_DIR)/ustagammon.tar -C $(BUILD_DIR)/deploy .
@echo "Archive prête : $(BUILD_DIR)/ustagammon.tar"
deploy-prod: ## Publie main sur CapRover (voir docs/deploiement.md)
@scripts/deploy.sh
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