上游项目CMake打包配置文件使用Qt5问题

CMake package configuration files for upstream projects using Qt5 problems

我正在开发一个更大的 C++ 库,该库使用 CMake 并依赖于 Qt。 我们从 Qt4 转移到 Qt5,现在我在使用我们的库时遇到了问题 在上游项目中。作为演示问题的最小工作示例,请查看此 repo:

https://github.com/philthiel/cmake_qt5_upstream

它包含两个独立的 CMake 项目:


问题是CMake在配置MyAPP项目时给我如下错误信息:

CMake Error at CMakeLists.txt:11 (add_executable):
   Target "MyAPP" links to target "Qt5::Core" but the target was not found.
   Perhaps a find_package() call is missing for an IMPORTED target, or an
   ALIAS target is missing?

此行为的原因是在自动生成的 MyLIBTargets.cmake 文件中,Qt5 Core 的 INTERFACE_LINK_LIBRARIES 条目是 Qt5::Core 符号。使用 Qt4,这里指定了 Qt 核心库的绝对路径。


现在,我可以使用

简单地解决这个问题
find_package(Qt5Core 5.X REQUIRED) 

在MyAPP项目中。

但是,我想知道这是否是 intended/generic 的方法,即请求我们库的上游项目自己搜索所需的传递 Qt5 依赖项,或者我是否可能在这里滥用 CMake 和需要更改我的配置程序吗?

打包文件生成的CMake文档

https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html

提到宏可以由包配置文件提供给上游。也许这是搜索 Qt5 等导入目标并在找不到这些依赖项时中断上游配置运行的正确位置?

最好的, 菲利普

[edit of the edit] 完整源代码示例

您需要为您的项目提供一个 CMake 配置文件,ConfigFile 可能应该通过 CMake 本身生成(因为您无法确定用户将在何处安装您的软件)。

提示,使用 ECM cmake 模块简化创建:

 find_package(ECM REQUIRED NO_MODULE)
 include(CMakePackageConfigHelpers)

 ecm_setup_version(${PROJECT_VERSION}
    VARIABLE_PREFIX ATCORE
    VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/atcore_version.h"
    PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5AtCoreConfigVersion.cmake"
    SOVERSION 1
)

 configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KF5AtCoreConfig.cmake.in"
                               "${CMAKE_CURRENT_BINARY_DIR}/KF5AtCoreConfig.cmake"
                          INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
  )

和 KF5AtCoreConfig.cmake.in:

@PACKAGE_INIT@

find_dependency(Qt5Widgets "@REQUIRED_QT_VERSION@")
find_dependency(Qt5SerialPort "@REQUIRED_QT_VERSION@")
find_dependency(KF5Solid "@KF5_DEP_VERSION@")

include("${CMAKE_CURRENT_LIST_DIR}/KF5AtCoreTargets.cmake")

这将生成包含所有依赖项的正确 FindYourSortware.cmake。

[edit] 更好地解释正在发生的事情。 如果您要提供一个将使用 Qt 的库,并且在编译用户的源代码之前还需要找到 Qt5 库,则您需要为自己提供一个 FindYourLibrary.cmake 代码,该代码将调用

 find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Whatever)

现在,如果需要 您的 可执行文件 linked,请使用组件而不是您现在的方式。

find_package(Qt5 REQUIRED COMPONENTS Core)

然后你 link 你的图书馆

 target_link_libraries(YourTarget Qt5::Core)