Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b5eca68
design 2026-10-29: target sets and legs, the packaging model revised,…
Sunrisepeak Oct 29, 2026
734d9c6
descriptor keys by the target's row; runner hosts, carrier entries an…
Sunrisepeak Oct 29, 2026
6eb85d6
runs_on in mcpp-package.json and the index entry; the Windows launche…
Sunrisepeak Oct 29, 2026
8bea56d
tests: the launchers' unit tests read the Windows launcher program, a…
Sunrisepeak Oct 29, 2026
87ab153
SPEC-015: target sets and legs -- a set expands to the table's rows o…
Sunrisepeak Oct 29, 2026
bdd9029
runs_on: a platform that states no runner hosts is read as every syst…
Sunrisepeak Oct 29, 2026
fcadaba
SPEC-014 2.0: a pack holds the legs it names -- sets expand, images o…
Sunrisepeak Oct 29, 2026
025b6f4
a tree that runs nowhere is refused: with runner hosts unstated read …
Sunrisepeak Oct 29, 2026
772a82d
design: the clangd probe's result -- clangd stays native per system i…
Sunrisepeak Oct 29, 2026
bab910d
SPEC-015, the target sets and test archives in docs/21, docs/08 and d…
Sunrisepeak Oct 29, 2026
9d7d057
ask.log is no file of this repository: a shell redirect's leftover
Sunrisepeak Oct 29, 2026
3074fa4
e2e 868: two --target over several members are two legs of each, no l…
Sunrisepeak Oct 29, 2026
2ac9ef6
design §10.4: one logo for every editor integration; the CLion plugin…
Sunrisepeak Oct 29, 2026
79e5ce1
the Windows launcher reads its own path with / between the names: ove…
Sunrisepeak Oct 29, 2026
b5ac373
openkal-platform 0.18.0: the built-in pin, the examples and the e2e t…
Sunrisepeak Oct 29, 2026
87505c7
mcpplibs.os 0.2.3: mcpp starts programs in a directory it may search …
Sunrisepeak Oct 29, 2026
7583184
a container already at the -o directory is kept: it was removed as th…
Sunrisepeak Oct 29, 2026
b2102cf
CI: six Linux e2e shards with the new tests' measured durations; e2e …
Sunrisepeak Oct 30, 2026
32cb9fa
a test archive is compressed as its name states, gzip passes zlib in …
Sunrisepeak Oct 30, 2026
de6e321
a macOS leg's tests start from an archive: the loader variable is sta…
Sunrisepeak Oct 30, 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

Large diffs are not rendered by default.

