Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4d320fb
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
speak-agent Oct 7, 2026
42e8b88
feat: support native Linux ARM64 with LLVM 23.1.3
speak-agent Oct 7, 2026
dd30d64
test: require native ARM64 runtime and ecosystem evidence
speak-agent Oct 7, 2026
bed4876
fix: align benchmark LLVM and preserve precise CI diagnostics
speak-agent Oct 7, 2026
0ea64e7
fix: keep Clang managed system headers hermetic
speak-agent Oct 7, 2026
c29e53d
test: admit native GNU and ARM64 openkal cross consumers
speak-agent Oct 7, 2026
821f216
fix: initialize native admission paths in a valid runner context
speak-agent Oct 7, 2026
0183ea3
fix: create native admission projects by their CLI names
speak-agent Oct 7, 2026
9229b97
test: align host flags with managed GNU header isolation
speak-agent Oct 7, 2026
553861c
fix: keep E2E registry paths out of GCC prefix controls
speak-agent Oct 7, 2026
6612505
test: verify native GCC mappings and retain ARM64 ELF link evidence
speak-agent Oct 7, 2026
b67e928
fix: keep the explicit ELF unwinder selection self-contained
speak-agent Oct 7, 2026
5a0d70e
fix: align ARM64 host std modules with compiler runtime selection
speak-agent Oct 8, 2026
cd6d44b
test: attest native ARM64 GNU and openkal acceptance
speak-agent Oct 8, 2026
a6cecdb
test: verify hosted openkal thread isolation and teardown
speak-agent Oct 8, 2026
daa3aab
test: keep hosted application fixture outside unit discovery
speak-agent Oct 8, 2026
3341ae5
test: normalize Windows hosted probe output paths
speak-agent Oct 8, 2026
8131ca3
test: consume indexed JSON in the openkal cross matrix
speak-agent Oct 8, 2026
0279594
test: preserve hosted probe source bytes across checkouts
speak-agent Oct 8, 2026
c976c70
fix: install the native CN sandbox backend by its package name
speak-agent Oct 8, 2026
2f70339
fix: install the published CN engine in global scope
speak-agent Oct 8, 2026
e862c65
test: accept LLVM spelling of the native ARM GNU identity
speak-agent Oct 8, 2026
3d90198
test: declare the measured four-host LLVM 23.1.3 matrix
speak-agent Oct 8, 2026
67ab1dd
ci: supply openkal test tools through xlings
speak-agent Oct 8, 2026
c6dca54
ci: execute the registered RISC-V emulator shim
speak-agent Oct 8, 2026
1916a5f
fix: explain the 32-bit MSVC coroutine failures and keep host headers…
Sunrisepeak Oct 8, 2026
41f7539
fix: decide the std module coroutine note from its command
Sunrisepeak Oct 8, 2026
325f082
docs: keep the Part 2 execution log out of the repository
Sunrisepeak Oct 8, 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
385 changes: 385 additions & 0 deletions .agents/docs/2026-10-07-llvm-2313-unified-default-cross-repo-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
---
```

327 records.
329 records.

## By subject

Expand Down Expand Up @@ -95,6 +95,11 @@ Records that declare one. Everything else is listed by date below.
- [SDK toolchains, the payload/engine seam, and openkal across iOS, Android and Web](2026-09-11-sdk-toolchains-and-ios-local-verification.md) — landed
- [Where a platform's knowledge belongs: iOS, Android and Web across the engine, the index and the plugins](2026-09-11-platform-targets-design-review.md) — active

### toolchain

- [LLVM 23.1.3 Part 2:Linux aarch64 默认工具链与 glibc 生态闭环](2026-10-08-llvm-2313-linux-aarch64-ecosystem-part2-design.md) — active
- [LLVM 23.1.3 全平台统一默认:跨仓库联动方案(mcpp × xim-pkgindex)](2026-10-07-llvm-2313-unified-default-cross-repo-design.md) — active

### triage

- [Eight reports after 2026.9.27.1: what each one is, where it belongs, and one optimisation plan](2026-09-27-eight-reports-by-home-and-one-optimisation-plan.md) — active
Expand All @@ -118,6 +123,8 @@ Records that declare one. Everything else is listed by date below.

### 2026-10

- [LLVM 23.1.3 Part 2:Linux aarch64 默认工具链与 glibc 生态闭环](2026-10-08-llvm-2313-linux-aarch64-ecosystem-part2-design.md) — active
- [LLVM 23.1.3 全平台统一默认:跨仓库联动方案(mcpp × xim-pkgindex)](2026-10-07-llvm-2313-unified-default-cross-repo-design.md) — active
- [2026.10.5.3 发布方案:32 位 x86 的架构词汇、资源编译器的识别与增量(#776 后续)](2026-10-06-windows-x86-arch-vocabulary-and-rc-follow-ups-design.md) — active
- [下一个版本的发布方案:标准库模块、原生 MSVC LTO 与导出发现、共享库的链接配置、Windows 参数引号(#768 后续、#770、#771)](2026-10-05-std-module-pair-msvc-lto-and-export-discovery-design.md) — active
- [`mcpp run` hands the terminal to the program, and the follow-ups of #761, #763 and #765 (#766)](2026-10-05-run-terminal-handoff-and-766-follow-ups-design.md) — landed
Expand Down
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# The cross-host admission compares the exact source bytes compiled by each host.
tests/fixtures/openkal-hosted-threads/src/main.cpp.in text eol=lf
2 changes: 1 addition & 1 deletion .github/actions/bootstrap-mcpp/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ inputs:
# `package.name`, so one of the two was simply unreachable — and which one
# depended on the machine, which is why CI failed on `compat:lua` on
# Windows and `mcpplibs.capi:lua` on Linux. Never pin below that.
default: '2026.9.30.1'
default: '2026.10.8.1'

outputs:
sandbox-key:
Expand Down
4 changes: 2 additions & 2 deletions .github/actions/setup-macos-llvm/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ inputs:
# Floor imposed by the index, not a routine bump — see
# .github/actions/bootstrap-mcpp/action.yml for why 0.4.69 is required
# (two packages named `lua` in one repo need openxlings/xlings#381).
default: '2026.9.30.1'
default: '2026.10.8.1'
image:
description: >
The runner label the job runs on (macos-15, xcode-27). It is part of the
Expand Down Expand Up @@ -72,7 +72,7 @@ runs:
# latest-first: test binaries now link the toolchain's own libc++
# (A1 root fix in flags.cppm), so new llvm releases are
# self-consistent — the macOS job is the proof for each new default.
xlings install llvm -y || xlings install llvm@20.1.7 -y
xlings install llvm@23.1.3 -y || xlings install llvm -y
LLVM_ROOT=$(find "$HOME/.xlings" -path "*/xpkgs/xim-x-llvm/*/bin/clang++" | head -1 | xargs dirname | xargs dirname)
ls "$LLVM_ROOT/bin/clang++"
"$LLVM_ROOT/bin/clang++" --version
Expand Down
13 changes: 13 additions & 0 deletions .github/actions/use-built-mcpp/use.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ fi
# The toolchain mcpp.toml names for this host is the one the build used, so it
# is the one whose payloads hold the binary's runtime.
manifest_toolchain() {
# Native ARM64 overrides the platform-wide GCC pin. Consumers must install
# the same payload used by build.yml, including the first launch's runtime.
if [ "$host" = linux-aarch64 ]; then
local native
native="$(awk '
/^\[/ { in_tc = ($0 == "[target.aarch64-linux-gnu]"); next }
in_tc && $1 == "toolchain" { gsub(/"/, "", $3); print $3; exit }
' mcpp.toml)"
if [ -n "$native" ]; then
printf '%s\n' "$native"
return
fi
fi
local key
case "$host" in
macos-*) key=macos ;;
Expand Down
2 changes: 1 addition & 1 deletion .github/tools/build_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ BUILD=(
# Built here for one reason worth the cost: it is the only example whose
# CPU-only configuration exercises `cfg(accelerator = "none")` and two rule
# packages in one build program, and both of those are engine paths that a
# description cannot cover. Its `[toolchain] default = "llvm@22.1.8"` means
# description cannot cover. Its `[toolchain] default = "llvm@23.1.3"` means
# this job installs an LLVM payload it otherwise would not -- the CUDA leg
# takes the clang route, because the nvcc route on the 12.9 line is refused
# by nvcc's own front end and the 13.x line raises the driver floor to r580.
Expand Down
39 changes: 0 additions & 39 deletions .github/tools/check_aarch64_llvm_deferral.sh

This file was deleted.

201 changes: 201 additions & 0 deletions .github/tools/check_aarch64_llvm_payload.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#!/usr/bin/env bash
# Positive admission for the native Linux ARM64 LLVM payload.
set -euo pipefail
[[ "$(uname -s)" == Linux && "$(uname -m)" == aarch64 ]] || {
echo 'FAIL: this gate requires a native Linux aarch64 host'; exit 1;
}
MCPP="${MCPP:-mcpp}"
index_seed="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/seed_native_xim_index.py"
seed_candidate() {
[[ -n "${MCPP_NATIVE_XIM_INDEX:-}" ]] || return 0
python3 "$index_seed" "${MCPP_HOME:-$HOME/.mcpp}" "$MCPP_NATIVE_XIM_INDEX"
}
verify_candidate() {
[[ -n "${MCPP_NATIVE_XIM_INDEX:-}" ]] || return 0
python3 "$index_seed" --verify "${MCPP_HOME:-$HOME/.mcpp}" "$MCPP_NATIVE_XIM_INDEX"
}
# Optional only for manual cross-repository admission; normal CI keeps main.
seed_candidate
"$MCPP" toolchain install llvm 23.1.3
verify_candidate
MCPP_E2E_LLVM_VERSION=23.1.3 source tests/e2e/_toolchain_env.sh
[[ -x "$LLVM_ROOT/bin/clang++" ]] || { echo 'FAIL: LLVM frontend missing'; exit 1; }
file -L "$LLVM_ROOT/bin/clang++" | grep -q 'ARM aarch64' || {
echo 'FAIL: LLVM frontend is not native ARM64'; exit 1;
}
"$LLVM_ROOT/bin/clang++" --version
work="$(mktemp -d)"
report="${MCPP_NATIVE_REPORT_DIR:-${RUNNER_TEMP:-$work}/native-llvm-arm64}"
mkdir -p "$report"
trap 'rm -rf "$work"' EXIT
export MCPP_HOME="$work/mcpp-home"
seed_candidate
"$MCPP" self config --mirror "${MCPP_E2E_MIRROR:-GLOBAL}"
"$MCPP" self env --format json | python3 -c 'import json,sys; d=json.load(sys.stdin); assert d["data"]["defaultToolchain"] == "llvm@23.1.3", d'
verify_candidate
(cd "$work" && "$MCPP" new native-probe)
mkdir -p "$work/nativeabi/src"
cat > "$work/nativeabi/mcpp.toml" <<'TOML'
[package]
name = "nativeabi"
version = "0.1.0"
[build]
sources = ["src/*.c"]
[targets.nativeabi]
kind = "shared"
soname = "libnativeabi.so.1"
TOML
printf 'int native_answer(int x) { return x + 1; }\n' > "$work/nativeabi/src/answer.c"
cd "$work/native-probe"
cat >> mcpp.toml <<'TOML'

[dependencies]
nativeabi = { path = "../nativeabi" }
TOML
cat > src/main.cpp <<'CPP'
import std;
import std.compat;
extern "C" int native_answer(int);
int native_headers();
struct alignas(16) Pair { unsigned long a, b; };
static_assert(sizeof(Pair) == 16);
int main() {
auto memory = std::make_unique<int>(41);
int value = 0;
std::thread worker([&] { value = native_answer(*memory); });
worker.join();
bool caught = false;
try { throw std::runtime_error("native"); }
catch (const std::runtime_error&) { caught = true; }
std::atomic<Pair> atom;
atom.store(Pair{0, 0});
Pair expected{0, 0};
bool exchanged = atom.compare_exchange_strong(expected, Pair{42, 7});
auto result = atom.load();
void* raw = ::malloc(32);
bool allocated = raw != nullptr;
::free(raw);
bool ok = value == 42 && caught && exchanged && result.a == 42
&& result.b == 7 && allocated && native_headers() == 1;
::printf("native-stdlib-cabi=%s\n", ok ? "ok" : "failed");
return ok ? 0 : 1;
}
CPP
cat > src/headers.cpp <<'CPP'
#include <features.h>
#include <stddef.h>
#include <unistd.h>
#include <pthread.h>
int native_headers() { return 1; }
CPP
"$MCPP" build
"$MCPP" run | tee "$report/runtime.log"
grep -qF 'native-stdlib-cabi=ok' "$report/runtime.log"
binary="$(find target/aarch64-linux-gnu -type f -path '*/bin/native-probe' | head -1)"
[[ -n "$binary" ]] || { echo 'FAIL: default did not produce a native GNU artifact'; exit 1; }
readelf -l "$binary" > "$report/program-headers.txt"
readelf -d "$binary" > "$report/dynamic.txt"
grep -q 'ld-linux-aarch64.so.1' "$report/program-headers.txt" || {
echo 'FAIL: native default is not glibc-linked'; exit 1;
}
interpreter="$(sed -n 's/.*Requesting program interpreter: \(.*\)]/\1/p' "$report/program-headers.txt")"
case "$interpreter" in
"$MCPP_HOME"/registry/data/xpkgs/xim-x-glibc/*/lib*/ld-linux-aarch64.so.1) ;;
*) echo "FAIL: GNU default uses an ambient loader: $interpreter"; exit 1 ;;
esac
"$interpreter" --list "$binary" > "$report/loader-resolution.txt"
python3 - "$report/loader-resolution.txt" <<'PYLOADER'
import pathlib, re, sys
text = pathlib.Path(sys.argv[1]).read_text()
assert not re.search(r'=> /(?:usr/lib|lib64?|usr/local/lib)/', text), text
print('PASS: the native loader resolves no ambient system library')
PYLOADER
grep -q 'libnativeabi.so.1' "$report/dynamic.txt" || {
echo 'FAIL: the C ABI consumer does not depend on the shared library'; exit 1;
}
# Replay the engine's effective header compile as a preprocess trace. The trace
# must resolve libc headers through the payload, without an ambient /usr tree.
python3 - "$report" <<'PYTRACE'
import json, os, pathlib, re, shlex, subprocess, sys
report = pathlib.Path(sys.argv[1])
cdb = next(pathlib.Path('target/aarch64-linux-gnu').rglob('compile_commands.json'))
entries = json.loads(cdb.read_text())
entry = next(e for e in entries if e['file'].endswith('/headers.cpp'))
args = entry.get('arguments') or shlex.split(entry['command'])
# The driver named by the cold project's CDB must itself have a managed
# ARM64 loader and dependency closure, independently of the program it emits.
store = (pathlib.Path(os.environ['MCPP_HOME']) / 'registry/data/xpkgs').resolve()
compiler = pathlib.Path(args[0]).resolve()
relative = compiler.relative_to(store)
assert relative.parts[:2] == ('xim-x-llvm', '23.1.3'), compiler

driver_env = dict(os.environ)
driver_env.pop('LD_LIBRARY_PATH', None)
driver_env.pop('LD_PRELOAD', None)

def capture(name, command):
result = subprocess.run(command, text=True, capture_output=True, env=driver_env)
text = result.stdout + result.stderr
(report / name).write_text(text)
assert result.returncode == 0, (command, text)
return text

header = capture('compiler-elf-header.txt', ['readelf', '-hW', str(compiler)])
assert re.search(r'Machine:\s+AArch64', header), header
version = capture('compiler-version.txt', [str(compiler), '--version'])
assert re.search(r'clang version 23\.1\.3(?:\s|$)', version), version
program_headers = capture('compiler-program-headers.txt', ['readelf', '-lW', str(compiler)])
match = re.search(r'Requesting program interpreter: ([^\]]+)', program_headers)
assert match, program_headers
loader = pathlib.Path(match.group(1)).resolve()
loader_relative = loader.relative_to(store)
assert loader_relative.parts[0] == 'xim-x-glibc', loader
assert loader.name == 'ld-linux-aarch64.so.1', loader
closure = capture('compiler-loader-resolution.txt', [str(loader), '--list', str(compiler)])
assert not re.search(r'=> /(?:usr/lib|lib64?|usr/local/lib)/', closure), closure
for path in re.findall(r'=> (/\S+)', closure):
pathlib.Path(path).resolve().relative_to(store)
print('PASS: cold LLVM frontend has native ARM64 managed loader and libraries')
clean = []
i = 0
while i < len(args):
arg = args[i]
if arg in ('-o', '-MF', '-MT', '-MQ'):
i += 2
continue
if arg in ('-c', '-MMD', '-MD', '-MP'):
i += 1
continue
clean.append(arg)
i += 1
result = subprocess.run(clean + ['-E', '-H'], cwd=entry['directory'],
text=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
(report / 'include-trace.txt').write_text(result.stderr)
assert result.returncode == 0, result.stderr
headers = [m.group(1) for line in result.stderr.splitlines()
if (m := re.match(r'^\.+ (.+)$', line))]
assert any('xim-x-glibc' in path and path.endswith('/features.h') for path in headers), headers
assert not any(re.match(r'/usr/(include|lib/gcc|local/include)(/|$)', path) for path in headers), headers
print('PASS: libc include trace uses the managed payload')
PYTRACE
cat "$report/program-headers.txt" "$report/loader-resolution.txt" \
"$report/compiler-version.txt" "$report/compiler-elf-header.txt" \
"$report/compiler-program-headers.txt" "$report/compiler-loader-resolution.txt" \
"$report/include-trace.txt"
"$MCPP" pack --mode self-contained --format dir --message-format json > "$report/pack.json"
bundle="$(python3 - "$report/pack.json" <<'PYPACK'
import json, sys
artifact = json.load(open(sys.argv[1]))['data']['artifacts'][0]
assert artifact['type'] == 'directory', artifact
print(artifact['path'])
PYPACK
)"
# Directory deployment exercises the documented portable bundle entry point.
cp -a "$bundle" "$work/deployed"
(cd / && env -u LD_LIBRARY_PATH "$work/deployed/native-probe") | tee "$report/deployed.log"
grep -qF 'native-stdlib-cabi=ok' "$report/deployed.log"
(cd "$work" && "$MCPP" new musl-probe)
cd "$work/musl-probe"
"$MCPP" build --target aarch64-linux-musl --toolchain gcc@16.1.0-musl
"$MCPP" run --target aarch64-linux-musl --toolchain gcc@16.1.0-musl
printf '%s\n' 'PASS: native ARM64 LLVM installs, builds and runs'
7 changes: 7 additions & 0 deletions .github/tools/check_default_toolchain_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ def expected_phrases(spec: str, os_name: str, arch: str) -> dict[str, list[str]]
"docs/20-toolchains.md": [f"- Linux x86_64 uses {s}"],
"docs/zh/20-toolchains.md": [f"- Linux x86_64 使用面向原生 glibc ABI 的 {s}"],
}
if arch in ("aarch64", "arm64"):
return {
"docs/01-getting-started.md": [f"| Linux aarch64 | {s} |"],
"docs/zh/01-getting-started.md": [f"| Linux aarch64 | {s} |"],
"docs/20-toolchains.md": [f"- Linux aarch64 uses {s}"],
"docs/zh/20-toolchains.md": [f"- Linux aarch64 使用面向原生 glibc ABI 的 {s}"],
}
return {
"docs/01-getting-started.md": [f"| other Linux architectures | {s} |"],
"docs/zh/01-getting-started.md": [f"| 其它 Linux 架构 | {s} |"],
Expand Down
8 changes: 4 additions & 4 deletions .github/tools/check_function_sizes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@
# WHAT THIS NEEDS
#
# A compile database that names BMIs explicitly (-fmodule-file=...), which
# only a build actually produces: `mcpp build --toolchain llvm@22.1.8` writes
# only a build actually produces: `mcpp build --toolchain llvm@23.1.3` writes
# compile_commands.json at the project root. This script does not build it:
# the caller runs that build first. check_file_lengths.sh needs no such
# division because it reads the tree.
#
# IN CI SINCE 2026.9.28.2 (#729). ci-linux.yml's "toolchain: musl + llvm" job
# builds mcpp with llvm@22.1.8 -- failing on the build's own status, which it
# builds mcpp with llvm@23.1.3 -- failing on the build's own status, which it
# did not do while it built with llvm@20.1.7 and read only the resolution line
# -- and runs this script after it, over the compile database that build
# writes. By hand: `mcpp build --toolchain llvm@22.1.8`, then this script.
# writes. By hand: `mcpp build --toolchain llvm@23.1.3`, then this script.
#
# clang-tidy itself is not part of the plain xim:llvm payload mcpp resolves
# for `--toolchain llvm@...` (measured: xim-x-llvm/22.1.8/bin has clang,
Expand Down Expand Up @@ -67,7 +67,7 @@ FAIL: $CDB does not exist.
This check reads clang-tidy's own function boundaries, which needs a
compile database that names every imported module's BMI explicitly.
Produce one first:
mcpp build --toolchain llvm@22.1.8
mcpp build --toolchain llvm@23.1.3
(any installed LLVM row works; the database is written at the project
root regardless of the row's exact version).
EOF
Expand Down
Loading
Loading