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

41

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

一个很好的例子是仅包含头文件的库,对于这种情况,CMake 3通过INTERFACE库的概念提供了良好的支持(请参考该SO答案以及CMake的特性文档)。

我们可以从模块A创建一个接口库目标:

add_library(module_A INTERFACE)

这样可以让我们拥有CMake目标的所有好处(可以将其用作另一个目标的依赖项,导出它,转发要求等)。

但在这种情况下,模块A中的头文件不会出现在我们的IDE中(Xcode尚未出现,但我们预计大多数/每个其他IDE都是相同的)。

这证明了工作流程中的一个重大缺点,因为我们需要在IDE中显示组成模块A的文件以进行编辑。是否有可能实现这一点?


啊,我刚刚删除了我的评论。好问题。 - IdeaHat
@IdeaHat 感谢您对这个问题的关注和建议。不幸的是,add_library 命令的 INTERFACE 形式不需要任何 文件 参数(请参见文档中的最后一种形式)。 实际上,我们并不一定需要一个 INTERFACE,但这是我们所知道的唯一可变的非二进制目标。 [为了背景,IdeaHat 想知道是否可以在 add_library 命令的 INTERFACE 形式中提供头文件] - Ad N
一种 hack 的方法是创建一个虚拟的自定义目标(不会被构建,或者没有构建步骤),并将这些文件作为源文件...作为我的个人教育,您是否有 CMake 中 mutable 的定义链接? - IdeaHat
是的...实际上,我不确定接口库相对于添加目标来说,除了更语义正确之外还能提供什么。迄今为止我使用CMake的经验是它总是能工作,但如果你希望它能够良好运行,你的构建脚本往往会有些不太正规:-( - IdeaHat
2
它被记录在功能请求http://www.cmake.org/Bug/view.php?id=15234下。 - IdeaHat
显示剩余3条评论
2个回答

25

几个月过去了,我没有找到一种直接列出 INTERFACE 库头文件的方法。

由于这个问题仍然有些浏览量,这里是我最终采取的方法(即目前可用的较小 hack)。

想象一下 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的未来版本提供更语义正确的方法,那时候我会接受 : )


一直在寻找这样的方法,而你的解决方案终于帮我解决了问题。谢谢! - nh_

16

您可以在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 所在目标无法导出的限制。


9
这个在你的库链接到其他现有项目时能够起作用,因为这些项目会包含你的库头文件,但是如果没有任何链接到你的库的项目,则无法起作用。因此,如果你有一个测试项目,其中可执行文件链接到你的接口库,那么该项目将包含库头文件以及其源代码。 - Francisco Aguilera
4
@FranciscoAguilera提出了一个非常好的观点。steveire,到目前为止还没有好的解决方案吗? - Ela782
1
我知道已经过了一段时间,但我不确定我完全理解你的评论 @FranciscoAguilera。第一句话“这意味着标头将添加到链接到您的库的其他现有项目中”,我理解这是正面案例,在预期的情况下可以正常工作。第二个句子“如果没有任何链接到您的库的项目,则无法工作”?我不理解这部分。在我看来,仅有标题的库没有编译独立程序的多少意义。然后关于测试项目的最后一个句子:这是指第一句话还是第二句话? - Satrapes
@Satrapes,我相信他的意思是库的头文件不会显示在库目标本身下面,而是会显示在链接到该库的目标下面。在现实世界的应用程序中,多个目标(可执行文件、测试、其他库等)链接到同一个库,这意味着相同(库)头文件将在不同的位置上有多个副本 - 在每个目标下面。 - oficsu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接