使用CMake构建C++20模块时出现FILE_SET源文件查找错误
CMake构建C++20模块报错:FILE_SET被识别为源文件
项目文件内容
main.cc
import mod; int main() { func(); return 0; }
mod.cc
#include <iostream> module mod; export void func() { std::cout << "Function in module `mod`" << '\n'; }
原CMakeLists.txt
cmake_minimum_required(VERSION 3.4) set(CMAKE_CXX_STANDARD 20) project(module_test) add_executable(mod_test main.cc) target_sources(mod_test PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES mod.cc )
报错信息
-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.19045. CMake Warning (dev) at CMakeLists.txt:8 (target_sources): Policy CMP0076 is not set: target_sources() command converts relative paths to absolute. Run "cmake --help-policy CMP0076" for policy details. Use the cmake_policy command to set the policy and suppress this warning. An interface source of target "mod_test" has a relative path. This warning is for project developers. Use -Wno-dev to suppress it. -- Configuring done CMake Error at CMakeLists.txt:6 (add_executable): Cannot find source file: FILE_SET Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc -- Generating done CMake Generate step failed. Build files cannot be regenerated correctly.
问题原因
FILE_SET是CMake 3.21版本才引入的特性,原配置指定的最低CMake版本为3.4,远低于要求版本,导致CMake无法识别该语法,错误地将FILE_SET当成了源文件名。此外,C++20模块的完整支持需要CMake配合对应版本的编译器。
解决方法
1. 提升CMake最低版本要求
将cmake_minimum_required改为至少3.21(推荐3.24及以上,以获得更完善的模块支持),同时启用C++标准强制要求:
修改后的CMakeLists.txt
cmake_minimum_required(VERSION 3.21) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) project(module_test) add_executable(mod_test main.cc) target_sources(mod_test PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES mod.cc )
2. 适配编译器参数
不同编译器对C++模块的支持需要额外参数:
- GCC 11+:添加
-fmodules-ts编译参数 - Clang 15+:添加
-fmodules编译参数 - MSVC VS2022 17.1+:无需额外参数(默认支持)
可在CMake中添加条件判断自动适配:
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") target_compile_options(mod_test PRIVATE -fmodules-ts) elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_compile_options(mod_test PRIVATE -fmodules) endif()
3. 规范模块文件后缀(可选)
部分编译器推荐使用.cppm作为模块实现文件的后缀,可将mod.cc重命名为mod.cppm,并同步修改CMakeLists中的文件名:
FILES mod.cppm
内容的提问来源于stack exchange,提问作者MBR-6161
相关产品推荐
相关产品推荐

