C++20私有模块实现:如何让模块仅库内部可用(CMake配置)
C++20私有模块(库内部可用、用户不可访问)的实现方案
完全可以实现这种仅库内部可用的私有模块,核心是通过CMake控制模块的可见性,不让私有模块的接口文件和编译产物暴露给库的使用者。以下是具体实现步骤和配置:
1. 规范文件结构
建议把公共模块和私有模块分开存放,避免用户误访问私有模块文件:
my_lib/ ├── include/ # 对外暴露的公共模块目录 │ └── public_module.ixx ├── src/ # 库内部私有代码目录 │ └── private_module.ixx └── CMakeLists.txt
2. CMake关键配置
CMake 3.28及以上版本对C++20模块的支持较为完善,以下是适配你需求的CMakeLists.txt示例:
cmake_minimum_required(VERSION 3.28) project(my_lib CXX) # 启用C++20标准 set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # 创建静态库目标(动态库同理) add_library(my_lib STATIC) # 配置公共模块:将public_module.ixx设为对外暴露的模块接口 target_sources(my_lib PUBLIC FILE_SET CXX_MODULES FILES include/public_module.ixx ) # 配置私有模块:仅作为库的内部源文件,不对外暴露 target_sources(my_lib PRIVATE src/private_module.ixx ) # 设置公共头文件目录(若有额外头文件) target_include_directories(my_lib PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> ) # 安装配置(若需要将库提供给其他项目使用) install(TARGETS my_lib EXPORT my_libTargets FILE_SET CXX_MODULES DESTINATION include ) install(EXPORT my_libTargets FILE my_libTargets.cmake DESTINATION lib/cmake/my_lib )
3. 配置原理说明
- 私有模块
private_module.ixx被标记为PRIVATE源文件,CMake不会将它的接口文件、编译生成的模块缓存(如MSVC的.ifc、GCC的.gcm)暴露给库的使用者。库编译时,CMake会自动处理内部模块的依赖关系,确保public_module.ixx能正常import my_lib_private_module。 - 公共模块通过
FILE_SET CXX_MODULES标记为PUBLIC,用户链接或安装库时,只能获取到这个公共模块的接口和编译信息,无法访问私有模块的任何资源,因此用户代码中import my_lib_private_module会因找不到模块而编译失败。
4. 编译器兼容性注意
确保使用支持C++20模块的编译器:
- GCC 11及以上版本
- Clang 16及以上版本
- MSVC 2022及以上版本
内容的提问来源于stack exchange,提问作者Dmytro Shalimov
相关产品推荐
相关产品推荐

