fix: 为模块消费者恢复已有 PCM - #15
Conversation
wellwei
left a comment
There was a problem hiding this comment.
审查结论:当前版本需要修改,暂不建议合并。问题本身是真实且有必要解决的,但扩展仅凭 CDB argv 无法证明两个 PCM 目录中的产物兼容,当前实现存在复制错误 PCM 的确定性路径。
阻塞问题
-
moduleCompatibilityKey()删除了全部-I、模块映射和 PCM 路径,却把剩余参数作为兼容身份。include context 可以改变宏、头文件内容和模块导出接口,不能忽略。我用 debug/release 两套不同-I的命令复现:两个 source 目录都会被判定兼容,较新的 release PCM 最终会覆盖 debug 消费者目录中的同名 PCM。 -
stageAvailableProjectPcms()从每个 source 目录复制全部.pcm,同名文件只按 mtime 决胜。mtime 不是 artifact identity,这会把不同构建 fingerprint 的std.pcm、std.compat.pcm、项目模块和依赖模块混入同一目录。尤其std.compat.pcm依赖精确匹配的std.pcm,不能分别按文件名和时间戳选择。 -
“同一项目”边界实际没有建立。
analyzeCompilationDatabase()不接收当前project.root,而是按每条记录自己的directory判断projectSource。最小反例中,/other项目的模块命令会成为/work/app消费者的 PCM source。-fprebuilt-module-path也没有限制在当前项目或 target 下,因此异常或陈旧 CDB 可以让扩展创建并覆盖项目外的.pcm文件。 -
copyFileSync()直接覆盖目标文件,不具备原子发布和并发保护。clangd 可能正在 mmap 该 PCM;Windows 上文件锁也可能使覆盖失败。mcpp 已经有临时文件、rename、内容校验和 Windows 重试的 staging 实现,不宜在扩展中重新实现一套更弱的版本。 -
模块接口扩展名被硬编码为
.cppm/.ixx/.mpp/.ccm,与 mcpp 的[build].module_extensions契约不一致。使用合法的.cxxm反例时,source 目录为空,模块接口被当作消费者,恢复逻辑完全不执行。
测试边界
我在最新 main + f82bde9 上验证了 npm test 269/269、VSIX 打包和 archive 检查,均通过。但新增测试只验证文本文件复制和理想 CDB,没有覆盖真实 Clang PCM 加载、不同 fingerprint、多 source 同名文件、跨项目路径、文件锁或中断写入,因此不能证明这套复制规则在 PCM 语义上正确。
另外,当前 GitHub 绿色 CI 检出的是旧虚拟 merge 74f8032,其 base 为 fcd8296;#14 合并后当前虚拟 merge 已变为 3d8b790(base ecf1448)。语义问题修复后还需要在最新 main 上重新跑 CI。
建议方向
更合适的修复位置是 mcpp 的 configure-only 路径:由掌握 BuildPlan、fingerprint、模块图和缓存元数据的 stage_configure_prerequisites() 暂存明确属于当前构建身份的项目 BMI;扩展只负责运行 configure-only、重启 clangd 和检查结果。
如果仍坚持在扩展侧实现,至少需要显式的 artifact provenance/fingerprint 元数据、严格的 project root 与目标目录约束、按模块依赖闭包选择文件、原子 staging,以及真实 clang 加载 PCM 的集成测试。单纯补充 argv 过滤规则或 mtime 判断不足以消除上述风险。
问题
mcpp 可能为同一项目生成多个兼容的构建上下文。模块接口的 PCM 已在一个上下文中生成,但测试或其他消费者的
compile_commands.json指向另一个pcm.cache。插件此前只按 CDB 启动 clangd,不会恢复消费者目录缺少的模块产物,因此一键配置或刷新编译数据库后仍可能出现:
Module 'mcpplibs.cmp' not foundmodule file not foundclangd 无法加载所需模块产物修复
插件不自行生成模块映射,也不会跨编译器或跨目标平台复用缓存。
验证
npm test:269/269 通过npm run package:成功生成 VSIXmcpp build与mcpp build --configure-only均成功module_not_found/ast_file_not_found作为结果环境说明
Windows 上 mcpp 2026.8.11.3 检查内置 xlings 时会使用 Linux 重定向写法,
cmd.exe因而输出The system cannot find the path specified.。本机已按 mcpp 支持的配置改用xlings.binary = "system",复用版本一致的 xlings 2026.8.11.2;该环境问题不需要由插件绕过。项目是纯库目标,因此
mcpp run返回error: no binary target in this package属于预期行为。