Skip to content

2026.10.11.1: build dependencies on one pipeline — the build programs' graph, instances per configuration, build plugins, one library interface, CalVer deprecations (#797) - #798

Merged
Sunrisepeak merged 12 commits into
mainfrom
release/2026.10.11.1
Oct 11, 2026

Conversation

@Sunrisepeak

@Sunrisepeak Sunrisepeak commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Closes #797.

Design: .agents/docs/2026-10-11-build-dependencies-one-pipeline-design.md (revision 3, §20 plan, §21 implementation notes); observations: …-repro.sh.

One pipeline for build dependencies

A node of the graph is a package in a configuration. The table states the configuration: [dependencies] is the target, [build-dependencies] is the build program. The entry states the products: the library unless it names only tools or artifacts; host-module = false declines it.

  • The build programs' graph. The build programs of one build that share a host toolchain and a C++ standard are members of a workspace at target/.build-mcpp/host/<group>/. mcpp plans and builds it as any workspace. Each library is compiled as its package, with its include directories, defines, features, dependencies and implementation units. build.mcpp (a .mcpp C++ source) is compiled by the same plan. cd <dir> && mcpp build reproduces the compile.
  • Instances. A package in both tables has a target instance and a build-program instance, each with the features its own edges request. A build-only package's usage requirements and link flags stay out of the target.
  • Program identity. A program's identity covers the engine version, host toolchain, standard, program text and every package of its graph, including a stat-accelerated content digest of each path or member tree. A header edit compiles the program and runs it again. When every identity stands, the graph is not planned.
  • Engine package. mcpp/mcpp.core live at $MCPP_HOME/engine/<version>/modules, a global dependency-cache entry (_engine/mcpp-build-module@<version>). mcpp self env reports it as engineModules.
  • Build plugins (SPEC-007 §10). A unit importing mcpp.core is a plugin unit. Plugins depend on plugins and libraries through [dependencies]. A plugin is planned in the build-program configuration when it is the root (mcpp build/mcpp test). Each of the following is refused with a stated cause:
    • a plugin in a target's [dependencies] (the refusal names the chain);
    • a program that imports mcpp;
    • --target for another machine;
    • mcpp pack.
  • Library interface (SPEC-008 v0.2). One definition: the interface root ([lib] path, Form B lib, or the convention), its public modules and the exported modules. [modules] exports is an assertion, and rule_module must be declared by a unit of its feature.
  • Build database (SPEC-005 R3.13). New sets: <pkg>:build, <pkg>:host, mcpp:core and mcpp:std:host, with configuration build-program. compile_commands.json is unchanged.
  • Observability. mcpp why build-programs, mcpp why compat, instances in resolution.json and why deps, and the host-graph, build-program, edges and compat log tags.

Deprecations dated by CalVer

mcpp.pm.compat.registry holds each deprecated reading with the release that deprecated it and the month it is removed (2027.1).

  • The warning names both releases. mcpp why compat lists the uses, --strict refuses them, and docs/51 lists the rows.
  • check_compat_registry.py and a unit test hold the code and the docs to the table, and fail once a floor is reached.
  • workspace-position moves from "1.0.0" to 2027.1.
  • New rows: host-module-in-dependencies and plugin-imports-from-build-dependencies.

Issues fixed

before after
R1 a module wrapper over a header library could not be imported from build.mcpp compiled as its package (e2e 902)
R2 a package in both tables lost its target library two instances (903)
R3 a build-only feature reached the target features per instance (904)
R4 [workspace.xlings.overrides] failed a rooted workspace's own build root position only (911)
R5 position warning on the root's own build only when the root is outside the workspace (911)
R6 an edited header did not recompile or rerun the program identity covers the tree (906)
R7 a plugin could not be built as a root build-program configuration (910)
R8 the database did not describe build.mcpp or the engine S1 sets (913)
W1 build.mcpp beside a root without [package] was ignored silently warned (911)
W2 features in [workspace.dependencies] was dropped inherited; request keys warned (911)
— [workspace.xlings.overrides] did nothing on a root without [package] given to its members (911)

Tests

  • e2e 902–913 are new; 902 runs on every platform.
  • Existing e2e tests that read the removed host-module store or its log lines now read the build programs' graph: 168, 189, 309, 610, 624, 798, 809, 854, 857–861, 867, 868, 897.
  • New unit tests: compat registry, library interface, source digest, Form B lib.
  • Locally on Linux: every test that passes on 2026.10.10.2 passes. The tests that need a fresh MCPP_HOME fail identically on both binaries in this sandbox, so CI decides them.

Docs

docs 04, 05, 07, 09, 20, 30, 31, 50, 51 (en, zh); SPEC-004 v1.15, SPEC-005 v1.8, SPEC-007 v0.9, SPEC-008 v0.2; examples 08, 09, 10, 12; CHANGELOG; version 2026.10.11.1.

Ecosystem follow-ups (after release)

  • mcpp-index: Form B lib for module wrappers; toml++ back to Form B.
  • mcpp-plugins: plugins that import plugins name them in [dependencies].
  • mcppls: issue for the :build/:host/mcpp:core sets (mcpp ≥ 2026.10.11.1).

