CMake target_include_directory 的作用域含义

与 CMake 的 target_include_directories相关的关键字 PUBLICPRIVATEINTERFACE的含义是什么?

46380 次浏览

则需要使用 INTERFACE、 PUBLIC 和 PRIVATE 关键字来指定 下列参数的作用域 填充 < target > . PUBLIC 和 接口项将填充 INTERFACE _ INCLUDE _ DIRECTORIES 属性 < target > 目录。

来自文档: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

用我自己的话重新措辞文件:

  • 您希望将目录添加到目标的包含目录列表中
  • 通过 PRIVATE,该目录被添加到目标的 include 目录中
  • 使用 INTERFACE,目标不会被修改,但 INTERFACE _ INCLUDE _ DIRECTORIES 由目录扩展。变量是库的公共包含目录列表。
  • 使用 PUBLIC 同时执行 PRIVATE 和 INTERFACE 的操作。

这些关键字用于告诉 什么时候需要传递给目标的包含目录列表。什么时候的意思是,如果需要包含目录:

  • 编译目标本身。
  • 编译依赖于该目标的其他目标(如使用其公共标头)。
  • 在上述两种情况下。

当 CMake 编译目标时,它使用目标 INCLUDE_DIRECTORIESCOMPILE_DEFINITIONSCOMPILE_OPTIONS属性。当在 target_include_directories()中使用 PRIVATE关键字或类似的关键字时,告诉 CMake 填充这些目标属性。

当 CMake 检测到目标 A 和另一个目标 B 之间的依赖关系时(就像使用 target_link_libraries(A B)命令时一样) ,它会将 B 使用要求传播到 A目标。这些 目标使用要求是依赖于 B的任何目标都必须满足的包含目录、编译定义等。它们由上面列出的属性(如 INTERFACE_INCLUDE_DIRECTORIES)的 INTERFACE_*版本指定,并在调用 target_*()命令时使用 INTERFACE关键字填充。

PUBLIC关键字的大致意思是 PRIVATE + INTERFACE

因此,假设您正在创建一个使用某些 Boost 头文件的库 A:

  • 如果只在源文件(.cpp)或私有头文件(.h)中使用那些 Boost 头文件,则为 target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})
  • 如果您不在源文件中使用那些 Boost 头文件,则使用 target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})(因此,不需要它们来编译 A)。我实在想不出一个真实的例子。
  • 如果您在公共头文件中使用了这些 Boost 头文件,那么就可以使用 target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS}),这些公共头文件既包含在 A的一些源文件中,也可能包含在您的 A库的任何其他客户端中。

CMake 3.0文档中有关于这个 建立规范和使用要求属性的更多详细信息。