Files
panopainter/docs/modernization/build-inventory.md

370 lines
23 KiB
Markdown

# Build And Platform Inventory
Status: live
Last updated: 2026-06-02
This inventory records the known build surfaces during the CMake migration.
Keep it updated as platform paths move to shared CMake targets.
## Existing Build Entrypoints
| Platform/Target | Current Entrypoint | Notes |
| --- | --- | --- |
| Windows desktop | Root `CMakeLists.txt`, preset `windows-msvc-default`; target preset `windows-vs2026-x64` retained for VS 2026 | Raw `.sln/.vcxproj` files removed on 2026-05-31; local machine currently uses Visual Studio 17 2022 |
| Windows AppX | `PanoPainterPackage/Package.appxmanifest`, `.wapproj` referenced by solution | Distribution packaging |
| macOS | `PanoPainter-OSX/` project files and `Info.plist` | Uses `NSOpenGLView` today |
| iOS | `PanoPainter/Info.plist`, related Apple sources | Uses OpenGL ES today |
| Android standard | `android/android/build.gradle`, `android/android/CMakeLists.txt` | Native library target `native-lib` |
| Android Quest | `android/quest/build.gradle`, `android/quest/CMakeLists.txt` | OVR SDK imported libraries |
| Android Focus/Wave | `android/focus/build.gradle`, `android/focus/CMakeLists.txt` | Wave SDK imported libraries |
| Linux | `linux/CMakeLists.txt` | Old CMake 3.4, C++14 flag |
| WebGL/Emscripten | `webgl/CMakeLists.txt` | Old CMake 3.4, WebGL2 flags |
## Existing Version Generation
- Script: `scripts/pre-build.py`
- Output: `src/version.gen.h`
- Current behavior: derives version from git branch, latest tag, short hash,
commit count, and configuration argument.
- Migration requirement: root CMake should call this script through a custom
command and avoid unnecessary tracked-file churn where possible.
## Existing Dependency Sources
Hybrid policy: migrate reliable packages to vcpkg and retain SDK/patched
dependencies until each platform triplet is proven.
| Dependency | Current Source | Initial Policy |
| --- | --- | --- |
| fmt | `libs/fmt` | Move to vcpkg |
| GLM | `libs/glm` | Move to vcpkg |
| tinyxml2 | `libs/tinyxml2` | Move to vcpkg |
| stb | `libs/stb` | Move to vcpkg or interface target if package friction |
| CURL | `libs/curl-win`, `libs/curl-android-ios` | Move to vcpkg where triplets work |
| SQLite | `libs/sqlite3` | Move to vcpkg |
| GLAD | `libs/glad` | Move to vcpkg or generated backend target |
| Catch2 | none yet | Add through vcpkg |
| OpenVR | `libs/openvr` | Retain initially |
| OVR Platform/Mobile | `libs/ovr_platform`, `libs/ovr_mobile` | Retain initially |
| Wave SDK | `libs/wave_sdk` | Retain initially |
| Wacom WinTab | `libs/wacom` | Retain initially |
| AppCenter Apple | `libs/appcenter-apple` | Retain initially |
| openh264/mp4v2/libyuv | `libs/openh264`, `libs/mp4v2`, `libs/libyuv` | Retain initially |
| jpeg helpers | `libs/jpeg` | Evaluate after image tests exist |
| poly2tri/nanort/base64/hash-library | `libs/*` | Evaluate after component split |
## Current Validation Commands
These commands are the current local baseline.
```powershell
cmake --preset windows-msvc-default
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter
ctest --preset desktop-fast --build-config Debug
ctest --preset fuzz --build-config Debug
ctest --preset stress --build-config Debug
powershell -ExecutionPolicy Bypass -File scripts\automation\test.ps1 -Preset desktop-fast -Configuration Debug
powershell -ExecutionPolicy Bypass -File scripts\automation\build.ps1 -Preset windows-msvc-default -Configuration Debug -Target pano_cli
cmake --build --preset windows-msvc-default --target panopainter_validate_shaders
powershell -ExecutionPolicy Bypass -File scripts\automation\analyze.ps1 -Preset windows-msvc-default -NoApp
$env:VCPKG_ROOT = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg"
cmake --preset windows-msvc-vcpkg-headless
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets windows-msvc-vcpkg-headless
ctest --preset desktop-fast-vcpkg --build-config Debug
cmake --preset android-arm64
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug
cmake --fresh --preset windows-clangcl-asan
```
Known local toolchain state:
- CMake: 4.0.0-rc4
- Local Visual Studio generator selected by CMake: Visual Studio 17 2022
- Bundled vcpkg: `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg`
(`vcpkg version` reports 2025-11-19)
- Android SDK: `C:\Users\omara\AppData\Local\Android\Sdk`
- Android NDK: `C:\Users\omara\AppData\Local\Android\Sdk\ndk\29.0.14206865`
- clang-cl: `C:\Program Files\LLVM\bin\clang-cl.exe` reports 18.1.8, but the
selected VS 2026-preview STL expects Clang 20 or newer; see DEBT-0014 before
treating `windows-clangcl-asan` as a passing sanitizer gate.
- Android arm64 headless configure/build passes through root CMake and the
`platform-build` automation wrapper for `pp_foundation`, `pp_assets`,
`pp_paint`, `pp_document`, `pp_renderer_api`, `pp_renderer_gl`,
`pp_paint_renderer`,
`pp_ui_core`, `pano_cli`, and their current headless test binaries,
including foundation binary-stream/event/logging/task queue coverage, PNG metadata and
decode, PPI header/layout/non-finite opacity and blend-mode rejection, settings document, document
snapshot/per-layer-frame/move/duration/face-pixel/PPI export coverage,
snapshot-embedded duplicate/invalid face-payload and selection-mask rejection, paint brush/final-blend/
stroke-alpha-blend/stroke spacing/stroke stress/stroke-script coverage,
renderer shader descriptor and OpenGL capability coverage, UI
color parsing, and layout XML parse coverage.
- 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
stroke sampler stress coverage.
- `pano_cli inspect-image` reports PNG IHDR metadata as JSON and is covered by
`pano_cli_inspect_png_metadata_smoke` with a tiny IHDR fixture.
- `pp_assets_image_pixels_tests` decodes PNG payloads, encodes RGBA8 pixels to
PNG, round-trips encoded pixels back through the decoder, and rejects corrupt
or malformed image payloads.
- `pano_cli import-image` accepts a PNG path, decodes RGBA8 pixels through
`pp_assets`, attaches them to a pure `pp_document` face payload, and is
covered for checked-in decodable PNG import by `pano_cli_import_image_smoke`
and metadata-valid truncated PNG rejection by
`pano_cli_import_image_rejects_truncated_png`.
- `pano_cli export-image` writes a deterministic RGBA8 PNG through `pp_assets`
and is covered by `pano_cli_export_image_roundtrip_smoke`, which imports the
generated file back through `pano_cli import-image`.
- `pano_cli inspect-project` reports validated PPI thumbnail/body byte layout,
body summary fields, layer/frame descriptors, and dirty-face PNG payload
metadata, and is covered by `pano_cli_inspect_project_layout_smoke` with a
minimal PPI fixture.
- `pp_document_ppi_import_tests` attaches decoded PPI dirty-face payloads to
`pp_document` layer/frame storage and rejects payloads outside document
layers.
- `pp_document_ppi_export_tests` exports pure `pp_document` metadata,
per-layer frame durations, and RGBA8 face payloads to PPI bytes through
`pp_assets`, then decodes and reimports them for round-trip coverage.
- `pano_cli simulate-document-export` exposes the same pure document-to-PPI
export, asset-level decode, and document reimport path through JSON
automation and is covered by `pano_cli_simulate_document_export_smoke`.
- `pano_cli save-document-project` writes that pure document export to a PPI
file and is covered by `pano_cli_save_document_project_roundtrip_smoke`,
which inspects and loads the generated file.
- `pano_cli load-project` creates a `pp_document` projection with per-layer
frame counts, durations, and decoded face-pixel payloads when present; the
metadata-only minimal fixture remains covered by
`pano_cli_load_project_metadata_smoke`.
- `pp_assets::create_ppi_project` writes generated multi-layer, multi-frame
PPI files with explicit per-layer names, opacity, blend mode, alpha lock,
visibility, per-layer frame durations, and targeted dirty-face layer/frame
payloads. `pano_cli save-project` exposes that path for automation and is
covered by `pano_cli_save_project_roundtrip_smoke` and
`pano_cli_save_project_payload_roundtrip_smoke`, which reload generated
metadata-only and targeted dirty-face-payload projects through
`pano_cli load-project`, plus
`pano_cli_save_project_rejects_non_finite_opacity`, which verifies rejected
automation floats do not create output files.
- `pano_cli create-document` supports `--frames` and `--frame-duration-ms` and
is covered by `pano_cli_create_animation_document_smoke`.
- `pano_cli simulate-document-edits` exercises pure document layer/frame edit
operations, renderer-free face payloads, and renderer-free selection masks,
and is covered by `pano_cli_simulate_document_edits_smoke`.
- `pano_cli simulate-document-history` exercises pure document history
apply/undo/redo behavior and is covered by
`pano_cli_simulate_document_history_smoke`.
- `pano_cli simulate-image-import` decodes an embedded tiny PNG through
`pp_assets`, attaches it to `pp_document`, and is covered by
`pano_cli_simulate_image_import_smoke`.
- `pano_cli simulate-blend` exposes deterministic final RGBA and stroke-alpha
blend reference vectors through JSON automation and is covered by
`pano_cli_simulate_blend_smoke`.
- `pano_cli simulate-stroke` exposes the pure stroke sampler for scripted
automation and is covered by `pano_cli_simulate_stroke_smoke`.
- `pano_cli simulate-stroke-script` loads a text stroke script fixture and is
covered by `pano_cli_simulate_stroke_script_smoke`.
- `pano_cli apply-stroke-script` parses a text stroke script fixture, samples
every stroke through `pp_paint`, maps the samples into a bounded
`pp_document` RGBA8 face payload, writes a PPI file, and is covered by
`pano_cli_apply_stroke_script_roundtrip_smoke`, which inspects the dirty-face
box and loads the generated file back as decoded document pixel data, plus
`pano_cli_apply_stroke_script_rejects_tiny_canvas` for invalid dimension
rejection.
- `panopainter_validate_shaders` validates the current combined GLSL shader
files for one vertex stage marker, one fragment stage marker, valid marker
order, and existing relative includes.
- `pp_renderer_api` owns the canonical PanoPainter shader catalog consumed by
the legacy OpenGL app initialization path; `pp_renderer_api_tests` validates
catalog size, key entries, duplicate rejection, and bad path rejection.
- `pp_renderer_gl` owns headless OpenGL runtime capability detection consumed
by the legacy app initialization path; `pp_renderer_gl_capabilities_tests`
validates framebuffer fetch, map-buffer alignment, desktop GL float support,
GLES float/half-float extensions, WebGL exclusion behavior, and the
upload-type mapping used by legacy `Texture2D` and `RTT` creation, plus the
RGBA pixel-format mapping used by `RTT` texture allocation. It also validates
image channel-count to OpenGL texture format mapping, including
invalid channel counts rejected by `Texture2D::create(Image)`, renderer API
texture-format to OpenGL internal/pixel/component token mapping including
depth-stencil formats, RGBA8/RGBA32F
readback formats, checked byte-count math, and PBO pixel-buffer target/usage/access
mapping used by `RTT` and `PBO` readbacks, and framebuffer status naming
used by `RTT` and `Texture2D` diagnostics. It also owns the 2D texture target,
framebuffer setup, readback format, mipmap target, and update component-type
tokens used by `Texture2D`, plus cube-map binding and allocation face targets
used by `TextureCube`. It also owns and
validates framebuffer blit color mask and linear/nearest filters used by
`RTT::resize` and `RTT::copy`, plus the default linear clamp-to-edge
render-target texture parameters, texture/renderbuffer targets, depth format,
framebuffer targets, binding queries, attachment points, and completion
status used by `RTT::create` and framebuffer bind/restore paths, plus RTT
clear color/depth masks and color-write-mask query tokens. `RTT` no longer
spells GL enum names directly. It also
validates Shape index-type, fill/stroke primitive-mode, buffer target, static
upload usage, and vertex attribute component/normalization mapping used by
the legacy mesh draw path, plus the PanoPainter cube-face to OpenGL
texture-target mapping used by `TextureCube`.
It also owns and validates sampler wrap S/T/R, min/mag filter, and desktop
border-color parameter mapping used by legacy `Sampler`. The PanoPainter
shader attribute binding catalog, shader stage tokens, compile/link status
queries, active-uniform count query, and matrix-uniform transpose token used
by legacy `Shader` creation also live here. `Shader` no longer spells GL enum
names directly. It also owns the PanoPainter shader uniform catalog and legacy hash
mapping used by `Shader` active-uniform discovery and the uniform uniqueness
check. App OpenGL initialization debug severity, debug output, GL info string,
default depth/program-point/line-smooth state, blend factor/equation, and UI
render-target RGBA8 format tokens are cataloged and tested here too, including
the legacy convert command and resize path. App clear color-buffer masks,
default framebuffer binding, scissor state, and sampler filter/wrap tokens
also consume the backend mapping. OpenGL extension enumeration query tokens
used before runtime capability detection are cataloged here. Legacy font
atlas texture formats, text mesh buffer targets, attribute component and
normalization tokens, draw primitive/index type, upload usage, and active
texture unit selection also consume the backend mapping. Canvas undo/redo
dirty-region texture updates and readbacks also consume the backend-owned 2D
texture target, RGBA pixel format, and unsigned-byte component mapping.
`NodeViewport` preview rendering also consumes backend-owned viewport query,
clear-color query, color-buffer clear mask, and blend-state tokens.
`NodeImageTexture` preview drawing also consumes backend-owned fallback 2D
texture bind and blend-state tokens.
`NodeImage` drawing and remote-image texture creation also consume
backend-owned mipmapped sampler filters, blend-state tokens, and RGBA8/RGBA
texture format mapping.
`NodeColorWheel` triangle-buffer setup and draw-state handling also consume
backend-owned array-buffer, static-upload, vertex-attribute, primitive-mode,
and blend-state tokens.
Simple UI text, text-input, border, scroll, and animation timeline draw
paths also consume backend-owned blend-state tokens.
Canvas layer cube/equirect generation, clear, restore, and snapshot paths
also consume backend-owned cube/2D texture targets, active texture units,
blend/clear state, and RGBA8 read/write pixel mapping.
`NodePanelGrid` heightmap preview and lightmap baking also consume
backend-owned texture readback formats, sampler filters, depth/blend state,
depth clears, viewport queries, color-mask booleans, active texture units,
and float render-target formats.
Legacy `util.cpp` OpenGL error naming and `gl_state` save/restore also
consume backend-owned error codes, state queries, framebuffer targets,
texture binding targets, and active texture units.
`NodeStrokePreview` brush preview rendering also consumes backend-owned
depth/scissor/blend state, viewport/clear-color queries, active texture
units, 2D texture targets, copy targets, and sampler filters/wraps.
Legacy `Texture2D`, `TextureManager`, `Sampler`, and `RTT` public headers no
longer expose raw OpenGL enum defaults; default texture formats, sampler
filters/wraps, and render-target formats resolve through backend-owned
overloads.
The Windows entrypoint also consumes backend-owned generic OpenGL
error-code/info-string tokens and WGL core-context/pixel-format attribute
catalogs.
Desktop VR drawing also consumes backend-owned scissor/depth/blend state,
depth clear masks, active texture units, and fallback 2D texture unbind
targets while retaining the existing VR SDK/platform bridge shape.
Canvas mode overlay, mask, and transform paths also consume backend-owned
blend/depth state, active texture units, 2D texture copy targets, and RGBA8
readback format tokens.
`NodeCanvas` panorama UI rendering also consumes backend-owned sampler
defaults, viewport/clear-state queries, blend/depth/scissor state, color
clear masks, active texture units, fallback 2D texture unbind targets, copy
targets, and RGBA8 render-target formats.
Canvas resource setup also consumes backend-owned stroke-buffer
RGBA8/RGBA16F/RGBA32F formats, flood-fill texture upload format/type,
brush/stencil/mix sampler filters and wraps, and image channel-count texture
formats for cube-strip imports. Clamp-to-border sampler wrap is now part of
the backend capability catalog and test coverage.
Early canvas draw helpers also consume backend-owned pick readback
format/type, stroke mixer depth/scissor/blend state, saved viewport and
clear-state queries, active texture units, fallback 2D texture unbind
targets, and stroke background copy targets.
Canvas stroke commit also consumes backend-owned saved viewport/clear/blend
state, history readback format/type, active texture units, fallback 2D
texture unbind targets, and layer compositing copy targets.
Canvas layer merge rendering and explicit layer-merge compositing also consume
backend-owned depth/blend state, active texture units, fallback 2D texture
unbind targets, and merge framebuffer copy targets.
Canvas equirectangular import drawing and depth export rendering also consume
backend-owned depth/blend state and active texture units.
Canvas thumbnail generation and object-drawing helpers also consume
backend-owned saved viewport/clear/blend state, active texture units,
readback format/type, framebuffer copy targets, and renderbuffer/depth
attachment parameters; `src/canvas.cpp` no longer contains raw `GL_*`
constants.
Windows desktop OpenGL context creation now consumes a tested
`windows_wgl_core_context_3_3_config()` catalog from `pp_renderer_gl` instead
of owning active WGL context/pixel-format attribute literals in `main.cpp`.
- `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test
for the current headless component matrix; see DEBT-0007 for remaining app
and platform triplet migration.
- `scripts/automation/analyze.*` runs shader validation plus a
renderer-boundary guard that reports JSON and fails if active non-backend
source code reintroduces raw `GL_*`/`WGL_*` constants outside the allowed
legacy OpenGL implementation files.
- `pp_renderer_api` exposes a headless `RecordingRenderDevice` that reports
renderer feature flags and validates backend-owned resource creation,
explicit texture usage flags, command order,
render-pass color/depth/stencil clear intent, scissor state, depth state,
blend state, texture-slot binding, sampler-state binding, texture-upload byte
counts, texture mip-level counts, texture/mesh/shader resource debug labels, mipmap-generation commands,
texture-state transitions, shader-uniform writes, explicit draw descriptor ranges, texture-copy regions,
readback/frame-capture/blit descriptor validation, readback bounds, destination buffer sizes, and
render-target blit regions, records
render-pass-clear/scissor/depth/blend/shader-uniform/texture-bind/
sampler-bind/draw/upload/mipmap-generation/texture-transition/texture-copy/readback/
frame-capture/blit commands, draw mesh inputs, explicit draw ranges, and
records trace markers and scopes without a window or GL context. Recorder
`clear()` also resets active render-pass and trace-scope state so automation
can reuse the same recording device after an interrupted frame.
- `pano_cli record-render` exposes the recording renderer through JSON
automation, including backend feature flags, render-pass/depth-clear counts, scissor/depth/blend/
shader-uniform/texture-bind/sampler-bind/upload/mipmap-generation/texture-transition/texture-copy/readback/
frame-capture/blit command and byte totals, trace marker/scope counts,
labeled descriptor counts, backend resource creation counts, plus draw
descriptor vertex/index totals. Its `--exercise-clear` mode verifies
interrupted-frame recorder clear/reuse behavior and reports the result in
JSON, and is covered by `pano_cli_record_render_smoke`,
`pano_cli_record_render_exercises_clear_reset`, plus
`pano_cli_record_render_rejects_oversized_target`.
- `pano_cli simulate-document-history` exposes `pp_document::DocumentHistory`
apply/undo/redo state through JSON automation and is covered by
`pano_cli_simulate_document_history_smoke`.
- `pano_cli simulate-document-edits` exposes `pp_document` layer metadata,
frame order, active-index, tiny face-payload state, and selection-mask state
through JSON automation and is covered by
`pano_cli_simulate_document_edits_smoke`.
- `pano_cli simulate-image-import` exposes embedded PNG decode and document
face-payload attachment through JSON automation and is covered by
`pano_cli_simulate_image_import_smoke`.
- `pano_cli import-image` exposes file-driven PNG decode and document
face-payload attachment through JSON automation and is covered by
`pano_cli_import_image_smoke` and
`pano_cli_import_image_rejects_truncated_png`.
- `pano_cli export-image` exposes deterministic RGBA8 PNG writing through JSON
automation and is covered by `pano_cli_export_image_roundtrip_smoke`; full
legacy canvas export remains a future CLI task.
- `pano_cli save-project` exposes generated multi-layer, multi-frame PPI
writing with layer metadata and targeted dirty-face layer/frame payloads
through JSON automation and is covered by metadata-only and
dirty-face-payload round-trip smoke tests; full legacy canvas save parity
remains tracked by DEBT-0013.
- `pp_document::export_ppi_project_document` exposes pure document-to-PPI byte
export through CTest coverage; legacy Canvas save integration remains a
future DEBT-0010/DEBT-0013 task.
- `pano_cli simulate-document-export` exposes document export round-trip state
through JSON automation for agent-driven checks.
- `pano_cli save-document-project` exposes file-writing document export
automation for inspect/load round trips.
- `pano_cli apply-stroke-script` exposes file-driven stroke-script application
to a pure document face payload and writes a PPI artifact for inspect/load
round-trip automation.
- `pp_ui_core` consumes vcpkg tinyxml2 only when `PP_USE_VCPKG_TINYXML2=ON`
through the vcpkg preset; default and Android validation still use the
retained vendored fallback tracked by DEBT-0012.
Known warnings after the current CMake app build:
- Legacy code/vendor warnings under `/W4`.
- Visual Studio vcpkg manifest warning because manifest mode is not enabled.
- `LNK4099` missing `yuv.pdb` for retained libyuv binaries.
- `LNK4098` runtime library conflict from retained vendor binaries.
Platform-specific commands should be added here when verified locally.