CMake target_include_directories范围的含义


Answers:


125

这些关键字用于指示何时需要您传递给目标的包含目录列表。在when时,表示是否需要包含这些目录:

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

当CMake的是编译一个目标,它使用目标INCLUDE_DIRECTORIESCOMPILE_DEFINITIONSCOMPILE_OPTIONS性能。当使用PRIVATEintarget_include_directories()和类似关键字时,您告诉CMake填充那些目标属性。

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

PUBLIC关键字大致装置PRIVATE + INTERFACE

因此,假设您正在创建A使用某些Boost标头的库。您可以这样做:

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

CMake 3.0文档具有有关此生成规范和使用要求属性的更多详细信息。


18
关于的真实示例INTERFACEtarget_include_directories(libname INTERFACE include PRIVATE include/libname)。这意味着您可以在库中直接包含文件,但是作为库用户,您必须首先插入文件libname/
KaareZ

2
这个答案对我创建库很有意义。但是,如何为可执行文件的目标调用target_include_directories呢?
诺曼·佩莱

1
@NormanPellet:target_include_directories()如果需要设置包含目录,可以找到这些可执行文件使用的头文件,则可以调用可执行文件目标(例如:Boost :: Program_options,如果使用它来解析函数中的main()参数) 。PRIVATE在这种情况下,您可能会使用关键字,因为编译可执行文件本身需要这些文件。我不知道是否有一些使用了INTERFACEPUBLIC上可执行,虽然。
TManhente

13

需要INTERFACE,PUBLIC和PRIVATE关键字来指定以下参数的范围。PRIVATE和PUBLIC项目将填充<target>的INCLUDE_DIRECTORIES属性。PUBLIC和INTERFACE项目将填充<target>的INTERFACE_INCLUDE_DIRECTORIES属性。以下参数指定包含目录。

从文档中:http : //www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

用我自己的话改写文档:

  • 您想要将目录添加到目标的包含目录列表中
  • 使用PRIVATE的目录被添加到目标的包含目录
  • 使用INTERFACE时,不会修改目标,但是目录会扩展INTERFACE_INCLUDE_DIRECTORIES。该变量是库的公共包含目录的列表。
  • 使用PUBLIC,可同时执行PRIVATE和INTERFACE的操作。

5
我浏览了CMAKE文档,但仍然没有了解它们的实际含义以及在什么情况下(生成文件或如何编译)?
Sirish 2014年

@Sirish:我试图改写文档,希望对您有所帮助。
usr1234567
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.