【问题标题】:How to link QtMain in CMake with Qt5?如何将 CMake 中的 QtMain 与 Qt5 链接?
【发布时间】:2012-12-16 09:43:50
【问题描述】:

我将我的项目代码从 Qt4 升级到了 Qt5。它使用 CMake。 除了一行与 Qt 相关的 Cmake 命令外,转换很顺利。 我在当前文档中找不到,比如

如何从 CMake(使用 Qt5)链接到 QtMain?

这是转换我的项目的唯一缺失位。 有人可以向我指出一个解释这一点的文档或解释如何用 Qt5 做到这一点吗?我的 Qt4 代码工作正常,但我找不到 Qt5 的 Cmake 宏。

EDIT> 这是我目前拥有的 CMake 文件:https://bitbucket.org/klaim/aos_qt5/src/593c195c4c6889f6968d68fca018ef425783a063/tools/aosdesigner/CMakeLists.txt?at=wip_qt5

我相信所有 qt5 必要的 CMake 宏都已正确设置,唯一不起作用的是链接到 QtMain 什么都不做,正如预期的那样,因为应该有一个 Qt5 特定的方式来做这件事,我没有在 Qt5 文档中找到。

您可以浏览文件历史记录以了解它是如何与 Qt4 一起工作的。

【问题讨论】:

  • 你当前的链接代码是什么样子的?
  • @FrankOsterfeld 这里是:bitbucket.org/klaim/aos_qt5/src/…
  • 您遇到的实际错误信息或问题是什么?
  • @DavidGrayson QtMain 没有发生链接,这使得编译假定标准 main() 函数是在启动时调用的函数,这在 Windows 上不是正确的,因为它不是控制台应用程序,但一个 GUI 应用程序。 QtMain 的目的是提供一个 WinMain() 实现,它将在 Windows 上调用您的标准 main() 实现,而无需显示控制台或让项目必须是控制台项目。更一般地说,它的目的是允许用户编写在所有平台上使用的标准 c++ 主函数并隐藏 Windows 细节。
  • @DavidGrayson 问题是(如果您查看链接文档的历史记录),使用 Qt4 有一种方法可以链接到 QtMain(仍在当前的 CMake 文件中),但所有CMake 宏在 Qt5 中发生了变化(为了更简单地将 Qt 与 CMake 一起使用,所以这只是很好的变化),但在文档中没有任何地方解释有什么不同或如何与 QtMain 链接,即使有关于 QtMain 的 Qt5 版本的文档。所以我让Qt4的方式来做,但如前所述,它没有与QtMain链接。

标签: c++ qt c++11 cmake qt5


【解决方案1】:

从您链接到的Qt docs,您似乎可以找到 Qt5Core 而不是 Qt5Widgets。这将创建一个名为Qt5::WinMain 的导入目标。来自Qt docs

为每个 Qt 模块创建导入的目标。这意味着Qt5<Module>_LIBRARIES 包含导入目标的名称,而不是库的路径。
...
Qt 5 中的每个模块都有一个库目标,其命名约定为Qt5::<Module>

find_package( Qt5Widgets REQUIRED )
find_package( Qt5Core REQUIRED )
...
add_executable( aosdesigner WIN32 ${AOSDESIGNER_ALL_FILES} )
target_link_libraries( aosdesigner
    ${Boost_LIBRARIES}
    utilcpp
    aoslcpp
    Qt5::WinMain  # <-- New target available via find_package ( Qt5Core )
)

qt5_use_modules( aosdesigner Widgets )

我还建议您删除两个 link_libraries 调用,因为它是一个 deprecated command,并且我会在 CMakeLists.txt 的顶部指定 CMake 版本 2.8.9 而不仅仅是 2.8 作为最低要求,因为that's required for qt5_use_modules

【讨论】:

  • 第一个建议不起作用,因为没有带有 WinMain 模块的目录。第二个有效,但随后它触发了一个错误,因为它是一个静态库,它是用 vs2010 编译的,我正在使用 vs2012。所以第二部分比其他答案更完整,我接受这个答案。请删除第一部分。
【解决方案2】:

从 CMake 2.8.11 和 Qt 5.1 开始,如果您在 add_executable 调用中指定 WIN32 或设置 WIN32_EXECUTABLE 目标属性,则链接到 Qt5::WinMain 是自动/隐式的。

演示文稿

https://devdays.kdab.com/wp-content/uploads/2012/cmake.pdf

视频在

http://www.youtube.com/watch?feature=player_detailpage&v=GJ0kMsLbk6Q#t=751

描述了使其成为 CMake 2.8.11 的功能。

有关使用 Qt 的 CMake 的更多信息,请参阅

http://www.kdab.com/modern-cmake-with-qt-and-boost/

【讨论】:

  • 请注意,Qt5::WinMain 目标的自动添加受POLICY CMP0020 cmake 策略的约束。默认是旧行为(不添加)。
  • 您的评论具有误导性。如果所需的最低 cmake 版本是 2.8.11,则默认行为是 NEW。
  • 来自cmake.org/cmake/help/git-master/policy/CMP0020.html:“此策略是在 CMake 版本 2.8.11 中引入的。CMake 版本 2.8.12.20140121-g1eb4d 会在未设置策略并使用 OLD 行为时发出警告。使用 cmake_policy 命令设置明确地将其设置为 OLD 或 NEW。”所以,当我读到它时,至少对于最新版本,默认是旧的,不管最低要求的 cmake 版本是什么 - 或者默认行为是否会根据所需的 cmake 版本而改变?如果是这样,它的任何文档来源,还是没有记录?
  • cmake.org/cmake/help/git-master/manual/cmake-policies.7.html 如果使用过旧版本的 CMake 构建项目,cmake_minimum_required() 命令不仅会报告错误。它还将该 CMake 版本或更早版本中引入的所有策略设置为新行为。
【解决方案3】:

编辑:感谢 Archi 评论(见下文),只需添加

target_link_libraries(<your_app> Qt5::WinMain)

target_link_libraries(<your_app> ${Qt5Core_QTMAIN_LIBRARIES})

在您应用程序的 CMakeLists.txt 中。两种语法都对我有用。

【讨论】:

  • 据此介绍:qtconference.kdab.com/sites/default/files/slides/cmake.pdf ${QT_QTMAIN_LIBS} 不是必需的,只需 add_executable(exec WIN32 ...)
  • @Tawene 我不明白什么是 Qt5::WinMain?新目标?
  • 是的,Qt5::WinMain 是由 Qt5Core cmake 文件创建的新目标。这条线对你有帮助吗?
  • 第一行有效。由于另一个答案更完整,我会接受它,但谢谢你,我投了赞成票。
  • 在 Linux 上怎么样? Qt5::WinMain 听起来非常特定于 Windows。我们必须打开一个强大的if (MSVC)...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 2017-11-27
  • 2021-08-21
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多