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
2,035 changes: 2,035 additions & 0 deletions .agents/docs/2026-08-24-graph-target-side-optimization-plan.md

Large diffs are not rendered by default.

1,090 changes: 1,090 additions & 0 deletions .agents/docs/2026-08-24-target-side-architecture.md

Large diffs are not rendered by default.

598 changes: 598 additions & 0 deletions .agents/docs/2026-08-24-target-side-design.md

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,82 @@
> 本文件追踪 `mcpp-community/mcpp` 公开仓的版本演进。
> 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)。

## [2026.8.24.2] — 2026-08-24

### 新增

- **目标侧是五层,而其中最大的一层此前没有名字。**

实测 `openkal-llvm-runtime` 编译的 729 个对象里,**498 个是 compiler-rt 的
builtins**、21 个是 libunwind 的。这个包最大的一块此前声明在 `mcpp:c++-abi`
名下 —— 而 `__udivti3` 及其同类是一个**纯 C 程序**需要的东西,与 C++ 无关。

⚠️ 把 builtins 算作 C++ 运行时的一部分,与 `targetside` 模块开头记录的缺陷同形:
一个交叉到 macOS 的 C 程序被问「有没有 C++ 运行时」,答「没有」,链接行因而
保留了载荷自带的 libc++。**一个只有部分程序需要的层仍然是层。**

五层为 `compiler` / `compiler-runtime` / `kernel-abi` / `c-abi` / `c++-abi`。
`compiler` 是唯一一个包不能供给的层 —— 族与族之间的差异(flag 拼写、模块模型、
BMI 格式、驱动 cfg)是引擎必须持有的事实,不是数据能描述的。

⚠️ `compiler` 层上报**族名**(`llvm`)而非驱动名(`clang`):使用者书写的每一处
都用族名,报告用驱动名会让 `requires = ["mcpp:compiler=llvm"]` 永远不可满足。

- **`requires = ["mcpp:<层>=<实现>"]` —— 在引擎里不出现实现名的前提下执行分层规则。**

libc++ 的源码由 clang 编译;递给 gcc 的实测结果是
`fatal error: __config: No such file or directory` —— 一个命名了读者从未打开过的
文件、且不提任何 mcpp 决定的消息。在引擎里写
`if (stdlib == "libc++" && compiler == gcc)` 会把两个实现名放进引擎;
写在包里,引擎只需检查一条它能一般性陈述的关系。

⚠️ 检查在**编译开始之前**运行,这正是声明它的全部意义。

- **规则一:每层恰好一个供给者。**

⚠️ 此前两个包供给同一层时,**图遍历顺序里第一个静默胜出** —— 那个顺序既不是
作者写的,也不是他能预测的 —— 而落选者的 `[build]` 段仍然进入命令行。
判据是失败模态:选错不会让链接失败,会得到一个能跑、偶尔崩的程序。
`[build] runner` 早已按同一条规则处理。

- **`docs/14-target-side.md`(中英)与 `docs/spec/target-side.md`(SPEC-002)。**

### 变更

- **`std-module` / `std-compat-module` / `std-module-flags` 移入 `[build]`。**

模块源是这个包的一个翻译单元 —— 引擎自己的注释早就这么写。放在 `[package]` 下
损失的恰恰是位置所决定的那件事:`[build]` 可条件化而 `[package]` 不可,于是
一个在多种 C 库之上供给同一 C++ 运行时的包无法为不同 C 库给出不同 flag。
`-D_GNU_SOURCE` 对 musl 与 glibc 是对的,对 picolibc 是错的。
`[package]` 写法保留为别名。

- **报告按需暴露。** 零配置构建的五个层全部来自同一份载荷,五行 `(payload)`
回答的是无人提出的问题。默认只列出来源不是编译器载荷的层;`MCPP_VERBOSE=1`
列出全部;**诊断始终列出它所依据的每一层**。

- **`Family` 去掉 `OpenkalLlvm`,拼写归一为 `llvm`。**

⚠️ 保留枚举项的代价不止一条死分支:可用工具链列表按族枚举,一份载荷挂在两个
族名下就出现两次,而安装状态按族记录 ⇒ **第二份被报成未安装,并被推荐给已经
装了它的人。**

- **词表 pin 替换用户默认时,状态行说出替换与修法;图已知后指出这次替换本可不必。**

⚠️ 让全局默认压过词表 pin 的做法被实测否掉:一个无依赖的工程、全局默认
`llvm@22.1.8`、`--target x86_64-windows-gnu`,**从能构建变成不能构建**。
行所 pin 的不是「偏好的编译器」而是「供给该目标 C 库的载荷」。
结构性修法(把 pin 的决定与目标侧一样后移)未在本版落地:`tc` 在解析后到图之间
被读写 39 处。

### 兼容性

- `hosted-standard-library` 继续表示 C++ 层;
- `openkal-llvm` 拼写继续解析;
- `[package]` 下三个 std-module 键继续被接受;
- ⚠️ 实测:**旧引擎(2026.8.24.1)读带 `requires` 的清单构建成功** ——
TOML 侧忽略未知键,xpkg 侧警告而非报错。已发布的包因此可以先行声明。

## [2026.8.20.2] — 2026-08-20

### 新增
Expand Down
30 changes: 30 additions & 0 deletions docs/05-mcpp-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,36 @@ blas = "compat.openblas" # equivalently: mcpp build --cap blas=compat.openbl
compat.openblas = "0.3.0" # the provider must be a real dependency in the graph
```

The reserved prefix `mcpp:` names the target-side layers this engine resolves,
and those names are validated against a closed set. A package-level `requires`
array carries the symmetric statement — what a target-side layer must resolve to
for this package to be usable.

```toml
[package]
name = "acme.llvm-runtime"
version = "0.1.0"
provides = ["mcpp:compiler-runtime=compiler-rt", "mcpp:c++-abi=libc++"]
requires = ["mcpp:compiler=llvm"]
```

A package that is a standard library states its `std` module source under
`[build]`, where the flags it needs become conditional like any other build
input.

```toml
[build]
std-module = "llvm-generated/std.cppm"
std-compat-module = "llvm-generated/std.compat.cppm"
std-module-flags = ["--no-default-config", "-nostdinc++"]

[target.'cfg(c-abi = "musl")'.build]
std-module-flags = ["-D_GNU_SOURCE"]
```

See [14 - The Target Side](14-target-side.md) for the five layers, the rules
that govern them, and the diagnostics.

Binding is **deterministic**:

| Providers of a required capability in the graph | Result |
Expand Down
Loading
Loading