| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
深度 review 完这个 PR 和 #371,以及结合 mcpp-community/mcpp-vscode#5 / mcpp-community/mcpp-vscode#8 的实际需求,结论如下:
下面是理由,都附了可复现的验证方式,不用采信我的断言。 一、核心前提需要复核:CDB 早就在 ninja 之前写了src/build/ninja_backend.cppm:1546: std::expected<BuildResult, BuildError> NinjaBackend::build(...) {
...
write_file(ninja_path, manifest);
auto flags = compute_flags(plan);
write_compile_commands(plan, flags); // ← 这里
... // 之后才 spawn ninja实测(mcpp 2026.8.6.3,即本分支的 pin 版本): mkdir -p probe/src && cd probe
printf '[package]\nname = "probe"\nversion = "1.0.0"\n' > mcpp.toml
printf '#include <cstdio>\n\nint main( {\n return missing_symbol;\n}\n' > src/main.cpp
mcpp build --no-color # → rc=1, "3 errors generated"
ls -l compile_commands.json
# → 1624 bytes,entry 完整:
# -std=c++23 -fprebuilt-module-path=... --no-default-config -nostdinc++ -isystem .../c++/v1也就是说,#371 的 "mcpp currently writes a useful compile database only after a successful build" 不成立。真正的门槛不是"编译成功",而是 prepare_build() 成功 —— 而 configure_project() 走的是同一个 prepare_build()(src/ide/configure.cppm:189)。 推论:在"源码编不过时还能拿到 CDB"这件事上,ide configure 和 mcpp build 能力完全相同。 tests/e2e/198_ide_configure.sh 精心构造的 int main( { 场景,mcpp build 一样能过。README 新增的那句 "so clangd can analyze a project whose source currently has build errors" 描述的是 main 上已有的行为。 剥掉这条之后,真实增量剩四条,其中只有第一条是核心:
这四条,mcpp build --configure-only 全部满足,约 150 行。 补充一点:stage_cached_module_prerequisites 的增量也比预期小 —— 它只 stage std BMI 和缓存命中的依赖 BMI,而 std BMI 在 prepare_build 里就 ensure_built 了(build 路径同样有);项目自身的模块 BMI 两条路都不构建(本 PR 文档 §6 也承认 "module completion may remain pending")。 二、按"只有 mcpp 能做的才让 mcpp 做"这条线算账
后三行不是"复杂度相当",是 mcpp 做明显更贵。原因是 mcpp 必须额外承担插件根本不需要的负担:只读性保证(e2e 197 要用整棵树 inventory 验证)、路径 containment(member 逃逸 / 符号链接逃逸)、选择器语义、诊断降级。插件在自己进程里读文件,单进程、私有、可随时改,这些负担都不存在。 把功能移进 mcpp,不是把复杂度搬过去,是把复杂度放大 —— 因为 mcpp 是多进程、公开契约、要向后兼容的。 另外两条实际成本:
三、两个 P0(即使不继续推进,也值得记录)P0-1:NDJSON stdout 还有一条没堵住的污染源 src/pm/package_fetcher.cppm:1036 硬编码 /*quiet=*/false: mcpp::xlings::ensure_official_package_index_fresh(
xlEnv, parsed.packageName, cfg_.searchTtlSeconds, /*quiet=*/false);往下追:
关键在于 xlings::print_status(src/xlings.cppm:395)不看 mcpp::ui::is_quiet(),只受调用方传下来的 bool 控制。QuietGuard 设的是 ui::set_quiet(true),对它无效。 触发条件不罕见:任一 xim: 包(含工具链)在本地索引缺失且未命中 debounce —— 新装机器、新增依赖、切换 toolchain 版本都会命中。 e2e 198 结构性覆盖不到:它用 _inherit_toolchain.sh 把宿主已装工具链复制进临时 MCPP_HOME,索引永远命中,这条路径一次都走不到。 根因是 stdout 归属分散在多个 bool 参数里 —— PR 已经逐点堵了 5 处(load_or_init 链、c++fly 摘要、tool build verbose、Kept/Restored ×2),这是第 6 处。建议的修法不是加第 7 个 bool,而是让 xlings::print_status 走 mcpp::ui::status(它有 g_quiet 门),或引入 ui::stdout_is_protocol() 一票否决。 P0-2:文档指定的客户端流程在 rooted workspace 的根成员上必然失败 docs/11-ide-protocol.md §7.2 要求客户端:
而 src/ide/inspect.cppm:248 对 rooted workspace 产出 workspacePath == "."(tests/unit/test_ide_snapshot.cpp 的 RootedWorkspaceSelectsRoot 明确断言 members[0].workspacePath == ".")。 把 . 喂回 configure: configure_project (configure.cppm:182)
→ discover_test_targets(*root, ".")
→ project::resolve_member_dir(m, root, ".") [project.cppm:140]
→ 遍历 [workspace].members,比 mp 与 path(mp).filename()
→ "." 两者都不匹配
→ unexpected("workspace member '.' not found in [workspace].members")
→ exit 3
根因是 member selector 语法在三处独立推导:project.cppm::resolve_member_dir / prepare.cppm:951(内联复制的同一份逻辑) / ide/inspect.cppm::matches_selector。前两处一致,第三处多了 . 别名。 现有测试恰好绕开:e2e 198 的 workspace 是 virtual(根无 [package],不产生 . 成员);单测里的 workspace 要么 virtual,要么 name / dir / workspacePath 三者相同。mcpp 自己也不是 workspace,dogfood 同样碰不到。 顺带一个相关的表示不一致:canonical_member_selector(model.cppm:128)对根包返回 nullopt,inspect 侧用 "." —— 同一件事两种编码。 四、A 部分:建议拆出来的清单这些有独立价值,和协议无关,建议单独开 PR 尽快合并:
src/ide/model.cppm 的 Diagnostic/Position/Range/Severity 和 src/ide/snapshot.cppm 的 envelope 构造 + 内容寻址 ID(合计约 150 行)设计质量很高,建议捞进 #379 提升为 mcpp.wire,服务所有 JSON 出口而不只是 IDE。 不建议合入的:inspect.cppm(433) / publish.cppm(333) / events.cppm(106) / cmd_ide.cppm(119) / ide 两个子命令 / IdePhase·SnapshotState·ArtifactState(生产代码零使用者) / describe_std_module(仅 test_toolchain_stdmod.cpp:84 调用) / .xlings.json pin bump(与本 PR 无关,且会制造合并冲突) / docs/superpowers/ 目录树(本仓库设计文档惯例是 .agents/docs/,159 个文件在那)。 五、mcpp-vscode 侧的影响是正向的改为: spawn `mcpp build --configure-only --format json` → 读退出码 → 读 compile_commands.json → 按 invalidatedBy 清单设置 watcher 相比解析 NDJSON 事件流(seq 校验 / operationId 关联 / 超期操作隔离 / 事件类型状态机),扩展侧代码更少。而且 mcpp-community/mcpp-vscode#5 里那些 TODO —— multi-root watcher、mcpp.path 变化重配、避免 build/configure 重复执行 —— 本来就在扩展侧,不受影响。 更重要的是解除阻塞:--configure-only 是个小改动,可以很快合入并发版;不必等一套 6562 行走完 review → 发布 → 索引传播 → pin 更新的全链路。 另外 mcpp-community/mcpp-vscode#5 里"明确首次打开工程是执行完整 build,还是只执行 IDE configure,避免重复工作"这个纠结,在前提复核之后就清楚了:两者能力相同,差别只在成本。所以答案是首次打开只跑 --configure-only,用户显式要求完整语义(模块 BMI)时才 mcpp build。 六、这个 PR 里做得好、值得保留到后续工作的部分不想让这些被一起丢掉,几处明显高于平均水平:
七、下一步
|
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary
Closes #371
Protocol surface
mcpp ide snapshot --format json
mcpp ide configure --format ndjson
Publication and compatibility
Build integration
IDE client responsibilities and current limits
The new protocol documentation records that clients must:
Version 1 intentionally does not provide daemon mode, cancellation, configure --workspace fan-out, active freshness recomputation, a ready-artifact phase or cross-toolchain BMI compatibility guarantees.
Test plan