diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 2da46d8..3cd3abc 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -17,8 +17,8 @@ Keep it updated as platform paths move to shared CMake targets. | Android standard | `android/android/build.gradle`, `android/android/CMakeLists.txt` | Retained native library target `native-lib`; CMake 3.10/C++23 baseline now links the standard arm64 package path with modern component/service sources and the generated `nanort` overlay helper | | Android Quest | `android/quest/build.gradle`, `android/quest/CMakeLists.txt` | OVR SDK imported libraries; CMake 3.10/C++23 baseline and current Yoga source list configure with the shared Android package compatibility helper | | Android Focus/Wave | `android/focus/build.gradle`, `android/focus/CMakeLists.txt` | Wave SDK imported libraries; CMake 3.10/C++23 baseline and current Yoga source list configure with the shared Android package compatibility helper | -| Linux | `linux/CMakeLists.txt` | Old CMake 3.4, C++14 flag | -| WebGL/Emscripten | `webgl/CMakeLists.txt` | Old CMake 3.4, WebGL2 flags | +| Linux | `linux/CMakeLists.txt` | Retained app target now uses CMake 3.10 and target-level C++23 while package/root target migration remains open | +| WebGL/Emscripten | `webgl/CMakeLists.txt` | Retained WebGL app target now uses CMake 3.10 and target-level C++23 with retained WebGL2/Emscripten link flags | ## Existing Version Generation @@ -211,6 +211,11 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p `panopainter_platform_build_apple_remote`. These targets call the existing platform automation scripts from CMake and keep platform validation discoverable from the CMake target graph while app/package target migration remains open. +- Retained Linux and WebGL app CMake entrypoints are still separate from root + CMake, but now share the modernization baseline of CMake 3.10 and + target-level `cxx_std_23`. `panopainter_retained_platform_cmake_self_test` + guards those baselines until these entrypoints are replaced by shared root + CMake package/app targets. - Root CMake exposes named `fuzz` and `stress` CTest presets. `fuzz` currently runs deterministic parser/serializer edge tests for binary streams, image metadata, PPI, stroke scripts, and layout XML; `stress` currently runs the diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 2458938..91f63a9 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -264,6 +264,11 @@ agent or engineer to remove them without reconstructing context from chat. and CMake `4.1.2` as `already-latest-available`; root Android `pp_assets`, retained standard `native-lib`, and retained Quest/Focus configure gates pass with that pair. +- 2026-06-05: DEBT-0004 was narrowed. Retained Linux and WebGL app CMake files + now require CMake 3.10 and use target-level `cxx_std_23` with extensions off + instead of global C++14 flags. `panopainter_retained_platform_cmake_self_test` + guards those baselines while root CMake app/package target migration remains + open. - 2026-06-05: DEBT-0011 was narrowed again. `package-smoke.ps1` now has `-AndroidNativeChecks`, which invokes the retained Android standard `native-lib` build and Quest/Focus configure helper for selected Android @@ -312,7 +317,7 @@ agent or engineer to remove them without reconstructing context from chat. | DEBT-0001 | Open | Modernization | Existing platform build files remain alongside new CMake | Required for incremental migration without losing platform coverage | Existing platform builds plus new CMake configure | Remove after all platform builds consume shared CMake targets | | DEBT-0002 | Open | Modernization | Vendored SDK and patched libraries retained initially, including the generated Android package `nanort` compatibility overlay tracked by DEBT-0060 | Some dependencies are SDK-only, patched, or have platform-specific binaries | Dependency inventory and platform build smoke tests | Replace with vcpkg packages or document permanent vendored status after triplet evaluation | | DEBT-0003 | Open | Modernization | Existing singletons remain during initial split; `App::open_document`, `App::request_close`, `App::share_file`, `App::cloud_upload`, `App::cloud_upload_all`, `App::cloud_browse`, `App::rec_start`, `App::rec_stop`, `App::rec_clear`, `App::rec_export`, `App::rec_loop`, `App::update_ui_observer`, `App::render_task*`, `App::ui_task*`, `App::render_thread_*`, `App::ui_thread_*`, file-menu save actions, `NodeCanvas` canvas hotkeys, new/open/browse dirty-document workflow prompts, new-document target/resolution/overwrite decisions, save-as document file naming and overwrite decisions, save-version target decisions, export start/menu/target naming/path/message/report decisions, share-file saved-path decisions, file/image/save/directory picker selected-path decisions, display-file external-open decisions, virtual-keyboard visibility decisions, recording lifecycle/export progress/worker decisions, cloud-upload prompt/save-before-upload decisions, cloud-browse availability and selected-download decisions, bulk cloud-upload progress decisions, tools/options app preference decisions, app status/display and renderer diagnostic decisions, app dialog metadata decisions, app frame/UI-observer decisions, app thread/task orchestration decisions, document resize decisions, layer rename/menu decisions, Tools menu/panel decisions, About menu/diagnostic decisions, main toolbar/status decisions, `pano_cli classify-open`, `pano_cli plan-open-route`, `pano_cli plan-file-menu`, `pano_cli plan-new-document`, `pano_cli plan-document-file`, `pano_cli plan-document-version`, `pano_cli plan-export-start`, `pano_cli plan-export-menu`, `pano_cli plan-export-target`, `pano_cli plan-export-message`, `pano_cli plan-export-report`, `pano_cli plan-recording-session`, `pano_cli plan-app-preferences`, `pano_cli plan-app-status`, `pano_cli plan-app-dialog`, `pano_cli plan-app-thread`, `pano_cli plan-tools-menu`, `pano_cli plan-tools-panel`, `pano_cli plan-about-menu`, `pano_cli plan-main-toolbar`, `pano_cli plan-document-resize`, `pano_cli plan-layer-rename`, `pano_cli plan-layer-menu`, `pano_cli plan-canvas-hotkey`, `pano_cli plan-share-file`, `pano_cli plan-picked-path`, `pano_cli plan-display-file`, `pano_cli plan-keyboard-visibility`, `pano_cli plan-cloud-upload`, `pano_cli plan-cloud-browse`, `pano_cli plan-cloud-upload-all`, and `pano_cli simulate-app-session` now consume pure `pp_app_core` route/session/export/recording/preferences/status/dialog/thread/share/platform-I/O/display/keyboard/cloud/resize/layer/tools/about/toolbar/canvas-command contracts, but document creation/loading, brush import execution, saving, export execution, tools/options UI execution, Tools panel creation/execution, About dialog/diagnostic execution, toolbar/status dialog/history/canvas execution, app dialog node creation, status/display UI rendering, renderer diagnostic capability adaptation, app task/thread execution, UI observer parent walking/callback execution, document resize execution, layer rename/menu execution, settings persistence, platform share service execution, picker service execution, display-file service execution, keyboard service execution, recording/MP4/PBO execution, cloud upload execution, and cloud browse/download execution still reach legacy `Canvas::I`/UI/network/video/platform singletons | Avoid behavior changes while introducing component boundaries | App launch and component tests; `pp_app_core_document_route_tests`; `pp_app_core_file_menu_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_recording_tests`; `pp_app_core_app_frame_tests`; `pp_app_core_app_preferences_tests`; `pp_app_core_app_status_tests`; `pp_app_core_app_dialog_tests`; `pp_app_core_app_thread_tests`; `pp_app_core_tools_menu_tests`; `pp_app_core_about_menu_tests`; `pp_app_core_main_toolbar_tests`; `pp_app_core_document_resize_tests`; `pp_app_core_document_layer_tests`; `pp_app_core_document_sharing_tests`; `pp_app_core_document_platform_io_tests`; `pp_app_core_document_cloud_tests`; `pp_app_core_document_session_tests`; `pp_app_core_canvas_hotkey_tests`; `pano_cli classify-open --path D:/Paint/demo.ppi`; `pano_cli plan-open-route --path D:/Paint/demo.ppi --unsaved`; `pano_cli plan-file-menu --command save-as`; `pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3 --target-exists`; `pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists`; `pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi`; `pano_cli plan-export-start --requires-license --demo`; `pano_cli plan-export-menu --kind animation-mp4 --demo`; `pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png`; `pano_cli plan-export-message --kind timelapse --destination success`; `pano_cli plan-export-report --kind license-disabled`; `pano_cli plan-recording-session --running --frame-count 12`; `pano_cli plan-recording-session --running --no-encoder`; `pano_cli plan-app-preferences --ui-scale 1.5 --display-density 2 --current-scale 1.6 --scale-option 1 --scale-option 1.5 --rtl`; `pano_cli plan-app-status --doc-name demo --unsaved --resolution 2048 --resolution-index 3 --zoom 1.25 --history-bytes 1572864 --recording-running --encoder-available --encoded-frames 12 --framebuffer-fetch --float32 --float32-linear --float16`; `pano_cli plan-app-dialog --kind message --cancel`; `pano_cli plan-app-frame`; `pano_cli plan-app-thread --kind ui-loop --live-reload`; `pano_cli plan-tools-menu --command shortcuts`; `pano_cli plan-tools-panel --panel layers`; `pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7`; `pano_cli plan-main-toolbar --command undo --undo-count 2`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint`; `pano_cli plan-canvas-hotkey --event key-up --key z --ctrl --undo-count 2`; `pano_cli plan-share-file --path D:/Paint/demo.ppi`; `pano_cli plan-picked-path --path D:/Paint/demo.ppi`; `pano_cli plan-display-file --path D:/Paint/export.png`; `pano_cli plan-keyboard-visibility --visible`; `pano_cli plan-cloud-upload --new-document --unsaved`; `pano_cli plan-cloud-browse --selected-file demo.ppi`; `pano_cli plan-cloud-upload-all --file-count 3`; `pano_cli simulate-app-session --unsaved --save-intent save-dirty-version`; `pano_cli simulate-app-session --no-canvas`; `ctest --preset desktop-fast --build-config Debug` | Replace singleton reaches with context/service injection at component boundaries | -| DEBT-0004 | Open | Modernization | Android, Linux, WebGL, Apple, and AppX build files remain platform-specific until root CMake alignment reaches them | Prevent platform regressions during incremental migration; raw Windows `.sln/.vcxproj` files were removed on 2026-05-31 by user decision | `cmake --preset windows-msvc-default`; platform-specific configure/build smoke checks as each platform is migrated | Root CMake owns every platform source list and package path | +| DEBT-0004 | Open | Modernization | Android, Linux, and WebGL retained CMake entrypoints now use the CMake 3.10/C++23 modernization baseline, but Android Gradle/APK, Linux app, WebGL app/package, Apple, and AppX build files remain platform-specific until root CMake alignment reaches them | Prevent platform regressions during incremental migration; raw Windows `.sln/.vcxproj` files were removed on 2026-05-31 by user decision | `cmake --preset windows-msvc-default`; `python scripts/dev/check_retained_platform_cmake.py`; platform-specific configure/build smoke checks as each platform is migrated | Root CMake owns every platform source list and package path | | DEBT-0005 | Open | Modernization | Temporary local CTest harness is used before Catch2 is wired through vcpkg | `vcpkg` is not currently on PATH, but headless tests need to run now | `ctest --preset desktop-fast --build-config Debug` | Replace `tests/test_harness.h` tests with Catch2 tests once vcpkg toolchain/presets are validated | | DEBT-0007 | Open | Modernization | `vcpkg.json` and `windows-msvc-vcpkg-headless` are validated for the headless Windows component matrix, and root CMake now exposes a focused `panopainter_platform_build_vcpkg_ui_core` target for the vcpkg-backed `pp_ui_core`/tinyxml2 boundary, but app targets still use vendored libraries and Android/Apple triplets are not proven | Dependency migration must stay incremental while SDK/patched/vendor dependencies remain in use | `cmake --preset windows-msvc-vcpkg-headless`; `ctest --preset desktop-fast-vcpkg --build-config Debug`; `cmake --build --preset windows-msvc-default --config Debug --target panopainter_platform_build_vcpkg_ui_core` | Component targets consume vcpkg packages where reliable and desktop app, Android, and Apple triplets are validated or explicitly documented as permanent vendor exceptions | | DEBT-0008 | Open | Modernization | `windows-msvc-default` preset is used for local validation because the VS 2026 generator is not installed here | The target VS 2026 preset must remain, but this machine configures with Visual Studio 17 2022 | `cmake --preset windows-msvc-default`; `ctest --preset desktop-fast --build-config Debug` | Validate `windows-vs2026-x64` on a machine with Visual Studio 2026 installed and make it the default Windows validation preset | diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index b7f25e5..4576113 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -1412,6 +1412,11 @@ checks: `panopainter_package_readiness`, `panopainter_android_native_package_smoke`. App/package entrypoints still need to consume shared targets and remain covered by debt until package validation is migrated from legacy package projects to root CMake. +Retained Linux and WebGL app CMake entrypoints now match the interim platform +baseline used by Android package paths: CMake 3.10 plus target-level +`cxx_std_23`, with `panopainter_retained_platform_cmake_self_test` guarding +against regressions while those entrypoints wait behind root CMake package/app +target migration. Apple compile validation now runs on the local Mac mini SSH host `panopainter-mac` through `scripts/automation/apple-remote-build.ps1`. The host uses Homebrew CMake/Ninja/Git plus full Xcode via `DEVELOPER_DIR`, pulls the @@ -2413,6 +2418,11 @@ Results: panopainter_windows_app_package_smoke`, which builds the CMake `PanoPainter` app target, validates the executable/runtime `data/` copy, and reports the still-blocked Windows AppX package state. +- Retained Linux and WebGL app CMake files now use CMake 3.10 and target-level + C++23 instead of global C++14 flags; `python + scripts/dev/check_retained_platform_cmake.py` and CTest + `panopainter_retained_platform_cmake_self_test` guard those baselines while + the actual Linux/WebGL app/package targets remain outside root CMake. - Root CMake now exposes platform validation targets for the default headless platform-build sweep, the Android standard/Quest/Focus root CMake asset component sweep, the vcpkg-backed UI core dependency boundary, and the diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index abb98ee..cd34727 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -1,7 +1,5 @@ -cmake_minimum_required(VERSION 3.4.1) -project(panopainter) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +cmake_minimum_required(VERSION 3.10) +project(PanoPainterLinux LANGUAGES C CXX) add_executable(panopainter src/main.cpp @@ -120,4 +118,7 @@ target_include_directories(panopainter PRIVATE ) target_link_libraries(panopainter glfw curl GL dl X11 pthread) +target_compile_features(panopainter PRIVATE cxx_std_23) +set_target_properties(panopainter PROPERTIES + CXX_EXTENSIONS OFF) target_compile_definitions(panopainter PUBLIC "$<$:_DEBUG>") diff --git a/scripts/dev/check_retained_platform_cmake.py b/scripts/dev/check_retained_platform_cmake.py new file mode 100644 index 0000000..2e4cb0d --- /dev/null +++ b/scripts/dev/check_retained_platform_cmake.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +"""Guard retained non-root platform CMake files during Phase 6 migration.""" + +from __future__ import annotations + +import json +import re +import sys +from pathlib import Path + + +RETAINED_PLATFORM_CMAKE = [ + Path("linux/CMakeLists.txt"), + Path("webgl/CMakeLists.txt"), +] + + +def repo_root() -> Path: + return Path(__file__).resolve().parents[2] + + +def cmake_minimum_version(text: str) -> tuple[int, ...] | None: + match = re.search(r"cmake_minimum_required\s*\(\s*VERSION\s+([0-9.]+)", text, re.I) + if not match: + return None + return tuple(int(part) for part in match.group(1).split(".")) + + +def main() -> int: + root = repo_root() + results: dict[str, object] = {} + ok = True + + for path in RETAINED_PLATFORM_CMAKE: + text = (root / path).read_text(encoding="utf-8") + minimum_version = cmake_minimum_version(text) + has_target_cxx23 = "target_compile_features(panopainter PRIVATE cxx_std_23)" in text + has_cxx_extensions_off = "CXX_EXTENSIONS OFF" in text + uses_global_cxx_standard_flag = bool(re.search(r"-std=c\+\+14|-std=c\+\+17|-std=c\+\+20", text)) + platform_ok = ( + minimum_version is not None + and minimum_version >= (3, 10) + and has_target_cxx23 + and has_cxx_extensions_off + and not uses_global_cxx_standard_flag + ) + ok = ok and platform_ok + results[str(path)] = { + "ok": platform_ok, + "minimumVersion": ".".join(str(part) for part in minimum_version) if minimum_version else None, + "hasTargetCxx23": has_target_cxx23, + "hasCxxExtensionsOff": has_cxx_extensions_off, + "usesGlobalCxxStandardFlag": uses_global_cxx_standard_flag, + } + + print(json.dumps({"ok": ok, "platforms": results}, separators=(",", ":"))) + return 0 if ok else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 937b487..d25f221 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,6 +15,11 @@ add_test(NAME panopainter_package_smoke_readiness_self_test set_tests_properties(panopainter_package_smoke_readiness_self_test PROPERTIES LABELS "tooling;desktop-fast") +add_test(NAME panopainter_retained_platform_cmake_self_test + COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/dev/check_retained_platform_cmake.py") +set_tests_properties(panopainter_retained_platform_cmake_self_test PROPERTIES + LABELS "tooling;desktop-fast") + add_library(pp_test_harness INTERFACE) target_include_directories(pp_test_harness INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/webgl/CMakeLists.txt b/webgl/CMakeLists.txt index 5b39cd4..c121197 100644 --- a/webgl/CMakeLists.txt +++ b/webgl/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.4.1) -project(panopainter) +cmake_minimum_required(VERSION 3.10) +project(PanoPainterWebGL LANGUAGES C CXX) file(COPY ../data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) add_executable(panopainter @@ -103,8 +103,10 @@ add_executable(panopainter ../src/node_shorcuts.cpp ../src/node_metadata.cpp ) -target_compile_options(panopainter PRIVATE -std=c++14 -O3) +target_compile_options(panopainter PRIVATE -O3) +target_compile_features(panopainter PRIVATE cxx_std_23) set_target_properties(panopainter PROPERTIES + CXX_EXTENSIONS OFF SUFFIX ".html" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/html" LINK_FLAGS "\