【问题标题】:How to create a cmake header-only library that depends on external non-header-only target?如何创建一个依赖于外部非仅标头目标的 cmake 仅标头库?
【发布时间】:2021-03-03 04:35:53
【问题描述】:

How to create a cmake header-only library that depends on external header files? 接近但不同。

我有一个单头库MyHeaderLib。在MyHeaderLib/MyHeader.h 我有#include <QString>,所以任何做#include "MyHeaderLib/MyHeader.h" 的人最好在他们的路径中有QString(即,我认为Qt5Core 到CMake(?))并且他们需要链接到Qt5Core。

什么属于我的CMakeLists.txt MyHeaderLib?我有

cmake_minimum_required(VERSION 3.12)

add_library(MyHeaderLib INTERFACE)

target_include_directories(MyHeaderLib include/) 
# (^ Where include/ contains MyHeaderLib/MyHeader.h)

我尝试使用target_link_libraries(MyHeaderLib 的任何操作都需要INTERFACE,如果我使用target_link_libraries(MyHeaderLib INTERFACE Qt5Core),这还不够。

最终我让它按如下方式工作,但我不明白发生了什么:

cmake_minimum_required(VERSION 3.12)

find_package(Qt5Core REQUIRED) # <- Can't be Qt5::Core

add_library(MyHeaderLib INTERFACE)

target_include_directories(MyHeaderLib include/) 
# (^ Where include/ contains MyHeaderLib/MyHeader.h)

target_link_libraries(MyHeaderLibrary 
INTERFACE
    Qt5::Core # <- Can't be Qt5Core
)

我收集带有:: 的目标是别名,但我很困惑为什么它需要完全像这样。此外,我在任何地方都找不到add_library(Qt5::Core ALIAS Qt5Core)。到底是怎么回事?为什么我必须find_package(Qt5Core REQUIRED) 而不是find_package(Qt5::Core REQUIRED),为什么target_link_libraries 不能接受Qt5Core

【问题讨论】:

  • 你的意思是CMake的内置Qt支持神奇地知道当我寻找Qt5Core时我得到Qt5::Core?我是 CMake n00b... 如果一个是另一个的别名,为什么这两个名称不能与 find_packagetarget_link_libraries 互换?
  • find_package(XYZ ...) 可以与您使用target_link_libraries 链接到的目标完全不同。在这种情况下,有一个FindQt5Core.cmake(或者可能是Qt5CoreConfig.cmake)声明了Qt5::Core 目标。他们本可以编写它来声明Qt5Core,但他们选择将其设为Qt5::Core

标签: c++ cmake


【解决方案1】:

包负责定义目标。 Qt 维护人员在决定定义 Qt5::Core 目标时选择将包命名为 Qt5Core

通常 CMake 包的约定是,名为 package-name 的包将定义 package-name::package-name 以及其他可选目标或 package-name::package-name 的子组件。

要回答为什么Qt不这样,看看Qt5CoreConfig.cmake里面,你会看到这一行:

add_library(Qt5::Core SHARED IMPORTED)

给你。该文件名为Qt5CoreConfig,因此它需要find_package(Qt5Core),但目标位于Qt5 命名空间下,因为他们选择定义它。

这可能是因为 Qt5 还有一个通用的包可以使用组件:

find_package(Qt5 REQUIRED COMPONENTS Core)
# Here Qt5::Core kinda make sense.

【讨论】:

  • 感谢您的澄清!所以问题是包和目标是不同的东西,find_package 至少在视觉上更有意义。如果你把它写成find_package(Qt5 COMPONENTS Core REQUIRED),它看起来也是一样的,读起来更像find_package(Qt5Core REQUIRED)
  • 但是……Qt5CoreConfig.cmake的存在如何定义一个名为Qt5Core的包?如果我尝试find_package(Foo REQUIRED),它会在某个路径中寻找FooConfig.cmake,这是否是魔法?我有点希望在某处看到add_package 命令说“我是 Qt5Core 包”,但显然这不是一回事。
  • @Ben 是的。在有关 cmake-packagesfind_package 的文档中适合自己
  • @Ben 您可以使用install(EXPORT ... 命令或手动编写文件来添加包。表现良好的 CMake 库会导出其目标。
猜你喜欢
  • 1970-01-01
  • 2017-02-14
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多