Skip to content

Commit ff04535

Browse files
authored
2026.9.29.5: a workspace's build programs are reused across selections, the build database plans by configuration, and a build reports each step once with its outcome while a status line states the build (#742)
The validation project's post-release run of 2026.9.29.4 and the cross-verification of this pull request found six problems in the commands around a workspace build, and a build that printed nothing for 40 minutes. - A member's build program is reused whichever members a command selects (its graph document lists only its own closure's requests), and the members' programs run dependencies first. - `mcpp emit build-database` and `mcpp build --configure-only` plan a workspace by configuration, as the build does; a command of several configurations publishes the root compile_commands.json once, as their union (SPEC-005 v1.6). - `mcpp pack` summarises more than eight outputs by directory. - A build reports each step once, with its outcome: ninja is read as it runs (its status lines, its log, a step record beside build.ninja, and the start of check and prepare actions from the engine's wrapper); a package's line is written when every step of it has run or when the build ends; dependencies are folded unless --verbose; a build program has one line; a failed step is reported when it fails; `Finished` states the whole command's time and how it was spent. - On a terminal the running lines and one status line are drawn below the output; in a log the status line is repeated after a minute of silence. Terminal detection works on macOS and Windows, and a Windows console receives UTF-16. - e2e 839 to 843, unit tests, docs in both languages, the design documents, CHANGELOG; version 2026.9.29.5. Merged after both gates passed: this pull request's CI (the two xcode-27 legs are the known #669) and the validation project's cross-verification with the mcpp built from this branch (Sunrisepeak/GalTranslPP run 36591168092).
1 parent 793221e commit ff04535

85 files changed

Lines changed: 5120 additions & 496 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.agents/docs/2026-09-29-build-progress-display-design.md‎

Lines changed: 728 additions & 0 deletions
Large diffs are not rendered by default.

‎.agents/docs/2026-09-29-workspace-build-graph-design.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,10 @@ read from the member, or made a value of the plan:
563563
| 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 |
564564
| 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 |
565565
| `${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 |
566+
| 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 |
567+
| the order of the members' programs (2026.9.29.5) | discovery order | dependencies first (a cycle skips its closing edge) | e2e 839 B2 |
568+
| `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 |
569+
| 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 |
566570

567571
Each criterion fails on 2026.9.29.1 and passes on 2026.9.29.2. The resource
568572
case also showed a defect of every build: a quoted `#include` in a script was

‎.agents/docs/README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ superseded_by: 2026-09-07-....md # when status is superseded
1818
---
1919
```
2020

21-
317 records.
21+
318 records.
2222

2323
## By subject
2424

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

3333
- [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
34+
- [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
3435
- [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
3536
- [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
3637
- [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
@@ -109,6 +110,7 @@ Records that declare one. Everything else is listed by date below.
109110
### 2026-09
110111

111112
- [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
113+
- [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
112114
- [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
113115
- [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
114116
- [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

‎CHANGELOG.md‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,91 @@
44
> Each `## [<version>]` section is that release's notes. Entries are written in English
55
> from 2026.9.28.3 on; earlier entries remain as written.
66

7+
## [2026.9.29.5] - 2026-09-29
8+
9+
This release completes the workspace build graph in the commands around the
10+
build, from the validation project's post-release run of 2026.9.29.4: build
11+
programs are reused across selections and run dependencies first, the build
12+
database and `--configure-only` plan by configuration, and the output names
13+
what it reports. A build now reports each step when its outcome is known, and
14+
shows what runs while it runs (`.agents/docs/2026-09-29-build-progress-display-design.md`).
15+
16+
### Added
17+
18+
- **A build reports each step once, with its outcome.** A package's line is
19+
written when every step the graph assigns to it has run (`done` with the
20+
span of its steps, read from ninja's log), when the global cache supplied it
21+
(`cached N units`), when a step of it failed (`failed`), or when the build
22+
ends. A package with nothing to do has no line. The packages the command was
23+
asked to build are listed; their dependencies are folded into one line, and
24+
a dependency that fails is named. `--verbose` lists every package and prints
25+
each step as ninja reports it (e2e 842).
26+
- **A status line states the build.** On a terminal the steps still running
27+
and one status line, `Building 612/1203 · 14:32 · gpp.gui: vcpkg install
28+
6:10`, are drawn below the output and updated in place; the status line
29+
names the longest-running `check` or `prepare` action, which the engine's
30+
action wrapper reports when it starts. In a log (CI, a pipe) only final lines
31+
are written, and the status line is written when the log has been silent for
32+
a minute (e2e 842, 843).
33+
- **`Finished` states the whole command's time**, and for a command of ten
34+
seconds or more how it was spent (`plan`, `programs`, `build`) and the step
35+
that took at least a quarter of the build.
36+
37+
### Fixed
38+
39+
- **A failed step is reported when it fails.** Its diagnostics were printed
40+
after ninja exited, that is, after every step still running had finished:
41+
a compile error beside a twenty-minute vcpkg install appeared twenty minutes
42+
late (e2e 842).
43+
- **macOS and Windows terminals are terminals.** Terminal detection was
44+
compiled only under `__unix__`, which Apple's compilers do not define, so
45+
the download bar and colours were drawn on Linux alone. A Windows console
46+
now receives mcpp's lines as UTF-16, so `·`, `→` and non-ASCII paths appear
47+
as written whatever its code page.
48+
49+
- **A member's build program is reused whichever members a command selects.**
50+
Its graph document listed every requester in the plan, the virtual root
51+
included, so the program's re-run key followed the selection: `-p`, `mcpp
52+
pack` and `mcpp emit build-database` reran the programs a `--workspace`
53+
build had run (7 to 15 s each in the validation project). A program's
54+
document now lists the requests made inside its own closure (e2e 839).
55+
- **A member's build program runs after those of the members it depends on.**
56+
They ran in discovery order, so a member's program could run before its
57+
dependency's had applied its directives (e2e 839).
58+
- **`mcpp emit build-database` and `mcpp build --configure-only` plan a
59+
workspace by configuration, as the build does.** They planned each member
60+
separately, so a package two members use was described once per member,
61+
each time with other arguments (the validation project's core library three
62+
times). A member that is a program is described as one, and its tests as
63+
tests. A configuration whose plan fails is planned member by member, so a
64+
member's failure still affects that member only (e2e 840; SPEC-005 v1.6).
65+
- **A command that plans several configurations writes the root
66+
`compile_commands.json` once**, as the union of their databases. Each
67+
configuration replaced it, and under `mcpp build --workspace`, whose
68+
configurations build at the same time, the file was the last one's (e2e 840).
69+
70+
### Behaviour changes
71+
72+
- **A build program has one line, which names its package and states its
73+
outcome**: `build.mcpp <package> ran <time>`, `cached` or `failed`, in
74+
place of `build.mcpp compiling <package>` and `running <package>`, and of
75+
`up to date <package> (cached)` (e2e 839, 842). The programs of the
76+
requested packages are listed, and those of their dependencies are folded
77+
into one line.
78+
- **`Compiling <package>` is written when the package's steps have run**, with
79+
their outcome, rather than for every direct dependency before ninja starts;
80+
the per-dependency `Cached <package> (N units)` line is `--verbose` output,
81+
as `cached N units` (e2e 842).
82+
- **A selected member is announced by its directory** in a `--workspace`
83+
build, also where another member depends on it (e2e 839).
84+
- **`mcpp pack` summarises many outputs.** A format that reports more than
85+
eight outputs is reported by the entry each lies in below their common
86+
directory, with a count; `--verbose` names every output, and
87+
`--message-format json` lists every one as before (e2e 841).
88+
- **Build database set names (SPEC-005 v1.6).** A set is named by its package;
89+
a document of several configurations prefixes each name with the
90+
configuration's build directory name, instead of `<member>/`.
91+
792
## [2026.9.29.4] - 2026-09-29
893

994
This release links a program that a workspace member ships through

‎docs/00-what-mcpp-is.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ int main() {
144144
```console
145145
$ mcpp run
146146
Inferred target hello (bin from src/main.cpp)
147-
Compiling hello v0.1.0 (.)
147+
Compiling hello v0.1.0 (.) done 0.61s
148+
148149
Finished dev [unoptimized + debuginfo] in 0.64s
149150
Running `target/x86_64-linux-gnu/0946988e9e4b52ba/bin/hello`
150151

‎docs/07-workspace.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,14 @@ member that several members use is compiled once.
441441
- **Resources.** A member's `[resources]` and `windows_code_page` are
442442
compiled against the member's directory and include directories and embedded
443443
into that member's programs and shared libraries only (2026.9.29.2+).
444+
- **Build programs.** The members' build programs run dependencies first, and
445+
a program's result is reused by every command whose inputs to it are
446+
unchanged, whichever members the command selects (2026.9.29.5+).
447+
- **Compile database.** `mcpp build --configure-only` and `mcpp emit
448+
build-database` plan as the build does, one plan per configuration with each
449+
member's tests, so a package the members share is described once per
450+
configuration. A command that planned several configurations writes the root
451+
`compile_commands.json` once, as the union of their databases (2026.9.29.5+).
444452
- **No-op builds.** A command repeated with nothing changed is answered by one
445453
check per configuration, without planning.
446454
- **Module names.** Members built in one graph share one module namespace:

‎docs/09-commands-by-scenario.md‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,56 @@ An index refresh is reported step by step when the xlings that mcpp drives
227227
emits progress events for it (xlings 2026.9.28.1+). With an older xlings it
228228
shows its status line and finishes silently, as before.
229229

230+
## What a build prints
231+
232+
A build reports each step once, when its outcome is known (2026.9.29.5+):
233+
234+
```console
235+
$ mcpp build --workspace
236+
build.mcpp gpp.core ran 16.00s
237+
build.mcpp gpp.gui ran 6.70s
238+
Compiling gpp.core (GalTranslPP) done 3m12s
239+
Compiling 23 dependencies done 6m20s
240+
Compiling gpp.gui (GPPGUI) done 38m05s
241+
242+
Finished fast-release [unoptimized + debuginfo] in 41m53s · plan 1m13s · programs 32s · build 40m08s · longest gpp.gui: vcpkg install 22m10s
243+
```
244+
245+
- A package's line names the package and states its outcome: `done` with the
246+
span of its steps, `cached` when the global cache supplied it, `failed`, or
247+
the number of its steps that ran when a failed build stopped before the
248+
package completed. A package with nothing to do has no line.
249+
- The packages the command was asked to build (the root package, or the
250+
selected members) are listed. The packages they depend on are folded into
251+
one line, and a dependency that fails is named.
252+
- A build program's line states `ran` with its time, `cached`, or `failed`.
253+
- A failed step is reported when it fails, with its diagnostics, while ninja
254+
waits for the steps still running.
255+
- `Finished` states the whole command's time. A command of ten seconds or
256+
more also states how the time was spent, and names the step that took at
257+
least a quarter of the build when there is one.
258+
259+
On a terminal, the steps still running and one status line are drawn below
260+
the output and updated in place:
261+
262+
```
263+
Compiling gpp.gui (GPPGUI) 61 steps
264+
265+
Building 612/1203 · 14:32 · gpp.gui: vcpkg install 6:10
266+
```
267+
268+
The status line counts the build's steps, shows the time since the command
269+
started, and names the longest-running `check` or `prepare` action; ninja
270+
reports every other step only when it finishes. When the output is not a
271+
terminal (a CI log, a pipe), only final lines are written, and the status line
272+
is written when the output has been silent for a minute. `TERM=dumb` selects
273+
that form on a terminal too.
274+
275+
`--verbose` lists every package, including those with nothing to do (`fresh`),
276+
states each build program's compile and run times, and prints every step as
277+
ninja reports it (`[f/t] <command>` and its output). `--quiet` prints none of
278+
it. Machine output (`--message-format json`) is unchanged.
279+
230280
## Validating a descriptor before publishing
231281

232282
`mcpp xpkg parse` reads a descriptor with the resolver's own grammar, so what

‎docs/10-pack-and-release.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ the last is the distributable and only it is printed as `Packed`. A format
265265
whose chain ends in two files is refused by `mcpp run --format`, naming both,
266266
because a runner takes one operand.
267267

268+
A format may report many outputs, one per file of a distribution tree. Up to
269+
eight are printed one per line; more are printed by the entry each lies in
270+
below their common directory, with a count (`Packed Release/app (1309
271+
files)`), and `--verbose` prints every one (2026.9.29.5+).
272+
`--message-format json` lists every output in either case.
273+
268274
An unknown `<name>` is refused naming the format set the resolved graph
269275
provides, the same set `mcpp pack --format bogus` reports. `--format` together
270276
with `--no-runner` is refused — an `.apk` or an installed `.app` cannot be

‎docs/30-build-mcpp.md‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,11 @@ one. `mcpp::graph_file()` names a JSON document that states the resolved graph:
10451045
`""`.** The root decides the graph, and when its program runs every input of
10461046
that decision is final, which is the reason `dep_linkage` is offered to it
10471047
alone.
1048+
- **In a workspace plan each selected member's program receives the document
1049+
of its own closure**, in which it is `root`, and `requested_by` lists the
1050+
requests made inside that closure (2026.9.29.5+). The document, and so the
1051+
program's re-run key, is therefore the same whichever members a command
1052+
selects. The members' programs run dependencies first.
10481053
- **`[package.metadata.<tool>]` is the package's statement about itself.** The
10491054
engine does not interpret the table. A path in it is resolved by the reader
10501055
against the entry's `manifest_dir`, because only the reader knows which values
@@ -1513,8 +1518,13 @@ variable, emit `mcpp:rerun-if-changed=config.h` / `mcpp:rerun-if-env-changed=USE
15131518
This replaces the old "process exited 0, so assume it's fine" guesswork with an
15141519
explicit input/output contract — incremental builds stay correct.
15151520
1516-
When nothing changed the output is `build.mcpp up to date (cached)`; otherwise
1517-
`build.mcpp compiling` / `running`.
1521+
Each program has one line, written when it finishes (2026.9.29.5+):
1522+
`build.mcpp <package> cached` when nothing changed, `build.mcpp <package> ran
1523+
<time>` when it was compiled or run (with `--verbose`, `compiled <time> · ran
1524+
<time>`), and `failed` when it failed. On a terminal the line shows `waiting`,
1525+
`compiling` or `running` with a clock while the program is pending or running.
1526+
The programs of the packages the command was asked to build are listed; those of
1527+
their dependencies are folded into one line, `build.mcpp N dependencies`.
15181528
15191529
## Host tools from a dependency (mcpp 2026.8.5.1+)
15201530

‎docs/40-baremetal.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,18 @@ cd blinky
200200
mcpp run
201201
```
202202

203-
Measured output:
203+
Output (2026.9.29.5; the times vary by machine):
204204

205205
```
206206
Resolving toolchain
207207
Resolved llvm@22.1.8 → riscv64-none-elf → @mcpp/registry/data/xpkgs/xim-x-llvm/22.1.8/bin/clang++
208208
Resolved host toolchain for build.mcpp: clang 22.1.8 (x86_64-unknown-linux-gnu)
209-
build.mcpp compiling
210-
build.mcpp running
209+
build.mcpp blinky ran 0.41s
211210
Inferred sources [src/**/*.{cppm,cpp,cc,c,S,s,asm}]
212211
Inferred target blinky (bin from src/main.cpp)
213-
Compiling blinky v0.1.0 (.)
214-
Cached riscv-virt-rt v0.3.0 (1 unit)
212+
Compiling blinky v0.1.0 (.) done 0.04s
213+
Compiling 1 dependency cached
214+
215215
Finished dev [unoptimized + debuginfo] in 0.05s
216216
Size blinky text 8572 data 80 bss 5668 total 14320
217217
Running `…/xim-x-qemu-riscv/9.2.4-1/bin/qemu-system-riscv64 … target/riscv64-none-elf/…/bin/blinky`

0 commit comments

Comments
 (0)