如何在 IDE 中让 CMake 显示不属于任何二进制目标的标头?

Posted

技术标签:

【中文标题】如何在 IDE 中让 CMake 显示不属于任何二进制目标的标头?【英文标题】:How to have CMake show headers-that are not part of any binary target-in the IDE? 【发布时间】:2015-01-18 06:43:25 【问题描述】:

在我们的工作流程中,我们可以有一个由多个头文件组成的 module Amodule A 不会产生任何二进制文件(旁注:它显然会被使用由其他模块,包括来自 module A 的一些标头以生成二进制文件)。

一个很好的例子是仅包含标头的库,由于 INTERFACE 库的概念(参见 this SO answer 和 CMake 的 documentation of the feature),CMake 3 引入了良好的支持。

我们可以用模块A制作一个接口库目标:

add_library(module_A INTERFACE)

这为我们提供了 CMakes 目标的所有优秀特性(可以将其用作另一个目标的依赖项、导出它、传递转发需求等)

但在这种情况下,module A 中的标头不会显示在我们的 IDE(Xcode,但我们希望它与大多数/所有其他 IDE 相同)。

这被证明是工作流程中的一个主要缺点,因为我们需要在 IDE 中显示构成 module A 的文件以进行编辑。有可能实现吗?

【问题讨论】:

啊删除了我的评论。好问题。 @IdeaHat 感谢您对这个问题的兴趣以及您的建议。遗憾的是,add_library 命令的INTERFACE 形式不期望任何 file 参数(请参阅the last form in the documentation)。事实上,我们不一定需要INTERFACE,但这是我们知道的唯一可变非二进制目标。 [对于上下文,IdeaHat 想知道我们是否可以在 add_library 命令的 INTERFACE 形式中提供头文件] 一种 hack 方法可以使用这些文件作为源来制作一个虚拟的自定义目标(从未构建或没有构建步骤)...对于我的个人教育,您是否有指向 CMake 的可变定义的链接? @IdeaHat 我会考虑这种方法,同意这将是一种骇人听闻的方式; ) 关于目标可变性的概念,我在文档中没有找到定义,但通过the Pseudo Targets documentation 的推断,我的猜测是:可变目标可以具有(至少一些)其属性写入。 [其中一些是指“白名单”属性的概念,例如。限制可以在INTERFACE] 上写入哪些属性。 它在功能请求cmake.org/Bug/view.php?id=15234下捕获 【参考方案1】:

几个月后,我没有找到直接列出INTERFACE 库的头文件的方法。

由于问题仍然有一些观点,这就是我最终做的事情(即看起来像目前可用的较小黑客)。

想象一下module A 是一个只有头文件的库。在 CMakeLists.txt 中声明其目标:

# Define 'modA_headers' variable to list all the header files
set(modA_headers 
  utility.h
  moreUtilities.h
  ...)

add_library(moduleA INTERFACE) # 'moduleA' is an INTERFACE pseudo target

#
# From here, the target 'moduleA' can be customised
#
target_include_directories(moduleA ...) # Transitively forwarded
install(TARGETS moduleA ...)

#
#  HACK: have the files showing in the IDE, under the name 'moduleA_ide'
#
add_custom_target(moduleA_ide SOURCES $modA_headers)

我不接受这个答案,因为我希望 CMake 的进一步版本能够提供更语义正确的方法,然后会被接受:)

【讨论】:

一直在寻找一种方法来做到这一点,而您的解决方案终于让我通过了。谢谢!【参考方案2】:

您可以在 CMake 3.1 中使用新的target_sources 命令。

add_library(moduleA INTERFACE)
target_include_directories(moduleA INTERFACE ...)
target_sources(moduleA INTERFACE 
  $CMAKE_CURRENT_SOURCE_DIR/utility.h
  $CMAKE_CURRENT_SOURCE_DIR/moreUtilities.h
)

它也是传递的。

http://www.cmake.org/cmake/help/v3.1/command/target_sources.html#command:target_sources

CMake 3.3 取消了无法导出具有 INTERFACE_SOURCES 的目标的限制。

【讨论】:

这意味着标题将被添加到链接到您的库的其他现有项目中,但如果您没有任何与您的库链接的项目,则不起作用。因此,如果您有一个包含链接到 INTERFACE 库的可执行文件的测试项目,那么此类项目将包含库头及其源代码。 这是@FranciscoAguilera 提出的一个很好的观点。 steveire,到目前为止还没有好的解决方案吗? 我知道已经有一段时间了,但我不确定我是否完全理解您的评论@FranciscoAguilera。第一句话“这在某种意义上有效,标头将被添加到链接到您的库的其他现有项目中”我理解这是它可以按预期工作的积极情况。第二句“如果您没有任何与您的库链接的项目,则不起作用”?这部分我不明白。仅标头库对于编译独立的 IMO 没有多大意义。那么关于测试项目的最后一句:这是指第一句还是第二句?

以上是关于如何在 IDE 中让 CMake 显示不属于任何二进制目标的标头?的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何支持 CMake 的 Windows IDE?

如何在 Qt Creator 的 CMakeLists.txt 中包含头文件?

在 GTK+ 中让窗口显示在全屏窗口上方

使用 Cmake,如何防止库源包含在我的 IDE 中?

宜搭中让当前的日期组件自动显示当天的日期

为什么我不选择cmake,而是premake