Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
9da1815
2026.10.27.1: a version the local index lacks is refreshed for when i…
Sunrisepeak Oct 27, 2026
a336ef0
fix: a kernel-abi package over the system's C library is placed into …
Sunrisepeak Oct 27, 2026
5a33a2e
docs: 637 end-to-end tests
Sunrisepeak Oct 27, 2026
a1a7ba3
design: platforms -- a target class's configuration as a versioned pa…
Sunrisepeak Oct 27, 2026
af48dac
platform: a package's [platform] states a class of targets; the engin…
Sunrisepeak Oct 27, 2026
d5fb211
platform: the report names the platform and what it added; mcpp.lock …
Sunrisepeak Oct 27, 2026
9762ab8
platform: self env --target/--host reports one configuration; toolcha…
Sunrisepeak Oct 27, 2026
1bb80f0
platform: the host graph's platform -- build programs built as its im…
Sunrisepeak Oct 27, 2026
104191e
platform: hosted targets; two versions of a header or layer package a…
Sunrisepeak Oct 27, 2026
2d67dc6
platform: --pkg-format; a platform package's tests run per target; th…
Sunrisepeak Oct 27, 2026
df41c53
platform: why toolchain says platform for a layer the platform added;…
Sunrisepeak Oct 27, 2026
cc4e5fb
docs: SPEC-013 (platforms), SPEC-014 (packaging and distribution); do…
Sunrisepeak Oct 27, 2026
cf07df5
docs/10: packaging around three axes and legs; --pkg-format; universa…
Sunrisepeak Oct 27, 2026
8749431
docs: platforms in 04, 08, 09, 21, 22, 24, 30, 34, 41 (en, zh); --pkg…
Sunrisepeak Oct 27, 2026
51a15cc
docs: CHANGELOG 2026.10.27.1 (platforms, packaging axes, --pkg-format…
Sunrisepeak Oct 27, 2026
8252daa
docs: SPEC-013 §5 states cfg(platform)'s specificity as the selector …
Sunrisepeak Oct 27, 2026
9206221
pack: the three axes (--linkage, --mode, --pkg-format tar|zip|dir|sin…
Sunrisepeak Oct 27, 2026
58fcb81
pack: mcpp emit xpkg --package describes packages mcpp pack wrote (a …
Sunrisepeak Oct 27, 2026
a0978e7
platform, pack: e2e 952 (a platform package of this machine's triples…
Sunrisepeak Oct 27, 2026
ac14201
e2e 869: an artifact record carries its sha256 (SPEC-014 §9)
Sunrisepeak Oct 27, 2026
579be5d
docs: SPEC-014 v1.1 states the packaging as implemented (zip deflated…
Sunrisepeak Oct 27, 2026
22d16c9
docs/10, 35, 50 (en, zh): the packaging as implemented -- the refusal…
Sunrisepeak Oct 27, 2026
3ab9239
docs: CHANGELOG 2026.10.27.1 packaging entries (three axes, universal…
Sunrisepeak Oct 27, 2026
0dec095
prepare: the state on the heap (a nested prepare overflowed a Windows…
Sunrisepeak Oct 27, 2026
9075899
pack: an aligned zip member's padding is zipalign's extra field (0xD9…
Sunrisepeak Oct 27, 2026
3c0ec4f
platform: the ELF linker of a payload under any of lld's names (ld.ll…
Sunrisepeak Oct 27, 2026
e99974e
explain: the platform's refusals by their reason tokens
Sunrisepeak Oct 27, 2026
10e2d8b
run, test: a runner the platform names as one of its tools is that to…
Sunrisepeak Oct 27, 2026
752c64c
pack: a generated program's tree is its bin/, or the tree itself for …
Sunrisepeak Oct 27, 2026
d14a53c
design part 2 §9: the measured sizes (image flags, -Oz, containers, o…
Sunrisepeak Oct 27, 2026
91b2e32
build programs: a cached run is replayed only while the paths it name…
Sunrisepeak Oct 27, 2026
5598567
e2e 956: the single file's cache on macOS is ~/Library/Caches; it run…
Sunrisepeak Oct 27, 2026
d593fe0
e2e 951: toolchain install --target prepares an ok-image project for …
Sunrisepeak Oct 27, 2026
ef650ca
pack: a Linux runner or carrier is built over the platform's hosted a…
Sunrisepeak Oct 27, 2026
c91bdb9
fixes from CI: a build program's replay ignores its actions' outputs …
Sunrisepeak Oct 28, 2026
751865e
pack: a runner row whose triple the target table does not state (aarc…
Sunrisepeak Oct 28, 2026
035675e
platform: the ok-image rows select openkal-platform 0.17.2 (universal…
Sunrisepeak Oct 28, 2026
d6fa98e
review: platform manifests refuse what they cannot honour and warn on…
Sunrisepeak Oct 28, 2026
c3d5ecc
pack.compress: an unstated level is -1 and every stated one is honour…
Sunrisepeak Oct 28, 2026
1430564
pack.distribution: unpack creates nothing outside its root and writes…
Sunrisepeak Oct 28, 2026
921b299
pack: a runner word a .cmd cannot hold is refused before staging; emi…
Sunrisepeak Oct 28, 2026
b48f61d
review: config.toml's unknown platform keys are said; a tree's execut…
Sunrisepeak Oct 28, 2026
a40a8f6
pack: an image's single file for a system whose row this mcpp builds …
Sunrisepeak Oct 28, 2026
33c1a9c
pack: every system's runner and carrier is built over the platform's …
Sunrisepeak Oct 28, 2026
ae24ce8
test: a launcher run through a link names the image by its physical p…
Sunrisepeak Oct 28, 2026
95827f7
platform: the ok-image rows select openkal-platform 0.17.3 (openkal-m…
Sunrisepeak Oct 28, 2026
3293985
CHANGELOG: runners over the hosted arrangement; trim_paths and the ta…
Sunrisepeak Oct 28, 2026
7c5ee0b
lock: what only the platform's packages reach is the platform's (orig…
Sunrisepeak Oct 28, 2026
8506078
prepare: the Windows first run's closures are their own step and the …
Sunrisepeak Oct 28, 2026
7575599
lock: each entry names the configurations that resolve it (`targets`,…
Sunrisepeak Oct 28, 2026
8ae5699
review (ecosystem): emit xpkg names the entry after the command it re…
Sunrisepeak Oct 28, 2026
a0dcd1c
pack: a library's implicit zip refuses a stated zstd or xz and leaves…
Sunrisepeak Oct 28, 2026
63d2f41
design: §15.1 what the implementation corrected (runners over the hos…
Sunrisepeak Oct 28, 2026
8992d59
e2e: Linux shard timings measured on #847's run, the tests since 900 …
Sunrisepeak Oct 28, 2026
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
580 changes: 580 additions & 0 deletions .agents/docs/2026-10-28-platforms-design.md

Large diffs are not rendered by default.

Large diffs are not rendered by default.

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

338 records.
340 records.

## By subject

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

### platform

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

### plugins

- [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
Expand Down Expand Up @@ -144,6 +149,8 @@ Records that declare one. Everything else is listed by date below.

### 2026-10

- [平台 part 2:打包与分发——三维模型、通用包、单文件、okb、体积,以及 openkal 0.17.2 轮](2026-10-28-platforms-part2-packaging-and-distribution-design.md) — active
- [平台:目标体系的通用扩展;openkal 作为第一个平台包;IDE 一线与 mcppls 的同批升级](2026-10-28-platforms-design.md) — active
- [生态设计 part 2:openkal 的最小原子与二进制映像、其上的 `mcpplibs.os`,以及 part 1 的收尾与回归记录](2026-10-26-ecosystem-part2-os-library-over-openkal-design.md) — active
- [控制契约、并发与性能、单一 C++ 运行时,以及 IDE 生态(生态级,#838、#839)](2026-10-26-control-contract-runtime-and-ide-ecosystem-design.md) — active
- [目标基座与执行宿主:sysroot 的通用模型、运行器契约、自备输入,以及同批的发布产物路径(#832)](2026-10-23-target-base-and-execution-host-design.md) — landed
Expand Down
2 changes: 2 additions & 0 deletions .agents/skills/mcpp-contributing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ git checkout -b <type>/<short-description>
- 遵循现有代码风格(查看相邻代码)
- 模块导入用 `import std;` 和 `import mcpp.xxx;`
- 只改需要改的,不顺手重构不相关代码
- **循环嵌套不超过两层**:第三层改为具名的辅助函数、一次扁平的遍历(例如带深度的
`recursive_directory_iterator`)或先收集再处理;确有必要保留三层时,在该处注释写明理由
- 平台相关代码放在 `src/platform/` 目录下

**构建验证**
Expand Down
17 changes: 13 additions & 4 deletions .github/tools/upgrade_lane.sh
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,21 @@ if [ "$VARIANT" = snapshot ]; then
|| fail "toolchain list does not offer the newer packaging"
fi
if [ "$VARIANT" = modules ]; then
# A BMI of the previous spelling is not read: the dependency is rebuilt
# once (its cache key carries the spelling), then served from the cache.
# A BMI of another spelling is not read: the dependency is rebuilt once (its
# cache key carries the spelling), then served from the cache. The spelling
# moved in 2026.10.26.2 (the module map's `$root`); a previous release from
# then on spells as this one, and its entry is served at once.
old_version=$("$OLD" --version | grep -Eo '[0-9]{4}\.[0-9]+\.[0-9]+\.[0-9]+' | head -1)
same_spelling=$(printf '%s\n2026.10.26.2\n' "$old_version" | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n | head -1)
modules_project m-new1
run new-modules1 "$W/m-new1" "$NEW" build -v || fail "the module project does not build over the previous release's cache"
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules1.log" \
&& fail "a dependency BMI of the previous spelling was taken from the cache"
if [ "$same_spelling" = 2026.10.26.2 ]; then
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules1.log" \
|| fail "a dependency BMI of the same spelling ($old_version) was not served from the cache"
else
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules1.log" \
&& fail "a dependency BMI of the previous spelling ($old_version) was taken from the cache"
fi
modules_project m-new2
run new-modules2 "$W/m-new2" "$NEW" build -v || fail "the second module project failed"
grep -q "STAGE gcm.cache/mcpplibs.openkal/" "$W/new-modules2.log" \
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ci-aarch64-fresh-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,11 @@ jobs:
# leg was written separately and never got it.
rm -f .xlings.json
mcpp self config --mirror GLOBAL 2>/dev/null || true
mcpp build --target aarch64-linux-musl
# Two compiles at a time: the runner (4 vCPU, 16 GB) received a
# shutdown signal twice at 656/689, with four of the engine's largest
# module units compiling at once with debug information
# (2026-10-28). The build is the same; only its width is not.
MCPP_JOBS=2 mcpp build --target aarch64-linux-musl
# Absolute: it is used again after `cd /tmp/xlings-src` below.
m=$(find "$PWD/target/aarch64-linux-musl" -type f -path '*/bin/mcpp' | head -1)
file "$m" | grep -q "ARM aarch64" || { echo "expected aarch64 mcpp"; exit 1; }
Expand Down Expand Up @@ -239,7 +243,8 @@ jobs:
# selects one that does not exist. Same removal as the self-host step
# above, same reason as install_released_mcpp.sh point 1.
rm -f .xlings.json
mcpp build --target aarch64-linux-musl
# Two compiles at a time, for the reason of the self-host step above.
MCPP_JOBS=2 mcpp build --target aarch64-linux-musl
self=$(find target/aarch64-linux-musl -type f -path '*/bin/mcpp' | head -1)
test -x "$self"
self=$(realpath "$self")
Expand Down
172 changes: 172 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,178 @@
> Each `## [<version>]` section is that release's notes. Entries are written in English
> from 2026.9.28.3 on; earlier entries remain as written.

## [2026.10.27.1] - 2026-10-27

### Added

- **Platforms: the configuration of a class of targets as one versioned package**
(SPEC-013; docs/35). A package's `[platform]` section states the targets it
serves, their toolchain and target base, the package for each target-side
layer (`[platform.layers]`, or `false`), the tools built for this machine
(`[platform.tools]`), the compile flags (`[platform.build]` and its
`cfg(...)` tables), the link (`[platform.link]`: `driver`, `flags`, `start`,
`script`, `inputs`, the names `exe` and `shared`, the `seal` steps), the
runner (`{ cmd, host = "same-arch" | "any", exclusive }`) and named runners,
the carrier of a self-contained program, a plugin run in the platform phase,
a version group (`[platform.versions]`) and the part a host triple takes
(`[platform.hosted]`). The engine selects a platform for the target graph
(`--platform`, `MCPP_TARGET_<T>_PLATFORM`, `[target.<selector>] platform`,
`config.toml`, the target table) and for the host graph (`--host-platform`,
`MCPP_HOST_PLATFORM`, `[host] platform`), merges the overrides a project and
this machine write under the same key names, adds the layers and tools the
graph lacks (a layer a package of the graph provides is left to it), links,
seals and names the artifact, runs it, and reports every value with its
source. `cfg(platform = "<name>")` selects by platform.
- **`x86_64-openkal` and `aarch64-openkal` need no declaration.** The target
table selects `mcpplibs.openkal-platform` for both rows, and the platform
states what a project wrote by hand in 2026.10.26.2: `llvm@23.1.3`,
openkal-musl, openkal-llvm-runtime, `okld` and `okrun`, the image's flags,
its link and seal, `{name}.oke` and `lib{name}.okso`, the runner and the M3
carrier. A project that names only its sources builds, runs, tests and
packs an ok image. The engine holds no openkal code (`src/okimage` is
removed).
- **The host graph's platform.** With `[host] platform` build programs and
their libraries are compiled as ok images of this machine's architecture,
with one toolchain on Linux, macOS and Windows, and run by the platform's
runner; a platform's own tools are always built natively. e2e 953; a
platform package unrelated to openkal is e2e 952.
- **Protocol 17** (SPEC-007 R9.10): `link_driver`, `link_input`,
`link_input_from`, `artifact_name`, `seal` and `run_host`, stated by a
platform's plugin in the platform phase (`mcpp::phase()` is `"platform"`)
or by any build program in its build phase.
- **One configuration, without a build.** `mcpp self env --target <triple>`
(`--host`, `--format json`) reports the toolchain, the platform with each
field's source, the tools, the runner and its program; `mcpp toolchain
install --target <triple>` fetches the target's platform and builds its
tools; `mcpp toolchain list` has a PLATFORM column.
- **`mcpp test` builds the package's programs first** and gives each test
`MCPP_BIN_<NAME>`, the path of the program `<name>`. In a platform package
with no `--target`, it builds the tests for each of the platform's targets
and runs those of this machine's architecture.
- **Packaging along three axes** (SPEC-014; docs/10): `--linkage
static|shared` (the program's dependency linkage; on Linux `static` is the
musl row), `--mode system|vendored|self-contained` (what the machine
provides; `--mode static` is `--linkage static --mode self-contained`),
`--pkg-format tar|zip|dir|single-file|<provided>` (what is delivered; a
format left unstated is a zip for a Windows program and a tar elsewhere) and
the legs (`--target`, repeatable). Impossible combinations are refused before
the build. `[pack] linkage`, `format`, `compress`, `sign` and `universal` are
the project's defaults. e2e 954.
- **Universal packages.** A platform with `universal = true` (openkal-platform)
packs every one of its targets into one package, `<name>-<version>-<platform>`,
with `lib/<arch>/` per leg and generated launchers (`bin/<name>`,
`bin/<name>.cmd`) that pick the machine's architecture and start the
platform's runner; `--mode self-contained` adds the runner of each system of
`--systems` and each architecture under `libexec/`, built over the platform's
hosted arrangement on any machine (a macOS or Windows runner is packed on
Linux with no SDK and no C run-time of that system); `--no-universal` packs
the selected target alone. e2e 955.
- **Single files.** `--pkg-format single-file` writes one executable: for a
native program the engine's launcher carrying the staged tree as a zstd
frame, extracted once into the user's cache under the payload's sha256 and
run from there; for an ok image the platform's carrier running the image
from memory, one file per system of `--systems`. e2e 956.
- **Compression in mcpp's own codecs.** `--compress gzip|zstd|xz|none[:level]`
(`.tar.gz`, `.tar.zst`, `.tar.xz`, `.tar`) with zlib, zstd and liblzma as
dependencies of mcpp: no compressor is looked for on `PATH`, and an archive
is the same bytes on every host. A zip's entries are deflated (`gzip`) or
stored (`none`).
- **`mcpp-package.json` and what reads it.** Every staged tree describes its
package: platform, the three choices, legs, systems, how it starts, and each
file with its role, leg and sha256. `mcpp pack --merge a --merge b` joins
packages written on several machines (legs and systems united, one digest
per path); `mcpp emit xpkg --package <archive> --url <prefix>` writes the
xim-pkgindex entry, one asset for every system for a universal package with
its runner as a dependency. `[pack] sign = [argv]` signs each program, image,
library and loader before the container, and each single file. e2e 957.
- The `mcpp.pack` envelope gains `linkage`, `mode`, `pkgFormat`, `legs`,
`systems` and each file artifact's `sha256`. A platform's plugin may provide
package formats (`pack-format`, `artifact` actions) in the platform phase.
- `mcpp.lock` records the packages a platform added, and those only they
reach, with `origin = "platform"`, and names each entry's configurations in
`targets` (absent for an entry of this machine's native configuration alone,
so a lock of a natively built project is unchanged): a build for this machine
and a build or pack for an ok image leave each other's entries as they were.
The `plan` event and `result.json` carry `configuration.platform` and
`hostPlatform`.

### Changed

- **`--pkg-format` is the package format of `mcpp pack` and `mcpp run`.**
`--format` there is the earlier spelling and prints a warning; on every other
command `--format` is the output encoding.
- The reason `image-tool-absent` is `platform-tool-absent`; new reasons
`platform-not-a-platform`, `platform-target-unserved`,
`platform-version-group` and `platform-phase-directive`.
- A layer the target's platform added is reported `platform`, and the
platform follows on a `Platform` line (`Host platform` for the host graph).
- A version of a dependency the index does not have is stated by mcpp: which
index, its revision and age, and whether it was refreshed now and why not;
the provider's own report is printed under `-v`.
- A package shared by several configurations of one command is announced once.
- **With `trim_paths`, clang is given `-ffile-reproducible`** (clang 17 and
later): `__FILE__` takes the target's separator where clang applies it. An ok
image built on Linux and one built on macOS are the same bytes; one built on
a Windows host is not, because clang keeps the `\` it joined an included
path with for a POSIX target (#850, upstream), and `mcpp pack --merge`
refuses its images beside the others.
- **`--pkg-format tar` writes `.tar.gz` on every host, Windows included**, with
mcpp's own zlib, for a program's package and a library's alike; no `tar` or
`gzip` program is run. `--compress none` writes `.tar`.
- `x86_64-openkal` and `aarch64-openkal` select openkal-platform 0.17.3
(openkal-musl 0.22.6, openkal-llvm-runtime 0.16.6): the C library takes a
program's arguments when it is entered, which a hosted program on macOS did
not receive.
- A platform's link with `ld.lld` itself finds the linker as `ld.lld`, `lld`
or `lld-link` beside the compiler (a Windows payload ships `lld-link`, run
with `-flavor gnu`); `mcpp explain <reason>` explains each `platform-*`
reason. A build program's cached run is replayed only while what it named
below its output directory is there (e2e 958).

### Fixed

- **A version the local index lacks is refreshed for when its install is
refused.** The walk refreshes the index when a descriptor is missing, and not
when a descriptor is present without the version asked for (version tables
are per system, so that absence is not proof). The provider's "not found" for
the version is, and it now reaches the refresh policy (offline,
`[index] auto_refresh`, the debounce, one sync per run); after a refresh the
install is asked once more. A dependency on a version published after the
index was last synced (`openkal-llvm-runtime = "0.16.3"`) was refused until
`mcpp index update`. e2e 949.
- **A kernel-abi package over the system's C library is placed into the shared
image that reaches it.** Every package providing an `mcpp:` layer was a
boundary of static placement and went into programs only, which is right for
a C library or a C++ runtime. On a hosted target openkal-linux (-macos,
-windows) sits on the system's C library and is an ordinary static library
under `mcpplibs.os`; a shared image reaching it was left with `kal_*`
undefined, and CPython could not load an extension built on `mcpplibs.os`
(`undefined symbol: kal_process_close`). A `kernel-abi` provider is now a
boundary only when a C library of the graph sits on it. e2e 950.
- **A kernel-abi package over the system's C library leaves a hosted row's
toolchain in place.** The musl and windows-gnu rows name the payload that
supplies the target's C library, and a graph that supplies a C library
replaces it; a kernel-abi package counted as one. On linux-aarch64 a project
reaching openkal-linux through `mcpplibs.os` then compiled `--linkage
static` (the musl row) with the machine's llvm against glibc's headers. A
kernel-abi package now supplies the system only on a target that has none of
its own (a freestanding or a loader-supplied row). e2e 292.
- **A package whose descriptor was read is the only one asked for.** A refused
install of a namespace-omitted dependency was tried again as
`compat:<name>` and `compat.<name>`, shown as downloading, and reported with
three addresses, although the descriptor had named the package in
`mcpplibs`. The compat spellings are tried only when no descriptor could be
read.
- **Two versions of a package that exports a header directory or provides a
target-side layer are refused**, naming both requests. A renamed copy kept
its C names and link symbols, and the two met in one link or one include
path at a place that named neither.
- **A version group is checked before the platform completes the graph.** A
family package the project pinned outside the group is refused as the
group's conflict, with both remedies.
- **The std module of a macOS build whose C library is the graph's takes the
deployment floor** every unit takes; it took the running system's version.

## [2026.10.26.2] - 2026-10-26

### Added
Expand Down
Loading
Loading