Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
728 changes: 728 additions & 0 deletions .agents/docs/2026-09-29-build-progress-display-design.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions .agents/docs/2026-09-29-workspace-build-graph-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,10 @@ read from the member, or made a value of the plan:
| the runtime files of a program shipped through `artifacts` (2026.9.29.3) | its link waited for the plan's deploy set, which a workspace plan does not place; its own runtime files were not in the member's directory | the link waits for no plan-level file; a member's runtime set includes the closures its `artifacts` edges reach | e2e 833 G9 |
| the link line of a program shipped through `artifacts` (2026.9.29.4) | the plan's line, which pools the dependencies' flags and not a member's, so a library its package's build program states was missing | a link group of its own closure that places nothing (`LinkGroup::linkOnly`) | e2e 838 |
| `${mcpp.bin_dir}` in a member's action (2026.9.29.4) | the plan's `bin/` | the declaring member's product directory | e2e 838 A4 |
| a member program's graph document (2026.9.29.5) | listed every requester in the plan, the virtual root included, so the program's re-run key followed the selection | the requests made inside the program's closure | e2e 839 B3, B4 |
| the order of the members' programs (2026.9.29.5) | discovery order | dependencies first (a cycle skips its closing edge) | e2e 839 B2 |
| `emit build-database`, `--configure-only` (2026.9.29.5) | one plan per member | one plan per configuration, each member's tests included; a failed configuration planned member by member | e2e 840 |
| the root compile database of several configurations (2026.9.29.5) | the last written configuration's, a race under concurrent groups | the union, published once by the command | e2e 840 B |

Each criterion fails on 2026.9.29.1 and passes on 2026.9.29.2. The resource
case also showed a defect of every build: a quoted `#include` in a script was
Expand Down
4 changes: 3 additions & 1 deletion .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ superseded_by: 2026-09-07-....md # when status is superseded
---
```

317 records.
318 records.

## By subject

Expand All @@ -31,6 +31,7 @@ Records that declare one. Everything else is listed by date below.
### design

- [The workspace as the unit of build: one graph per configuration, one scheduler, product directories, and a reusable graph module](2026-09-29-workspace-build-graph-design.md) — landed
- [Build progress: each step's line states its outcome, and one status line states the build](2026-09-29-build-progress-display-design.md) — landed
- [An ecosystem design for mcpp and xlings: one authority per fact, and the work that follows from it](2026-09-28-ecosystem-design-and-optimisation-plan.md) — landed
- [Build cost, foreign toolsets, the build-plugin architecture and the library surface: engine, plugin and index design (#734)](2026-09-28-build-cost-foreign-toolsets-and-library-surface-design.md) — landed
- [The compile database, `emit build-database`, and #701/#702: triage against the specifications, and one design](2026-09-26-compile-database-and-issue-699-design.md) — landed
Expand Down Expand Up @@ -109,6 +110,7 @@ Records that declare one. Everything else is listed by date below.
### 2026-09

- [The workspace as the unit of build: one graph per configuration, one scheduler, product directories, and a reusable graph module](2026-09-29-workspace-build-graph-design.md) — landed
- [Build progress: each step's line states its outcome, and one status line states the build](2026-09-29-build-progress-display-design.md) — landed
- [Two days of mcpp and xlings: a review of what merged, what is known, and what is open](2026-09-28-ecosystem-review-of-two-days-of-mcpp-and-xlings.md) — active
- [An ecosystem design for mcpp and xlings: one authority per fact, and the work that follows from it](2026-09-28-ecosystem-design-and-optimisation-plan.md) — landed
- [Build cost, foreign toolsets, the build-plugin architecture and the library surface: engine, plugin and index design (#734)](2026-09-28-build-cost-foreign-toolsets-and-library-surface-design.md) — landed
Expand Down
85 changes: 85 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,91 @@
> Each `## [<version>]` section is that release's notes. Entries are written in English
> from 2026.9.28.3 on; earlier entries remain as written.

## [2026.9.29.5] - 2026-09-29

This release completes the workspace build graph in the commands around the
build, from the validation project's post-release run of 2026.9.29.4: build
programs are reused across selections and run dependencies first, the build
database and `--configure-only` plan by configuration, and the output names
what it reports. A build now reports each step when its outcome is known, and
shows what runs while it runs (`.agents/docs/2026-09-29-build-progress-display-design.md`).

### Added

