如何将 Qt 的 windeployqt 集成为 Visual Studio 构建工作流程的一部分?

How to integrate Qt's windeployqt as part of Visual Studio build workflow?

每次在Visual Studio中第一次构建新的Qt项目时,即使安装了VS工具,我也必须复制一些Qt相关的二进制文件(Qt5Core.dll、平台文件。 ..).否则,当 Visual Studio 中的 运行、Qt5Core.dll(或调试一个)被正确找到但不是平台 DLL 时:

显然,当 运行 从 IDE 外部完成时,它也会失败,例如,在自动构建的单元测试期间。

Qt 有一个工具可以做到这一点,称为 windeployqt,它主要是查找依赖项 (Qt) 并复制它们。例如:

c:\Qt\Qt5.12.1\bin\windeployqt c:\projects\qt-project\Release --release

将分析 c:\projects\qt-project\Release 中的可执行文件并将所需的 DLL、插件、翻译和其他相关二进制文件复制到该位置。

我对如何将 windeployqt 集成到 Visual Studio 的构建工作流程中感兴趣,因此这个过程是自动的(即使在不同的计算机上检出)。

您显然可以创建批处理文件并执行它,但请记住您必须在 编译项目后执行此操作,因为该工具将查看可执行文件.此外,您还必须处理构建路径和 Qt 安装目录位置,以使其可跨系统移植。

(请参阅此答案末尾的更新)

一种更方便的方法是将 windeployqt 配置为项目中的 post-build 事件(项目属性 > 构建事件 > Post-Build 事件)。 我在这里记录这个,因为我找不到任何明确的参考,我花了一段时间才弄明白。

处理便携性:

  • $(QTDIR):这个变量扩展到当前Qt版本的安装路径(我假设它是一个Qt项目,当然,安装了Qt VS Tools ).用它来定位 windeployqt(在 $(QTDIR)\bin\ 下)。

  • $(OutDir):扩展到可执行文件的构建目录。像往常一样,引用它来处理带空格的路径。这里的问题是 $(OutDir) 通常以 back-slash (\) 结尾,所以当 "$(OutDir)" 展开时它会创建一个转义字符 \"解释。为了修复它,您可以 trim 前导斜杠:"$(OutDir.TrimEnd('\'))" (credits).

  • $(Configuration):扩展为当前配置的名称(通常是DebugRelease,阅读下面的其他配置名称)。现在,windeployqt--debug--release 参数区分大小写,并且配置名称是标题大小写。要lower-case它:--$(Configuration.toLower()) (credits)。这一步只是为了有一个通用命令,可以通过手动设置 --debug--release 标志来跳过。

至此,完整的post-build命令如下:

"$(QTDIR)\bin\windeployqt.exe" "$(OutDir.TrimEnd('\'))" --$(Configuration.toLower())

该命令可以在项目的所有平台和配置中统一应用。

现在,如果您有 ReleaseDebug 以外的其他配置,您可以:

  • 相应地添加--debug--release修改命令,或

  • 为“debug-based 配置”和“release-based 配置”创建自定义 属性 页面并设置变量(例如 BaseConfigurationDebugRelease,然后在命令中使用这个新变量。

更新

自从 Qt VS Tools 的几个版本之前(不确定是哪个,但至少是 2.7.1),部署工具可以直接从项目的属性添加到构建链中 sheet:

如果您只想 运行 and/or 从 Visual Studio 调试您的应用程序,则不必复制那些 dll,您可以将依赖项路径添加到Visual Studio 中的调试器环境。

您可以在 Visual Studio 中这样做:

  • 在解决方案资源管理器中右键单击 vcxproj 文件
  • 从该上下文菜单中单击 Properties
  • 在打开的对话框中导航到 Debugging(在左侧面板中)
  • 在右侧面板中查找 Environment,您可以在其中使用如下内容:

    PATH=$(QTDIR)\bin;$(PATH)

注意:当您编辑回来时,您可以看到“;”的一些编码这不是问题,您只需要在编辑时小心,以免错过“;”在任意两条路径之间。

如果项目依赖于更多库,您可以在其中添加更多环境路径,并且不要忘记为所有构建选项编辑它 (Release/Debug/x64/x86/etc),并且您可以使用 base 定义自己的变量每个外部库的路径。

现在回到 Qt,QTDIR 变量在 .user 文件中定义,对于所有构建配置,您将拥有如下内容:

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <QTDIR>C:\Qt.12.1\msvc2017_64</QTDIR>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
    <LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
  </PropertyGroup>

我遇到的一个问题是 QTDIRLocalDebuggerEnvironment 交换(我的意思是首先定义了 LocalDebuggerEnvironment),显然这不起作用,所以如果它是在这种情况下,只需用您喜欢的文本(或 xml)编辑器手动交换这 2 个定义,以便在之前定义 QTDIR。

所以我建议使用此方法而不是将 windeploy 用作自定义构建步骤的一部分,而是将 windeploy 用于生成(或准备文件)安装程序的脚本。