4 changes: 3 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
---
```

341 records.
342 records.

## By subject

Expand Down Expand Up @@ -94,6 +94,7 @@ Records that declare one. Everything else is listed by date below.
### platform

- [另一架构的 ok 映像的运行、测试与打包,以及 ok 映像与 Web 的关系(2026.10.29.1)](2026-10-29-openkal-run-test-pack-design.md) — active
- [生态设计:目标集合与腿、打包模型 rev、运行覆盖、不回落、外部构建接入、mcppls 单包与编辑器](2026-10-29-ecosystem-target-sets-packaging-and-editors-design.md) — active
- [平台 part 2:打包与分发——三维模型、通用包、单文件、okb、体积,以及 openkal 0.17.2 轮](2026-10-28-platforms-part2-packaging-and-distribution-design.md) — landed
- [平台:目标体系的通用扩展;openkal 作为第一个平台包;IDE 一线与 mcppls 的同批升级](2026-10-28-platforms-design.md) — landed

Expand Down Expand Up @@ -151,6 +152,7 @@ Records that declare one. Everything else is listed by date below.
### 2026-10

- [另一架构的 ok 映像的运行、测试与打包,以及 ok 映像与 Web 的关系(2026.10.29.1)](2026-10-29-openkal-run-test-pack-design.md) — active
- [生态设计:目标集合与腿、打包模型 rev、运行覆盖、不回落、外部构建接入、mcppls 单包与编辑器](2026-10-29-ecosystem-target-sets-packaging-and-editors-design.md) — active
- [平台 part 2:打包与分发——三维模型、通用包、单文件、okb、体积,以及 openkal 0.17.2 轮](2026-10-28-platforms-part2-packaging-and-distribution-design.md) — landed
- [平台:目标体系的通用扩展;openkal 作为第一个平台包;IDE 一线与 mcppls 的同批升级](2026-10-28-platforms-design.md) — landed
- [生态设计 part 2:openkal 的最小原子与二进制映像、其上的 `mcpplibs.os`,以及 part 1 的收尾与回归记录](2026-10-26-ecosystem-part2-os-library-over-openkal-design.md) — active
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/ci-linux-e2e.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: ci-linux-e2e

# The e2e suite (tests/e2e/run_all.sh) on Linux, called by ci.yml beside
# ci-linux.yml after the Linux build. Four shards, assigned by measured
# duration (tests/e2e/timings/linux.tsv, rule R4 of the 2026-10-02 CI record),
# ci-linux.yml after the Linux build. Six shards, assigned by measured
# duration (tests/e2e/timings/linux.tsv, rule R4 of the 2026-10-02 CI record):
# the table holds about 72 minutes of tests (2026-10-30, with the target-set
# and packaging tests of 2026.10.30.1), about 12 a shard,
# each running the one binary build.yml produced (use-built-mcpp, rule R1).
# Each shard writes a per-test report that the e2e-coverage job of ci.yml reads
# (rule R5).
Expand All @@ -15,15 +17,15 @@ on:

jobs:
e2e:
name: e2e ${{ matrix.shard }}/4 (linux x86_64, self-host)
name: e2e ${{ matrix.shard }}/6 (linux x86_64, self-host)
runs-on: ubuntu-24.04
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
shard: [1, 2, 3, 4, 5, 6]
env:
E2E_SHARD: ${{ matrix.shard }}/4
E2E_SHARD: ${{ matrix.shard }}/6
E2E_TIMINGS: tests/e2e/timings/linux.tsv
E2E_REPORT: ${{ github.workspace }}/e2e-report-linux-${{ matrix.shard }}.tsv
MCPP_HOME: /home/runner/.mcpp
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/ci-target-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,14 @@ jobs:
exit 1
fi
echo "ok: wasm32-emscripten ran through the payload's runner; the decoy node was never run"
# #851 (e2e 981) needs the emsdk payload this step has just installed;
# the shards have none and skip it, so it runs here, in that home.
MCPP="$MCPP_UNDER_TEST" bash tests/e2e/981_a_web_link_has_the_profiles_level_and_the_wasm_exception_model.sh 2>&1 \
| tee "$RUNNER_TEMP/981.log"
if grep -q '^SKIP' "$RUNNER_TEMP/981.log" || ! grep -qx 'PASS: 981' "$RUNNER_TEMP/981.log"; then
echo "::error::e2e 981 did not run to its PASS line over the installed emsdk"
exit 1
fi

coverage:
# THE DENOMINATOR. Every check above is per host, and no per-host check
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/cross-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,18 @@ jobs:
grep -qxF "$line" "$log" || { echo "::error::797 did not print: $line"; exit 1; }
done

# The Windows launcher of an ok-image tree (`bin/<name>.exe`, built over
# the platform's hosted arrangement) finds its package from a Windows
# path. The shards have no wine; this job does.
- name: "e2e: the Windows launcher finds its package from a Windows path (988)"
run: |
set -o pipefail
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
log="$RUNNER_TEMP/988.log"
bash tests/e2e/988_the_windows_launcher_finds_its_package_from_a_windows_path.sh 2>&1 | tee "$log"
grep -qxF "PASS: 988 the Windows launcher finds its package from a Windows path" "$log" \
|| { echo "::error::988 did not print its PASS line"; exit 1; }

# 257 needs a Linux-hosted MinGW compiler AND wine, which only this job
# has; on the shards it skipped, and it had run on no runner (finding F9
# of the 2026-10-02 CI record).
Expand Down
111 changes: 111 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,117 @@
> 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.30.1] - 2026-10-30

### Added

- **Target sets (SPEC-015).** A `--target` whose first segment is a system
word names every row of the target table with that system and environment:
`openkal` is `x86_64-openkal` and `aarch64-openkal`, `linux-musl` the musl
rows this mcpp builds. Each member is a leg. `build` builds every leg (planned
one after another, built at once); `run` runs the first leg this machine
reaches, its own architecture first; `test` runs the legs it reaches, reports
the others built and not run, and fails when no test ran. The `mcpp.build`
envelope adds `legs`, the events their `triple`; `self env` adds `legs`
(e2e 963). `[build] target` takes one target.
- **Tests built once, run elsewhere.** `mcpp test --no-run --archive <file>`
writes every leg's tests with `mcpp-tests.json`; `mcpp test --archive <file>`
in a checkout runs what this machine reaches and builds nothing. The archive
is a tar compressed as its name states (`.tar.gz`, `.tgz`, `.tar.zst`,
`.tar.xz`, `.tar`); another name is refused before the build (e2e 964). A
leg of the host's own system runs from an archive as an openkal leg does
(e2e 989, on every system); on macOS the first build of this release started
none of them, giving each an environment entry of an empty name.
- **The build's contract, `${mcpp.contract}`.** Every configuration writes
`mcpp-contract.json` beside its compile database: the compiler of each
language with the words every unit is compiled with (target, sysroot,
target-side headers, platform and profile flags), and the link driver, its
words and the archiver. A build program's action names it with
`${mcpp.contract}` and reads it while ninja runs, so a foreign build system
compiles for the target as the engine does; the engine's own C++ dialect and
module words are not in it (e2e 982). mcpp-plugins 0.21.0's `deps-cmake`
compiles a cross build's subproject from it.
- **`[platform] runner.hosts`, carrier entries and `descriptor_keys`.** A
platform states the `<os>-<arch>` pairs its runner exists for, any number of
carrier entries each for the pairs in its `hosts` (an entry of a carrier
model this mcpp does not build is skipped with a warning), and the
descriptor blocks its targets read (SPEC-013 §1.1, §10, §11, §14).
- **`runs_on` in `mcpp-package.json`.** Where a package runs is computed once
when it is packed: `self`, the pairs it runs on with what it carries, and
`with.<runner>`, the pairs it runs on given the machine's runner.

### Changed

- **A pack holds the legs it names (SPEC-014 2.0).** `--target
x86_64-openkal` packs that architecture; `--target openkal` packs both into
one tree. The platform no longer widens a pack: `[platform] universal`,
`[pack] universal` and `--no-universal` lose their effect, with a message
that names the new spelling (`[pack] targets = ["openkal"]`; docs/51).
Images of a platform with a runner have one layout whatever the number of
legs: `bin/<name>`, `bin/<name>.exe`, `lib/<arch>/`, and with
`--mode self-contained` `libexec/<runner>/<os>-<arch>/`. The image embedded
in a carrier belongs to `--pkg-format single-file` only. A set of native
programs is a package per leg (e2e 955, 983, 984).
- **The Windows launcher is a program.** `bin/<name>.exe` replaces
`bin/<name>.cmd`: no "Terminate batch job" prompt, and the process is named
after the package. The POSIX launcher hands over to it under Git Bash, MSYS
and Cygwin.
- **`--systems` takes `<os>`, `<os>-<arch>` and `all`, and `[pack] systems`.**
`--pkg-format` takes a list of containers of one staged tree (`tar,okb`),
built once (e2e 985). Single files cover legs × systems (e2e 986).
- **The pack summary names where the package runs.** `Runs on` and one `Not
covered` line per pair the package does not reach; `mcpp.pack` adds
`pkgFormats` and `runsOn`. A tree that runs nowhere is refused.
- **A target reads the descriptor blocks its row names, never the build
machine's (#851).** A target that is not Linux, macOS or Windows read the
block of the system mcpp ran on, so a Web build took a dependency's `linux`
block on Linux and its `windows` block on Windows, and an ok image the block
of whichever system built it. Each row now names its blocks in order:
`wasm32-emscripten` reads `emscripten`, then `linux`; `<arch>-openkal`
`openkal`, then `linux` (a platform may state its own); iOS `ios`, then
`macosx`; bare metal `none`. Version resolution, the synthesised manifest
and the index refresh read the same block (unit `DescriptorKeys`).
- **The Web link carries the profile's optimisation level (#851).** emcc runs
wasm-opt and minifies the JavaScript launcher at the link, which had no
`-O`: a release Web program was linked at `-O0`. The hello world's
JavaScript is 13 KB rather than 66 KB (e2e 981).
- **`[target.<sel>.abi] exceptions` takes the model (#851).** `"wasm"` selects
WebAssembly's exception handling (`-fwasm-exceptions`), `"js"` the
JavaScript model; `true` keeps the JavaScript model it has selected since
2026.9.12.3. The model is part of every cache key (e2e 981).
- **`mcpp emit xpkg` names where a package runs (#860).** A
self-contained universal package's entry named every system with every
image architecture, so an Intel Mac installed a package that carries no
runner for it. Each system's block names the architectures `runs_on` gives:
the carried runners for a self-contained package, the pairs the platform's
runner exists for otherwise.

### Fixed

- **A name two dependencies answer to is no package's (#852).** Two
dependencies whose manifests both say `rules` warned on every build, and the
bare name went to one of them. It is now published for neither:
`MCPP_DEP_AMBIGUOUS_RULES` lists the qualified names, each qualified name
keeps its own directory, and `dep_dir("rules")` ends the build program naming
both (e2e 980).
- **Programs start in the Android app sandbox again (#857).** Under `run-as`
(SELinux `runas_app`) every program mcpp started failed with "not found"
since 2026.10.26.2. A static strace showed one failing call, before any
process was created: the root directory opened for reading, which the
domain may search but not read. openkal-linux 0.18.3 opens every directory
handle with `O_PATH`; mcpp is built on mcpplibs.os 0.2.3, which pins it, and
openkal-platform 0.18.0 carries it to every ok image and hosted program.
- **A gzip stream over 4 GiB.** zlib counts in 32 bits, and mcpp handed it the
whole tree at once: a `.tar.gz` of more than 4 GiB was refused as "an input
over 4 GiB", by `mcpp pack` and by a test archive alike. Input and output
now pass in pieces of 1 GiB, so such a tree is one gzip member as any other.
- **A program that cannot be started is reported with the system's account.**
Every condition beyond not found, permission and not a program was reported
as "error 5" (EIO), the system's own message dropped. The classification now
covers invalid, no memory, directory, not supported and too large, and the
report of `mcpp test` and `mcpp test --archive` carries what was being done
and the kernel layer's value.

## [2026.10.29.1] - 2026-10-29

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion docs/04-mcpp-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,7 @@ the platform's own key names ([35 — Platforms](35-platforms.md)):

```toml
[target.'cfg(os = "openkal")']
platform = "openkal-platform@0.17.3" # or { path = "…" }, or "none"
platform = "openkal-platform@0.18.0" # or { path = "…" }, or "none"