Found on the CI runners and fixed here

  • Host sub-builds target the host (BuildOverrides::host_target). Neither [build] target nor the configured default target applies to them: a Windows host whose default target is x86_64-windows-gnu planned its build programs for it.
  • One directory, every spelling.
    • Affected: workspace members and the engine package.
    • Spellings: macOS /var ≡ /private/var; Windows 8.3 and long names.
    • Effect before the fix: a member reached through the other spelling took the default namespace, and its program was not found.
  • The run key does not depend on launched children. On Windows a child's environment is applied to mcpp itself, and MCPP_TOOL_ENV composed PATH from that mutated value, so every second build ran its programs again. The value now starts from the PATH the process inherited.
    • The run record keeps each contract key (build.mcpp.ctx).
    • -v names the keys that moved.
  • Program locations kept.
    • The synthesised rule program is written at target/.build-mcpp/build.mcpp again.
    • A copy of each compiled program is placed at target/.build-mcpp/build.mcpp.bin (.exe on Windows), where tools run it by hand.
    • e2e 168, 97 and 798 keep their original assertions.
  • Tests. Tests that look up the target's build directory exclude the build programs' graph.

mcpp-plugins at this head, against this engine: all jobs pass (run 38102446399, via mcpp_source_ref).

…ce; compat registry; workspace overrides at the root position (#797)
…e package, plugin roots; remove the single-unit host module path (#797)
…pendency cache, quiet sub-build; tests follow the build programs' graph (#797)
…abase describes build programs, host instances and the engine interface (#797)
…recations dated by CalVer; 2026.10.11.1 (#797)

- e2e 902-913: libraries of a build program, two instances of one package,
  features per instance, whole libraries, program identity, the library
  interface, the request of a build dependency, the deprecation registry,
  build plugins (P1-P5), workspace tables (R4, R5, W1, W2), shared build
  programs' graph across configuration groups, the build database.
- Existing tests read the build programs' graph under target/.build-mcpp/host
  instead of the removed host module store and its log lines.
- The host graph carries the build root's [xlings.overrides] and the project
  whose .mcpp holds the custom indices' packages; its directory states both.
- A root without [package] gives its members [workspace.xlings.overrides], and
  its schema warnings are reported when its members are built.
- A path package is editable wherever it lies; the source digest re-reads a
  racily clean file; a CalVer month has a four-digit year and a month 1-12.
- graph.cpp's lookups move to graph_closures.cpp (file length limit).
- Examples 08, 09, 10 and 12 use [build-dependencies] without host-module.
- docs (en, zh), SPEC-004/005/007/008, CHANGELOG; version 2026.10.11.1.
…ts find the target's build directory (#797)

- `BuildOverrides::host_target`: the build programs' graph and a host tool's
  sub-build target the machine doing the build; `[build] target` and the
  configured default target name the target of the build that asked
  (e2e 97 on a Windows host whose default target is x86_64-windows-gnu).
- The engine package and a workspace member are recognised through any
  spelling of their directory (macOS /var and /private/var, Windows 8.3 and
  long names): a member reached through another spelling was named with the
  default namespace and its program was not found (e2e 857, 858, 913).
- The verbose log states why a build program's cached run is not used.
- The error for a missing program names the programs the plan has.
- Tests that look up a build directory under target/ exclude the build
  programs' graph under target/.build-mcpp/host; 92 and 857 read the new
  object names and either path separator.
…un record names the contract keys that moved (#797)

- `build_program_dir`: one definition of where a package's build program keeps
  its record, graph document and synthesised program (the root's and a
  workspace member's below their own target/, a dependency's below the
  build's). A synthesised rule program is written there again, as
  target/.build-mcpp/build.mcpp, the file a project copies to take it over
  (mcpp-plugins spirv-zero-config; e2e 798 back to its original assertion).
- The run record keeps each contract key with the digest of its value
  (`build.mcpp.ctx`); a run that is not replayed because the contract moved
  names the keys in the verbose log.
- e2e 97 finds the program in the build programs' graph; 913 compares
  arguments up to the directory above the graph, with one separator.
…n mcpp has launched (#797)

On Windows a child's environment is applied to mcpp itself (`_putenv_s`), and
`build_env_for_cl` composed the toolset's PATH from the process's current
PATH. The value reached `MCPP_TOOL_ENV`, part of a build program's run key: a
build that had compiled its programs through the build programs' graph ran
ninja first, so its PATH carried the toolset's directory once more than the
next build's, and every program ran again (e2e 89, 839, 842; mcpp-plugins
cmake-consumer). The toolset's PATH and a program's PATH now start from the
PATH the process was started with (`env::inherited_path`), captured before
anything is launched.
…ain (#797)

The build programs' graph compiles and runs a program in its own directory.
A copy is placed where the program was before the graph,
target/.build-mcpp/build.mcpp.bin (build.mcpp.exe on Windows), beside the
package's run record: the file a person or a test runs by hand with an
environment of its choosing (mcpp-plugins' plan checks for dist-apple,
dist-apk, dist-wix and ios-app). e2e 168 and 97 keep their original
assertions; docs/30 states the location.
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.

build.mcpp cannot import an ordinary module library: host-module and [dependencies] disagree on export surface and compile context

1 participant