简介:本文将详细解析CMake中用于目标间依赖关系的PUBLIC, PRIVATE, 和 INTERFACE关键字,并通过实例展示它们在实际项目中的应用。
在CMake中,当我们定义一个库或可执行文件,并希望它依赖于其他库或目标时,我们可以使用target_link_libraries或target_sources等命令来建立这种依赖关系。但除了这些基本命令,CMake还提供了三个关键字:PUBLIC, PRIVATE, 和 INTERFACE,用于更细致地控制这些依赖关系的作用域和可见性。
当我们将一个目标A链接到另一个目标B,并指定PUBLIC关键字时,意味着目标B可以直接使用目标A中的公共符号(如函数和变量)。此外,任何链接到目标B的其他目标也可以访问这些符号。换句话说,PUBLIC关键字允许依赖关系向下传递。
PRIVATE关键字与PUBLIC类似,但它限制了依赖关系的传递。当目标A以PRIVATE方式链接到目标B时,只有目标B可以访问目标A中的公共符号。任何链接到目标B的其他目标都无法访问目标A中的符号。PRIVATE关键字提供了最强的封装性。
INTERFACE关键字定义了一组接口符号,这些符号可以被链接到目标B的其他目标访问,但目标B本身不能访问这些符号。这允许我们创建一个纯粹的接口库,其中只包含其他库或目标所需的头文件和声明,而不包含实现代码。
假设我们有一个项目结构如下:
project/├── libA│ ├── include│ │ └── liba.h│ └── src│ └── liba.cpp├── libB│ ├── include│ │ └── libb.h│ └── src│ └── libb.cpp└── main└── main.cpp
其中,libA是一个独立的库,libB依赖于libA,并且main程序依赖于libB。
在CMakeLists.txt文件中,我们可以这样配置:
add_library(libA STATIC liba.cpp)target_include_directories(libA PUBLIC include)add_library(libB STATIC libb.cpp)target_link_libraries(libB PRIVATE libA)target_include_directories(libB PUBLIC include)add_executable(main main.cpp)target_link_libraries(main PUBLIC libB)
在这个例子中,libB以PRIVATE方式链接到libA,这意味着只有libB可以访问libA中的公共符号,而main程序不能直接访问它们。但是,由于main程序链接到libB,并且libB的公共符号是可见的,因此main程序可以间接地使用libA中的符号。
通过这种方式,我们可以更好地控制项目中的依赖关系,并确保代码的模块化和可维护性。
PUBLIC, PRIVATE, 和 INTERFACE关键字为CMake中的目标依赖关系提供了灵活的控制。通过合理地使用这些关键字,我们可以创建出结构清晰、易于维护的项目。希望本文能帮助您更好地理解这些关键字的作用和应用场景。