CMake接口库File Set可见性疑问:PRIVATE设置未限制头文件访问?
CMake接口库File Set可见性疑问
作为CMake新手,我对接口库的File Set可见性存在困惑:当接口库的头文件File Set设为INTERFACE可见性时,消费者能访问的内容很明确,但改成PRIVATE后,消费者居然还能访问到头文件,这和我预期的不一样。
场景复现
项目里有两个接口库ggg和ggg1:
ggg包含头文件include/g.hggg1依赖ggg,自身包含include/g1.h- 主目标
main链接ggg1
当ggg1的File Set设为INTERFACE时,main能正常访问g.h和g1.h;但把ggg1的File Set改成PRIVATE后,我本以为构建会失败,结果却成功了。
项目结构:根目录有CMakeLists.txt、src和build目录,相关代码如下:
CMakeLists.txt
# file: CMakeLists.txt cmake_minimum_required(VERSION 3.30) project(test20 VERSION 1.0 LANGUAGES CXX) add_library(ggg INTERFACE) target_sources(ggg INTERFACE FILE_SET ggg_headers TYPE HEADERS BASE_DIRS include FILES include/g.h ) add_library(ggg1 INTERFACE) target_sources(ggg1 PRIVATE FILE_SET ggg1_headers TYPE HEADERS BASE_DIRS include FILES include/g1.h ) target_link_libraries(ggg1 INTERFACE ggg ) add_executable(main) target_sources(main PRIVATE src/main.cpp ) target_link_libraries(main PRIVATE ggg1 )
src/main.cpp
// file: src/main.cpp #include <iostream> #include "g.h" #include "g1.h" int main() { g(); g1(); return 0; }
include/g.h
// file: include/g.h #ifndef G_H #define G_H #include <iostream> inline void g() { std::cout << "g()\n"; } #endif
include/g1.h
// file: include/g1.h #ifndef G1_H #define G1_H #include <iostream> inline void g1() { std::cout << "g1()\n"; } #endif
问题原因解释
你遇到的情况核心有两点原因:
- INTERFACE库的
PRIVATE属性无实际编译上下文:INTERFACE库本身不参与编译,只是用来传递属性给依赖它的目标。CMake对INTERFACE库的PRIVATE文件集不会做严格的“隐藏”限制,但更关键的是第二点—— include目录已通过ggg间接传递给main:ggg的INTERFACE File Set将include目录设置为INTERFACE级别的包含目录,而ggg1通过INTERFACE方式链接了ggg,所以main在链接ggg1时,会自动继承ggg的INTERFACE属性,把include目录加入自己的头文件搜索路径。此时g1.h就放在这个公共的include目录下,编译器自然能直接找到它,这和ggg1的File Set可见性设置无关。
验证方式
如果想验证PRIVATE可见性的实际效果,可以做两个调整:
- 把
ggg的File Set也改成PRIVATE,此时include目录不会传递给main,构建会失败; - 把
g1.h放到ggg1专属的子目录(比如include/ggg1),同时修改ggg1的File Set配置:
此时add_library(ggg1 INTERFACE) target_sources(ggg1 PRIVATE FILE_SET ggg1_headers TYPE HEADERS BASE_DIRS include/ggg1 FILES include/ggg1/g1.h )main.cpp里的#include "g1.h"会找不到文件,因为include/ggg1不会被传递给main,构建失败。
内容的提问来源于stack exchange,提问作者user2926204
相关产品推荐
相关产品推荐

