如何在 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 A,module 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 显示不属于任何二进制目标的标头?的主要内容,如果未能解决你的问题,请参考以下文章