Skip to content

Commit ca6646f

Browse files
committed
2026.10.1.2: a pack states its build, every drive takes the job count, and a unit's compile does not depend on the member selection (#751, #753)
Implements .agents/docs/2026-10-01-pack-drive-and-selection-independent-compile-design.md. - Every ninja drive takes the job count and the stale-token reclaim from the plan, and is reported whenever the command opened the report, unless its caller states that it writes its own lines (mcpp test's per-test drives). - mcpp pack states its build: package lines, the status row, and Finished before the first Packing line; one Finished for several configurations; the dispatch pass is reported; a pack fills the global dependency cache. - Every package's BMIs lie below its own directory except the root's, as object files do since #233; a unit reads one module map of what it reaches through its imports (a GCC mapper, or a clang/MSVC argument file). - A file a member lists from outside its directory belongs to that member, not to the workspace's virtual root. - Position independence follows the target: every unit of an ELF target that is not freestanding is compiled with -fPIC.
1 parent 80d1fde commit ca6646f

34 files changed

Lines changed: 1983 additions & 274 deletions

‎.agents/docs/2026-10-01-pack-drive-and-selection-independent-compile-design.md‎

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

‎.agents/docs/README.md‎

Lines changed: 5 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-
321 records.
21+
322 records.
2222

2323
## By subject
2424

@@ -30,6 +30,7 @@ Records that declare one. Everything else is listed by date below.
3030

3131
### design
3232

33+
- [A pack's build reported as a build, and a unit's compile independent of the member selection: triage and design (#753, #751)](2026-10-01-pack-drive-and-selection-independent-compile-design.md) — active
3334
- [Member selection, build programs prepared once, a pack over several members, and the output streams of `mcpp run`: the plan for the release after 2026.9.30.2 (#748, #749, #750)](2026-09-30-member-selection-and-build-program-cost-plan.md) — landed
3435
- [The build's wall time, its progress count, a hang after the build, and #732 and #744: measurements and a remediation plan](2026-09-30-build-wall-time-progress-count-and-hang-plan.md) — landed
3536
- [Build output, revision 3: every package that does work is named, the live display is one line drawn in one write, and a repeated warning is stated once per file](2026-09-30-build-output-refinement-design.md) — landed
@@ -110,6 +111,9 @@ Records that declare one. Everything else is listed by date below.
110111

111112
## By date
112113

114+
### 2026-10
115+
116+
- [A pack's build reported as a build, and a unit's compile independent of the member selection: triage and design (#753, #751)](2026-10-01-pack-drive-and-selection-independent-compile-design.md) — active
113117
### 2026-09
114118

115119
- [Member selection, build programs prepared once, a pack over several members, and the output streams of `mcpp run`: the plan for the release after 2026.9.30.2 (#748, #749, #750)](2026-09-30-member-selection-and-build-program-cost-plan.md) — landed

‎CHANGELOG.md‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,72 @@
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.10.1.2] - 2026-10-01
8+
9+
This release implements the design for a pack's build and a compile that does
10+
not depend on the member selection
11+
(`.agents/docs/2026-10-01-pack-drive-and-selection-independent-compile-design.md`),
12+
and resolves mcpp#751 and mcpp#753. A project that imports a module of a
13+
dependency, and every project on an ELF target, is compiled once more after the
14+
upgrade, because its commands change (both under **Changed**).
15+
16+
### Fixed
17+
18+
- **A unit is compiled by the same command in every selection of a
19+
workspace.** The selections of one configuration share a build directory,
20+
and three facts about the whole graph reached the commands of members they
21+
did not concern, so each switch between `--workspace` and `-p` recompiled
22+
them (mcpp#751; GalTranslPP 3.1.3 recompiled its core for 3m22s):
23+
- a module name that two members provide moved every BMI of that name below
24+
its provider's directory, and told the importers so, only when the graph
25+
held both providers;
26+
- a file that a member lists from outside its own directory was owned by the
27+
workspace's virtual root, whose object census depended on how many members
28+
listed it;
29+
- a member that builds a shared library put `-fPIC` on every unit of the
30+
graph.
31+
A command now depends on the unit's package, the packages it reaches, the
32+
features the selection activates for it and the declarations a selected
33+
member holds as the root, and on nothing else in the graph. `mcpp build
34+
--workspace` followed by `mcpp build -p <member>` compiles nothing, and so
35+
does any alternation of selections (e2e 872).
36+
- **`mcpp pack` states the build it performs.** Its build wrote no package
37+
line, no status row and no `Finished`, so a release job whose pack
38+
recompiled mcpp showed `Planning` for six minutes (mcpp#753). A pack is now
39+
stated as `mcpp build` states one, with `Finished` before the first `Packing`
40+
line and one `Finished` for a pack over several configurations; the second
41+
pass of a dispatched `--format` is stated in the same way (e2e 871).
42+
- **`[build] jobs` bounds every command that compiles.** `mcpp test` and
43+
`mcpp pack` ran ninja's default number of jobs whatever `[build] jobs`,
44+
`--jobs` or `MCPP_JOBS` said, which on a machine with little memory exceeded
45+
the bound the key exists to enforce. The backend reads the job count from
46+
the plan, and the reclaim of stale `bmi_schedule = "on"` tokens, which ran
47+
only under `mcpp build`, runs before the first drive of every build
48+
directory (e2e 871).
49+
- **A pack fills the global dependency cache** with the dependencies its
50+
build compiled, as `mcpp build` and `mcpp test` do.
51+
52+
### Changed
53+
54+
- **Every package's BMIs lie below the package's directory, except the root
55+
package's.** The rule is the one object files have followed since mcpp#233:
56+
`gcm.cache/<package>/<module>.gcm` (`pcm.cache` with clang). A unit that
57+
imports a module of another package reads one module map of the modules it
58+
reaches through its imports: a mapper file with GCC, and an argument file
59+
`@<build directory>/modmap/<package>-<hash>.modmap` of `-fmodule-file=` or
60+
`/reference` lines with clang or MSVC. A project whose modules are all its
61+
own is laid out, and every command spelled, as before. A package whose
62+
module name another package of the graph provides is served from the global
63+
dependency cache again; 2026.9.30.2 compiled it in the project.
64+
- **Every unit of an ELF target that is not freestanding is compiled with
65+
`-fPIC`,** whether or not the graph links a shared library, as rustc's
66+
default relocation model does on these targets: an object compiled once
67+
serves a program and a shared object. Mach-O compilers produce
68+
position-independent code by default, PE has no such flag, and nothing
69+
changes on those targets or on freestanding ones. The global dependency
70+
cache keys these entries by the flag, so each is compiled once more and
71+
then served again.
72+
773
## [2026.10.1.1] - 2026-10-01
874

975
This release implements the plan for member selection, build programs prepared

‎docs/04-mcpp-toml.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,9 @@ jobs = "auto" # or a positive number; --jobs / MCPP_JOBS override it
819819
bmi_schedule = "off" # auto (default, = off) | on | off
820820
```
821821

822-
`jobs` is how many compiles run at once. `"auto"` is resolved **against the
822+
`jobs` is how many compiles run at once, in every command that compiles:
823+
`build`, `run`, `test` and `pack` (2026.10.1.2+; before it, `test` and `pack`
824+
ran ninja's default number of jobs whatever the key said). `"auto"` is resolved **against the
823825
machine doing the build**, never frozen into the manifest: it takes the physical
824826
core count on a heterogeneous CPU (a 13900K is 8 P-cores + 16 E-cores, so its 32
825827
threads are not 32 equal workers) and clamps that by free memory, because a

‎docs/05-dependencies.md‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -551,14 +551,22 @@ each of them may have its own module of one name.
551551
are built separately.
552552
- Two packages that one program links may not provide the same name. The build
553553
is refused, and the message names the package whose closure holds both.
554-
- When two packages of one build provide a name, each BMI lies below its
555-
package's directory in the build directory, and every compile that may import
556-
the name is told which one it means: through a module map with GCC, through
557-
`-fmodule-file=` with Clang, and through `/reference` with MSVC. When every
558-
name has one provider, the build directory and every command are as they
559-
were before.
560-
- A package that provides such a name is compiled in the project, not served
561-
from the global dependency cache.
554+
- Every package's BMIs lie below the package's directory in the build
555+
directory, `gcm.cache/<package>/` (`pcm.cache` with Clang), except the root
556+
package's, which lie at their names, as object files do (2026.10.1.2+). A
557+
compile that imports a module of another package is told where its BMI is,
558+
and where the BMIs of the modules that one imports are, through one module
559+
map: a mapper file with GCC (`-fmodule-mapper=`), and an argument file of
560+
`-fmodule-file=` lines with Clang or `/reference` lines with MSVC
561+
(`@<build directory>/modmap/<package>-<hash>.modmap`). The map lists what the
562+
unit reaches through its imports and nothing else, so the command does not
563+
change with the rest of the graph. A project whose modules are all its own
564+
is laid out, and every command spelled, as before.
565+
- Until 2026.10.1.2 a BMI moved below its package's directory only when two
566+
packages of the graph provided its name, and such a package was not served
567+
from the global dependency cache. Both depended on which packages a command
568+
selected, so a workspace member was compiled again at each switch between
569+
`-p` and `--workspace` (mcpp#751).
562570
- clangd finds a module by its name in the compilation database, so for a name
563571
two packages provide it may show the other program's module. The build is
564572
not affected.

‎docs/07-workspace.md‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,17 @@ member that several members use is compiled once.
486486
- **Selection.** `--workspace`, and a virtual root without `-p`, select every
487487
member. `-p X`, and a command run in X's directory, plan X and what X
488488
reaches; `-p X -p Y` plans both together, as one selection (§5.3). The
489-
selections share the build directory, so `mcpp build --workspace`
489+
selections share the build directory, and a unit is compiled by the same
490+
command in every selection that holds it: the command depends on the unit's
491+
package, the packages that package reaches, the features the selection
492+
activates for it and the declarations a selected member holds as the root,
493+
and on nothing else in the graph (2026.10.1.2+). So `mcpp build --workspace`
490494
followed by `mcpp build -p X` compiles nothing, and a package is compiled
491-
again only when its active features differ between the two commands.
495+
again only when its active features, or the root declarations of the
496+
selected members, differ between the two commands. Before 2026.10.1.2,
497+
three facts about the whole graph also reached other members' commands: a
498+
module name that two members provide, a file that two members list from
499+
outside their own directories, and a member that builds a shared library.
492500
- **Flags.** A member's `cflags`, `cxxflags`, `ldflags` and defines apply to
493501
that member's commands. Editing them recompiles that member and what
494502
imports it; the build directory stays the same.
@@ -570,6 +578,8 @@ myproject/
570578
└── target/<triple>/<configuration>/
571579
├── build.ninja, compile_commands.json # one graph and one database per configuration
572580
├── obj/<package>/ # intermediate objects of every package
581+
├── gcm.cache/<package>/ # each package's BMIs (pcm.cache with clang)
582+
├── modmap/ # the module maps of the units that import them
573583
└── bin/
574584
├── server/ # a member's products: bin/<package name>/
575585
│ ├── server

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,16 @@ relative `-o` keeps meaning the directory the command was typed in.
170170
take, with the same precedence: `--profile` wins over either, on all three
171171
commands.
172172

173+
A pack states the build it performs as `mcpp build` states one (mcpp
174+
2026.10.1.2+): a line for each package that does work, the status row while it
175+
runs, and `Finished` before the first `Packing` line. A pack over several
176+
configurations builds every configuration first and writes one `Finished`. The
177+
second pass of a dispatched `--format` is stated in the same way, and its
178+
`Distributing` and `Packed` lines follow it. The build runs `[build] jobs`
179+
compiles at once, as every command that compiles does. Before 2026.10.1.2 the
180+
build of a pack wrote none of this, and a pack that recompiled for minutes
181+
showed only `Planning`.
182+
173183
### Packing several members (mcpp 2026.10.1.1+)
174184

175185
`-p` may be repeated, and `--workspace` and `--exclude` select members as they do

‎docs/91-toolchain-internals.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ reads this flag**.
645645

646646
| axis | the question | examples | the form of the query |
647647
|---|---|---|---|
648-
| **target format** | what kind of image is produced | `-fPIC` (PE code is position independent by design; clang refuses the flag outright) | `triple::parse(...)->is_pe()`, host fallback |
648+
| **target format** | what kind of image is produced | `-fPIC`: on every unit of an ELF target that is not freestanding, whether or not the graph links a shared library (2026.10.1.2+), and never on PE, whose code is position independent by design and where clang refuses the flag outright | `triple::parse(...)->object_format()`, `is_pe()`, host fallback |
649649
| **target ABI** | which linker will consume this | `--out-implib` vs `/IMPLIB:`, `/DEF:`, the SONAME / install-name form | `is_msvc_target(tc)`, `triple->is_msvc_env()` |
650650
| **dialect** | which program mcpp is invoking | `-L` vs `/LIBPATH:`, `-I` vs `/I`, the archive command | `dialect_for(tc)`, `LinkStyle::SeparateLinker` |
651651

‎docs/specs/build-database.md‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,17 @@ mcpp 输出的 S1 文档满足 S1 等级 2,不输出 `ide.options`。等级 3
126126
真的编译就能得到(§3.4)。`ide.toolchains.<id>.build-id` 给出编译器的构建标识,
127127
取自 mcpp 已经算出的驱动身份(工具链指纹的同一个字段),同一工具链的两次运行
128128
之间保持稳定。**已实现**
129-
- **R3.8a** 一个模块名在一个程序之内标识一个模块,而一个配置可以包含多个程序。同一
130-
配置中两个包提供同一个模块名时(两者不在同一个包的闭包中,#732),两个单元的
131-
`provides` 都列出这个名字;可能导入它的每个单元,其 `arguments` 带有构建所用的
132-
绑定:GCC 为 `-fmodule-mapper=<映射文件>`(相对 `work-directory`),Clang 为
133-
`-fmodule-file=<名字>=<路径>`,MSVC 为 `/reference <名字>=<路径>`。只按名字在文档中
134-
查找提供方的消费方,因此可能取到另一个程序的模块;构建本身不受影响。每个名字只有
135-
一个提供方时,文档与此前逐字相同。**已实现**
129+
- **R3.8a** 一个模块名在一个程序之内标识一个模块,而一个配置可以包含多个程序
130+
(#732)。除根包之外,每个包的 BMI 都位于其所属包的子目录下(2026.10.1.2+,#751)。
131+
导入其他包模块的单元,以及提供这样一个模块的单元,其 `arguments` 带有构建所用的
132+
一份模块映射:GCC 为 `-fmodule-mapper=<映射文件>`(相对 `work-directory`),Clang
133+
与 MSVC 为一个参数文件 `@<绝对路径>/modmap/<包>-<哈希>.modmap`,其中每行一个
134+
`-fmodule-file=<名字>=<路径>` 或 `/reference <名字>=<路径>`。映射只列出该单元经其
135+
导入所能到达的模块,因此同一单元在一个配置的每一种成员选择下,`arguments` 逐字相同。
136+
`.modmap` 后缀与 CMake 模块映射相同,读者可据此把未展开的参数文件识别为模块机制。
137+
同一个名字由两个包提供时,两个单元的 `provides` 都列出它;只按名字在文档中查找提供方
138+
的消费方,因此可能取到另一个程序的模块,构建本身不受影响。模块全部属于根包的工程,
139+
文档与此前逐字相同。**已实现**
136140
- **R3.9** `ide.role` 取自扫描器读到的模块声明形式:
137141

138142
| 声明 | `ide.role` |

‎docs/zh/04-mcpp-toml.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,9 @@ jobs = "auto" # or a positive number; --jobs / MCPP_JOBS override it
778778
bmi_schedule = "off" # auto (default, = off) | on | off
779779
```
780780

781-
`jobs` 是同时运行多少个编译。`"auto"` 是**相对正在执行构建的这台机器**
781+
`jobs` 是同时运行多少个编译,适用于每一条会编译的命令:`build`、`run`、`test` 与 `pack`
782+
(2026.10.1.2+;此前 `test` 与 `pack` 无论这个键怎么写都按 ninja 的默认并行数运行)。
783+
`"auto"` 是**相对正在执行构建的这台机器**
782784
解析的,绝不会被冻结进 manifest:它取一颗异构 CPU 的物理核心数(一颗
783785
13900K 是 8 个 P-core + 16 个 E-core,所以它的 32 个线程不是 32 个
784786
等价的工作者),并按空闲内存夹紧这个数字,因为单次模块接口编译峰值

0 commit comments

Comments
 (0)