Repository navigation
manifest: per-glob flags in [target.'cfg(os)'.build] (parity with descriptor mcpp.<os> flags/#253) — blocks vendored-opencv windows leg #258
Description
Activity
One more data point from the same opencv-m branch: with the cross-OS UNION flag table (the only in-grammar shape today), every off-OS entry now trips the #253 dead-glob warning on every build — e.g. the linux run prints ~24 warnings for the windows stub-namespace globs, the macos run warns for every x86 ISA entry, and vice versa. They are all structurally-expected, not authoring mistakes, but they bury real dead-glob signals.
If per-OS tables land ([target.'cfg(os)'.build] flags), the noise disappears by construction. If that takes longer, a tiny stopgap would help immediately: an
optional = truekey on a flags entry (or a?-prefix on the glob) meaning 'zero matches are fine, skip the warning' — authors of multi-OS packages would mark exactly the entries that are off-OS by design.Clarification: #253 fixed the feature axis, this issue is the OS axis
Worth stating explicitly, because "didn't #253 already fix the dead-glob warning?" is the natural reading of the changelog.
af25d18(#253, 0.0.101) changed the zero-hit path insrc/modgraph/scanner.cppm:933-945so that afeatures.<n>.flagsentry only exists inbuildConfig.globFlagswhen its feature is active — i.e. a feature-off build no longer carries the rule at all, so it cannot warn. That is a real fix, and it fully closes the feature dimension.The 23 warnings we still get are all the OS dimension, which #253 did not touch:
warning files exist on warns on **/modules/{core,imgproc}/**/*.{avx,avx2,avx512_skx,sse4_1,sse4_2}.cpp(10 entries)linux / windows (x86) macOS (arm64 — no x86 dispatch TUs in its source set) gen/windows/tu/w/<group>/**(12 entries)windows linux + macOS third_party/opencv-5.0.0/**/*.asmx86 targets macOS arm64 The asymmetry is structural, not authoring error:
sourcesis OS-conditional,flagsis not.
[target.'cfg(os)'.build]reads exactlycflags / cxxflags / ldflags / sources(+.dependencies) —src/manifest/toml.cppm:975-987— while[[build.flags]]is global-only. One manifest covering 3 OSes therefore must present each OS with the other two OSes' flag entries, and each of those matches zero sources by construction.Why there is no package-side workaround (checked, all three fail)
- Anchor/dummy files on disk — no effect: the hit counter is over the build's source set (
globFlagHitsis bumped inside the per-scanned-fileapply_glob_flagsloop), not over the filesystem. The 12gen/windows/tu/w/**dirs are committed and present on every OS, and they still warn on linux/macOS. - A no-op TU compiled on every OS to keep each glob alive — breaks the build: the x86 ISA entries carry
-mavx/-msse4.1, which clang rejects on macOS arm64. - Park the off-OS entries in a feature and auto-enable it per OS — not expressible: per-OS feature activation (
mcpp.<os>.features) exists only in the xpkg descriptor grammar;mcpp.tomlhas no equivalent key, andbuild.mcppcan only readMCPP_FEATURE_<N>, never enable a feature.
So the warning is only removable inside mcpp — which is what this issue asks for.
Implementation sketch (the plumbing already exists)
Reading the current tree, per-OS
flagslooks like ~4 mechanical sites, all reusing existing code:src/manifest/types.cppm:276— addstd::vector<GlobFlags> globFlags;toConditionalConfig(sits next to the existingsources).src/manifest/toml.cppm:975-987— in the[target.<pred>.build]reader, parseflagswith the existingparse_glob_flags_valuehelper (toml.cppm:62) — same grammar/validation as[build].flags, zero new parser.src/build/prepare.cppm:429merge_conditional_sources_flags— inside thecfgpred::matchesbranch that already appendscc.sources, appendcc.globFlagstom.buildConfig.globFlags. Appending AFTER the base entries gives the "last flag wins" override power the body asks for (which is what makes the windows removal cases expressible).src/manifest/xpkg.cppm— mirror for descriptor parity if desired (it already hasparse_glob_flags_array).
Fingerprint/scanner/per-TU landing need no change — everything downstream consumes the single
buildConfig.globFlagsfunnel, exactly as #253 arranged.What lands the day this ships (opencv-m side)
The stub-namespace workaround is currently shipping in
Sunrisepeak/opencv-m#13, and it costs:- 703 committed stub files (
gen/windows/tu/w/426 +gen/windows/tu/wdnn/277), each a one-line#includeof the real TU, existing solely to give windows TUs OS-unique paths so the global flag table can key on them - 32 windows glob entries in
mcpp.tomlpointing at those stub dirs - the 23 warnings above, on every build, on every OS
All three disappear by construction with
[target.'cfg(os)'.build].flags— the parked tables (windows-flags-PARKED.toml,windows-dnn-flags-PARKED.toml) drop straight in.- Anchor/dummy files on disk — no effect: the hit counter is over the build's source set (
Fixed in 0.0.102 (PR #264, squashed to main as 5807e36).
[target.'cfg(...)'.build]now accepts the same per-globflagsarray[build]does, plusinclude_dirs/include_dirs_after; the xpkg descriptor'starget_cfggets the same for parity.The fix is the type behind the feature. mcpp's two conditional axes (cfg and features) each hand-picked which build fields they could carry and picked different subsets — the drift that made per-glob flags inexpressible here. Extracting
BuildInputsmakes membership answerable by the type instead of a hand-kept list. Conditional entries append after the base table, so GNU last-wins makes a per-OS removal expressible (-UHAVE_UNISTD_Hagainst a base-D), and off-OS entries never enterglobFlagsat all, so the ~23 structurally-dead-glob warnings disappear by construction rather than by anoptional=truesuppression hatch (deliberately not added).That retires the 703 stub files / 32 globs the vendored-opencv windows leg needed. e2e 149 covers all four quadrants (match reaches TU, override/removal, off-OS silence, and a control proving a genuinely dead glob still warns).
Note: making the unknown-key policy consistent across sections was split out as #263 — it has a compatibility surface and this issue didn't depend on it.
- added a commit that references this issue
on Aug 6, 2026 - added a commit that references this issue
on Aug 15, 2026
Summary
Feature request: support per-glob flags inside conditional target sections —
[target.'cfg(<os>)'.build](and[target.<triple>.build]) should accept the sameflags = [{ glob, cflags, cxxflags, asmflags, defines }]array that[build]accepts. Today the conditional build section parses onlycflags/cxxflags/ldflags/sources(src/manifest/toml.cppm:976-987), and[features.<n>.flags]is likewise global-only; the per-OS flag semantics that #253 added exist only in the xpkg descriptor grammar (mcpp.<os>.features,mcpp.<os>.flags).This is now the single blocker for the opencv-m single-repo windows leg (Sunrisepeak/opencv-m
feat/vendor-single-repo— the vendored OpenCV build that retirescompat.opencv).Why hoisting/global tricks cannot cover windows
The three frozen per-OS snapshots need different per-glob defines on the same TU paths:
linux vs macos deltas are pure per-OS additions with group-unique names (
PNG_INTEL_SSE_OPTvsPNG_ARM_NEON_OPT,NEON_INTRINSICS,HAVE_CAMV4L2, …) — we hoisted those to per-OS globalcflagsand shipped the macos leg that way. Workable, but already a hack: it relies on grep-verifying that each define name is only read by its own code group.windows needs both additions and REMOVALS on shared globs, e.g.:
**/3rdparty/zlib/**: linux/mac sayHAVE_UNISTD_H=1; windows must NOT define it (clang-MSVC has no unistd.h) and addsNO_FSEEKOthird_party/.../core/src/alloc.cpp:HAVE_MEMALIGN/HAVE_POSIX_MEMALIGN(unix) vsHAVE_WIN32_ALIGNED_MALLOC=1(win)**/modules/videoio/**:HAVE_CAMV4L2/HAVE_FFMPEG_LIBAVDEVICE(linux) absent on windowsWIN32 _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE _SCL_SECURE_NO_WARNINGS _VARIADIC_MAX=10 _WIN32_WINNT=0x0601 _WINDOWSaddedA removal cannot be expressed by any global-flag overlay:
[[build.flags]]is unconditional, so the unix-DHAVE_UNISTD_H=1from the union table reaches windows TUs;-Ucounter-entries would need to be windows-only — same gap, recursed.The only in-grammar workaround is resurrecting a per-OS tu-stub indirection layer (per-OS wrapper TUs whose paths are OS-unique so globs can key on them) for every conflicting group — the pre-0.0.97 #233-era machinery this project was happy to delete.
Proposed grammar
Merge semantics: append the matching conditional entries AFTER
[build].flagsin the ordered vector (same "last flag wins" rule) — that also gives-U/re--Doverride power over the unconditional table, which covers the removal case. Same for[target.<sel>.'features'.…]or at least[target.<sel>.build.flags]reachable from features via the existing feature-flag funnel.Symmetry argument: the descriptor grammar already has exactly this (per-OS
flagsinsidemcpp.<os>, #253); manifest-built packages (single-repo/vendored libraries, workspace members, path deps) are second-class without it. Dep builds already run the conditional merge through the single #229 funnel (merge_conditional_sources_flags), so the plumbing point is well-defined.Context / evidence
windows-flags-PARKED.toml,windows-dnn-flags-PARKED.toml) ready to drop in the day this lands.pkgs/c/compat.opencv.lua@8692bb26.Environment: mcpp 0.0.101.