【问题标题】:Linking Qt app with CMake and Visual Studio将 Qt 应用程序与 CMake 和 Visual Studio 链接
【发布时间】:2025-12-31 03:15:16
【问题描述】:

我正在尝试使用 CMake 和 Visual Studio 2019 构建一个简单的测试 Qt 应用程序。

我的测试基于这个例子:https://github.com/jasondegraw/Qt-CMake-HelloWorld

我用 Visual Studio 打开了 CMakeLists.txt 文件。在构建期间我得到:

[7/7] cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\helloworld.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x86\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x86\mt.exe --manifests  -- C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1422~1.279\bin\Hostx86\x64\link.exe /nologo CMakeFiles\helloworld.dir\helloworld_autogen\mocs_compilation.cpp.obj CMakeFiles\helloworld.dir\main.cpp.obj CMakeFiles\helloworld.dir\mainwindow.cpp.obj CMakeFiles\helloworld.dir\helloworld_autogen\EWIEGA46WW\qrc_resources.cpp.obj  /out:helloworld.exe /implib:helloworld.lib /pdb:helloworld.pdb /version:0.0  /machine:x64 /debug /INCREMENTAL /subsystem:windows  D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Widgetsd.a D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Guid.a D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Cored.a D:\Program\Qt\5.13.1\mingw73_64\lib\libqtmaind.a kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
  FAILED: helloworld.exe 
  cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\helloworld.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x86\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x86\mt.exe --manifests  -- C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1422~1.279\bin\Hostx86\x64\link.exe /nologo CMakeFiles\helloworld.dir\helloworld_autogen\mocs_compilation.cpp.obj CMakeFiles\helloworld.dir\main.cpp.obj CMakeFiles\helloworld.dir\mainwindow.cpp.obj CMakeFiles\helloworld.dir\helloworld_autogen\EWIEGA46WW\qrc_resources.cpp.obj  /out:helloworld.exe /implib:helloworld.lib /pdb:helloworld.pdb /version:0.0  /machine:x64 /debug /INCREMENTAL /subsystem:windows  D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Widgetsd.a D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Guid.a D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Cored.a D:\Program\Qt\5.13.1\mingw73_64\lib\libqtmaind.a kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
  LINK Pass 1: command "C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1422~1.279\bin\Hostx86\x64\link.exe /nologo CMakeFiles\helloworld.dir\helloworld_autogen\mocs_compilation.cpp.obj CMakeFiles\helloworld.dir\main.cpp.obj CMakeFiles\helloworld.dir\mainwindow.cpp.obj CMakeFiles\helloworld.dir\helloworld_autogen\EWIEGA46WW\qrc_resources.cpp.obj /out:helloworld.exe /implib:helloworld.lib /pdb:helloworld.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:windows D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Widgetsd.a D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Guid.a D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Cored.a D:\Program\Qt\5.13.1\mingw73_64\lib\libqtmaind.a kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\helloworld.dir/intermediate.manifest CMakeFiles\helloworld.dir/manifest.res" failed (exit code 1120) with the following output:
D:\Download\mocs_compilation.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: struct QMetaObject * __cdecl QObjectData::dynamicMetaObject(void)const " (__imp_?dynamicMetaObject@QObjectData@@QEBAPEAUQMetaObject@@XZ) referenced in function "public: virtual struct QMetaObject const * __cdecl MainWindow::metaObject(void)const " (?metaObject@MainWindow@@UEBAPEBUQMetaObject@@XZ)

之后加载更多 LNK2019 错误。唯一不同的是我注释掉了 CMakeLists.txt 中的“-Wall”行。

据我所知,这个示例包含所有需要的元素。

我唯一注意到的是我安装了 Qt 5.13.1 msvc2017 并且正在运行 msvc2019 但 Qt 论坛上的一个帖子指出这两个版本是二进制兼容的。

对这个问题有什么想法吗?

更新:正如@Tsyvarev 所指出的,当Visual Studio 运行CMake 时,它​​使用与msvc 一起安装的MinGW 工具包。我在哪里可以告诉 Visual Studio 哪个 Qt 工具包是正确的?

【问题讨论】:

  • "我唯一注意到的是我安装了 Qt 5.13.1 msvc2017" - 嗯?链接路径 D:\Program\Qt\5.13.1\mingw73_64\lib\libQt5Widgetsd.a 表明您使用 MinGW 构建了 QT,而不是 Visual Studio(除了 mingw 子目录之外,还有一个库的后缀 .a,但 Visual Studio 使用本机 Windows 库的后缀,.dll)。实际上,我觉得 CMake 选择 .a 库很有趣(=奇怪),即使它在 Visual Studio 下工作也是如此。可能,你已经为 CMake 传递了一些额外的选项?
  • 我安装了 mingw 和 msvc 工具包。我天真地假设 Visual Studio 会选择 msvc 一个:/ 我将在哪里指定要使用的 Qt 安装? (编辑:我正在使用右键单击“生成 cmake 缓存”,所以据我所知我没有指定任何内容)
  • 嗯,如果你在 CMake 缓存中有 QT_DIR 变量,设置为 D:\Program\Qt\5.13.1\mingw73_64,则相应地更改此变量。
  • 该条目现在称为 Qt5_DIR,我还为其他模块编辑了看起来像 Qt5Widgets_DIR 和其他的条目。它现在运行。但是必须为每个新模块编辑缓存并且在缓存被清除时必须再次执行此操作似乎并不正确。我会更新问题。
  • 您可以将CMAKE_PREFIX_PATH 变量设置为正确的路径,而不是*_DIR 变量。但这应该通过 clean cache 完成(即在第一个“配置”之前)。在my answer 中查看有关该变量的更多信息到另一个问题。

标签: c++ qt visual-c++ cmake


【解决方案1】:

感谢@Tsyvarev 指出问题并修复。

总结一下发生了什么:

  • 当 Visual Studio 运行 CMake 时,它​​不会提示它应该使用 MSVC
  • CMake 最终找到了安装在系统上的 MinGW 工具包

以(据我所知)持久的方式修复它:

  • 右键 CMakeList 文件并清除 CMake 缓存
  • 右键单击CMakeList文件并选择“CMake设置”
  • 然后点击右上角的“Edit JSON”
  • 您可以在 JSON 中添加 CMake 变量
{
  "configurations": [
    {
      "name": "x64-Debug",
      "generator": "Ninja",
      "configurationType": "Debug",
      "inheritEnvironments": [ "msvc_x64_x64" ],
      "buildRoot": "${projectDir}\\out\\build\\${name}",
      "installRoot": "${projectDir}\\out\\install\\${name}",
      "cmakeCommandArgs": "",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "variables": [
        {
          "name": "CMAKE_PREFIX_PATH",
          "value": "D:\\Program\\Qt\\5.13.1\\msvc2017_64",
          "type": "STRING"
        }
      ]
    }
  ]
}

注意这是定义变量的部分:

    "variables": [
        {
          "name": "CMAKE_PREFIX_PATH",
          "value": "D:\\Program\\Qt\\5.13.1\\msvc2017_64",
          "type": "STRING"
        }
      ]

您应该相应地更新该值。文件的其余部分由 Visual Studio 生成。

  • 现在应该使用正确的工具包生成 CMake 缓存

再次感谢@Tsyvarev。

【讨论】: