Skip to content

xpkg per-OS sections splice by HOST OS, not the resolved target — cross builds pick the wrong per-OS payload #254

Description

@Sunrisepeak

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions