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:对目标自身不生效,但传播给依赖目标。
