上游项目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 项目:
MyLIB:一个使用来自 Qt5::Core 的 QString 的小型库。
它生成并安装包配置文件
MyLIBConfig.cmake、MyLIBConfigVersion.cmake 和 MyLIBTargets.cmake
为了能够被 CMake find_package()
搜索到
MyAPP:依赖于 MyLIB 的小型可执行文件
该项目使用 find_package(MyLIB) 并创建一个使用 MyLIB
的可执行文件
问题是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)
我正在开发一个更大的 C++ 库,该库使用 CMake 并依赖于 Qt。 我们从 Qt4 转移到 Qt5,现在我在使用我们的库时遇到了问题 在上游项目中。作为演示问题的最小工作示例,请查看此 repo:
https://github.com/philthiel/cmake_qt5_upstream
它包含两个独立的 CMake 项目:
MyLIB:一个使用来自 Qt5::Core 的 QString 的小型库。
它生成并安装包配置文件 MyLIBConfig.cmake、MyLIBConfigVersion.cmake 和 MyLIBTargets.cmake 为了能够被 CMake find_package()
搜索到
MyAPP:依赖于 MyLIB 的小型可执行文件
该项目使用 find_package(MyLIB) 并创建一个使用 MyLIB
的可执行文件
问题是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)