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

23 KiB

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.

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), RGBA8/RGBA32F readback formats, 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 bounds, frame-capture sources, 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.