Skip to content

Commit e0b1133

Browse files
2026.10.27.1: platforms (SPEC-013) -- ok images need no declaration; packaging and distribution (SPEC-014) -- three axes, universal packages, single files, okb (#847)
Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
1 parent 7d70482 commit e0b1133

163 files changed

Lines changed: 15088 additions & 2180 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-10-28-platforms-design.md‎

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

‎.agents/docs/2026-10-28-platforms-part2-packaging-and-distribution-design.md‎

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

‎.agents/docs/README.md‎

Lines changed: 8 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-
338 records.
21+
340 records.
2222

2323
## By subject
2424

@@ -91,6 +91,11 @@ Records that declare one. Everything else is listed by date below.
9191
- [openkal 生态:完整性收尾与验收方案](2026-09-21-openkal-ecosystem-completion-and-acceptance.md) — active
9292
- [C 环境生态方案:执行计划](2026-09-20-ecosystem-execution-plan.md) — active
9393

94+
### platform
95+
96+
- [平台 part 2:打包与分发——三维模型、通用包、单文件、okb、体积,以及 openkal 0.17.2 轮](2026-10-28-platforms-part2-packaging-and-distribution-design.md) — active
97+
- [平台:目标体系的通用扩展;openkal 作为第一个平台包;IDE 一线与 mcppls 的同批升级](2026-10-28-platforms-design.md) — active
98+
9499
### plugins
95100

96101
- [The category the plugin taxonomy does not name, and what a platform actually decomposes into](2026-09-11-distribution-plugins-and-platform-decomposition.md) — active
@@ -144,6 +149,8 @@ Records that declare one. Everything else is listed by date below.
144149

145150
### 2026-10
146151

152+
- [平台 part 2:打包与分发——三维模型、通用包、单文件、okb、体积,以及 openkal 0.17.2 轮](2026-10-28-platforms-part2-packaging-and-distribution-design.md) — active
153+
- [平台:目标体系的通用扩展;openkal 作为第一个平台包;IDE 一线与 mcppls 的同批升级](2026-10-28-platforms-design.md) — active
147154
- [生态设计 part 2:openkal 的最小原子与二进制映像、其上的 `mcpplibs.os`,以及 part 1 的收尾与回归记录](2026-10-26-ecosystem-part2-os-library-over-openkal-design.md) — active
148155
- [控制契约、并发与性能、单一 C++ 运行时,以及 IDE 生态(生态级,#838、#839)](2026-10-26-control-contract-runtime-and-ide-ecosystem-design.md) — active
149156
- [目标基座与执行宿主:sysroot 的通用模型、运行器契约、自备输入,以及同批的发布产物路径(#832)](2026-10-23-target-base-and-execution-host-design.md) — landed

‎.agents/skills/mcpp-contributing/SKILL.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ git checkout -b <type>/<short-description>
121121
- 遵循现有代码风格(查看相邻代码)
122122
- 模块导入用 `import std;` 和 `import mcpp.xxx;`
123123
- 只改需要改的,不顺手重构不相关代码
124+
- **循环嵌套不超过两层**:第三层改为具名的辅助函数、一次扁平的遍历(例如带深度的
125+
`recursive_directory_iterator`)或先收集再处理;确有必要保留三层时,在该处注释写明理由
124126
- 平台相关代码放在 `src/platform/` 目录下
125127

126128
**构建验证**

‎.github/tools/upgrade_lane.sh‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,21 @@ if [ "$VARIANT" = snapshot ]; then
218218
|| fail "toolchain list does not offer the newer packaging"
219219
fi
220220
if [ "$VARIANT" = modules ]; then
221-
# A BMI of the previous spelling is not read: the dependency is rebuilt
222-
# once (its cache key carries the spelling), then served from the cache.
221+
# A BMI of another spelling is not read: the dependency is rebuilt once (its
222+
# cache key carries the spelling), then served from the cache. The spelling
223+
# moved in 2026.10.26.2 (the module map's `$root`); a previous release from
224+
# then on spells as this one, and its entry is served at once.
225+
old_version=$("$OLD" --version | grep -Eo '[0-9]{4}\.[0-9]+\.[0-9]+\.[0-9]+' | head -1)
226+
same_spelling=$(printf '%s\n2026.10.26.2\n' "$old_version" | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n | head -1)
223227
modules_project m-new1
224228
run new-modules1 "$W/m-new1" "$NEW" build -v || fail "the module project does not build over the previous release's cache"
225-
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules1.log" \
226-
&& fail "a dependency BMI of the previous spelling was taken from the cache"
229+
if [ "$same_spelling" = 2026.10.26.2 ]; then
230+
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules1.log" \
231+
|| fail "a dependency BMI of the same spelling ($old_version) was not served from the cache"
232+
else
233+
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules1.log" \
234+
&& fail "a dependency BMI of the previous spelling ($old_version) was taken from the cache"
235+
fi
227236
modules_project m-new2
228237
run new-modules2 "$W/m-new2" "$NEW" build -v || fail "the second module project failed"
229238
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules2.log" \

‎.github/workflows/ci-aarch64-fresh-install.yml‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,11 @@ jobs:
168168
# leg was written separately and never got it.
169169
rm -f .xlings.json
170170
mcpp self config --mirror GLOBAL 2>/dev/null || true
171-
mcpp build --target aarch64-linux-musl
171+
# Two compiles at a time: the runner (4 vCPU, 16 GB) received a
172+
# shutdown signal twice at 656/689, with four of the engine's largest
173+
# module units compiling at once with debug information
174+
# (2026-10-28). The build is the same; only its width is not.
175+
MCPP_JOBS=2 mcpp build --target aarch64-linux-musl
172176
# Absolute: it is used again after `cd /tmp/xlings-src` below.
173177
m=$(find "$PWD/target/aarch64-linux-musl" -type f -path '*/bin/mcpp' | head -1)
174178
file "$m" | grep -q "ARM aarch64" || { echo "expected aarch64 mcpp"; exit 1; }
@@ -239,7 +243,8 @@ jobs:
239243
# selects one that does not exist. Same removal as the self-host step
240244
# above, same reason as install_released_mcpp.sh point 1.
241245
rm -f .xlings.json
242-
mcpp build --target aarch64-linux-musl
246+
# Two compiles at a time, for the reason of the self-host step above.
247+
MCPP_JOBS=2 mcpp build --target aarch64-linux-musl
243248
self=$(find target/aarch64-linux-musl -type f -path '*/bin/mcpp' | head -1)
244249
test -x "$self"
245250
self=$(realpath "$self")

‎CHANGELOG.md‎

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,178 @@
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.27.1] - 2026-10-27
8+
9+
### Added
10+
11+
- **Platforms: the configuration of a class of targets as one versioned package**
12+
(SPEC-013; docs/35). A package's `[platform]` section states the targets it
13+
serves, their toolchain and target base, the package for each target-side
14+
layer (`[platform.layers]`, or `false`), the tools built for this machine
15+
(`[platform.tools]`), the compile flags (`[platform.build]` and its
16+
`cfg(...)` tables), the link (`[platform.link]`: `driver`, `flags`, `start`,
17+
`script`, `inputs`, the names `exe` and `shared`, the `seal` steps), the
18+
runner (`{ cmd, host = "same-arch" | "any", exclusive }`) and named runners,
19+
the carrier of a self-contained program, a plugin run in the platform phase,
20+
a version group (`[platform.versions]`) and the part a host triple takes
21+
(`[platform.hosted]`). The engine selects a platform for the target graph
22+
(`--platform`, `MCPP_TARGET_<T>_PLATFORM`, `[target.<selector>] platform`,
23+
`config.toml`, the target table) and for the host graph (`--host-platform`,
24+
`MCPP_HOST_PLATFORM`, `[host] platform`), merges the overrides a project and
25+
this machine write under the same key names, adds the layers and tools the
26+
graph lacks (a layer a package of the graph provides is left to it), links,
27+
seals and names the artifact, runs it, and reports every value with its
28+
source. `cfg(platform = "<name>")` selects by platform.
29+
- **`x86_64-openkal` and `aarch64-openkal` need no declaration.** The target
30+
table selects `mcpplibs.openkal-platform` for both rows, and the platform
31+
states what a project wrote by hand in 2026.10.26.2: `llvm@23.1.3`,
32+
openkal-musl, openkal-llvm-runtime, `okld` and `okrun`, the image's flags,
33+
its link and seal, `{name}.oke` and `lib{name}.okso`, the runner and the M3
34+
carrier. A project that names only its sources builds, runs, tests and
35+
packs an ok image. The engine holds no openkal code (`src/okimage` is
36+
removed).
37+
- **The host graph's platform.** With `[host] platform` build programs and
38+
their libraries are compiled as ok images of this machine's architecture,
39+
with one toolchain on Linux, macOS and Windows, and run by the platform's
40+
runner; a platform's own tools are always built natively. e2e 953; a
41+
platform package unrelated to openkal is e2e 952.
42+
- **Protocol 17** (SPEC-007 R9.10): `link_driver`, `link_input`,
43+
`link_input_from`, `artifact_name`, `seal` and `run_host`, stated by a
44+
platform's plugin in the platform phase (`mcpp::phase()` is `"platform"`)
45+
or by any build program in its build phase.
46+
- **One configuration, without a build.** `mcpp self env --target <triple>`
47+
(`--host`, `--format json`) reports the toolchain, the platform with each
48+
field's source, the tools, the runner and its program; `mcpp toolchain
49+
install --target <triple>` fetches the target's platform and builds its
50+
tools; `mcpp toolchain list` has a PLATFORM column.
51+
- **`mcpp test` builds the package's programs first** and gives each test
52+
`MCPP_BIN_<NAME>`, the path of the program `<name>`. In a platform package
53+
with no `--target`, it builds the tests for each of the platform's targets
54+
and runs those of this machine's architecture.
55+
- **Packaging along three axes** (SPEC-014; docs/10): `--linkage
56+
static|shared` (the program's dependency linkage; on Linux `static` is the
57+
musl row), `--mode system|vendored|self-contained` (what the machine
58+
provides; `--mode static` is `--linkage static --mode self-contained`),
59+
`--pkg-format tar|zip|dir|single-file|<provided>` (what is delivered; a
60+
format left unstated is a zip for a Windows program and a tar elsewhere) and
61+
the legs (`--target`, repeatable). Impossible combinations are refused before
62+
the build. `[pack] linkage`, `format`, `compress`, `sign` and `universal` are
63+
the project's defaults. e2e 954.
64+
- **Universal packages.** A platform with `universal = true` (openkal-platform)
65+
packs every one of its targets into one package, `<name>-<version>-<platform>`,
66+
with `lib/<arch>/` per leg and generated launchers (`bin/<name>`,
67+
`bin/<name>.cmd`) that pick the machine's architecture and start the
68+
platform's runner; `--mode self-contained` adds the runner of each system of
69+
`--systems` and each architecture under `libexec/`, built over the platform's
70+
hosted arrangement on any machine (a macOS or Windows runner is packed on
71+
Linux with no SDK and no C run-time of that system); `--no-universal` packs
72+
the selected target alone. e2e 955.
73+
- **Single files.** `--pkg-format single-file` writes one executable: for a
74+
native program the engine's launcher carrying the staged tree as a zstd
75+
frame, extracted once into the user's cache under the payload's sha256 and
76+
run from there; for an ok image the platform's carrier running the image
77+
from memory, one file per system of `--systems`. e2e 956.
78+
- **Compression in mcpp's own codecs.** `--compress gzip|zstd|xz|none[:level]`
79+
(`.tar.gz`, `.tar.zst`, `.tar.xz`, `.tar`) with zlib, zstd and liblzma as
80+
dependencies of mcpp: no compressor is looked for on `PATH`, and an archive
81+
is the same bytes on every host. A zip's entries are deflated (`gzip`) or
82+
stored (`none`).
83+
- **`mcpp-package.json` and what reads it.** Every staged tree describes its
84+
package: platform, the three choices, legs, systems, how it starts, and each
85+
file with its role, leg and sha256. `mcpp pack --merge a --merge b` joins
86+
packages written on several machines (legs and systems united, one digest
87+
per path); `mcpp emit xpkg --package <archive> --url <prefix>` writes the
88+
xim-pkgindex entry, one asset for every system for a universal package with
89+
its runner as a dependency. `[pack] sign = [argv]` signs each program, image,
90+
library and loader before the container, and each single file. e2e 957.
91+
- The `mcpp.pack` envelope gains `linkage`, `mode`, `pkgFormat`, `legs`,
92+
`systems` and each file artifact's `sha256`. A platform's plugin may provide
93+
package formats (`pack-format`, `artifact` actions) in the platform phase.
94+
- `mcpp.lock` records the packages a platform added, and those only they
95+
reach, with `origin = "platform"`, and names each entry's configurations in
96+
`targets` (absent for an entry of this machine's native configuration alone,
97+
so a lock of a natively built project is unchanged): a build for this machine
98+
and a build or pack for an ok image leave each other's entries as they were.
99+
The `plan` event and `result.json` carry `configuration.platform` and
100+
`hostPlatform`.
101+
102+
### Changed
103+
104+
- **`--pkg-format` is the package format of `mcpp pack` and `mcpp run`.**
105+
`--format` there is the earlier spelling and prints a warning; on every other
106+
command `--format` is the output encoding.
107+
- The reason `image-tool-absent` is `platform-tool-absent`; new reasons
108+
`platform-not-a-platform`, `platform-target-unserved`,
109+
`platform-version-group` and `platform-phase-directive`.
110+
- A layer the target's platform added is reported `platform`, and the
111+
platform follows on a `Platform` line (`Host platform` for the host graph).
112+
- A version of a dependency the index does not have is stated by mcpp: which
113+
index, its revision and age, and whether it was refreshed now and why not;
114+
the provider's own report is printed under `-v`.
115+
- A package shared by several configurations of one command is announced once.
116+
- **With `trim_paths`, clang is given `-ffile-reproducible`** (clang 17 and
117+
later): `__FILE__` takes the target's separator where clang applies it. An ok
118+
image built on Linux and one built on macOS are the same bytes; one built on
119+
a Windows host is not, because clang keeps the `\` it joined an included
120+
path with for a POSIX target (#850, upstream), and `mcpp pack --merge`
121+
refuses its images beside the others.
122+
- **`--pkg-format tar` writes `.tar.gz` on every host, Windows included**, with
123+
mcpp's own zlib, for a program's package and a library's alike; no `tar` or
124+
`gzip` program is run. `--compress none` writes `.tar`.
125+
- `x86_64-openkal` and `aarch64-openkal` select openkal-platform 0.17.3
126+
(openkal-musl 0.22.6, openkal-llvm-runtime 0.16.6): the C library takes a
127+
program's arguments when it is entered, which a hosted program on macOS did
128+
not receive.
129+
- A platform's link with `ld.lld` itself finds the linker as `ld.lld`, `lld`
130+
or `lld-link` beside the compiler (a Windows payload ships `lld-link`, run
131+
with `-flavor gnu`); `mcpp explain <reason>` explains each `platform-*`
132+
reason. A build program's cached run is replayed only while what it named
133+
below its output directory is there (e2e 958).
134+
135+
### Fixed
136+
137+
- **A version the local index lacks is refreshed for when its install is
138+
refused.** The walk refreshes the index when a descriptor is missing, and not
139+
when a descriptor is present without the version asked for (version tables
140+
are per system, so that absence is not proof). The provider's "not found" for
141+
the version is, and it now reaches the refresh policy (offline,
142+
`[index] auto_refresh`, the debounce, one sync per run); after a refresh the
143+
install is asked once more. A dependency on a version published after the
144+
index was last synced (`openkal-llvm-runtime = "0.16.3"`) was refused until
145+
`mcpp index update`. e2e 949.
146+
- **A kernel-abi package over the system's C library is placed into the shared
147+
image that reaches it.** Every package providing an `mcpp:` layer was a
148+
boundary of static placement and went into programs only, which is right for
149+
a C library or a C++ runtime. On a hosted target openkal-linux (-macos,
150+
-windows) sits on the system's C library and is an ordinary static library
151+
under `mcpplibs.os`; a shared image reaching it was left with `kal_*`
152+
undefined, and CPython could not load an extension built on `mcpplibs.os`
153+
(`undefined symbol: kal_process_close`). A `kernel-abi` provider is now a
154+
boundary only when a C library of the graph sits on it. e2e 950.
155+
- **A kernel-abi package over the system's C library leaves a hosted row's
156+
toolchain in place.** The musl and windows-gnu rows name the payload that
157+
supplies the target's C library, and a graph that supplies a C library
158+
replaces it; a kernel-abi package counted as one. On linux-aarch64 a project
159+
reaching openkal-linux through `mcpplibs.os` then compiled `--linkage
160+
static` (the musl row) with the machine's llvm against glibc's headers. A
161+
kernel-abi package now supplies the system only on a target that has none of
162+
its own (a freestanding or a loader-supplied row). e2e 292.
163+
- **A package whose descriptor was read is the only one asked for.** A refused
164+
install of a namespace-omitted dependency was tried again as
165+
`compat:<name>` and `compat.<name>`, shown as downloading, and reported with
166+
three addresses, although the descriptor had named the package in
167+
`mcpplibs`. The compat spellings are tried only when no descriptor could be
168+
read.
169+
- **Two versions of a package that exports a header directory or provides a
170+
target-side layer are refused**, naming both requests. A renamed copy kept
171+
its C names and link symbols, and the two met in one link or one include
172+
path at a place that named neither.
173+
- **A version group is checked before the platform completes the graph.** A
174+
family package the project pinned outside the group is refused as the
175+
group's conflict, with both remedies.
176+
- **The std module of a macOS build whose C library is the graph's takes the
177+
deployment floor** every unit takes; it took the running system's version.
178+
7179
## [2026.10.26.2] - 2026-10-26
8180

9181
### Added

0 commit comments

Comments
 (0)