Files

91 lines
3.5 KiB
Makefile
Raw Permalink Normal View History

# php-qml framework skeleton — Make targets.
.DEFAULT_GOAL := help
Phase 1 sub-commit 6: skeleton wiring — make dev runs end-to-end Symfony app under framework/skeleton/symfony/: minimal bin/console, public/index.php, MicroKernel-based src/Kernel.php, services.yaml, framework/security/mercure config, and a demo App\Controller\PingController that GETs /api/ping (returning JSON pong) and republishes the same payload to the Mercure topic app://ping. composer.json uses a path repository to symlink the bundle from ../../php so local edits are picked up live. QML app under framework/skeleton/qml/: top-level CMake that add_subdirectory's framework/qml, a main.cpp that creates the Qt process, runs SingleInstance.acquireOrForward before any QML loads, exposes SingleInstance via context property, and loadFromModule's Skeleton.Main. Main.qml uses BackendConnection / RestClient / MercureClient from PhpQml.Bridge and renders status dots, a Ping button, and an event log. Caddyfile binds 127.0.0.1:8765, enables in-memory Mercure with a 256-bit dev JWT (matches symfony/.env, lcobucci/jwt requires this). Makefile wraps build / dev / doctor / clean; scripts/dev.sh starts FrankenPHP --watch and the Qt host together with explicit PID-based teardown (process-group `kill 0` proved unreliable when frankenphp's watch fork reparented). Bug fixes uncovered in this sub-commit: - SingleInstance.acquireOrForward: probe-first, then removeServer + retry-listen. The original loop-with-removeServer-after-failed-bind silently exited on stale sockets from prior runs. - Main.qml: MercureClient does NOT inherit BackendConnection.token — Mercure subscribes anonymously in dev (Caddyfile), and forwarding the bridge bearer made it 401-loop. - /api/ping was 500ing because the dev MERCURE_JWT_SECRET was 144 bits; bumped to 64-char (>=256 bit) to satisfy lcobucci/jwt. - Linked the framework lib (php_qml_bridge) explicitly in addition to the QML plugin so SingleInstance.h resolves. - Auto-generated config/reference.php gitignored. Smoke verified offscreen: /healthz 200, /api/ping 200, 1 publish, 1 subscriber, zero 401s, clean shutdown with no zombies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:50:16 +02:00
SYMFONY_DIR := symfony
QML_SRC_DIR := qml
BUILD_DIR := build/qml
QT_BIN := $(BUILD_DIR)/skeleton
skeleton: bring AppImage parity, scaffolded apps inherit the packaging flow The v0.1.0 shakedown fixes for AppImage assembly (path-repo symlink:false sed, writable-cache redirect) all landed in examples/todo. The skeleton — which is what bin/php-qml-init copies when scaffolding a new app — had no `appimage` target at all, so every scaffolded app would have to either copy the example's Makefile by hand or re-discover the same shakedown bugs. Brings parity: - framework/skeleton/Makefile gains `staging-symfony` and `appimage` targets, mirroring the example's. Two new variables (BUNDLE_SRC, PACKAGING) parameterise the framework-tree paths so bin/php-qml-init can rewrite them at scaffold time without sed-touching the recipe. - framework/skeleton/packaging/skeleton.{desktop,png} added — minimum surface for the AppImage assembly to succeed without the user needing to author them. - framework/skeleton/Makefile's staging-symfony recipe handles both relative (framework default `../../php`) and absolute (post-scaffold) BUNDLE_SRC values via a case statement. - bin/php-qml-init renames packaging/skeleton.* → packaging/$NAME.*, rewrites the .desktop file's Name/Exec/Icon, and updates the Makefile's --app-name / --output / --desktop / --icon flags + BUNDLE_SRC + PACKAGING variables. For --vendor mode, framework's packaging/linux/ is also vendored to .bridge-packaging/ alongside the existing .bridge/ + .bridge-qml/. Verified by scaffolding both modes: - non-vendored: BUNDLE_SRC + PACKAGING absolute paths - --vendor: BUNDLE_SRC=../.bridge, PACKAGING=.bridge-packaging, .bridge-packaging/ contains build-appimage.sh Skeleton's `make quality` still green; staging-symfony works locally (vendor/php-qml/bridge resolves to a real directory, not a symlink). Closes the v0.1.1 follow-up "bin/php-qml-init parity" tracked in PLAN.md §13. Bundled drive-by: docs/makers.md picked up two markdownlint auto-fixes (blank lines around lists) when the IDE saved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:43:48 +02:00
# Path to framework/php (path-repo source) and packaging/linux (build-appimage.sh).
# Both are framework-tree relative; bin/php-qml-init rewrites them at scaffold time
# to either an absolute framework path (default) or a vendored copy under .bridge/.
BUNDLE_SRC := ../../php
PACKAGING := ../../packaging/linux
Phase 1 sub-commit 6: skeleton wiring — make dev runs end-to-end Symfony app under framework/skeleton/symfony/: minimal bin/console, public/index.php, MicroKernel-based src/Kernel.php, services.yaml, framework/security/mercure config, and a demo App\Controller\PingController that GETs /api/ping (returning JSON pong) and republishes the same payload to the Mercure topic app://ping. composer.json uses a path repository to symlink the bundle from ../../php so local edits are picked up live. QML app under framework/skeleton/qml/: top-level CMake that add_subdirectory's framework/qml, a main.cpp that creates the Qt process, runs SingleInstance.acquireOrForward before any QML loads, exposes SingleInstance via context property, and loadFromModule's Skeleton.Main. Main.qml uses BackendConnection / RestClient / MercureClient from PhpQml.Bridge and renders status dots, a Ping button, and an event log. Caddyfile binds 127.0.0.1:8765, enables in-memory Mercure with a 256-bit dev JWT (matches symfony/.env, lcobucci/jwt requires this). Makefile wraps build / dev / doctor / clean; scripts/dev.sh starts FrankenPHP --watch and the Qt host together with explicit PID-based teardown (process-group `kill 0` proved unreliable when frankenphp's watch fork reparented). Bug fixes uncovered in this sub-commit: - SingleInstance.acquireOrForward: probe-first, then removeServer + retry-listen. The original loop-with-removeServer-after-failed-bind silently exited on stale sockets from prior runs. - Main.qml: MercureClient does NOT inherit BackendConnection.token — Mercure subscribes anonymously in dev (Caddyfile), and forwarding the bridge bearer made it 401-loop. - /api/ping was 500ing because the dev MERCURE_JWT_SECRET was 144 bits; bumped to 64-char (>=256 bit) to satisfy lcobucci/jwt. - Linked the framework lib (php_qml_bridge) explicitly in addition to the QML plugin so SingleInstance.h resolves. - Auto-generated config/reference.php gitignored. Smoke verified offscreen: /healthz 200, /api/ping 200, 1 publish, 1 subscriber, zero 401s, clean shutdown with no zombies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:50:16 +02:00
.PHONY: help
help: ## Show available targets
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-12s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
Phase 1 sub-commit 6: skeleton wiring — make dev runs end-to-end Symfony app under framework/skeleton/symfony/: minimal bin/console, public/index.php, MicroKernel-based src/Kernel.php, services.yaml, framework/security/mercure config, and a demo App\Controller\PingController that GETs /api/ping (returning JSON pong) and republishes the same payload to the Mercure topic app://ping. composer.json uses a path repository to symlink the bundle from ../../php so local edits are picked up live. QML app under framework/skeleton/qml/: top-level CMake that add_subdirectory's framework/qml, a main.cpp that creates the Qt process, runs SingleInstance.acquireOrForward before any QML loads, exposes SingleInstance via context property, and loadFromModule's Skeleton.Main. Main.qml uses BackendConnection / RestClient / MercureClient from PhpQml.Bridge and renders status dots, a Ping button, and an event log. Caddyfile binds 127.0.0.1:8765, enables in-memory Mercure with a 256-bit dev JWT (matches symfony/.env, lcobucci/jwt requires this). Makefile wraps build / dev / doctor / clean; scripts/dev.sh starts FrankenPHP --watch and the Qt host together with explicit PID-based teardown (process-group `kill 0` proved unreliable when frankenphp's watch fork reparented). Bug fixes uncovered in this sub-commit: - SingleInstance.acquireOrForward: probe-first, then removeServer + retry-listen. The original loop-with-removeServer-after-failed-bind silently exited on stale sockets from prior runs. - Main.qml: MercureClient does NOT inherit BackendConnection.token — Mercure subscribes anonymously in dev (Caddyfile), and forwarding the bridge bearer made it 401-loop. - /api/ping was 500ing because the dev MERCURE_JWT_SECRET was 144 bits; bumped to 64-char (>=256 bit) to satisfy lcobucci/jwt. - Linked the framework lib (php_qml_bridge) explicitly in addition to the QML plugin so SingleInstance.h resolves. - Auto-generated config/reference.php gitignored. Smoke verified offscreen: /healthz 200, /api/ping 200, 1 publish, 1 subscriber, zero 401s, clean shutdown with no zombies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:50:16 +02:00
.PHONY: install
install: ## Install Composer dependencies for the Symfony app
cd $(SYMFONY_DIR) && composer install
.PHONY: build
build: ## Build the Qt host
cmake -S $(QML_SRC_DIR) -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=Debug
cmake --build $(BUILD_DIR) --parallel
.PHONY: dev
Phase 1 sub-commit 6: skeleton wiring — make dev runs end-to-end Symfony app under framework/skeleton/symfony/: minimal bin/console, public/index.php, MicroKernel-based src/Kernel.php, services.yaml, framework/security/mercure config, and a demo App\Controller\PingController that GETs /api/ping (returning JSON pong) and republishes the same payload to the Mercure topic app://ping. composer.json uses a path repository to symlink the bundle from ../../php so local edits are picked up live. QML app under framework/skeleton/qml/: top-level CMake that add_subdirectory's framework/qml, a main.cpp that creates the Qt process, runs SingleInstance.acquireOrForward before any QML loads, exposes SingleInstance via context property, and loadFromModule's Skeleton.Main. Main.qml uses BackendConnection / RestClient / MercureClient from PhpQml.Bridge and renders status dots, a Ping button, and an event log. Caddyfile binds 127.0.0.1:8765, enables in-memory Mercure with a 256-bit dev JWT (matches symfony/.env, lcobucci/jwt requires this). Makefile wraps build / dev / doctor / clean; scripts/dev.sh starts FrankenPHP --watch and the Qt host together with explicit PID-based teardown (process-group `kill 0` proved unreliable when frankenphp's watch fork reparented). Bug fixes uncovered in this sub-commit: - SingleInstance.acquireOrForward: probe-first, then removeServer + retry-listen. The original loop-with-removeServer-after-failed-bind silently exited on stale sockets from prior runs. - Main.qml: MercureClient does NOT inherit BackendConnection.token — Mercure subscribes anonymously in dev (Caddyfile), and forwarding the bridge bearer made it 401-loop. - /api/ping was 500ing because the dev MERCURE_JWT_SECRET was 144 bits; bumped to 64-char (>=256 bit) to satisfy lcobucci/jwt. - Linked the framework lib (php_qml_bridge) explicitly in addition to the QML plugin so SingleInstance.h resolves. - Auto-generated config/reference.php gitignored. Smoke verified offscreen: /healthz 200, /api/ping 200, 1 publish, 1 subscriber, zero 401s, clean shutdown with no zombies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:50:16 +02:00
dev: build ## Run skeleton in dev mode (FrankenPHP --watch + Qt host)
./scripts/dev.sh
.PHONY: doctor
Phase 1 sub-commit 6: skeleton wiring — make dev runs end-to-end Symfony app under framework/skeleton/symfony/: minimal bin/console, public/index.php, MicroKernel-based src/Kernel.php, services.yaml, framework/security/mercure config, and a demo App\Controller\PingController that GETs /api/ping (returning JSON pong) and republishes the same payload to the Mercure topic app://ping. composer.json uses a path repository to symlink the bundle from ../../php so local edits are picked up live. QML app under framework/skeleton/qml/: top-level CMake that add_subdirectory's framework/qml, a main.cpp that creates the Qt process, runs SingleInstance.acquireOrForward before any QML loads, exposes SingleInstance via context property, and loadFromModule's Skeleton.Main. Main.qml uses BackendConnection / RestClient / MercureClient from PhpQml.Bridge and renders status dots, a Ping button, and an event log. Caddyfile binds 127.0.0.1:8765, enables in-memory Mercure with a 256-bit dev JWT (matches symfony/.env, lcobucci/jwt requires this). Makefile wraps build / dev / doctor / clean; scripts/dev.sh starts FrankenPHP --watch and the Qt host together with explicit PID-based teardown (process-group `kill 0` proved unreliable when frankenphp's watch fork reparented). Bug fixes uncovered in this sub-commit: - SingleInstance.acquireOrForward: probe-first, then removeServer + retry-listen. The original loop-with-removeServer-after-failed-bind silently exited on stale sockets from prior runs. - Main.qml: MercureClient does NOT inherit BackendConnection.token — Mercure subscribes anonymously in dev (Caddyfile), and forwarding the bridge bearer made it 401-loop. - /api/ping was 500ing because the dev MERCURE_JWT_SECRET was 144 bits; bumped to 64-char (>=256 bit) to satisfy lcobucci/jwt. - Linked the framework lib (php_qml_bridge) explicitly in addition to the QML plugin so SingleInstance.h resolves. - Auto-generated config/reference.php gitignored. Smoke verified offscreen: /healthz 200, /api/ping 200, 1 publish, 1 subscriber, zero 401s, clean shutdown with no zombies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:50:16 +02:00
doctor: ## Run bridge:doctor inside the Symfony app
cd $(SYMFONY_DIR) && bin/console bridge:doctor
.PHONY: doctor-connect
doctor-connect: ## Run bridge:doctor with backend connectivity probe
cd $(SYMFONY_DIR) && bin/console bridge:doctor --connect
.PHONY: clean
clean: ## Remove build artefacts
skeleton: bring AppImage parity, scaffolded apps inherit the packaging flow The v0.1.0 shakedown fixes for AppImage assembly (path-repo symlink:false sed, writable-cache redirect) all landed in examples/todo. The skeleton — which is what bin/php-qml-init copies when scaffolding a new app — had no `appimage` target at all, so every scaffolded app would have to either copy the example's Makefile by hand or re-discover the same shakedown bugs. Brings parity: - framework/skeleton/Makefile gains `staging-symfony` and `appimage` targets, mirroring the example's. Two new variables (BUNDLE_SRC, PACKAGING) parameterise the framework-tree paths so bin/php-qml-init can rewrite them at scaffold time without sed-touching the recipe. - framework/skeleton/packaging/skeleton.{desktop,png} added — minimum surface for the AppImage assembly to succeed without the user needing to author them. - framework/skeleton/Makefile's staging-symfony recipe handles both relative (framework default `../../php`) and absolute (post-scaffold) BUNDLE_SRC values via a case statement. - bin/php-qml-init renames packaging/skeleton.* → packaging/$NAME.*, rewrites the .desktop file's Name/Exec/Icon, and updates the Makefile's --app-name / --output / --desktop / --icon flags + BUNDLE_SRC + PACKAGING variables. For --vendor mode, framework's packaging/linux/ is also vendored to .bridge-packaging/ alongside the existing .bridge/ + .bridge-qml/. Verified by scaffolding both modes: - non-vendored: BUNDLE_SRC + PACKAGING absolute paths - --vendor: BUNDLE_SRC=../.bridge, PACKAGING=.bridge-packaging, .bridge-packaging/ contains build-appimage.sh Skeleton's `make quality` still green; staging-symfony works locally (vendor/php-qml/bridge resolves to a real directory, not a symlink). Closes the v0.1.1 follow-up "bin/php-qml-init parity" tracked in PLAN.md §13. Bundled drive-by: docs/makers.md picked up two markdownlint auto-fixes (blank lines around lists) when the IDE saved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:43:48 +02:00
rm -rf $(BUILD_DIR) build/staging-symfony
.PHONY: staging-symfony
staging-symfony: ## Stage a --no-dev composer copy of symfony for AppImage assembly
# See examples/todo/Makefile for the rationale; same logic, mirrored here
# so scaffolded apps inherit a working AppImage flow without copy-paste.
# BUNDLE_SRC may be absolute (after `php-qml-init` rewrites it for a
# scaffolded app) or relative-to-symfony (framework default `../../php`);
# the case-statement handles both.
rm -rf build/staging-symfony
rsync -a --delete \
--exclude='vendor/' \
--exclude='var/cache/' --exclude='var/log/' \
$(SYMFONY_DIR)/ build/staging-symfony/
set -e; case "$(BUNDLE_SRC)" in \
/*) BUNDLE_ABS="$(BUNDLE_SRC)" ;; \
*) BUNDLE_ABS="$$(cd $(SYMFONY_DIR)/$(BUNDLE_SRC) && pwd)" ;; \
esac; \
sed -i "s|\"$(BUNDLE_SRC)\"|\"$$BUNDLE_ABS\"|" build/staging-symfony/composer.json
sed -i 's|"symlink": true|"symlink": false|' build/staging-symfony/composer.json
rm -f build/staging-symfony/composer.lock
cd build/staging-symfony && composer install --no-dev --no-interaction --classmap-authoritative
.PHONY: appimage
appimage: build staging-symfony ## Package as a single-file Linux AppImage at build/Skeleton-x86_64.AppImage
$(PACKAGING)/build-appimage.sh \
--app-name skeleton \
--host-binary $(QT_BIN) \
--symfony-dir build/staging-symfony \
--frankenphp $${FRANKENPHP:-frankenphp} \
--caddyfile Caddyfile \
--desktop packaging/skeleton.desktop \
--icon packaging/skeleton.png \
--output build/Skeleton-x86_64.AppImage \
$${APPIMAGE_UPDATE_INFO:+--update-info "$$APPIMAGE_UPDATE_INFO"}
@echo
@echo "AppImage built. Test with: ./build/Skeleton-x86_64.AppImage"
.PHONY: quality
v0.2.0 (13/N): qmltestrunner harness + CI wiring + close out v0.2.0 plan Closes the testing-strategy row of PLAN.md §13 v0.2.0 and parks the two remaining items with rationales. Shipped: - framework/qml/tests/{CMakeLists.txt, main.cpp, tst_smoke.qml} Qt Quick Test scaffold: QUICK_TEST_MAIN bootstrap + one smoke test proving the harness loads. New tests land as tst_<feature>.qml in the same dir; qmltestrunner auto-discovers them. Built only when -DBUILD_TESTING=ON (production AppImages stay clean). - skeleton + example/todo Makefiles: `make qmltest` target invokes the configure → build → ctest dance. `make quality` now depends on qmltest. - .gitea/workflows/ci.yml: `QML unit tests` step after qmllint in the Quality job. Out-of-tree build dir (build-tests) so the CTest run doesn't pollute the cached release build. Verified locally: configure + build + ctest pass, both smoke assertions pass, runs in 0.5s. Closed in PLAN.md §13 v0.2.0 with rationale (no code change): - Build-time Symfony cache warmup → moved to v0.3.0. The obvious approach (cache:warmup at build, copy at first launch) doesn't save any time because Symfony bakes absolute kernel.project_dir into the compiled cache, and the AppImage's FUSE mount path changes every launch — every cached path is stale on launch N+1. Doing it properly requires virtualising getProjectDir(), symlink fix-up, multi-app namespacing — its own minor's worth of design. - ReactiveObject cursor pagination → closed N/A. ReactiveObject already has pending / invoke() / Idempotency-Key correlation / version-gap detection at parity with ReactiveListModel; the only feature it lacks is *pagination*, which is meaningless for a single-entity model. That fully closes the v0.2.0 plan as documented. Remaining v0.2.0 items in PLAN.md §13 are the audit-ends already shipped earlier in the cycle (interfaces / BridgeOp / BridgeBundleInfo / Maker DRY / --with-dto / port negotiation / pre-migration backup / bridge:export / periodic auto-update / native-dialogs doc / event maker / read-model maker / qmltestrunner) plus the two parked items documented above. Ready to tag when the user gives the word. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 21:02:30 +02:00
quality: build qmltest ## Run PHPStan, php-cs-fixer (check), PHPUnit, qmllint, qmltest, maker snapshots
cd ../php && composer quality
cmake --build $(BUILD_DIR) --target all_qmllint
Phase 3 sub-commit 5: maker-output snapshot test + phase closure framework/php/tests/snapshot/ holds reference output for every shipped maker (resource Todo, command MarkAllDone, window Todo). The run.sh script: - git-archives the skeleton into a temp dir - composer-installs against the bundle's real path - removes the existing maker outputs so the regenerators don't bail - runs the three makers - diffs each generated file against the matching baseline CI / make quality fail on any drift; if a template change is intended, the baselines must be regenerated in the same commit. Wired into: - framework/skeleton/Makefile's `quality` target (local/dev runs) - .gitea/workflows/ci.yml (CI runs after qmllint) Plus a few hardenings discovered while wiring this up: - The resource maker template now injects NormalizerInterface (not SerializerInterface — that interface lacks ::normalize()). All Todo controllers re-rendered to match. - The command maker template emits a $this->em->flush() so the injected EntityManager isn't a property.onlyWritten violation in PHPStan after the user fills in the body. - phpstan.neon and php-cs-fixer's Finder both exclude tests/snapshot so the baselines aren't auto-rewritten or analysed as live code. CI workflow now also installs FrankenPHP, builds the todo example, and runs the bridge-integration test from Phase 3 sub-commit 4. Phase 3 done. Outstanding follow-ups (deferred per spec): the qmltestrunner-driven QML unit tests, make:bridge:event, make:bridge:read-model, ReactiveObject pagination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:03:41 +02:00
../php/tests/snapshot/run.sh
v0.2.0 (13/N): qmltestrunner harness + CI wiring + close out v0.2.0 plan Closes the testing-strategy row of PLAN.md §13 v0.2.0 and parks the two remaining items with rationales. Shipped: - framework/qml/tests/{CMakeLists.txt, main.cpp, tst_smoke.qml} Qt Quick Test scaffold: QUICK_TEST_MAIN bootstrap + one smoke test proving the harness loads. New tests land as tst_<feature>.qml in the same dir; qmltestrunner auto-discovers them. Built only when -DBUILD_TESTING=ON (production AppImages stay clean). - skeleton + example/todo Makefiles: `make qmltest` target invokes the configure → build → ctest dance. `make quality` now depends on qmltest. - .gitea/workflows/ci.yml: `QML unit tests` step after qmllint in the Quality job. Out-of-tree build dir (build-tests) so the CTest run doesn't pollute the cached release build. Verified locally: configure + build + ctest pass, both smoke assertions pass, runs in 0.5s. Closed in PLAN.md §13 v0.2.0 with rationale (no code change): - Build-time Symfony cache warmup → moved to v0.3.0. The obvious approach (cache:warmup at build, copy at first launch) doesn't save any time because Symfony bakes absolute kernel.project_dir into the compiled cache, and the AppImage's FUSE mount path changes every launch — every cached path is stale on launch N+1. Doing it properly requires virtualising getProjectDir(), symlink fix-up, multi-app namespacing — its own minor's worth of design. - ReactiveObject cursor pagination → closed N/A. ReactiveObject already has pending / invoke() / Idempotency-Key correlation / version-gap detection at parity with ReactiveListModel; the only feature it lacks is *pagination*, which is meaningless for a single-entity model. That fully closes the v0.2.0 plan as documented. Remaining v0.2.0 items in PLAN.md §13 are the audit-ends already shipped earlier in the cycle (interfaces / BridgeOp / BridgeBundleInfo / Maker DRY / --with-dto / port negotiation / pre-migration backup / bridge:export / periodic auto-update / native-dialogs doc / event maker / read-model maker / qmltestrunner) plus the two parked items documented above. Ready to tag when the user gives the word. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 21:02:30 +02:00
.PHONY: qmltest
qmltest: ## Run QML unit tests (Qt::QuickTest via qmltestrunner)
cmake -S ../qml -B ../qml/build-tests -DBUILD_TESTING=ON
cmake --build ../qml/build-tests --target qml_unit_tests --parallel
QT_QPA_PLATFORM=offscreen ctest --test-dir ../qml/build-tests --output-on-failure -R qml_unit_tests