Skip to content

2026.9.28.3: the build-plugin architecture -- mcpp.core, build information, members built once, batched placement, pack -p, the library interface (#734) - #735

Merged
Sunrisepeak merged 18 commits into
mainfrom
feat/734-build-plugin-architecture
Sep 28, 2026
Merged

Sunrisepeak merged 18 commits into
mainfrom
feat/734-build-plugin-architecture

Conversation

@speak-agent

@speak-agent speak-agent commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Implements the engine half of #734, as designed in .agents/docs/2026-09-28-build-cost-foreign-toolsets-and-library-surface-design.md (revision 5; §13 records the tasks and the departures). Release 2026.9.28.3; mcpp-plugins 0.17.0 takes it as its floor.

What changes

Item Change Test
E1 A workspace member used as a path dependency is built once, in its own directory, and consumers take its objects and BMIs through stage edges. The admission compares the member's build-key inputs (less package.index). Stage edges compare content, and concurrent consumers take a lock. e2e 830
E2 Build information for build programs (protocol 14): tool, abi_tool, tool_env, toolset_identity, msvc_instance_dir, ninja_program, cxx_runtime, msvc_crt_linkage. Each is read from the producer the engine's own command lines read. e2e 824 (Linux), 825 (Windows)
E3 mcpp pack -p <member> e2e 829
E4 mcpp stage --list; two or more deploy entries become one placement edge. e2e 827, test_ninja_backend
E5 The fast path never served on macOS, Windows or SDK-sysroot targets: the runtime validation holds ELF/glibc rules only and wrote no record elsewhere, so no validated snapshot existed (read on the macOS row). Where no rule applies the record is now written as Pass. Two defects found on the way, both present in 2026.9.28.2 on Linux: the sweep of a path dependency read only its src/, and a build that confirmed the graph left build.ninja's time behind, so every build after an edit was planned in full. Under -v each refusal is a sentence. e2e 645, 831, 832
E6 SPEC-008 phase 1: W1 reworded; W2 and a complete "Withheld" row in mcpp pack; W3 in mcpp build. Warnings only. e2e 828
E7 A build-program import of a module behind a disabled feature names the package and the feature. e2e 826
E8 mcpp.core names the interface; mcpp is its permanent equivalent. e2e 823, tests/scripts/test_protocol_table.py
E9 [package] mcpp = ">=V" and [workspace.package] mcpp e2e 822
E10 Plugin module names: mcpp.<own namespace>.* is accepted; reserved second segments belong to namespace mcpp. e2e 826, test_provisions
E11 mcpp::report({severity, message, impact, hint}), rendered by mcpp.diag and replayed on a cache hit. It writes through printf only, so no FILE reaches the module interface (GCC otherwise rejects #include <cstdio> after import mcpp;). e2e 826, 651
E12 [lib] reports unknown keys. e2e 822
W3 scope W3 leaves members of the package's own workspace alone; mcpp's own build printed seventeen. e2e 828
Downloads One line per download: the completion line, with size and time, in both modes. test_progress_render
MSVC ABI clang on the MSVC ABI warns when msvc@system finds no toolset, naming the managed-toolset commands (it failed at 'cstdio' file not found). plugins CI, masked row

Documentation and specifications

  • docs/04, 07, 10, 12 and 30, in both languages.
  • SPEC-007 v0.6 §9: the three layers, mcpp.core, the protocol table, build information, diagnostics, placement, plugin names, the feature error and the package floor.
  • New SPEC-008 (library interface).
  • The CHANGELOG entry lists the compatibility effects: protocol 14; one extra run of every build program; one compile of shared members in their own directory; one run of the placement edge.

Readings

  • Linux, locally. mcpp test passes: 134 units. The new e2e 822 to 832 pass; 831 and 832 fail with the released 2026.9.28.2. Among the related existing e2e, the failures seen locally (215, 321, 324, 617) fail identically with 2026.9.28.2 on this machine, whose default toolchain is not the GCC they require.
  • mcpp-plugins 0.17.0 (feat/734-plugins-0.17.0) builds against this branch: its test kit's 14 cases and the Linux deps fixtures pass locally on the LLVM and GCC rows.
  • Windows and macOS. Read from this PR's CI.

…the ABI's tools, their environment, identity, instance, ninja, the runtime contract (#734 E2, protocol 14)
…ssing module, and the plugin naming rule under mcpp. (#734 E11, E7, E10)
…wn directory, and consumers take its objects from there (#734 E1)
…otocol table check; W3 needs the text scanner's re-exports (#734)
…nterface (#734 E11)

GCC rejected a build program that includes <cstdio> after 'import mcpp;'
once an inline function of the interface named stdout and fputc: the BMI
then carried struct _IO_FILE, and the textual include conflicted with it.
e2e 651 read the defect on the GCC row.
…after a confirmed edit; its reasons are statements (#734 E5)

The dependency sweep read only src/, so an edit to a host module elsewhere in
a path dependency (mcpp-plugins keeps its members in deps/, rules/, dist/ and
tools/) was replayed as no work: such a unit is compiled into the consumer's
build program, which no edge of build.ninja names. The sweep now walks the
dependency's tree, skipping hidden directories, target and nested packages.

A full build that confirms the graph left an unchanged build.ninja unwritten,
and the fast path compares every source with its time, so after any edit every
later build was planned in full until the graph's text changed. The backend
now moves the file's time when it confirms the graph. 2026.9.28.2 shows both
defects on Linux; e2e 831 and 832 fail with it and pass with this change.

Under -v each refusal is now a statement of its condition rather than the
condition's code.
qt-base revision 1 no longer ships the VC++ runtime DLLs the step removes, so
its listing exited 2 and bash -e failed the step before any measurement.
…partures, and the plugins' implementation
…MSVC ABI says when msvc@system finds no toolset (#734)

W3 warned on every import of a non-public module of a sibling workspace
member: mcpp's own build printed seventeen. Such a member is built from source
together with the package, so the packed-form consequence the warning states
does not arise; SPEC-008 §4 and docs/12 state the exception.

With no Visual Studio instance, the default `msvc@system` selection returned
nothing and clang went on to fail at `'cstdio' file not found` while the
`mcpp` module precompiled. The resolution now warns, naming the managed
toolset commands. Measured on the plugins' CI row whose Visual Studio is
masked.
…; two prepare steps split under the size gate (#734)

- The placement list is written with forward slashes on every host, which is
  its stated format; on Windows the unit test read `bin\msvcp140.dll`.
- A refusal from `mcpp stage --list` names the failing group's entries as the
  list writes them. With one edge for the whole list, ninja's echo of the
  command no longer shows which files were involved (e2e 646 on Windows).
- step13_serve_workspace_members (E1) and host_module_units are split out of
  step13_dependency_cache and step6_host_module_registration, which the
  function-size gate reported over 400 lines. `workspace_member_of` is one
  function shared by E1 and W3.
- The design record states three further plugin departures.
…and time, in both modes (#734)

Output that is not a terminal printed a start line and a completion line for
every item; it now prints the completion line (or the line saying the item did
not complete). A terminal redraws the bar in place, as before, and ends it
with the same completion line, which now states the size and the time.
…hree e2e made portable (#734)

The runtime validation holds ELF/glibc rules and returned before writing its
record on every other target, so the project fast path found no validated
artifact snapshot there and every build was planned in full (read on the
macOS row: e2e 645, 831 and 832). Where no rule applies, each artifact's stamp
is now recorded with a Pass verdict, which is the module's definition of Pass;
a relinked artifact still sends the fast path to the full build.

e2e 827 no longer uses GNU stat, 828 no longer uses GNU sed -i, and 646 accepts
the destination in the placement list when the program has two or more
placements (a Windows program places its C++ runtime as well).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants