fix: support .ccm/.cxxm/.ixx module interface extensions#272
Open
ZheFeng7110 wants to merge 2 commits into
Open
fix: support .ccm/.cxxm/.ixx module interface extensions#272ZheFeng7110 wants to merge 2 commits into
ZheFeng7110 wants to merge 2 commits into
Conversation
Member
|
这几个后缀比较小众, 先保留PR 后面看是否有很多相关项目真实使用 到时候 再评估是否再合入, 目前先以推荐 cppm / cpp 为推荐 看是否可以形成共识 简化表达 |
Contributor
Author
|
好的。 但我还是认为最好能支持这些后缀,因为 C++ 社区的代码风格就是比较多样化:甚至有模块接口单元就是普通的 并且目前的这个设计也还存在缺陷:我尝试过使用 .ccm ,最终在构建的时候 ninja 提示“模块无法找到”。最后让 AI 查看了源代码才发现是 mcpp 不支持使用 .ccm 作为后缀,最后通过代码生成绕过了这个问题。既然希望让使用“cpp/cppm”形成共识,那应该直接提示用户“必须使用 .cppm 作为模块后缀名”,而不是编译失败提示“找不到模块”。 附上 AI 分析的原因: 根据对 plan.cppm 源码的分析,问题出在 plan.cppm 中两处硬编码的 .cppm 扩展名判断导致 .ccm 文件的对象文件永远不会被链接:
根本原因:plan.cppm 的链接单元组装逻辑
plan.cppm:make_plan() 为每个 link unit 添加对象文件时有两个循环:
1. 模块接口对象循环(.ccm 被遗漏)
// plan.cppm — 添加模块接口单元的对象
for (auto& cu : plan.compileUnits) {
if (sharedDepPackages.contains(cu.packageName)) continue;
if (cu.source.extension() == ".cppm") { // ← 只匹配 .cppm
lu.objects.push_back(cu.object);
}
}
2. 实现源文件循环(.ccm 也不在列表中)
bool is_implementation_source(const std::filesystem::path& source) {
auto ext = source.extension();
return ext == ".cpp" || ext == ".cc" || ext == ".cxx" || ext == ".c" || ext == ".m"
|| ext == ".S" || ext == ".s" || ext == ".asm";
// ↑ 没有 .ccm
}
后果
扫描器能正确识别 .ccm 中的 export module 声明 → 它会被加入 plan.compileUnits
Ninja 会为它生成编译规则(生成 .o)→ 编译阶段不报错
但 .ccm 的 .o 永远不会被加入任何 linkUnit.objects → 链接阶段缺少该模块的符号
最终二进制中找不到模块,触发 "module not found" 错误
解决方案
方案一:把 .ccm 文件重命名为 .cppm(mcpp 唯一官方模块扩展名)
方案二:修改 plan.cppm,将扩展名判断改为语义判断:
把 cu.source.extension() == ".cppm" 改为 cu.providesModule.has_value()(基于内容而非扩展名)
把 is_implementation_source() 改为白名单取反(providesModule 为空且不是 C/汇编)
方案三:手动在 [build].sources 中把 .ccm 加入 glob,并在 mcpp 仓库提 PR 修复这两处硬编码。 |
Member
|
目前可以先使用 build.mcpp 进行 rename 后缀, 后面进行评估 真实按理备注 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
plan.cppmhardcoded.cppmextension checks, causing non-.cppmmodule interface files (.ccm,.cxxm,.ixx) to have their object files excluded from link units, resulting in "module not found" linker errors.Changes
src/build/plan.cppm: Link object collection now usescu.providesModulesemantic check instead of extension check;object_filename_fortreats all 4 module extensions equally with.mprefixsrc/build/execute.cppm: Freshness check now recognizes.ccm/.cxxm/.ixxtests/unit/test_module_extensions.cpp(new): Unit tests forobject_filename_fordisambiguationtests/e2e/152_module_extensions.sh(new): End-to-end build→link→run test for all 4 extensionsTest plan
mcpp buildself-host passes