fix(csrc): clang 交叉需要 aarch64 libc 头 —— 只装 1.7MB 头包,不装 10MB 编译器

## CI 实测暴露的下一层问题

上一版让 clang 做交叉编译后,安装步骤成功且**完全跳过 apt**(cmake/clang 都在
镜像里),但 `make check-csrc` 红在:

    In file included from /usr/lib/llvm-18/lib/clang/18/include/stdint.h:52:
    /usr/include/stdint.h:26:10: fatal error: 'bits/libc-header-start.h' file not found

真因:`clang --target=aarch64-linux-gnu` 切换的是**目标架构**,但系统头
仍按**宿主**(amd64)找 —— `bits/libc-header-start.h` 是 amd64 的布局,
aarch64 目标下不该用。本地能过是本机装了完整交叉 GCC,带来了
`/usr/aarch64-linux-gnu/include`。

## 试过但走不通的两条路(记录以免重复踩)

| 尝试 | 结果 |
|---|---|
| `-nostdinc` + clang 内建头 | ❌ clang 内建**不含 `string.h`**(那是 libc 的) |
| `-ffreestanding -nostdlibinc` | ❌ 同上,代码实际用了 `strlen`/`memcpy` |

## 采用:只装 libc 头,不装编译器

    libc6-dev-arm64-cross     1.7 MB(+ libc6-arm64-cross、linux-libc-dev-arm64-cross)
    gcc-aarch64-linux-gnu     含 cpp-13(10.8MB)+ gcc-16 等,实测下载卡死

既然只需要**头文件**(不做链接、不跑代码),就不该拉整个交叉 GCC。
装上头后 clang 就能完成 `-fsyntax-only`。

### Makefile 配合

`csrc-cross` 的 clang-target 模式现在自动探测并注入 aarch64 头路径:

    for d in /usr/aarch64-linux-gnu/include /usr/include/aarch64-linux-gnu; do
        [ -d "$d" ] && ARM64_SYSINC="$ARM64_SYSINC -isystem $d"
    done

探测改用**真实头文件**(`#include <string.h>`)而非空 main,这样
"clang 版本支持 --target" 与 "aarch64 头是否齐备" 两个条件一起验;
缺头时明确 SKIP 并说清装哪个包(`libc6-dev-arm64-cross`)。

## 本地实测

| 验证 | 结果 |
|---|---|
| 有 aarch64 头时 | ✅ clang-target 通过(0 告警) |
| `make check-csrc` 全门禁 | ✅ 全部通过,0 SKIP |
| YAML 可解析 | ✅ |
| 上一版三条失败路径(编译器不存在/真写坏/正常) | ✅ 仍然正确(PIPESTATUS 修复未回退) |
This commit is contained in:
JianFeeeee
2026-10-22 23:59:37 +08:00
parent 7fdec0670f
commit 0e5077497e
2 changed files with 12 additions and 3 deletions

View File

@ -204,6 +204,10 @@ jobs:
need=""
command -v cmake >/dev/null || need="$need cmake"
command -v clang >/dev/null || need="$need clang"
# aarch64 的 libc 头(1.7MB,仅头文件,**不含编译器**)。
# 用它 + 已预装的 clang 交叉前端,替代 10MB+ 的完整交叉 GCC
# (实测那个会卡在下载 cpp-13-aarch64,180s 超时)。
[ -d /usr/aarch64-linux-gnu/include ] || need="$need libc6-dev-arm64-cross"
if [ -z "$need" ]; then
echo "✅ 依赖已存在,跳过 apt-get:$(command -v cmake clang | tr '\n' ' ')"