问题描述
CMake 具有实验性的 C++20 模块依赖项扫描 (!5562)。我尝试使用 CMake 3.20、g++-11 和 ninja-1.10 来构建带有模块的项目。
// main.cpp
import mod;
int main() { return 0; }
// mod.ixx
export module mod;
export void f() {}
CMakeLists.txt 是对 https://gitlab.kitware.com/ben.boeckel/cmake/blob/cpp-modules/Modules/Compiler/GNU-CXX.cmake
的改编cmake_minimum_required(VERSION 3.20)
project(simple)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
"<CMAKE_CXX_COMPILER> <DEFInes> <INCLUDES> <FLAGS> -E -x c++ <SOURCE>"
" -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>"
" -fmodules-ts -fdep-file=<DYNDEP_FILE> -fdep-output=<OBJECT>"
" -fdep-format=trtbd")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
" -fmodules-ts -fmodule-mapper=<MODULE_MAP_FILE>"
" -fdep-format=trtbd -x c++")
set(CMAKE_CXX_FLAGS "-fmodules-ts")
add_executable(simple main.cpp mod.ixx)
但是 CMake 和 ninja 不构建项目:
$ mkdir build && cd build
$ cmake -DCMAKE_CXX_COMPILER=<path to g++-11>/g++-11 -G Ninja ..
-- The C compiler identification is GNU 10.3.1
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
...
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: <...>
$ ninja
<...>/g++-11 -fmodules-ts -std=gnu++20 -MD -MT <...>/main.cpp.o
-MF <...>/main.cpp.o.d -o <...>/main.cpp.o -c ../main.cpp
In module imported at ../main.cpp:1:1:
mod: error: Failed to read compiled module: No such file or directory
mod: note: compiled module file is ‘gcm.cache/mod.gcm’
mod: note: imports must be built before being imported
mod: Fatal error: returning to the gate for a mechanical issue
compilation terminated.
ninja: build stopped: subcommand Failed.
此处评分最高的答案(来自 ComicSansMS)说我们可以使用实验功能来构建 C++20 模块: How to use c++20 modules with CMake?
CMake 是否可以自动扫描模块依赖并构建项目?
解决方法
GCC + CMake 的模块系统在这一点上非常具有实验性,在我看来,现在不值得篡改。我花了大约一个小时试图让它自动扫描,但我认为文档还没有完整说明如果可能的话。我需要查看非官方文档的 github 问题,看看是否有办法。就目前而言,我认为没有办法做到这一点。
您最好的选择是使用 Visual C++ 的模块系统,因为它们的 C++20 实现是功能完整的(没有最终的 ABI 实现)。我已经使用过它,除了内部编译错误之外,它对于我的测试项目来说足够稳定。那些是由于复杂的 constevals 而通过简化它们来缓解的。我确定其他复杂的模块代码也存在同样的问题,因此请注意它是否符合您的项目目标。