【发布时间】:2014-12-02 07:16:10
【问题描述】:
与CMake的target_include_directories相关的关键字PUBLIC、PRIVATE、INTERFACE是什么意思?
【问题讨论】:
标签: cmake
与CMake的target_include_directories相关的关键字PUBLIC、PRIVATE、INTERFACE是什么意思?
【问题讨论】:
标签: cmake
这些关键字用于告诉何时需要您传递给目标的包含目录列表。 when 表示是否需要这些包含目录:
当 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。
因此,假设您正在创建一个库 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 文档对此build specification and usage requirements 属性有更多详细信息。
【讨论】:
INTERFACE 的真实示例。 target_include_directories(libname INTERFACE include PRIVATE include/libname)。这意味着您可以在库中直接包含文件,但作为库的用户,您必须先插入 libname/。
main() 函数中的参数)。在这种情况下,您可能会使用PRIVATE 关键字,因为需要这些文件来编译可执行文件本身。不过,我不知道INTERFACE 或PUBLIC 在可执行文件上是否有用。
include/libname/file1.h 包含include/libname/file2.h 仅使用#include <file2.h>,则当使用您的库的可执行文件包含file1.h(通过#include <libname/file1.h>)时,它将中断。 include/libname 不会在可执行文件的包含搜索路径中,因此无法找到 file2.h。
需要 INTERFACE、PUBLIC 和 PRIVATE 关键字来指定 以下论点的范围。 PRIVATE 和 PUBLIC 项目将 填充
的 INCLUDE_DIRECTORIES 属性。公众和 INTERFACE 项目将填充 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 关键字。