feat(ide): add versioned project snapshots and pre-build CDB - #372
feat(ide): add versioned project snapshots and pre-build CDB#372wellwei wants to merge 26 commits into
Conversation
|
深度 review 完这个 PR 和 #371,以及结合 mcpp-community/mcpp-vscode#5 / mcpp-community/mcpp-vscode#8 的实际需求,结论如下:
下面是理由,都附了可复现的验证方式,不用采信我的断言。 一、核心前提需要复核:CDB 早就在 ninja 之前写了
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" 不成立。真正的门槛不是"编译成功",而是 推论:在"源码编不过时还能拿到 CDB"这件事上, 剥掉这条之后,真实增量剩四条,其中只有第一条是核心:
这四条, 补充一点: 二、按"只有 mcpp 能做的才让 mcpp 做"这条线算账
后三行不是"复杂度相当",是 mcpp 做明显更贵。原因是 mcpp 必须额外承担插件根本不需要的负担:只读性保证(e2e 197 要用整棵树 inventory 验证)、路径 containment(member 逃逸 / 符号链接逃逸)、选择器语义、诊断降级。插件在自己进程里读文件,单进程、私有、可随时改,这些负担都不存在。 把功能移进 mcpp,不是把复杂度搬过去,是把复杂度放大 —— 因为 mcpp 是多进程、公开契约、要向后兼容的。 另外两条实际成本:
三、两个 P0(即使不继续推进,也值得记录)P0-1:NDJSON stdout 还有一条没堵住的污染源
mcpp::xlings::ensure_official_package_index_fresh(
xlEnv, parsed.packageName, cfg_.searchTtlSeconds, /*quiet=*/false);往下追:
关键在于 触发条件不罕见:任一 e2e 198 结构性覆盖不到:它用 根因是 stdout 归属分散在多个 bool 参数里 —— PR 已经逐点堵了 5 处( P0-2:文档指定的客户端流程在 rooted workspace 的根成员上必然失败
而 把 根因是 member selector 语法在三处独立推导: 现有测试恰好绕开:e2e 198 的 workspace 是 virtual(根无 顺带一个相关的表示不一致: 四、A 部分:建议拆出来的清单这些有独立价值,和协议无关,建议单独开 PR 尽快合并:
不建议合入的: 五、mcpp-vscode 侧的影响是正向的改为: 相比解析 NDJSON 事件流(seq 校验 / operationId 关联 / 超期操作隔离 / 事件类型状态机),扩展侧代码更少。而且 mcpp-community/mcpp-vscode#5 里那些 TODO —— multi-root watcher、 更重要的是解除阻塞: 另外 mcpp-community/mcpp-vscode#5 里"明确首次打开工程是执行完整 build,还是只执行 IDE configure,避免重复工作"这个纠结,在前提复核之后就清楚了:两者能力相同,差别只在成本。所以答案是首次打开只跑 六、这个 PR 里做得好、值得保留到后续工作的部分不想让这些被一起丢掉,几处明显高于平均水平:
七、下一步
|
|
@wellwei 可以把A部分拆解个新PR, 然后其他的可以 在下面RFC讨论 |
Summary
Closes #371
Protocol surface
mcpp ide snapshot --format jsonpartial/stale/configuredstateconfiguredas metadata plus regular-file existence, not active freshness or JSON validationmcpp ide configure --format ndjsonBuildPlanand compile flags used by a normal buildoperation-started,snapshot-publishedandoperation-finishedevents with stable operation correlationtests/**/*.cpptranslation units and enables their development-dependency contextPublication and compatibility
.mcpp/ide/replies/.mcpp/ide/current.jsoncompile_commands.jsonas a compatibility projection for existing language-server clientsBuild integration
mcpp testuse the same names, member scope and per-glob flagsmcpp test --listinventory for invalid manifests while real build/configure remains strict inprepare_build()IDE client responsibilities and current limits
The new protocol documentation records that clients must:
build.mcpp, and update lock/cache/resolution stateworkspace.members[].workspacePathand one--packageconfigure per memberseq/operationId, retain the previous usable CDB on failure and mark it staleVersion 1 intentionally does not provide daemon mode, cancellation, configure
--workspacefan-out, active freshness recomputation, a ready-artifact phase or cross-toolchain BMI compatibility guarantees.Test plan
mcpp build --no-colormcpp test --no-color(65 passed; 0 failed)tests/e2e/159_test_list.shtests/e2e/196_ide_snapshot.shtests/e2e/197_ide_snapshot_read_only.shtests/e2e/198_ide_configure.shtests/e2e/199_ide_configure_windows.shon native Windows/MSVC CIgit diff --check origin/main