Summary
mcpp has five different unknown-key policies spread across its two manifest grammars. The same authoring mistake — a typo, or a key the current mcpp doesn't understand — is a hard error in one section, a warning in another, and completely silent in a third. Which one you get depends on which table you happened to write it in, not on how serious the mistake is.
This is a schema-consistency issue, not a feature request. Split out of #258, where it surfaced: [target.'cfg(...)'.build] silently drops any key outside its four hardcoded ones (so a flags = [...] entry written there today vanishes with zero diagnostics), while the xpkg descriptor's equivalent target_cfg hard-errors on the same input.
The five policies
| Grammar / section |
Unknown key behavior |
Code |
mcpp.toml [build] |
silent — every key is a positive doc->get("build.X") lookup, nothing enumerates the table |
src/manifest/toml.cppm:221,234,238,839-888 |
mcpp.toml [target.<pred>.build] |
silent — four read_list calls, no allowlist |
src/manifest/toml.cppm:976-987 |
mcpp.toml [targets.<name>] |
warning → schemaWarnings, promoted to error under --strict |
src/manifest/toml.cppm:487-503, src/build/prepare.cppm:722-726 |
mcpp.toml [[build.flags]] entry |
hard error |
src/manifest/toml.cppm:84-93 |
| mcpp.toml array-of-tables path (#227) |
hard error, but only checks where an AOT may appear, not key names |
src/manifest/toml.cppm:147-160 |
xpkg mcpp segment top level |
warning with did-you-mean, via xpkgUnknownKeys |
src/manifest/xpkg.cppm:1477-1486, src/build/prepare.cppm:52-73 |
xpkg mcpp.features.<n>.<sub> |
warning, same channel |
src/manifest/xpkg.cppm:1247-1259 |
xpkg mcpp.target_cfg.<pred>.<sub> |
hard error |
src/manifest/xpkg.cppm:1085-1090 |
xpkg flags entry |
hard error |
src/manifest/xpkg.cppm:828-844 |
So within a single mcpp.toml, flags = [{ glob = "x", bogus = [] }] is a hard error, [targets.foo] bogus = 1 is a warning, and [build] bogus = 1 / [target.'cfg(linux)'.build] bogus = 1 are silent. Within a single xpkg descriptor, an unknown top-level key warns while an unknown target_cfg sub-key errors.
Why it matters
Direction (needs a decision, not obviously one-size-fits-all)
- Pick one policy per axis and state it. A defensible split: unknown key = warning with did-you-mean by default (forward-compat: an older mcpp reading a newer manifest should not refuse to build), promoted to error under
--strict — i.e. generalize what [targets.*] already does, and what xpkgUnknownKeys already does, to every table in both grammars. Entry-level grammars that are already hard errors (flags entries) stay hard errors, since those are closed by construction and there is no forward-compat story for a malformed entry.
- Requires enumerating the tables, which today's positive-lookup parsing does not do —
[build] and [target.<pred>.build] need to iterate their table and diff against a known-key list, the way [targets.<name>] does at toml.cppm:487-503.
- Compatibility surface: any manifest in the wild carrying a stray key in
[build] or a conditional section starts emitting warnings. That is the point, but it should land in its own release note rather than riding along with a feature.
- Reuse
closest_known_xpkg_key's Levenshtein suggester (xpkg.cppm:151-176) for the TOML side so both grammars give the same did-you-mean quality.
Scope note
Deliberately not bundled into the #258 fix: #258's unblock (per-OS per-glob flags for the vendored-opencv windows leg) has no dependency on this, and mixing a compatibility-affecting schema policy change into a feature PR would make both harder to review and to revert.
Environment: mcpp 0.0.101 (af25d18).
Summary
mcpp has five different unknown-key policies spread across its two manifest grammars. The same authoring mistake — a typo, or a key the current mcpp doesn't understand — is a hard error in one section, a warning in another, and completely silent in a third. Which one you get depends on which table you happened to write it in, not on how serious the mistake is.
This is a schema-consistency issue, not a feature request. Split out of #258, where it surfaced:
[target.'cfg(...)'.build]silently drops any key outside its four hardcoded ones (so aflags = [...]entry written there today vanishes with zero diagnostics), while the xpkg descriptor's equivalenttarget_cfghard-errors on the same input.The five policies
[build]doc->get("build.X")lookup, nothing enumerates the tablesrc/manifest/toml.cppm:221,234,238,839-888[target.<pred>.build]read_listcalls, no allowlistsrc/manifest/toml.cppm:976-987[targets.<name>]schemaWarnings, promoted to error under--strictsrc/manifest/toml.cppm:487-503,src/build/prepare.cppm:722-726[[build.flags]]entrysrc/manifest/toml.cppm:84-93src/manifest/toml.cppm:147-160mcppsegment top levelxpkgUnknownKeyssrc/manifest/xpkg.cppm:1477-1486,src/build/prepare.cppm:52-73mcpp.features.<n>.<sub>src/manifest/xpkg.cppm:1247-1259mcpp.target_cfg.<pred>.<sub>src/manifest/xpkg.cppm:1085-1090flagsentrysrc/manifest/xpkg.cppm:828-844So within a single
mcpp.toml,flags = [{ glob = "x", bogus = [] }]is a hard error,[targets.foo] bogus = 1is a warning, and[build] bogus = 1/[target.'cfg(linux)'.build] bogus = 1are silent. Within a single xpkg descriptor, an unknown top-level key warns while an unknowntarget_cfgsub-key errors.Why it matters
[target.<pred>.build]is the concrete case from manifest: per-glob flags in [target.'cfg(os)'.build] (parity with descriptor mcpp.<os> flags/#253) — blocks vendored-opencv windows leg #258: per-globflagswritten there parse fine and disappear.xpkg.cppm:1477-1479, and [enhancement] xpkg 描述符 mcpp 段未知键静默忽略(dependencies 误写无诊断,deps 才是正确键) #237/[bug] #233 消歧后链接输入未跟随改名:依赖包与消费者同名源(如双方都有 main.cpp)即 'obj/main.o missing and no known rule' #240 added thexpkgUnknownKeyschannel precisely to enforce it. mcpp.toml never got the same treatment.Direction (needs a decision, not obviously one-size-fits-all)
--strict— i.e. generalize what[targets.*]already does, and whatxpkgUnknownKeysalready does, to every table in both grammars. Entry-level grammars that are already hard errors (flagsentries) stay hard errors, since those are closed by construction and there is no forward-compat story for a malformed entry.[build]and[target.<pred>.build]need to iterate their table and diff against a known-key list, the way[targets.<name>]does attoml.cppm:487-503.[build]or a conditional section starts emitting warnings. That is the point, but it should land in its own release note rather than riding along with a feature.closest_known_xpkg_key's Levenshtein suggester (xpkg.cppm:151-176) for the TOML side so both grammars give the same did-you-mean quality.Scope note
Deliberately not bundled into the #258 fix: #258's unblock (per-OS per-glob flags for the vendored-opencv windows leg) has no dependency on this, and mixing a compatibility-affecting schema policy change into a feature PR would make both harder to review and to revert.
Environment: mcpp 0.0.101 (
af25d18).