Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
69 changes: 69 additions & 0 deletions .agents/docs/2026-05-15-stdcompat-restat-e2e.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# std.compat 支持 + cxx_scan restat + 增量零重编 E2E

> 2026-05-15 — 收尾三个遗留项,一个 PR 完成

## 1. 三个任务

### 1.1 std.compat 模块支持

**现状**:`import std.compat` 在语法层面被识别(`is_std_module()` 返回 true),会触发 std BMI 构建。但 `std.compat.cppm`(Clang)/ `bits/std_compat.cc`(GCC)从未被发现和编译,没有独立的 BMI 产出。

**Clang**:`~/.mcpp/.../xim-x-llvm/20.1.7/share/libc++/v1/std.compat.cppm` 存在。需要 `--precompile` 编译为 `pcm.cache/std.compat.pcm` + `std.compat.o`。
**GCC**:`bits/std_compat.cc` 在当前 xlings GCC 16.1.0 包中**不存在**。GCC 的 `import std.compat` 由 `bits/std.cc` 隐式覆盖(编译 `std.cc` 自动产出 `std.compat` 的 gcm)。因此 GCC **不需要额外处理**。

**改动点**:
1. `Toolchain` 新增 `stdCompatSource`(可选路径)
2. `clang.cppm::find_libcxx_std_module_source` → 同时查找 `std.compat.cppm` 路径
3. `clang.cppm::enrich_toolchain` → 设置 `stdCompatSource`
4. `stdmod.cppm` → 若 `stdCompatSource` 非空,额外编译 `std.compat.pcm` + `std.compat.o`
5. `BuildPlan` 新增 `stdCompatBmiPath` + `stdCompatObjectPath`
6. `ninja_backend.cppm` → 当 Clang + 有 std.compat 时,stage `std.compat.pcm` 和 `std.compat.o`
7. `flags.cppm` → 若有 std.compat,加 `-fmodule-file=std.compat=<pcm>`
8. E2E 测试:在 `38_llvm_modules.sh` 或新增测试中用 `import std.compat` 验证

**GCC 不变**:GCC 的 `import std.compat` 已经通过 `bits/std.cc` 的隐式 gcm 工作,无需额外构建。

### 1.2 cxx_scan restat(P2 重新实现)

**之前失败原因**:经调查,CI 失败是 GitHub Actions 缓存 fallback restore(`restore-keys` 匹配到旧 commit 的 `target/`),导致 gtest `.o` 是旧的但 ninja 认为 up-to-date。与 restat 无关 — PR #35 第二次运行(无任何代码改动)就成功了。

**方案**:重新实现 backup-compare-restore + `restat = 1`,与 `cxx_module` 的 BMI 保留模式完全一致。

**改动点**:`ninja_backend.cppm` 的 `cxx_scan` rule。

### 1.3 增量零重编 E2E

**改动点**:增强 `tests/e2e/39_llvm_incremental.sh`,新增一个验证步骤:
- touch `greet.cppm` 但不改内容
- rebuild with verbose
- 验证 SCAN 跑了但 MOD/OBJ 没跑(restat 截断了级联)

## 2. 实施计划

所有改动在一个 PR 中,按以下顺序实施。

### Step 1:std.compat — 工具链层
- `model.cppm`:`Toolchain` 加 `stdCompatSource` 字段
- `clang.cppm`:`find_libcxx_std_compat_source()` + `enrich_toolchain` 填充
- `clang.cppm`:`std_compat_build_commands()` — 两步编译(同 std)
- `clang.cppm`:`std_compat_bmi_path()` / `staged_std_compat_bmi_path()`

### Step 2:std.compat — 构建管线层
- `plan.cppm`:`BuildPlan` 加 `stdCompatBmiPath` + `stdCompatObjectPath`
- `stdmod.cppm`:若 `tc.stdCompatSource` 非空,额外编译
- `cli.cppm`:`prepare_build` 中把 `StdModule` 的 compat 路径传入 plan
- `ninja_backend.cppm`:stage `std.compat.pcm` + `std.compat.o`(cp_bmi 边)
- `flags.cppm`:Clang 时加 `-fmodule-file=std.compat=<staged_pcm>`

### Step 3:cxx_scan restat
- `ninja_backend.cppm`:backup-compare-restore + `restat = 1`

### Step 4:E2E 测试
- 新增 `tests/e2e/41_llvm_std_compat.sh`:`import std.compat` + C 函数使用
- 增强 `tests/e2e/39_llvm_incremental.sh`:touch 零重编验证

## 3. 不做的事

- GCC std.compat 额外构建 — GCC 的 `bits/std.cc` 隐式覆盖
- 改 E2E 04_incremental.sh(GCC) — 已有且工作正常
- macOS / Windows — 远期
99 changes: 99 additions & 0 deletions .agents/docs/2026-05-16-cross-platform-clang-analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# MCPP 跨平台 Clang/LLVM 支持分析报告

> 2026-05-16 — Linux Clang 平权现状 + 跨平台设计路线

