You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake无法构建C++23分区模块(GCC/Clang命令行可正常构建)

C++23分区模块CMake构建失败排查与解决

环境

  • Ubuntu 24.04
  • Clang 19、GCC 14
  • CLion 2024.3.4

问题现象

作为演讲和书籍示例的C++23分区模块(包含MIU文件与实现文件)无法通过CMake构建,但非分区模块示例可正常构建。CMake执行构建时出现如下错误:

cmake -E cmake_ninja_dyndep --tdi=Javanese/CMakeFiles/javanese.dir/CXXDependInfo.json --lang=CXX --modmapfmt=gcc --dd=Javanese/CMakeFiles/javanese.dir/CXX.dd @Javanese/CMakeFiles/javanese.dir/CXX.dd.rsp
CMake Error: Output Javanese/CMakeFiles/javanese.dir/balinese.cpp.o provides the `Javanese:Balinese` module 
but it is not found in a `FILE_SET` of type `CXX_MODULES`
ninja: build stopped: cannot make progress due to previous errors.

但直接使用Clang或GCC命令行可正常编译运行,Clang编译命令及输出如下:

+ clang++ -std=c++23 --precompile Balinese.cppm -o bin/Javanese-Balinese.pcm
+ clang++ -std=c++23 --precompile -fprebuilt-module-path=bin Javanese.cppm -o bin/Javanese.pcm
+ clang++ -std=c++23 -c -fprebuilt-module-path=bin Javanese.cppm -o bin/Javanese.o
+ clang++ -std=c++23 -c -fprebuilt-module-path=bin javanese.cpp -o bin/javanese.o
+ clang++ -std=c++23 -c -fprebuilt-module-path=bin balinese.cpp -o bin/balinese.o
+ clang++ -std=c++23 -r bin/Javanese.o bin/javanese.o bin/balinese.o -o bin/Javanese.Module.o
+ clang++ -std=c++23 -c -fprebuilt-module-path=bin main.cpp -o bin/main.o
+ clang++ -std=c++23 bin/Javanese.Module.o bin/main.o -o bin/main
+ bin/main
Kucing jawa ngomong 'mbelong'
Balinese anak kucing says 'meong'

相关配置与代码文件

父目录CMakeLists.txt

cmake_minimum_required(VERSION 3.30.5)

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# must appear before project()
set(CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS "/usr/bin/clang-scan-deps")
endif ()

project(pragmatic_modules LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# other subdirectories
add_subdirectory(Javanese)

Javanese目录CMakeLists.txt(原错误版本)

cmake_minimum_required(VERSION 3.30.5)
project(Javanese LANGUAGES CXX)
set(module_name javanese)

add_executable(${PROJECT_NAME} main.cpp)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
target_link_libraries(${PROJECT_NAME} ${module_name})

add_library(${module_name})
target_compile_features(${module_name} PUBLIC cxx_std_23)
target_sources(${module_name}
               PUBLIC
               FILE_SET cxx_modules TYPE CXX_MODULES
               FILES
                    Balinese.cppm
                    ${PROJECT_NAME}.cppm
               PRIVATE
                    ${module_name}.cpp
                    balinese.cpp
)

分区模块MIU文件Balinese.cppm

module;

export module Javanese:Balinese;

namespace Balinese {
   export void meong();
}

分区模块实现文件balinese.cpp

module;

#include <print>

module Javanese:Balinese;

namespace Balinese {
   auto meong() -> void {
      std::println("Balinese anak kucing says 'meong'");
   }
}

问题原因

CMake处理C++23模块时,要求所有模块单元(包括分区模块的实现单元)都必须被包含在CXX_MODULES类型的FILE_SET中。原配置里,balinese.cpp作为Javanese:Balinese分区模块的实现单元,被错误放在PRIVATE源文件列表中,而非FILE_SET cxx_modules的FILES集合内,导致CMake扫描模块依赖时无法识别该文件属于已声明的模块集合,从而抛出错误。

解决方案

修改Javanese目录下的CMakeLists.txt,将balinese.cpp移至FILE_SET cxx_modules的FILES列表中;如果javanese.cpp是主模块的实现单元,同样需要移入该集合:

cmake_minimum_required(VERSION 3.30.5)
project(Javanese LANGUAGES CXX)
set(module_name javanese)

add_executable(${PROJECT_NAME} main.cpp)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
target_link_libraries(${PROJECT_NAME} ${module_name})

add_library(${module_name})
target_compile_features(${module_name} PUBLIC cxx_std_23)
target_sources(${module_name}
               PUBLIC
               FILE_SET cxx_modules TYPE CXX_MODULES
               FILES
                    Balinese.cppm
                    ${PROJECT_NAME}.cppm
                    balinese.cpp
                    ${module_name}.cpp
)

调整后CMake可正确识别所有模块单元,完成依赖扫描与构建。


内容的提问来源于stack exchange,提问作者Rud48

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:54:52