[target.'cfg(platform = "openkal")'.layers]
c-abi = { path = "../openkal-musl" }
Expand Down
20 changes: 20 additions & 0 deletions docs/08-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,26 @@ otherwise, so it needs no `libc++_shared.so` on the device.
The runner itself, named runners, and what a board declares are
[41 — Reaching a Device](41-devices.md).

### Built once, run elsewhere (mcpp 2026.10.30.1+)

An ok image is the same bytes on every system, and a test built for
`x86_64-windows-gnu` on Linux runs on Windows. `--archive` separates the two
halves:

```bash
mcpp test --target openkal --no-run --archive tests.tar.gz # build every leg's tests, write them
mcpp test --archive tests.tar.gz # in a checkout: run what this machine reaches
```

The archive holds each leg's test programs and `mcpp-tests.json`, which names
each test's leg, arguments and working directory. Reading it builds nothing;
the tests run in the checkout, through this machine's runner or system, and the
report is `mcpp test`'s. A failed test exits 1, and so does an archive of which
no test ran. Legs this machine does not reach are reported as not run
([SPEC-015 §4](specs/target-sets.md)). The archive is a tar compressed as its
name states: `.tar.gz` (or `.tgz`), `.tar.zst`, `.tar.xz` or `.tar`; another
name is refused before anything is built.

## Tests that cannot run beside each other

`mcpp test` runs test programs on a worker pool. One board on one probe, one
Expand Down
Loading
Loading