Skip to content

Commit 334de05

Browse files
committed
docs: Windows platform maturity plan (P0-P5 optimization roadmap)
1 parent e1b1ef4 commit 334de05

1 file changed

Lines changed: 240 additions & 0 deletions

File tree

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
# Windows 平台成熟度提升方案
2+
3+
> 基于 PR #52 code review 反馈,针对 Windows 支持从"可自举"到"生产就绪"的优化路径。
4+
5+
## 当前状态
6+
7+
| 能力 | Linux | macOS | Windows | 差距 |
8+
|------|-------|-------|---------|------|
9+
| self-host |||||
10+
| `mcpp test` (unit) |||| 缺 clang-scan-deps |
11+
| E2E 覆盖 | 46/46 | 33/46 | 22/49 | 27 项 skip |
12+
| `mcpp pack` | ✅ (musl static) | ✅ (手动) | ❌ (CI 手写 zip) | pack 不支持 PE |
13+
| release workflow |||| 无 build-windows job |
14+
| MSVC 工具链 | N/A | N/A | 模型预留 | detect 不支持 |
15+
| 默认工具链回退 | gcc@15.1.0-musl | llvm@20.1.7 | llvm@20.1.7 | ✅ 已修 |
16+
17+
## 优化方案(按优先级)
18+
19+
### P0: 补齐 release workflow + 减少 E2E skip
20+
21+
**目标:** Windows 二进制进入正式 release 发布流程。
22+
23+
#### 1. release.yml 加 build-windows job
24+
25+
参照 `build-macos` 结构,在 `release.yml` 中增加 `build-windows` job:
26+
27+
```yaml
28+
build-windows:
29+
name: build (Windows / x64)
30+
runs-on: windows-latest
31+
needs: build-release
32+
# xlings install mcpp → mcpp build → package zip → upload
33+
```
34+
35+
产出 `mcpp-<version>-windows-x86_64.zip` + sha256,上传到 GitHub Release。
36+
37+
#### 2. 修复高价值 E2E skip 项
38+
39+
按投入产出排序:
40+
41+
| 测试 | 修复方式 | 工作量 |
42+
|------|----------|--------|
43+
| `02_new_build_run.sh` | 检查 `bin/hello``bin/hello.exe` ||
44+
| `16_test_failing.sh` | 调查 Windows 上 exit code 传递 ||
45+
| `35_workspace.sh` | 同上,binary 名加 `.exe` 检查 ||
46+
| `36_llvm_toolchain.sh` | 同上 ||
47+
| `19_bmi_cache_reuse.sh` | 修复 `cp_bmi` rule 的混合路径 ||
48+
| `24_git_dependency.sh` | CRLF + Windows 路径处理 ||
49+
| `38_self_config_mirror.sh` | xlings mirror cmd.exe 路径 ||
50+
51+
**预计可把 E2E 从 22 passed 提升到 ~30 passed。**
52+
53+
### P1: PlatformTraits 抽象
54+
55+
**目标:** 减少散落的 `#if defined(_WIN32)` / `#if defined(__APPLE__)`
56+
57+
新建 `src/platform.cppm`,集中平台差异:
58+
59+
```cpp
60+
export module mcpp.platform;
61+
import std;
62+
63+
export namespace mcpp::platform {
64+
65+
constexpr std::string_view exe_suffix =
66+
#if defined(_WIN32)
67+
".exe";
68+
#else
69+
"";
70+
#endif
71+
72+
constexpr std::string_view static_lib_ext =
73+
#if defined(_WIN32)
74+
".lib";
75+
#else
76+
".a";
77+
#endif
78+
79+
constexpr std::string_view shared_lib_ext =
80+
#if defined(_WIN32)
81+
".dll";
82+
#elif defined(__APPLE__)
83+
".dylib";
84+
#else
85+
".so";
86+
#endif
87+
88+
constexpr std::string_view null_redirect =
89+
#if defined(_WIN32)
90+
"2>nul";
91+
#else
92+
"2>/dev/null";
93+
#endif
94+
95+
constexpr std::string_view lib_prefix =
96+
#if defined(_WIN32)
97+
"";
98+
#else
99+
"lib";
100+
#endif
101+
102+
std::string shell_quote(std::string_view s); // 取代散落的 shq
103+
104+
} // namespace mcpp::platform
105+
```
106+
107+
**受益文件:** `plan.cppm`、`flags.cppm`、`ninja_backend.cppm`、`probe.cppm`、`clang.cppm`、`config.cppm`
108+
109+
### P2: ToolchainProvider 重构
110+
111+
**目标:** 把工具链行为从散落的 `if (isClang)` / `if (isGcc)` 收敛到 provider 接口。
112+
113+
当前工具链代码分散在:
114+
- `gcc.cppm` — GCC 行为
115+
- `clang.cppm` — Clang/libc++ 行为 + MSVC STL fallback
116+
- `llvm.cppm` — xlings 包映射
117+
- `detect.cppm` — 只处理 GCC/Clang
118+
- `flags.cppm` — 编译/链接 flags 按平台分支
119+
- `ninja_backend.cppm` — 构建规则按平台分支
120+
121+
建议拆成明确的 provider:
122+
123+
```
124+
ToolchainProvider (interface)
125+
├── GccProvider — GCC + glibc/musl
126+
├── ClangLibcxxProvider — Clang + libc++ (Linux/macOS)
127+
├── ClangMsvcProvider — Clang + MSVC STL (Windows)
128+
└── MsvcProvider — cl.exe (未来)
129+
```
130+
131+
每个 provider 声明:
132+
- `frontend()` → 编译器路径
133+
- `c_compiler()` → C 编译器
134+
- `archive_tool()` → ar/llvm-ar/lib.exe
135+
- `scanner()` → clang-scan-deps 路径
136+
- `stdlib_id()` → libc++/libstdc++/msvc-stl
137+
- `find_std_module()` → std.cppm/std.cc/std.ixx
138+
- `compile_flags()` → 平台相关编译 flags
139+
- `link_flags()` → 平台相关链接 flags
140+
- `bmi_traits()` → .gcm/.pcm/.ifc
141+
142+
### P3: 跨平台 Process Runner
143+
144+
**目标:** 消除 shell 字符串拼接,统一子进程执行。
145+
146+
当前问题:
147+
- `popen` + cmd.exe 字符串拼接(路径空格、引号转义脆弱)
148+
- `shq()` 在 Windows 上有 cmd.exe 首 token 引号剥离问题
149+
- `_putenv_s` 污染全局进程环境
150+
151+
建议新建 `src/process.cppm`:
152+
153+
```cpp
154+
struct ProcessOptions {
155+
std::vector<std::string> argv;
156+
std::map<std::string, std::string> env; // 进程级环境变量
157+
std::filesystem::path cwd;
158+
bool capture_stdout = true;
159+
bool capture_stderr = false;
160+
};
161+
162+
struct ProcessResult {
163+
int exit_code;
164+
std::string stdout_output;
165+
std::string stderr_output;
166+
};
167+
168+
ProcessResult run(const ProcessOptions& opts);
169+
```
170+
171+
POSIX: `fork/exec` + `pipe`
172+
Windows: `CreateProcessW` + `STARTUPINFOW`
173+
174+
**受益范围:** `probe.cppm``xlings.cppm``stdmod.cppm``ninja_backend.cppm``config.cppm`
175+
176+
### P4: `mcpp pack` Windows 支持
177+
178+
**目标:** `mcpp pack` 原生支持 Windows PE 打包。
179+
180+
当前 `pack.cppm` 依赖:
181+
- `LD_TRACE_LOADED_OBJECTS` (Linux ELF)
182+
- `patchelf` (RPATH 修改)
183+
- `tar -czf` (打包格式)
184+
185+
Windows 需要:
186+
- DLL 依赖收集(`dumpbin /dependents``llvm-objdump`
187+
- 无需 RPATH(DLL 在 exe 同目录自动找到)
188+
- `.zip` 打包 + `.bat` wrapper
189+
190+
建议 pack 做成平台策略:
191+
192+
```
193+
PackStrategy (interface)
194+
├── LinuxElfPack — ldd + patchelf + tar.gz
195+
├── MacosMachoPack — otool + install_name_tool + tar.gz
196+
└── WindowsPePack — dumpbin + zip + .bat
197+
```
198+
199+
### P5: E2E 能力标签化
200+
201+
**目标:** 从"平台 skip 列表"升级为"能力标签"。
202+
203+
在每个 E2E 脚本头部声明需求:
204+
205+
```bash
206+
# requires: elf — 需要 ELF 工具链
207+
# requires: gcc — 需要 GCC
208+
# requires: symlink — 需要 ln -sf
209+
# requires: scan-deps — 需要 clang-scan-deps
210+
# requires: import-std — 需要 import std (std.cppm/std.ixx)
211+
# requires: pack — 需要 mcpp pack
212+
```
213+
214+
`run_all.sh` 读取标签,根据当前平台的能力集决定 skip,不再维护平台 skip 列表。
215+
216+
## 实施顺序
217+
218+
```
219+
P0 release + E2E 修复 ← 立即可做,产出最大
220+
221+
P1 PlatformTraits ← 减少 #if 散落,降低后续维护成本
222+
223+
P2 ToolchainProvider ← 为 MSVC 支持打基础
224+
225+
P3 Process Runner ← 消除 shell 拼接风险
226+
227+
P4 mcpp pack Windows ← 产品化打包
228+
229+
P5 E2E 标签化 ← 测试治理
230+
```
231+
232+
## 预期里程碑
233+
234+
| 阶段 | 目标 | Windows E2E 通过率 |
235+
|------|------|-------------------|
236+
| 当前 | self-host + 基础 E2E | 22/49 (45%) |
237+
| P0 完成 | release + 高价值 E2E | ~30/49 (61%) |
238+
| P1+P2 完成 | 平台抽象 + provider | ~35/49 (71%) |
239+
| P3+P4 完成 | process runner + pack | ~40/49 (82%) |
240+
| P5 完成 | 能力标签 | 动态评估 |

0 commit comments

Comments
 (0)