【问题标题】:What is the difference between include_directories and target_include_directories in CMake?CMake 中的 include_directories 和 target_include_directories 有什么区别?
【发布时间】:2015-11-05 07:38:18
【问题描述】:

我的 C++ 代码有一个目录结构,如下所示:

|
|->include
|->src

我正在为我的代码编写一个 CMakeLists.txt 文件。我想了解CMakeinclude_directoriestarget_include_directories 之间的区别。

它们的用法和添加我的包含文件路径之间有什么区别,我应该使用哪一个?

【问题讨论】:

  • 您阅读过include_directoriestarget_include_directories 的文档吗?你不明白它们之间的区别是什么?
  • 文档中没有明确说明。我阅读了它并推测了 Angew 在他的回答中所写的内容,但是没有描述,没有示例,对于用于项目构建的系统,CMake 文档中没有基于项目的示例。如果有完整的 CMake 文档,我就不会因为这些问题而给社区带来负担。
  • cmake 的概念文档很少。尤其是目标和“非目标”。
  • 同意 CMake 文档不好,不提供示例他们节省了多少精力?当我刚接触 CMake 时,我经常对新旧语法感到困惑。
  • 30 年的编码经验告诉我,未记录的软件与不存在的软件一样好,而记录不良的软件比甚至不编译的代码更糟糕。因此,我认为这个问题应该被视为错误报告。

标签: c++ cmake


【解决方案1】:

include_directories(x/y) 影响目录范围。此 CMakeList 中的所有目标,以及在其调用点之后添加的所有子目录中的目标,都会将路径 x/y 添加到它们的包含路径中。

target_include_directories(t x/y) 具有目标范围——它将x/y 添加到目标t 的包含路径中。

如果您的所有目标都使用有问题的包含目录,则您需要前一个。如果路径特定于目标,或者您想要更好地控制路径的可见性,则需要后者。后者来自target_include_directories() 支持PRIVATEPUBLICINTERFACE 限定符这一事实。

【讨论】:

  • 我认为通常应该首选后一种(只要使用的是cmake 3)。它的额外好处是将x/y 放在任何在其target_link_libraries 命令中使用t 的依赖目标的包含路径中。前者当然有一席之地,但我相信后者通常更好。
  • 原来的回答说只有include_directories之后添加的目标和子目录才会受到影响。我正在编辑答案:文档明确指出当前 CMakeLists 中的 all 目标都受到影响。文档没有提到,但只有调用后的子目录受到影响(如原始答案中正确说明的那样)
  • @Phil, target_include_directories 已在 CMake 2.8.11(2013 年 5 月)中引入
  • @tamas.kenez 感谢您提请我注意,已修复。我非常确信这是“从现在开始”的事情。
  • 我应该把你的答案放到include_directories的官方文档上,简洁明了,谢谢!那么target_include_directories 是木匠的锤子,include_directories 是大锤。
【解决方案2】:

除了Angew's answer 的正确表述之外,include_directoriestarget_include_directories 之间的另一个非常重要的区别是,当与PUBLICINTERFACE 一起使用时,后者填充目标的INTERFACE_INCLUDE_DIRECTORIES 属性。当另一个目标使用target_link_libraries 链接到原始目标时,此属性很有用,因为链接目标将自动添加那些包含目录。见example

这个重要的特性很好地隐藏在文档中:target_include_directories 提到填充INTERFACE_INCLUDE_DIRECTORIES,其documentation 说:

当使用target_link_libraries()指定目标依赖时, CMake 将从所有目标依赖项中读取此属性以 确定消费者的构建属性。

【讨论】:

  • 这是我第一次阅读对PUBLIC等属性的可理解解释!谢谢:D
  • 消除歧义:当您将PUBLICINTERFACEtarget_include_directories 一起使用时,INTERFACE_INCLUDE_DIRECTORIES 属性将填充为针对目标的标头进行编译所需的包含目录。跨度>
  • 如果您想了解更多关于关键字PRIVATEPUBLICINTERFACE的含义,请使用target_include_directories查看here
【解决方案3】:

正如@Angew 所说,区别在于:

1,源树中的所有文件都可以访问 include_directories() 2、target_include_directories() 仅在编译时对特定目标可访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多