Ninja生成器是否支持C++20模块分区?CMake构建报错求助
问题概述
使用Visual Studio 2022生成器可正常构建的CMake项目,切换到Ninja生成器时构建失败,询问Ninja生成器是否支持C++20模块分区。
报错信息
C:\cmake\bin\ninja\cl : Command line warning D9025: overriding '/std:c20' with '/std:clatest'
[3/8] Generating CXX dyndep file Common\Collector\CMakeFiles\Collector.dir\CXX.dd
FAILED: Common/Collector/CMakeFiles/Collector.dir/CXX.dd C:/cmake/bin/ninja/Common/Collector/CMakeFiles/Collector.dir/CXXModules.json Common/Collector/CMakeFiles/Collector.dir/MetricAgent.cpp.obj.modmap Common/Collector/CMakeFiles/Collector.dir/MetricCollector.cpp.obj.modmap Common/Collector/CMakeFiles/Collector.dir/MetricAgent.ixx.obj.modmap Common/Collector/CMakeFiles/Collector.dir/MetricCollector.ixx.obj.modmap
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E cmake_ninja_dyndep --tdi=Common\Collector\CMakeFiles\Collector.dir\CXXDependInfo.json --lang=CXX --modmapfmt=msvc --dd=Common\Collector\CMakeFiles\Collector.dir\CXX.dd @Common\Collector\CMakeFiles\Collector.dir\CXX.dd.rsp
C:\cmake\bin\ninja\EXEC : CMake error : Output Common\Collector\CMakeFiles\Collector.dir\MetricAgent.cpp.obj provides theMetricCollector:Agentmodule but it is not found in aFILE_SETof typeCXX_MODULES
ninja: build stopped: subcommand failed.Build failed.
CMake配置
顶层CMakeLists.txt
cmake_minimum_required(VERSION 3.29) project(Agent LANGUAGES CXX) # Set the C++ standard to C++20 set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) set(CXX_SCAN_FOR_MODULES ON) set(CMAKE_CXX_SCAN_FOR_MODULES ON)
项目级CMakeLists.txt
project(Collector CXX) set(CODE_SOURCES MetricAgent.cpp MetricCollector.cpp ) set(INTERF_SOURCES MetricAgent.ixx MetricCollector.ixx ) add_library(${PROJECT_NAME} STATIC ${CODE_SOURCES} ${INTERF_SOURCES}) target_sources(${PROJECT_NAME} PRIVATE ${CODE_SOURCES} PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_SOURCE_DIR}/Common/Collector FILES ${INTERF_SOURCES} )
模块代码
MatricCollector.ixx(注意:存在拼写错误,应为MetricCollector.ixx)
module; export module MetricCollector; export import : Agent;
MatricCollector.cpp(注意:存在拼写错误,应为MetricCollector.cpp)
module; module MetricCollector;
MetricAgent.ixx
module; export module MetricCollector : Agent;
MetricAgent.cpp
module; module MetricCollector : Agent;
解决方案
Ninja生成器支持C++20模块分区,报错源于CMake配置问题:MetricAgent.cpp作为MetricCollector:Agent模块分区的实现文件,未被纳入CXX_MODULES文件集,导致动态依赖扫描无法识别其归属。
修复步骤:
- 修正文件拼写错误:将
MatricCollector.ixx和MatricCollector.cpp重命名为MetricCollector.ixx和MetricCollector.cpp,避免模块名称匹配失败。 - 调整CMake配置:将模块实现文件(
.cpp)加入CXX_MODULES文件集,确保CMake正确追踪模块依赖。修改后的项目级CMakeLists.txt如下:
project(Collector CXX) set(CODE_SOURCES MetricAgent.cpp MetricCollector.cpp ) set(INTERF_SOURCES MetricAgent.ixx MetricCollector.ixx ) add_library(${PROJECT_NAME} STATIC) target_sources(${PROJECT_NAME} PRIVATE ${CODE_SOURCES} PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_SOURCE_DIR}/Common/Collector FILES ${INTERF_SOURCES} ${CODE_SOURCES} )
- 确保
target_sources的语法缩进正确,BASE_DIRS和FILES需对齐在FILE_SET CXX_MODULES下方,避免CMake解析错误。
内容的提问来源于stack exchange,提问作者Uriel

