Context
Found while implementing #253 (design doc: .agents/docs/2026-07-20-issue-253-feature-flags-and-per-os-features-design.md §2.3).
mcpp has two platform axes, and they key on different things:
mcpp.<os> descriptor sections are applied by textual splice at parse time, keyed on mcpp::platform::xpkg_platform — a compile-time HOST constant (src/platform/common.cppm:96-105, chosen via _WIN32/__APPLE__/__linux__). Splice: src/manifest/xpkg.cppm (osKey = osOverride.empty() ? xpkg_platform : osOverride).
target_cfg / [target.'cfg(...)'] conditional config is evaluated against the RESOLVED target triple (cfgpred::context_for in src/build/prepare.cppm, host fallback only for native builds).
Consequence
Cross-compiling (e.g. the 0.0.100-era mcpp build --target x86_64-windows-gnu MinGW flow) against an xpkg dependency with per-OS sections selects the host OS section: per-OS sources, flags, deps, include_dirs, features (#253), and the xpm version/asset table all come from the wrong leg. Native builds are unaffected (host == target), which is why this stays invisible in the normal three-platform CI.
Direction (needs its own design pass)
- Build/prepare adoption sites (
prepare.cppm xpkg dep manifest synthesis) should pass the resolved target OS (mapped to xpkg vocabulary linux/macosx/windows) as osOverride — the parameter seam already exists (it powers mcpp xpkg parse --all-os).
- pm/install-time consumers need separate judgment: source packages compiled for the target want target-keyed sections, while host-tool packages want host — an audit of
synthesize_from_xpkg_lua / list_xpkg_versions call sites is required before flipping anything.
- Zero behavior change for native builds must be locked by e2e (host == target ⇒ same splice).
Deliberately split out of #253 (its unblock — native macOS/windows opencv dnn legs — doesn't need this).
Context
Found while implementing #253 (design doc:
.agents/docs/2026-07-20-issue-253-feature-flags-and-per-os-features-design.md§2.3).mcpp has two platform axes, and they key on different things:
mcpp.<os>descriptor sections are applied by textual splice at parse time, keyed onmcpp::platform::xpkg_platform— a compile-time HOST constant (src/platform/common.cppm:96-105, chosen via_WIN32/__APPLE__/__linux__). Splice:src/manifest/xpkg.cppm(osKey = osOverride.empty() ? xpkg_platform : osOverride).target_cfg/[target.'cfg(...)']conditional config is evaluated against the RESOLVED target triple (cfgpred::context_forinsrc/build/prepare.cppm, host fallback only for native builds).Consequence
Cross-compiling (e.g. the 0.0.100-era
mcpp build --target x86_64-windows-gnuMinGW flow) against an xpkg dependency with per-OS sections selects the host OS section: per-OSsources,flags,deps,include_dirs,features(#253), and thexpmversion/asset table all come from the wrong leg. Native builds are unaffected (host == target), which is why this stays invisible in the normal three-platform CI.Direction (needs its own design pass)
prepare.cppmxpkg dep manifest synthesis) should pass the resolved target OS (mapped to xpkg vocabulary linux/macosx/windows) asosOverride— the parameter seam already exists (it powersmcpp xpkg parse --all-os).synthesize_from_xpkg_lua/list_xpkg_versionscall sites is required before flipping anything.Deliberately split out of #253 (its unblock — native macOS/windows opencv
dnnlegs — doesn't need this).