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
598 changes: 598 additions & 0 deletions .agents/docs/2026-09-13-four-upstream-asks-from-a-ui-framework.md

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ superseded_by: 2026-09-07-....md # when status is superseded
---
```

282 records.
283 records.

## By subject

Records that declare one. Everything else is listed by date below.

### build-program

- [Four upstream asks from a UI framework: what each one is under mcpp's design, and the combined plan](2026-09-13-four-upstream-asks-from-a-ui-framework.md) — active

### docs

- [The documentation as a book: a chapter-by-chapter design](2026-09-08-the-documentation-as-a-book.md) — active
Expand Down Expand Up @@ -61,6 +65,7 @@ Records that declare one. Everything else is listed by date below.

### 2026-09

- [Four upstream asks from a UI framework: what each one is under mcpp's design, and the combined plan](2026-09-13-four-upstream-asks-from-a-ui-framework.md) — active
- [The engine gaps left open after the SDK batch](2026-09-12-engine-gaps-after-the-sdk-batch.md) — landed
- [A verified Web run that asked the host for node](2026-09-12-a-verified-web-run-that-asked-the-host-for-node.md) — landed
- [Implementation plan: a UI framework on Android, iOS and Web (#622)](2026-09-12-622-implementation-plan.md) — landed
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/openkal-cross.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,27 @@ jobs:
"$MCPP_UNDER_TEST" toolchain install llvm 22.1.8
"$MCPP_UNDER_TEST" toolchain default 'llvm@22.1.8'

# WHAT THIS RUNNER ACTUALLY PROVIDES FOR THE mingw TARGET. On a Windows
# host `openkal-windows`'s build program generates no import libraries
# ("the system's own are present"), so `-lntdll` and its neighbours are
# found by lld only where the host, the sandbox or the payload puts
# them. This job was green with one sandbox lineage and red with the
# next (2026-09-13, PR #629, same sources, same image), which is the
# signature of a dependency on cached state nobody declared. The lines
# below say where the libraries come from, so the next such reading is
# diagnosed from the log rather than from a bisect over caches.
- name: What this host provides for x86_64-w64-windows-gnu
if: matrix.host == 'windows'
run: |
echo "PATH=$PATH" | tr ':' '\n' | head -40
ls "${MCPP_HOME:-$HOME/.mcpp}/registry/data/xpkgs" 2>/dev/null || echo "(no xpkgs dir)"
CLANG=$(ls "${MCPP_HOME:-$HOME/.mcpp}"/registry/data/xpkgs/xim-x-llvm/22.1.8/bin/clang++.exe 2>/dev/null | head -1)
echo "clang=$CLANG"
[ -n "$CLANG" ] && "$CLANG" --target=x86_64-w64-windows-gnu -print-search-dirs
[ -n "$CLANG" ] && "$CLANG" --target=x86_64-w64-windows-gnu -print-file-name=libntdll.a
[ -n "$CLANG" ] && "$CLANG" --target=x86_64-w64-windows-gnu -print-file-name=libkernel32.a
command -v x86_64-w64-mingw32-gcc gcc 2>/dev/null || true

- name: The program — one source, three targets
run: |
set -euo pipefail
Expand Down
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,35 @@

## [Unreleased]

### `mcpp::action` 的列表不再有长度上限;`${mcpp.self}` 让 action 叫出引擎自己

内置的 `mcpp` 模块此前把一个 action 的 `inputs`、`outputs`、`command` 等六个列表
放在定长数组里(`inputs` 与 `outputs` 各 8192 字节的序列化 JSON),放不下的声明
被拒绝为「arguments did not fit」。上限按字节计,于是一个消费者的 checkout 深度
决定了 44 个资源文件的列表能否通过(HuxerUI#130 量得的余量是 45 字节);而
`outputs` 是作者无法缩短的那一个列表:没有点名的产物无法构建,也不存在面向
outputs 的 depfile。六个数组换成模块内部基于 `realloc` 增长的 std-free 缓冲,
导出接口、协议版本与原本放得下的 action 的序列化字节全部不变(缓存键因此不变)。
`"overflow":true` 标记保留,含义改为分配失败,引擎侧消息随之重写。运行期的命令
仍受操作系统 argv 上限约束,那是工具自己命令行的事。

`${mcpp.self}` 加入 action argv 的替换家族,替换为引擎自己的绝对路径。action 的
命令是没有 shell 的 argv,构建程序此前没有可移植的拷贝手段;`${mcpp.self} stage
--verify content --output <dst> <src>` 即每条 `stage_file` 边已在执行的那次拷贝。
`mcpp stage` 的参数形状自此成为契约,其帮助文本改为陈述真实的默认值(content)。

顺带修正引擎的命令长度守卫:它此前把每条 `build` 行读成命令的代理,这对展开
`$in`/`$out` 的规则成立,对命令是字面 argv 的 action 规则不成立 —— 一个 200 个
输出的 action 在 Windows 分片上被整条边行当 argv 计数而拒绝。守卫现在对字面命令
量它自己的文本。

- 判据:`tests/e2e/659`(600 个输入与 600 个输出的 action 整体进入 build.ninja,
边行越过每个宿主的 argv 上限而不被守卫误拒,缓存回放后仍完整;在 2026.9.12.4
上同一夹具被拒绝),`tests/e2e/660`
(`${mcpp.self}` 在每个分片上完成一次拷贝,空转重建不再拷贝;在 2026.9.12.4
上 token 原样落入 build.ninja)。
- 设计记录:`.agents/docs/2026-09-13-four-upstream-asks-from-a-ui-framework.md`。

### wasm 产物契约:启动器改名为 `.js`,`.wasm` 是隐式输出(#622 A5)

`wasm32-emscripten` 行此前用的是宿主借来的裸名 —— `bin/<name>`(Linux 宿主)或
Expand Down
15 changes: 15 additions & 0 deletions docs/30-build-mcpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,20 @@ and the module graph during prepare, so an output whose *name* is unknown
cannot be built. Content may arrive later; names may not. A malformed action is
a hard error, never a silent skip.

**The lists have no declared size limit** (2026.9.13.1+). `inputs`, `outputs`
and `command` grow with what is declared; a generated tree of two hundred files
is two hundred `output` calls. Until 2026.9.13.1 the bundled module held each
list in a fixed array (8192 bytes of serialised JSON for `inputs` and
`outputs`) and refused a declaration that did not fit, so a consumer's
checkout depth decided whether a list of forty files was accepted. What
remains bounded is the **command at run time**, by the operating system's
limit on a process's arguments (128 KiB per argument on Linux, 32767
characters for a Windows `CreateProcess`); that is a limit on the tool's own
command line, and a tool that takes hundreds of files takes them through a
response file or a directory argument of its own. The engine's own guard
against it measures the command, not the edge: an action's inputs and
outputs are graph edges, never argv.

For a generated **module interface**, declare its interface too:

```cpp
Expand Down Expand Up @@ -705,6 +719,7 @@ none to rely on), and the only interpolations are a closed set:
| `${mcpp.compile_db}` | path to `compile_commands.json` (what clang-tidy's `-p` wants) |
| `${mcpp.target_file:<name>}` | the built file of target `<name>` |
| `${mcpp.stage_dir}` *(2026.9.11.1+)* | the tree `mcpp pack` staged, absolute. `artifact` role only, and only under `mcpp pack --format <name>` |
| `${mcpp.self}` *(2026.9.13.1+)* | the engine's own executable, absolute. An action's command is an argv with no shell, so a build program has no portable way to copy a file; the engine is present wherever a build runs, and `${mcpp.self} stage --verify content --output <dst> <src>` copies one file, creates the destination's parent, and writes only when the bytes differ. That argument shape is a contract from 2026.9.13.1 on; a build program that names it declares that release as its floor |

The raw stdout protocol above remains the low-level substrate; `import mcpp;`
is the typed layer over it.
Expand Down
11 changes: 11 additions & 0 deletions docs/zh/30-build-mcpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,16 @@ mcpp 为那条边写出 `depfile =` 与 `deps = gcc`,ninja 读取该文件并把
所以名字未知的产物无法构建。内容可以晚到,名字不行。畸形 action 是**硬错误**,
绝不静默跳过。

**列表没有声明上的长度上限**(2026.9.13.1+)。`inputs`、`outputs` 与 `command`
随声明增长;一棵两百个文件的生成树就是两百次 `output` 调用。2026.9.13.1 之前,
内置模块把每个列表放在定长数组里(`inputs` 与 `outputs` 各 8192 字节的序列化
JSON),放不下的声明会被拒绝,于是一个消费者的 checkout 深度决定了四十个文件的
列表能否被接受。仍然有上限的是**运行期的命令**,由操作系统对进程参数的限制决定
(Linux 上每个参数 128 KiB,Windows 的 `CreateProcess` 是 32767 个字符);那是
工具自己命令行的上限,一个要接收几百个文件的工具用它自己的 response file 或目录
参数来接收。引擎自己针对它的守卫量的是命令而不是边:action 的输入与输出是图上的
边,从不进入 argv。

生成**模块接口**时,把它的接口也声明出来:

```cpp
Expand Down Expand Up @@ -606,6 +616,7 @@ mcpp 会写出 `<暂存树>.stage-manifest` —— 一个兄弟文件,永不是
| `${mcpp.compile_db}` | `compile_commands.json` 的路径(clang-tidy 的 `-p` 要的就是它) |
| `${mcpp.target_file:<name>}` | target `<name>` 构建出的文件 |
| `${mcpp.stage_dir}` *(2026.9.11.1+)* | `mcpp pack` 暂存出的那棵树,绝对路径。仅 `artifact` role 可用,且仅在 `mcpp pack --format <name>` 下可用 |
| `${mcpp.self}` *(2026.9.13.1+)* | 引擎自己的可执行文件,绝对路径。action 的命令是没有 shell 的 argv,构建程序因此没有可移植的拷贝手段;引擎在构建运行的每台机器上都在,`${mcpp.self} stage --verify content --output <dst> <src>` 拷贝一个文件、创建目标的父目录、只在字节不同时写入。这个参数形状自 2026.9.13.1 起是契约;写下它的构建程序即以该版本为下限 |

上面的裸 stdout 协议仍是底层基底;`import mcpp;` 是其上的类型化层。

Expand Down
2 changes: 1 addition & 1 deletion mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mcpp"
version = "2026.9.12.4"
version = "2026.9.13.1"
description = "Modern C++ build & package management tool"
license = "Apache-2.0"
authors = ["mcpp-community"]
Expand Down
25 changes: 13 additions & 12 deletions modules/buildmcpp/src/directives.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -1088,20 +1088,21 @@ std::string deploy_directive_error(const mcpp::manifest::Manifest& m, const Dire

std::string action_error(const Directives& d) {
for (auto const& payload : d.at(Slot::Actions)) {
// The typed API sets this when an argv did not fit its fixed buffer.
// Diagnosed separately because "malformed action" would send the
// author looking for a typo in something that was actually correct
// and merely too long.
// The typed API sets this when the build program could not allocate
// memory for one of the action's lists. Diagnosed separately because
// "malformed action" would send the author looking for a typo in a
// declaration that was correct and merely cut short. The lists have
// no declared size limit (they had one, 8192 bytes of serialised
// JSON, until 2026.9.13.1); the OS bounds the COMMAND's argv at run
// time, and that is a limit of the tool's own command line, which a
// response file or a directory argument shortens.
if (payload.find("\"overflow\":true") != std::string::npos) {
return std::format(
"build.mcpp declared an action whose arguments did not fit.\n"
" The typed `mcpp::action` builder uses fixed buffers "
"(the bundled module has to stay\n"
" buildable before a std module exists, so it cannot use "
"std::string).\n"
" Shorten the command — e.g. pass a response file, or a "
"directory instead of\n"
" enumerating its files.\n"
"build.mcpp declared an action whose lists could not be stored.\n"
" The build program ran out of memory while collecting the "
"action's inputs,\n"
" outputs or command, so the declaration is incomplete "
"and cannot be used.\n"
" payload: {}", payload);
}
if (decode_action(payload)) continue;
Expand Down
2 changes: 1 addition & 1 deletion modules/versioning/src/version.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ import std;

export namespace mcpp {

inline constexpr std::string_view MCPP_VERSION = "2026.9.12.4";
inline constexpr std::string_view MCPP_VERSION = "2026.9.13.1";

} // namespace mcpp
Loading
Loading