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,可以优化编译依赖,避免不必要的传播。
ICP备案:
公安联网备案: