何时应在 cmake 中使用 PUBLIC/PRIVATE/INTERFACE 的示例

Ale*_*ter 14 c++ cmake

我正在阅读有关 cmake 关键字PUBLIC、的内容PRIVATE,并cmake 文档中INTERFACE遇到了这一段。

通常,如果仅由库的实现而不是在头文件中使用,则应在使用 target_link_libraries() 时使用 PRIVATE 关键字指定依赖项。如果在库的头文件中另外使用依赖项(例如用于类继承),则应将其指定为 PUBLIC 依赖项。库的实现不使用而仅由其标头使用的依赖项应指定为 INTERFACE 依赖项。

target_link_libraries我了解您在这三个关键字之间的选择如何影响和的行为target_include_directories,但我不明白本段中解释的三种情况之间的区别。有人可以提供一个玩具示例吗

  1. 在库的实现中使用依赖项,但不在头文件中使用依赖项 ( PRIVATE)
  2. 在库的实现以及头文件中使用依赖项 ( PUBLIC)
  3. 在库的头文件中使用依赖项,但不在实现中使用依赖项 ( INTERFACE)

fab*_*ian 17

让我们首先处理PUBLICPRIVATE

假设您正在使用 Qt GUI 编写一个工具。您知道这个 GUI 应该允许您使用插件动态地将元素添加到 GUI。此外,用户应该能够通过设置激活和停用插件,并且在将来启动程序时需要激活相同的插件。

Your library therefore provides 2 functionalities:

  1. Creating Qt GUI elements. You need to use types from Qt in your public headers, so you add Qt includes to those headers. Every library needs to have access to the Qt headers, so you link Qt PUBLICly
  2. For persisting the plugin settings you choose Boost.JSON to store the settings in a file at a given location on the file system. The user of your libary won't actually deal with the JSON parsing/writing themselves, so you don't include any boost headers in your public headers and link Boost.JSON PRIVATEly.

INTERFACE visibility

You'll rarely use this visibility. Usually you'll need access to the headers, ect. in your own libary.

Header only libraries are one scenario where INTERFACE visibility is used though. Header only libraries won't actually result in a target being created in your build system and they cannot be built separately. The CMake target itself is just a convenient way making headers and dependent libraries available via target_link_libraries.

Another scenario where INTERFACE visibility is used are imported targets. Those aren't compiled as part of your project either. They just contain information about an library that's already built. For imported targets you can only use INTERFACE visibility.