- **A build reports each step once, with its outcome.** A package's line is
written when every step the graph assigns to it has run (`done` with the
span of its steps, read from ninja's log), when the global cache supplied it
(`cached N units`), when a step of it failed (`failed`), or when the build
ends. A package with nothing to do has no line. The packages the command was
asked to build are listed; their dependencies are folded into one line, and
a dependency that fails is named. `--verbose` lists every package and prints
each step as ninja reports it (e2e 842).
- **A status line states the build.** On a terminal the steps still running
and one status line, `Building 612/1203 · 14:32 · gpp.gui: vcpkg install
6:10`, are drawn below the output and updated in place; the status line
names the longest-running `check` or `prepare` action, which the engine's
action wrapper reports when it starts. In a log (CI, a pipe) only final lines
are written, and the status line is written when the log has been silent for
a minute (e2e 842, 843).
- **`Finished` states the whole command's time**, and for a command of ten
seconds or more how it was spent (`plan`, `programs`, `build`) and the step
that took at least a quarter of the build.

### Fixed

- **A failed step is reported when it fails.** Its diagnostics were printed
after ninja exited, that is, after every step still running had finished:
a compile error beside a twenty-minute vcpkg install appeared twenty minutes
late (e2e 842).
- **macOS and Windows terminals are terminals.** Terminal detection was
compiled only under `__unix__`, which Apple's compilers do not define, so
the download bar and colours were drawn on Linux alone. A Windows console
now receives mcpp's lines as UTF-16, so `·`, `→` and non-ASCII paths appear
as written whatever its code page.

- **A member's build program is reused whichever members a command selects.**
Its graph document listed every requester in the plan, the virtual root
included, so the program's re-run key followed the selection: `-p`, `mcpp
pack` and `mcpp emit build-database` reran the programs a `--workspace`
build had run (7 to 15 s each in the validation project). A program's
document now lists the requests made inside its own closure (e2e 839).
- **A member's build program runs after those of the members it depends on.**
They ran in discovery order, so a member's program could run before its
dependency's had applied its directives (e2e 839).
- **`mcpp emit build-database` and `mcpp build --configure-only` plan a
workspace by configuration, as the build does.** They planned each member
separately, so a package two members use was described once per member,
each time with other arguments (the validation project's core library three
times). A member that is a program is described as one, and its tests as
tests. A configuration whose plan fails is planned member by member, so a
member's failure still affects that member only (e2e 840; SPEC-005 v1.6).
- **A command that plans several configurations writes the root
`compile_commands.json` once**, as the union of their databases. Each
configuration replaced it, and under `mcpp build --workspace`, whose
configurations build at the same time, the file was the last one's (e2e 840).

### Behaviour changes

- **A build program has one line, which names its package and states its
outcome**: `build.mcpp <package> ran <time>`, `cached` or `failed`, in
place of `build.mcpp compiling <package>` and `running <package>`, and of
`up to date <package> (cached)` (e2e 839, 842). The programs of the
requested packages are listed, and those of their dependencies are folded
into one line.
- **`Compiling <package>` is written when the package's steps have run**, with
their outcome, rather than for every direct dependency before ninja starts;
the per-dependency `Cached <package> (N units)` line is `--verbose` output,
as `cached N units` (e2e 842).
- **A selected member is announced by its directory** in a `--workspace`
build, also where another member depends on it (e2e 839).
- **`mcpp pack` summarises many outputs.** A format that reports more than
eight outputs is reported by the entry each lies in below their common
directory, with a count; `--verbose` names every output, and
`--message-format json` lists every one as before (e2e 841).
- **Build database set names (SPEC-005 v1.6).** A set is named by its package;
a document of several configurations prefixes each name with the
configuration's build directory name, instead of `<member>/`.

## [2026.9.29.4] - 2026-09-29

This release links a program that a workspace member ships through
Expand Down
3 changes: 2 additions & 1 deletion docs/00-what-mcpp-is.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ int main() {
```console
$ mcpp run
Inferred target hello (bin from src/main.cpp)
Compiling hello v0.1.0 (.)
Compiling hello v0.1.0 (.) done 0.61s

Finished dev [unoptimized + debuginfo] in 0.64s
Running `target/x86_64-linux-gnu/0946988e9e4b52ba/bin/hello`

Expand Down
8 changes: 8 additions & 0 deletions docs/07-workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,14 @@ member that several members use is compiled once.
- **Resources.** A member's `[resources]` and `windows_code_page` are
compiled against the member's directory and include directories and embedded
into that member's programs and shared libraries only (2026.9.29.2+).
- **Build programs.** The members' build programs run dependencies first, and
a program's result is reused by every command whose inputs to it are
unchanged, whichever members the command selects (2026.9.29.5+).
- **Compile database.** `mcpp build --configure-only` and `mcpp emit
build-database` plan as the build does, one plan per configuration with each
member's tests, so a package the members share is described once per
configuration. A command that planned several configurations writes the root
`compile_commands.json` once, as the union of their databases (2026.9.29.5+).
- **No-op builds.** A command repeated with nothing changed is answered by one
check per configuration, without planning.
- **Module names.** Members built in one graph share one module namespace:
Expand Down
50 changes: 50 additions & 0 deletions docs/09-commands-by-scenario.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,56 @@ An index refresh is reported step by step when the xlings that mcpp drives
emits progress events for it (xlings 2026.9.28.1+). With an older xlings it
shows its status line and finishes silently, as before.

## What a build prints

A build reports each step once, when its outcome is known (2026.9.29.5+):

```console
$ mcpp build --workspace
build.mcpp gpp.core ran 16.00s
build.mcpp gpp.gui ran 6.70s
Compiling gpp.core (GalTranslPP) done 3m12s
Compiling 23 dependencies done 6m20s
Compiling gpp.gui (GPPGUI) done 38m05s

Finished fast-release [unoptimized + debuginfo] in 41m53s · plan 1m13s · programs 32s · build 40m08s · longest gpp.gui: vcpkg install 22m10s
```

- A package's line names the package and states its outcome: `done` with the
span of its steps, `cached` when the global cache supplied it, `failed`, or
the number of its steps that ran when a failed build stopped before the
package completed. A package with nothing to do has no line.
- The packages the command was asked to build (the root package, or the
selected members) are listed. The packages they depend on are folded into
one line, and a dependency that fails is named.
- A build program's line states `ran` with its time, `cached`, or `failed`.
- A failed step is reported when it fails, with its diagnostics, while ninja
waits for the steps still running.
- `Finished` states the whole command's time. A command of ten seconds or
more also states how the time was spent, and names the step that took at
least a quarter of the build when there is one.

On a terminal, the steps still running and one status line are drawn below
the output and updated in place:

```
Compiling gpp.gui (GPPGUI) 61 steps

Building 612/1203 · 14:32 · gpp.gui: vcpkg install 6:10
```

The status line counts the build's steps, shows the time since the command
started, and names the longest-running `check` or `prepare` action; ninja
reports every other step only when it finishes. When the output is not a
terminal (a CI log, a pipe), only final lines are written, and the status line
is written when the output has been silent for a minute. `TERM=dumb` selects
that form on a terminal too.

`--verbose` lists every package, including those with nothing to do (`fresh`),
states each build program's compile and run times, and prints every step as
ninja reports it (`[f/t] <command>` and its output). `--quiet` prints none of
it. Machine output (`--message-format json`) is unchanged.

## Validating a descriptor before publishing

`mcpp xpkg parse` reads a descriptor with the resolver's own grammar, so what
Expand Down
6 changes: 6 additions & 0 deletions docs/10-pack-and-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ the last is the distributable and only it is printed as `Packed`. A format
whose chain ends in two files is refused by `mcpp run --format`, naming both,
because a runner takes one operand.

A format may report many outputs, one per file of a distribution tree. Up to
eight are printed one per line; more are printed by the entry each lies in
below their common directory, with a count (`Packed Release/app (1309
files)`), and `--verbose` prints every one (2026.9.29.5+).
`--message-format json` lists every output in either case.

An unknown `<name>` is refused naming the format set the resolved graph
provides, the same set `mcpp pack --format bogus` reports. `--format` together
with `--no-runner` is refused — an `.apk` or an installed `.app` cannot be
Expand Down
14 changes: 12 additions & 2 deletions docs/30-build-mcpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,11 @@ one. `mcpp::graph_file()` names a JSON document that states the resolved graph:
`""`.** The root decides the graph, and when its program runs every input of
that decision is final, which is the reason `dep_linkage` is offered to it
alone.
- **In a workspace plan each selected member's program receives the document
of its own closure**, in which it is `root`, and `requested_by` lists the
requests made inside that closure (2026.9.29.5+). The document, and so the
program's re-run key, is therefore the same whichever members a command
selects. The members' programs run dependencies first.
- **`[package.metadata.<tool>]` is the package's statement about itself.** The
engine does not interpret the table. A path in it is resolved by the reader
against the entry's `manifest_dir`, because only the reader knows which values
Expand Down Expand Up @@ -1513,8 +1518,13 @@ variable, emit `mcpp:rerun-if-changed=config.h` / `mcpp:rerun-if-env-changed=USE
This replaces the old "process exited 0, so assume it's fine" guesswork with an
explicit input/output contract — incremental builds stay correct.

When nothing changed the output is `build.mcpp up to date (cached)`; otherwise
`build.mcpp compiling` / `running`.
Each program has one line, written when it finishes (2026.9.29.5+):
`build.mcpp <package> cached` when nothing changed, `build.mcpp <package> ran
<time>` when it was compiled or run (with `--verbose`, `compiled <time> · ran
<time>`), and `failed` when it failed. On a terminal the line shows `waiting`,
`compiling` or `running` with a clock while the program is pending or running.
The programs of the packages the command was asked to build are listed; those of
their dependencies are folded into one line, `build.mcpp N dependencies`.

## Host tools from a dependency (mcpp 2026.8.5.1+)

Expand Down
10 changes: 5 additions & 5 deletions docs/40-baremetal.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,18 @@ cd blinky
mcpp run
```

Measured output:
Output (2026.9.29.5; the times vary by machine):

```
Resolving toolchain
Resolved llvm@22.1.8 → riscv64-none-elf → @mcpp/registry/data/xpkgs/xim-x-llvm/22.1.8/bin/clang++
Resolved host toolchain for build.mcpp: clang 22.1.8 (x86_64-unknown-linux-gnu)
build.mcpp compiling
build.mcpp running
build.mcpp blinky ran 0.41s
Inferred sources [src/**/*.{cppm,cpp,cc,c,S,s,asm}]
Inferred target blinky (bin from src/main.cpp)
Compiling blinky v0.1.0 (.)
Cached riscv-virt-rt v0.3.0 (1 unit)
Compiling blinky v0.1.0 (.) done 0.04s
Compiling 1 dependency cached

Finished dev [unoptimized + debuginfo] in 0.05s
Size blinky text 8572 data 80 bss 5668 total 14320
Running `…/xim-x-qemu-riscv/9.2.4-1/bin/qemu-system-riscv64 … target/riscv64-none-elf/…/bin/blinky`
Expand Down
2 changes: 1 addition & 1 deletion docs/specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
| [SPEC-002](target-side.md) | 目标侧模型与能力声明(`mcpp:` 保留命名空间、五层、三条规则) | 评审中 v1.0 | 2026-08-24 | mcpp >= 2026.8.24.2 |
| [SPEC-003](exit-codes.md) | 退出码契约(分类、语义、稳定性承诺) | 评审中 v1.0 | 2026-09-01 | mcpp >= 2026.9.1.1 |
| [SPEC-004](manifest-semantics.md) | `mcpp.toml` 的平面划分、条件化形状、解析轴与命名规约 | 草案 v1.10 | 2026-09-28 | 条件化形状 mcpp >= 2026.8.29.1;目标轴 mcpp >= 2026.9.6.4;`linkage` 默认值 mcpp >= 2026.9.15.2;链接 flag 的词读法 mcpp >= 2026.9.26.2;条件化的 `dialect_cxxflags` 与 `-p` 的包身份 mcpp >= 2026.9.28.1;条件表按具体程度生效 mcpp >= 2026.9.28.2 |
| [SPEC-005](build-database.md) | 构建数据库:`mcpp emit build-database` 的内容、取值规则与不写工程目录的保证 | 评审中 v1.5 | 2026-09-28 | mcpp >= 2026.9.15.1;v1.3 条款 mcpp >= 2026.9.26.2;v1.4 条款 mcpp >= 2026.9.27.1;v1.5 条款 mcpp >= 2026.9.28.1 |
| [SPEC-005](build-database.md) | 构建数据库:`mcpp emit build-database` 的内容、取值规则与不写工程目录的保证 | 评审中 v1.6 | 2026-09-29 | mcpp >= 2026.9.15.1;v1.3 条款 mcpp >= 2026.9.26.2;v1.4 条款 mcpp >= 2026.9.27.1;v1.5 条款 mcpp >= 2026.9.28.1;v1.6 条款 mcpp >= 2026.9.29.5 |
| [SPEC-006](toolchain-management.md) | 工具链管理:身份、来源、选择与载荷契约 | 草案 v0.4 | 2026-09-28 | 逐条标注;已实现条款 mcpp >= 2026.9.24.1;§3.7 mcpp >= 2026.9.28.1;§3.7.1 mcpp >= 2026.9.28.2 |
| [SPEC-007](build-plugins.md) | 构建插件:配置、施工与校验的分工,运行时与规划期的义务 | 草案 v0.6 | 2026-09-28 | 逐条标注;mcpp >= 2026.9.26.2;v0.3 条款 mcpp >= 2026.9.27.1;v0.4 条款 mcpp >= 2026.9.28.1;v0.5 条款 mcpp >= 2026.9.28.2;v0.6(§9)mcpp >= 2026.9.28.3 |
| [SPEC-008](library-interface.md) | 库的接口:公开模块、发布闭包与两种形态的一致 | 草案 v0.1 | 2026-09-28 | 第一阶段(只警告)mcpp >= 2026.9.28.3 |
Expand Down
Loading
Loading