与CMake的target_include_directories
相关的关键词PUBLIC
,PRIVATE
和INTERFACE
的含义是什么?
与CMake的target_include_directories
相关的关键词PUBLIC
,PRIVATE
和INTERFACE
的含义是什么?
这些关键词用于告诉目标需要传递的包含目录列表何时使用。这里的何时指的是,如果这些包含目录是需要的:
当CMake编译目标时,它会使用目标的INCLUDE_DIRECTORIES
,COMPILE_DEFINITIONS
和COMPILE_OPTIONS
属性。当您在target_include_directories()
等中使用PRIVATE
关键字时,您告诉CMake填充那些目标属性。
当CMake检测到目标A和另一个目标B之间的依赖关系(例如当您使用target_link_libraries(A B)
命令时),它会传递性地将B的使用要求传播到A目标。那些目标使用要求是任何依赖于B
的目标必须满足的包含目录,编译定义等。它们由上面列出的属性的INTERFACE_*
版本指定(如INTERFACE_INCLUDE_DIRECTORIES
),并且通过调用target_*()
命令时使用INTERFACE
关键字进行填充。
PUBLIC
关键字的含义大致相当于PRIVATE + INTERFACE
。
因此,假设您正在创建一个使用一些Boost头文件的库A
。您可以执行以下操作:
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})
如果你在 A
库的公共头文件中使用了那些 Boost 头文件,这些头文件既被包含在 A
的一些源文件中,也可能被包含在任何其他客户端代码中。有关此构建规范和用法要求的更多详细信息,请参见 CMake 3.0 文档中的属性。
target_include_directories(libname INTERFACE include PRIVATE include/libname)
意味着您可以直接包含库中的文件,但作为库的用户,您必须首先插入“libname/”。 - KaareZmain()
函数中使用它来解析参数),则可以为可执行目标调用target_include_directories()
。在这种情况下,您可能会使用PRIVATE
关键字,因为这些文件是编译可执行文件本身所需的。我不知道在可执行文件上是否有INTERFACE
或PUBLIC
的用途。 - TManhente#include <file2.h>
来包含include/libname/file2.h
,当使用您的库的可执行文件包含file1.h
(通过#include <libname/file1.h>
)时,就会出现问题。因为include/libname
不在可执行文件的包含搜索路径中,所以它无法找到file2.h
。 - ToddRfoo/interface/a.h
- 这将提供给库的使用者,并且只包含使用库所需的内容foo/include/a.h
- 这将用于内部构建库,并且其内容类似于foo/interface/a.h
,但具有额外的内容。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
使用我的话重新表述文档:
target_link_libraries
或target_include_directories
而没有指定PRIVATE
、PUBLIC
或INTERFACE
关键字。 - IgNite