Skip to content

Commit 42e8b88

Browse files
committed
feat: support native Linux ARM64 with LLVM 23.1.3
Add the ARM64 first-run pin, native GNU host row and runtime paths; preserve explicit musl and existing user defaults. Add cold payload admission, complete xcode-27 shards, respect MCPP_HOME and capture Windows compiler failure evidence. Prepare release 2026.10.8.1. Native ARM64 remains preview until the coordinated resources and client release pass the measured integration gates. Refs: #784, #783
1 parent 4d320fb commit 42e8b88

39 files changed

Lines changed: 830 additions & 194 deletions

‎.agents/docs/2026-10-08-llvm-2313-linux-aarch64-ecosystem-part2-design.md‎

Lines changed: 403 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
subject: toolchain
3+
status: active
4+
---
5+
6+
# LLVM 23.1.3 Part 2:任务依赖与生态交付记录
7+
8+
本记录落实 [Part 2 方案](2026-10-08-llvm-2313-linux-aarch64-ecosystem-part2-design.md)。
9+
状态只根据代码、构建进程、CI、发布资源和真实消费结果更新。未执行的门不计为完成。
10+
维护者已授权实现、每仓库集中 PR、CI 修复、发布、CN 镜像补传、SubOS 实测及已完成 issue 的关闭。
11+
12+
## 1. 架构边界与任务依赖
13+
14+
```mermaid
15+
flowchart TD
16+
A[当前事实与问题复现] --> B[原生 ARM64 配套资源构建]
17+
A --> C[xlings 元数据架构上下文修复]
18+
A --> D[mcpp 引擎与 review 缺口修正]
19+
B --> E[LLVM ARM64 carve 与准入]
20+
C --> F[xlings 三平台 CI与发布]
21+
F --> G[索引客户端与架构资源接线]
22+
E --> G
23+
G --> H[索引双镜像和原生消费 CI]
24+
H --> I[mcpp 全矩阵与 openkal 联测]
25+
D --> I
26+
I --> J[生态自审与合入]
27+
J --> K[mcpp 发布与索引传播]
28+
K --> L[CN SubOS与生态闭环审计]
29+
```
30+
31+
LLVM 与 glibc 是原生 aarch64 的新默认组合;x86_64 保持 GCC,显式旧配置保留。
32+
资源选择按客户端进程 ABI,不能以硬件架构替代;这保持 Rosetta、WOW64 和 Linux emulation 的一致性。
33+
同一 glibc loader 与核心库来源绑定是稳定性门。libc++ 与 libstdc++ 的 C++ ABI 不混用。
34+
35+
## 2. 仓库交付与责任
36+
37+
| 任务 | 仓库与跟踪 | 依赖 | 验收依据 | 当前状态 |
38+
|---|---|---|---|---|
39+
| T1 review 修正与引擎默认 | [mcpp #784](https://github.com/mcpp-community/mcpp/issues/784),沿用 #781 | T4 公开资源后完整 CI | 冷 home、默认双轴、GNU native、自举、modules、Windows 诊断 | 实现中 |
40+
| T2 ARM64 配套与 carve | [xim-pkgindex #937](https://github.com/openxlings/xim-pkgindex/issues/937) | 原生构建机 | 架构、来源摘要、loader/runtime、编译运行 | 原生构建已启动 |
41+
| T3 配方元数据上下文 | [xlings #646](https://github.com/openxlings/xlings/issues/646) | 现有 libxpkg LoaderContext | metadata 与 install 相同架构;三平台回归 | 已复现并实现,构建中 |
42+
| T4 索引接线与镜像 | [xim-pkgindex #938](https://github.com/openxlings/xim-pkgindex/pull/938) | T2、T3 发布 | 每架构哈希、旧版本拒绝、双镜像 GET、消费门 | draft |
43+
| T5 原生与生态消费 | mcpp、xlings、mcpp-index、openkal | T1、T4 | 原生 ARM64、CN SubOS sandbox、真实 build/test/run/pack | 待资源与客户端就绪 |
44+
| T6 自审与发布 | mcpp、xlings、资源与索引 | T1–T5 | 最终头 CI、发版产物、指针传播、消费审计 | 待前置门 |
45+
46+
单个仓库的实现集中在一个 PR:mcpp 沿用 #781,索引使用 #938;xlings 因实测发现客户端缺陷而新增必要 PR。
47+
发布版本同时纳入相应实现 PR。发布后生成的资源索引更新依赖已发布摘要,若不能纳入尚未合入的索引 PR,
48+
使用必要的自动索引收尾 PR;bootstrap pin 也只在资源已公开且索引传播后前移。该依赖不能通过提前填写未来版本规避。
49+
50+
## 3. 多角度验收
51+
52+
| 角度 | 约束 | 可验证证据 |
53+
|---|---|---|
54+
| 架构 | runtime、target、client ABI 分别命名 | ELF、LoaderContext、GNU/musl target 与解析报告 |
55+
| 稳定性 | loader 与 libc 同源、私有共享库闭包 | NEEDED、INTERP、RUNPATH、运行与 relocation 探针 |
56+
| 简洁性 | 使用现有 host row、两包 carve、统一 recipe loader | 无新 toolchain 语法、无第二套资源解析器 |
57+
| 用户体验 | 新安装不要求手工装配依赖 | new/build/run 冷安装及诊断 |
58+
| 兼容性 | 旧配置与历史版本保持事实边界 | 旧 LLVM 在 ARM64 不误报可装,旧 x86 recipe 不回归 |
59+
| 跨平台 | 只扩展已发布架构,不扩大 GNU cross 承诺 | 各宿主矩阵与具名 refusal |
60+
| 一致性 | 元数据读取与 install 使用同一上下文 | live recipe、catalog、安装对照测试 |
61+
| 升级 | 保留声明,说明双轴差异,不悄悄改 ABI | fresh 与 retained defaultTarget、prebuilt/BMI 失效检查 |
62+
| 覆盖 | capability、分片和缓存前提必须可观察 | 按镜像完整分片,890 冷安装,candidate 精确钉 |
63+
| 生态 | 索引与发布版客户端实际协作 | CN sandbox、mcpp-index、openkal 运行与 pack |
64+
65+
## 4. 已取得的证据
66+
67+
2026-10-08:发布版 xlings 2026.10.4.1 在隔离 XLINGS_HOME 中通过 add-xpkg 和 info
68+
读取 `description = os.arch()` 的 live recipe,输出 `recipe architecture: unknown`。
69+
代码核查确认 catalog 元数据读取省略 LoaderContext,install 则传入平台与进程架构。
70+
T3 将两者统一;这项必要客户端修复应在新 ARM64 loader metadata 公开前发布。
71+
72+
索引原生资源构建:[run 37684733504](https://github.com/openxlings/xim-pkgindex/actions/runs/37684733504),
73+
ubuntu-24.04-arm,生成 UAPI、zlib、libxml2、gcc-runtime、glibc 和 LLVM 双包。
74+
这是运行中的构建,尚无资源通过或发布结论。
75+
76+
本地测试按变更契约聚焦执行,避免用重复测试占据资源制作与集成时间。
77+
最终闭环审计仍须逐项覆盖方案 G0–G9;局部通过不能替代整个生态已可用。

‎.agents/docs/README.md‎

Lines changed: 5 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-
328 records.
21+
330 records.
2222

2323
## By subject
2424

@@ -97,6 +97,8 @@ Records that declare one. Everything else is listed by date below.
9797

9898
### toolchain
9999

100+
- [LLVM 23.1.3 Part 2:任务依赖与生态交付记录](2026-10-08-llvm-2313-part2-execution-and-dependencies.md) — active
101+
- [LLVM 23.1.3 Part 2:Linux aarch64 默认工具链与 glibc 生态闭环](2026-10-08-llvm-2313-linux-aarch64-ecosystem-part2-design.md) — active
100102
- [LLVM 23.1.3 全平台统一默认:跨仓库联动方案(mcpp × xim-pkgindex)](2026-10-07-llvm-2313-unified-default-cross-repo-design.md) — active
101103

102104
### triage
@@ -122,6 +124,8 @@ Records that declare one. Everything else is listed by date below.
122124

123125
### 2026-10
124126

127+
- [LLVM 23.1.3 Part 2:任务依赖与生态交付记录](2026-10-08-llvm-2313-part2-execution-and-dependencies.md) — active
128+
- [LLVM 23.1.3 Part 2:Linux aarch64 默认工具链与 glibc 生态闭环](2026-10-08-llvm-2313-linux-aarch64-ecosystem-part2-design.md) — active
125129
- [LLVM 23.1.3 全平台统一默认:跨仓库联动方案(mcpp × xim-pkgindex)](2026-10-07-llvm-2313-unified-default-cross-repo-design.md) — active
126130
- [2026.10.5.3 发布方案:32 位 x86 的架构词汇、资源编译器的识别与增量(#776 后续)](2026-10-06-windows-x86-arch-vocabulary-and-rc-follow-ups-design.md) — active
127131
- [下一个版本的发布方案:标准库模块、原生 MSVC LTO 与导出发现、共享库的链接配置、Windows 参数引号(#768 后续、#770、#771)](2026-10-05-std-module-pair-msvc-lto-and-export-discovery-design.md) — active

‎.github/actions/use-built-mcpp/use.sh‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ fi
2929
# The toolchain mcpp.toml names for this host is the one the build used, so it
3030
# is the one whose payloads hold the binary's runtime.
3131
manifest_toolchain() {
32+
# Native ARM64 overrides the platform-wide GCC pin. Consumers must install
33+
# the same payload used by build.yml, including the first launch's runtime.
34+
if [ "$host" = linux-aarch64 ]; then
35+
local native
36+
native="$(awk '
37+
/^\[/ { in_tc = ($0 == "[target.aarch64-linux-gnu]"); next }
38+
in_tc && $1 == "toolchain" { gsub(/"/, "", $3); print $3; exit }
39+
' mcpp.toml)"
40+
if [ -n "$native" ]; then
41+
printf '%s\n' "$native"
42+
return
43+
fi
44+
fi
3245
local key
3346
case "$host" in
3447
macos-*) key=macos ;;

‎.github/tools/check_aarch64_llvm_deferral.sh‎

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bash
2+
# Positive admission for the native Linux ARM64 LLVM payload.
3+
set -euo pipefail
4+
[[ "$(uname -s)" == Linux && "$(uname -m)" == aarch64 ]] || {
5+
echo 'FAIL: this gate requires a native Linux aarch64 host'; exit 1;
6+
}
7+
MCPP="${MCPP:-mcpp}"
8+
"$MCPP" toolchain install llvm 23.1.3
9+
MCPP_E2E_LLVM_VERSION=23.1.3 source tests/e2e/_toolchain_env.sh
10+
[[ -x "$LLVM_ROOT/bin/clang++" ]] || { echo 'FAIL: LLVM frontend missing'; exit 1; }
11+
file -L "$LLVM_ROOT/bin/clang++" | grep -q 'ARM aarch64' || {
12+
echo 'FAIL: LLVM frontend is not native ARM64'; exit 1;
13+
}
14+
"$LLVM_ROOT/bin/clang++" --version
15+
work="$(mktemp -d)"
16+
trap 'rm -rf "$work"' EXIT
17+
export MCPP_HOME="$work/mcpp-home"
18+
"$MCPP" self config --mirror "${MCPP_E2E_MIRROR:-GLOBAL}"
19+
"$MCPP" self env --format json | python3 -c 'import json,sys; d=json.load(sys.stdin); assert d["data"]["defaultToolchain"] == "llvm@23.1.3", d'
20+
"$MCPP" new "$work/native-probe"
21+
cd "$work/native-probe"
22+
"$MCPP" build
23+
"$MCPP" run
24+
binary="$(find target/aarch64-linux-gnu -type f -path '*/bin/native-probe' | head -1)"
25+
[[ -n "$binary" ]] || { echo 'FAIL: default did not produce a native GNU artifact'; exit 1; }
26+
readelf -l "$binary" | grep -q 'ld-linux-aarch64.so.1' || {
27+
echo 'FAIL: native default is not glibc-linked'; exit 1;
28+
}
29+
"$MCPP" build --target aarch64-linux-musl --toolchain gcc@16.1.0-musl
30+
"$MCPP" run --target aarch64-linux-musl --toolchain gcc@16.1.0-musl
31+
printf '%s\n' 'PASS: native ARM64 LLVM installs, builds and runs'

‎.github/tools/check_default_toolchain_docs.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ def expected_phrases(spec: str, os_name: str, arch: str) -> dict[str, list[str]]
4444
"docs/20-toolchains.md": [f"- Linux x86_64 uses {s}"],
4545
"docs/zh/20-toolchains.md": [f"- Linux x86_64 使用面向原生 glibc ABI 的 {s}"],
4646
}
47+
if arch in ("aarch64", "arm64"):
48+
return {
49+
"docs/01-getting-started.md": [f"| Linux aarch64 | {s} |"],
50+
"docs/zh/01-getting-started.md": [f"| Linux aarch64 | {s} |"],
51+
"docs/20-toolchains.md": [f"- Linux aarch64 uses {s}"],
52+
"docs/zh/20-toolchains.md": [f"- Linux aarch64 使用面向原生 glibc ABI 的 {s}"],
53+
}
4754
return {
4855
"docs/01-getting-started.md": [f"| other Linux architectures | {s} |"],
4956
"docs/zh/01-getting-started.md": [f"| 其它 Linux 架构 | {s} |"],

‎.github/tools/check_workflow_assertions.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,27 @@ def last_statement(script: str) -> str:
224224
return stmts[-1] if stmts else ""
225225

226226

227+
def incomplete_shards(matrix_text: str) -> list[str]:
228+
"""Each explicitly declared image runs every shard exactly once."""
229+
rows = re.findall(r"- image:\s*(\S+)\s+shard:\s*(\d+)\s+shards:\s*(\d+)", matrix_text)
230+
grouped: dict[str, list[tuple[int, int]]] = {}
231+
for image, shard, total in rows:
232+
grouped.setdefault(image, []).append((int(shard), int(total)))
233+
problems = []
234+
for image, entries in grouped.items():
235+
totals = {n for _, n in entries}
236+
if len(totals) != 1 or sorted(s for s, _ in entries) != list(range(1, entries[0][1] + 1)):
237+
problems.append(f"W4 image {image}: incomplete or duplicate shard coverage {entries}")
238+
return problems
239+
240+
227241
def check(workflows: list[Path], check_open: bool) -> list[str]:
228242
problems: list[str] = []
229243
known_red: list[tuple[str, str, int]] = []
230244
for path in workflows:
231245
wf = parse(path)
232246
for job in wf.jobs:
247+
problems.extend(f"{p} ({path}:{job.line})" for p in incomplete_shards(job.matrix_text))
233248
for step in job.steps:
234249
where = f"{path}:{step.line} ({job.key} / {step.name or 'unnamed step'})"
235250
shell = effective_shell(wf, job, step)

‎.github/workflows/ci-macos-e2e.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ jobs:
3737
- image: xcode-27
3838
shard: 1
3939
shards: 2
40+
- image: xcode-27
41+
shard: 2
42+
shards: 2
4043
runs-on: ${{ matrix.image }}
4144
timeout-minutes: 60
4245
env:

‎.github/workflows/ci-target-matrix.yml‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ jobs:
9999
done
100100
[ "$fail" = 0 ] || exit 1
101101
102-
# A DEFERRAL NOBODY RECHECKS IS INDISTINGUISHABLE FROM A DEFECT. This
103-
# step fails when its reason STOPS holding — the day an aarch64 llvm is
104-
# published — which is the opposite of what a check usually does.
105-
- name: The aarch64 llvm deferral still has its reason
102+
- name: Native ARM64 LLVM payload admission
106103
if: matrix.host == 'linux-aarch64'
107-
run: bash .github/tools/check_aarch64_llvm_deferral.sh
104+
env:
105+
MCPP: ${{ env.MCPP_UNDER_TEST }}
106+
MCPP_VENDORED_XLINGS: ${{ env.XLINGS_BIN }}
107+
run: bash .github/tools/check_aarch64_llvm_payload.sh
108108

109109
- name: Each invariant RAN
110110
run: |
@@ -162,7 +162,7 @@ jobs:
162162
"OK: a capability pin is not a preference" \
163163
"gcc is not installed here" || fail=1
164164
fi
165-
if [ "${{ matrix.host }}" = linux-x86_64 ]; then
165+
if [[ "${{ matrix.host }}" = linux-* ]]; then
166166
check 298_overriding_a_convention_requires_replacing_it.sh \
167167
"OK: a convention may be overridden, but not merely removed" || fail=1
168168
else
@@ -308,6 +308,9 @@ jobs:
308308
want="$(awk -F'\t' -v h='${{ matrix.host }}' \
309309
'NF>=11 && $2==h {print $4}' tests/matrix/expected.tsv \
310310
| sort -u)"
311+
if [ "${{ matrix.host }}" = linux-aarch64 ]; then
312+
want="$(printf '%s\n' "$want" llvm@23.1.3 | sort -u)"
313+
fi
311314
if [ -z "$want" ]; then
312315
echo " ? ${{ matrix.host }} 尚无期望行 —— 扫描它现有的工具链"
313316
exit 0
@@ -343,6 +346,9 @@ jobs:
343346
MATRIX_COMPILERS="$(awk -F'\t' -v h='${{ matrix.host }}' \
344347
'NF>=11 && $2==h {print $4}' tests/matrix/expected.tsv \
345348
| sort -u | tr '\n' ' ')"
349+
if [ "${{ matrix.host }}" = linux-aarch64 ]; then
350+
MATRIX_COMPILERS="$MATRIX_COMPILERS llvm@23.1.3"
351+
fi
346352
export MATRIX_COMPILERS
347353
echo "declared compiler axis: ${MATRIX_COMPILERS:-<none — scanning what is installed>}"
348354
# 两种体系各自成表。scan 把 mode 写进第一列,而比对必须按 mode 分开

0 commit comments

Comments
 (0)