CMake中的PUBLIC、PRIVATE 和 INTERFACE用法
在CMake中,PUBLIC
、PRIVATE
和 INTERFACE
是用于指定目标属性(如编译选项、链接库、包含路径等)的访问范围的关键字。它们主要用于target_link_libraries
、target_include_directories
、target_compile_definitions
等命令中,影响到哪些目标可以继承这些属性。
1. PRIVATE
- 目标的属性只对该目标本身可见。
- 不会传播给依赖该目标的其他目标。
2. PUBLIC
- 目标的属性不仅对该目标可见,也会传播给依赖该目标的其他目标。
3. INTERFACE
- 目标的属性不会作用在该目标本身,只会传播给依赖该目标的其他目标。
举例说明
假设你有以下三个库:A
、B
、C
,其中B
依赖于A
,而C
依赖于B
。
例子代码结构:
add_library(A STATIC a.cpp)
add_library(B STATIC b.cpp)
add_library(C STATIC c.cpp)
target_include_directories(A PUBLIC include/A)
target_include_directories(B PRIVATE include/B)
target_include_directories(C INTERFACE include/C)
target_link_libraries(B PUBLIC A)
target_link_libraries(C INTERFACE B)
具体说明:
-
target_include_directories(A PUBLIC include/A)
:- 由于
include/A
是PUBLIC
,任何依赖A
的目标(比如B
)也能访问到include/A
路径。因此,编译B
时会使用include/A
作为包含路径。
- 由于
-
target_include_directories(B PRIVATE include/B)
:- 由于
include/B
是PRIVATE
,这个路径仅在编译B
时使用,而不会传播到依赖B
的目标C
。所以,编译C
时,不会使用include/B
作为包含路径。
- 由于
-
target_include_directories(C INTERFACE include/C)
:- 由于
include/C
是INTERFACE
,C
本身不会使用include/C
,但是任何依赖C
的目标会使用这个路径。如果有一个目标D
依赖于C
,D
会使用include/C
路径。
- 由于
链接依赖:
target_link_libraries(B PUBLIC A)
: 由于A
是PUBLIC
,B
不仅链接了A
,而且任何依赖B
的目标(比如C
)也会自动链接A
。target_link_libraries(C INTERFACE B)
: 由于B
是INTERFACE
,C
本身不会链接B
,但是任何依赖C
的目标会链接B
和A
(因为B
是PUBLIC依赖A
的)。
总结:
PRIVATE
:只对目标自身生效,不传播。PUBLIC
:对目标自身和依赖目标都生效。INTERFACE
:对目标自身不生效,但传播给依赖目标。