我正在阅读cmake关键字PUBLIC
,PRIVATE
,INTERFACE
,并在cmake文档中看到了这段话。
通常,如果依赖项仅由库的实现使用,而不是在头文件中使用,则应该在使用target_link_libraries()时使用PRIVATE关键字指定它。如果依赖项在库的头文件中被额外使用(例如用于类继承),那么它应该被指定为PUBLIC依赖项。如果一个依赖项不被一个库的实现使用,而只被它的头文件使用,那么它应该被指定为INTERFACE依赖项。
我理解你在这三个关键词之间的选择如何影响target_link_libraries
和target_include_directories
的行为,但我不理解这段中解释的三种情况之间的区别。谁能提供一个
- 在库的实现中使用依赖项,但不是在头文件(
PRIVATE
) - 在库的实现和头文件(
PUBLIC
)中使用依赖项 - 在库的头文件中使用依赖项,而不是在实现(
INTERFACE
)
让我们首先处理PUBLIC
和PRIVATE
:
假设你正在编写一个带有Qt GUI的工具。您知道这个GUI应该允许您使用插件动态地向GUI添加元素。此外,用户应该能够通过设置激活和停用插件,并且相同的插件需要在将来启动程序时激活。
因此,你的库提供了两个功能:- 创建Qt GUI元素。你需要在你的公共头文件中使用Qt的类型,所以你要在这些头文件中添加Qt include。每个库都需要访问Qt头文件,所以您可以链接Qt
PUBLIC
ly - 要保持插件设置,您选择Boost。JSON将设置存储在文件系统上给定位置的文件中。您的库的用户实际上不会处理JSON解析/编写自己,所以您不包括任何boost头在您的公共头和链接boost。JSON
PRIVATE
ly.
INTERFACE
可视性
您将很少使用这种可见性。通常,您需要访问标题等。在你自己的库中
头库是使用INTERFACE
可见性的一个场景。只有头文件的库实际上不会导致在构建系统中创建目标,并且它们不能单独构建。CMake目标本身只是一种方便的方式,使头文件和依赖库通过target_link_libraries
可用。
使用INTERFACE
可见性的另一个场景是导入目标。这些也不会作为项目的一部分进行编译。它们只包含已经建立的库的信息。对于导入的目标,您只能使用INTERFACE
可见性。