CMake PUBLIC、PRIVATE、INTERFACE用法和区别详解
在 CMakeLists.txt 中,PUBLIC、INTERFACE 和 PRIVATE 主要用于 target_include_directories、target_link_libraries、target_compile_definitions 这些命令,作用是指定目标的可见性/作用域范围。
如下是 PUBLIC、INTERFACE 和 PRIVATE 各自的含义:
CMake 官方的 Documentation 也对其有定义,感兴趣的读者可猛击这里详细了解。
所以作用域关键字的作用也很明显,适当选择 PUBLIC、PRIVATE 和 INTERFACE,可以优化编译依赖,避免不必要的传播。
如下是 PUBLIC、INTERFACE 和 PRIVATE 各自的含义:
关键字 | 作用范围 |
---|---|
PUBLIC | 该目标和所有依赖它的目标都可见 |
INTERFACE | 仅对依赖该目标的目标可见(但自身不可用) |
PRIVATE | 仅对该目标可见,依赖它的目标不可见 |
CMake 官方的 Documentation 也对其有定义,感兴趣的读者可猛击这里详细了解。
用法示例
1) target_include_directories用法
用于指定头文件路径的可见性:add_library(MyLib STATIC mylib.cpp) target_include_directories(MyLib PUBLIC ${CMAKE_SOURCE_DIR}/include # MyLib 及其依赖的目标都可见 PRIVATE ${CMAKE_SOURCE_DIR}/src # 仅 MyLib 自己可见 INTERFACE ${CMAKE_SOURCE_DIR}/api # 仅 MyLib 的依赖可见,MyLib 本身不可用 )如果 AnotherLib 依赖 MyLib:
add_library(AnotherLib STATIC anotherlib.cpp) target_link_libraries(AnotherLib PRIVATE MyLib)
-
include/
目录可用于 MyLib 和 AnotherLib; -
src/
目录只能用于 MyLib; -
api/
目录只能用于 AnotherLib;
2) target_link_libraries用法
用于指定库的链接方式:target_link_libraries(MyLib PUBLIC SomeLib # MyLib 及其依赖的目标都需要链接 SomeLib PRIVATE HiddenLib # 只有 MyLib 需要链接 HiddenLib INTERFACE UtilLib # MyLib 不需要链接,但依赖它的目标需要 )如果 AnotherLib 依赖 MyLib :
target_link_libraries(AnotherLib PRIVATE MyLib)
- SomeLib 会被 AnotherLib 和 MyLib 使用
- HiddenLib 只会被 MyLib 使用
- UtilLib 不会被 MyLib 使用,但 AnotherLib 会使用 UtilLib
3) target_compile_definitions用法
用于定义编译宏:target_compile_definitions(MyLib PUBLIC USE_FEATURE_X # MyLib 及其依赖的目标都会定义 USE_FEATURE_X PRIVATE DEBUG_MODE # 仅 MyLib 定义 DEBUG_MODE INTERFACE ENABLE_LOG # MyLib 不定义 ENABLE_LOG,但依赖它的目标会定义 )
总结
- PRIVATE:仅限当前目标使用,依赖它的目标无法使用。
- PUBLIC:当前目标和所有依赖它的目标都可使用该配置。
- INTERFACE:当前目标自己不会使用,但依赖它的目标可使用该配置。
所以作用域关键字的作用也很明显,适当选择 PUBLIC、PRIVATE 和 INTERFACE,可以优化编译依赖,避免不必要的传播。