C++20引入Module特性后,目前C++三大主流编译器MSVC、GCC、Clang都已经相应支持。但是C++的跨平台编译工具CMake还未原生支持Module的自动化构建,虽然可以自定义函数功能解决编译问题,但如果Module交叉、多层嵌套,自己来编写函数解决依赖问题,显得较复杂。所幸至CMake 3.25起,已经初步支持Module的自动化构建,在CMakeLists.txt加入相应API代码即可。
1 2 3 4 5 6
| set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
|
仍以《C++高级编程》第五版中第一章中25_ConstAirlineTicket源码为例,编写对应的CMake编译文件如下:
CMakeLists.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| cmake_minimum_required(VERSION 3.26) set(CMAKE_C_COMPILER /usr/bin/clang) set(CMAKE_CXX_COMPILER /usr/bin/clang++) set(CMAKE_CXX_FLAGS " -Wall -Werror -O3 -DNDEBUG ")
project(25_ConstAirlineTicket)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) set(CMAKE_CXX_EXTENSIONS OFF)
add_compile_options(-stdlib=libc++) add_compile_options(-fmodules) add_compile_options(-fbuiltin-module-map) add_compile_options(-fimplicit-module-maps) add_compile_options(-fexperimental-library)
add_library(AirlineTicket) target_sources(AirlineTicket PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" FILES AirlineTicket.cppm )
set (TARGET App) set (SOURCES AirlineTicket.cpp AirlineTicketTest.cpp)
add_executable(${TARGET} ${SOURCES}) target_link_libraries(${TARGET} AirlineTicket) target_link_options(${TARGET} PUBLIC -stdlib=libc++ -fexperimental-library -fuse-ld=lld)
|
由于目前CMake的Module测试功能还不支持生成Unix Makefiles,加-GNinja
生成后编译。
注意,CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API得和相应版本Cmake的UUID匹配,否则会报如下错误代码。
1 2
| CMake Error at CMakeLists.txt:23 (target_sources): target_sources File set TYPE may only be "HEADERS"
|
好消息,CMake 3.28正式支持C++20 Module特性自动化构建,无需设置MAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API变量。
此外Clang库文件中已经支持 std::format()
,加入-fexperimental-library
即可。
FILE_SET
是CMake 3.23新引入的一个功能。
1 2 3 4
| target_sources(<target> [<INTERFACE|PUBLIC|PRIVATE> [FILE_SET <set> [TYPE <type>] [BASE_DIRS <dirs>...] [FILES <files>...]]... ]...)
|
其中,TYPE类型有:HEADERS、CXX_MODULES、CXX_MODULE_HEADER_UNITS,看来是专为Module特性引入的。
为了Module文件编写规范化,减少编译过程中错误,一个推荐的 Module 规范结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| module; #include <standard library header> #include "library not ready for modularization" ... export module top.middle.bottom;
import modularized.standard.library.component; import other.modularized.library; ...
#include "module internal header"
non-exported declarations; ... export namespace top { namespace middle { namespace bottom { exported declarations; ... }}}
|
本文链接: https://azurelake.cn/posts/bacfc96f3e1b/
版权声明: 转载请注明出处(必须保留作者署名及链接)