## 一、Linux Clang 已达 GCC 平权

通过 PR #34 (Clang module pipeline parity) 到 `c7c1c3e` (std.compat + restat),12 个核心 Blocker 已全部解决:

| 能力 | GCC | Clang | 状态 |
|---|---|---|---|
| 工具链检测 & 安装 | `gcc@16` | `llvm@20` | ✅ 对等 |
| 非模块 C/C++ 编译 | ✅ | ✅ | ✅ 对等 |
| `import std` | `bits/std.cc` → `gcm.cache/std.gcm` | `std.cppm` → `pcm.cache/std.pcm` | ✅ 对等 |
| `import std.compat` | GCC 隐式覆盖 | `std.compat.cppm` → `pcm.cache/std.compat.pcm` | ✅ 对等 |
| 多模块项目 (dyndep) | `-fdeps-format=p1689r5` | 同一 flag (去掉 `-fmodules`) | ✅ 对等 |
| BMI 缓存 (跨项目) | `gcm.cache/*.gcm` | `pcm.cache/*.pcm` | ✅ 对等 |
| 增量重编 | ✅ | ✅ + restat | ✅ 对等 |
| Fingerprint 隔离 | ✅ | ✅ (独立 fingerprint) | ✅ 对等 |
| E2E 测试覆盖 | 6+ 个 | 6 个 (36-41) | ✅ 对等 |

核心抽象层 `BmiTraits` (`model.cppm:46-56`) 是平权的关键。

## 二、跨平台差距分析

### 2.1 macOS (Apple Clang) — 难度:中等

**可复用**:BmiTraits、clang.cppm 检测 (已识别 `apple clang version`)、P1689 扫描、两步编译

**Blocker (6 个)**:

| # | 问题 | 说明 |
|---|---|---|
| M1 | Apple Clang 版本差异 | Apple Clang 版本号与 upstream 不同 |
| M2 | libc++ 模块源码路径 | macOS 的 libc++ 在 Xcode SDK 内 |
| M3 | Sysroot 发现 | 需要 `xcrun --show-sdk-path` |
| M4 | 链接器差异 | macOS 用 `ld64`/`ld_prime`,`-rpath` 语法不同 |
| M5 | 运行时库 | macOS 自带 libc++,不需要额外 rpath |
| M6 | xlings 包管理 | macOS 上包名/路径适配 |

### 2.2 Windows (MSVC) — 难度:高

**Blocker (10+ 个)**:全新编译器族 (`.ifc`)、编译命令语法 (`/std:c++latest`)、P1689 (`/scanDependencies`)、路径分隔符、Ninja shell 可移植性、VS 环境发现 (`vswhere`)、链接器差异等。

### 2.3 Windows (Clang-cl) — 难度:中高

相比 MSVC 稍简单,可作为 Windows 支持第一步。

## 三、架构设计

### 3.1 分层架构

```
┌─────────────────────────────────────────────┐
│ mcpp CLI / Build Pipeline │ ← 平台无关
├─────────────────────────────────────────────┤
│ BmiTraits + CompilerProfile │ ← 编译器抽象 (已有)
├──────────┬──────────┬──────────┬────────────┤
│ gcc.cppm │clang.cppm│ msvc.cppm│apple_clang │ ← 编译器实现
├──────────┴──────────┴──────────┴────────────┤
│ PlatformTraits (新增) │ ← 平台抽象
├──────────┬──────────┬───────────────────────┤
│ linux │ macos │ windows │ ← 平台实现
├──────────┴──────────┴───────────────────────┤
│ xlings / Registry │ ← 包管理
└─────────────────────────────────────────────┘
```

### 3.2 建议新增 PlatformTraits

```cpp
struct PlatformTraits {
std::string_view os; // "linux" | "macos" | "windows"
std::string_view exeExt; // "" | ".exe"
std::string_view staticLibExt; // ".a" | ".lib"
std::string_view sharedLibExt; // ".so" | ".dylib" | ".dll"
std::string_view copyCmd; // "cp -p" | "copy"
std::string_view cmpCmd; // "cmp -s" | "fc /b"
std::string_view rmCmd; // "rm -f" | "del /f"
};
```

### 3.3 实施路线

```
Phase 1 (已完成): Linux GCC + Linux Clang 平权
Phase 2: macOS Apple Clang (复用 clang.cppm, Unix-like)
Phase 3: Windows Clang-cl (新增 PlatformTraits, Ninja shell 可移植化)
Phase 4: Windows MSVC (新增 msvc.cppm, .ifc, vswhere)
```

## 四、关键决策

1. **macOS**: 复用 `clang.cppm`,内部 `is_apple_clang()` 分支
2. **Windows 首选**: 先 Clang-cl (复用 `.pcm`),后 MSVC
3. **Ninja shell 可移植**: backup-compare-restore 抽取为 `mcpp internal bmi-guard` 子命令
4. **xlings 跨平台**: `publisher.cppm` 已有三平台支持,包管理层基本就绪
Loading
Loading