如何将 Qt 的 windeployqt 集成为 Visual Studio 构建工作流的一部分?
Posted
技术标签:
【中文标题】如何将 Qt 的 windeployqt 集成为 Visual Studio 构建工作流的一部分?【英文标题】:How to integrate Qt's windeployqt as part of Visual Studio build workflow? 【发布时间】:2019-02-20 14:26:50 【问题描述】:每次在 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 的构建工作流中很感兴趣,因此这个过程是自动的(即使在不同的计算机上签出)。
【问题讨论】:
【参考方案1】:您显然可以创建一个批处理文件并执行它,但请记住,您必须在编译项目之后执行它,因为该工具将查看可执行文件。此外,您还必须处理构建路径和 Qt 安装目录位置,以使其可跨系统移植。
(有关此问题的更新,请参阅此答案的末尾)
更方便的方法是将windeployqt
配置为项目中的构建后事件(项目属性> 构建事件> 构建后事件)。 我在这里记录了这一点,因为我找不到任何明确的参考资料,我花了一段时间才弄清楚。
处理可移植性:
$(QTDIR)
:这个变量扩展为当前Qt版本的安装路径(当然我假设它是一个Qt项目,并且安装了Qt VS Tools)。用它来定位windeployqt
(在$(QTDIR)\bin\
下)。
$(OutDir)
:展开到可执行文件的构建目录。像往常一样,引用它来处理带有空格的路径。这里的问题是 $(OutDir)
通常以反斜杠 (\
) 结尾,因此当 "$(OutDir)"
展开时,它会创建一个转义字符 \"
,这将被错误地解释。为了修复它,您可以修剪前导斜杠:"$(OutDir.TrimEnd('\'))"
(credits)。
$(Configuration)
:扩展为当前配置的名称(通常是 Debug 或 Release,请阅读下文了解其他配置名称)。现在,windeployqt
对--debug
或--release
参数区分大小写,配置名称为标题大小写。小写:--$(Configuration.toLower())
(credits)。这一步只是为了有一个通用的命令,可以通过手动放置--debug
或--release
标志来跳过。
这样,完整的post-build命令如下:
"$(QTDIR)\bin\windeployqt.exe" "$(OutDir.TrimEnd('\'))" --$(Configuration.toLower())
此命令可以在项目的所有平台和配置中统一应用。
现在,如果您有除 Release
和 Debug
之外的其他配置,您可以:
相应地添加--debug
或--release
来修改命令,或者
为“基于调试的配置”和“基于发布的配置”创建自定义属性页,并将变量(例如BaseConfiguration
)设置为Debug
或Release
,然后在命令中使用这个新变量而是。
更新
由于 Qt VS 工具的几个版本(不确定是哪个,但至少是 2.7.1),部署工具可以直接从项目的属性表添加到构建链:
【讨论】:
【参考方案2】:如果您只想从 Visual Studio 运行和/或调试应用程序,则不必复制这些 dll,您可以将依赖项路径添加到 Visual Studio 中的调试器环境。
您可以在 Visual Studio 中这样做:
在解决方案资源管理器中右键单击 vcxproj 文件 从该上下文菜单中单击Properties
在打开的对话框中导航到Debugging
(在左侧面板中)
在右侧面板中查找Environment
,您可以在其中使用如下内容:
PATH=$(QTDIR)\bin;$(PATH)
注意:当您编辑回来时,您可以看到“;”的一些编码这不是问题,您只需要在编辑时小心,以免错过';'在任意 2 条路径之间。
如果项目依赖于更多库,您可以在其中添加更多环境路径,并且不要忘记为所有构建选项(Release/Debug/x64/x86/etc)进行编辑,您可以定义自己的变量每个外部库的基本路径。
现在回到 Qt,QTDIR 变量是在 .user 文件中定义的,对于所有构建配置,您将拥有如下内容:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<QTDIR>C:\Qt\5.12.1\msvc2017_64</QTDIR>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
我遇到的一个问题是 QTDIR
与 LocalDebuggerEnvironment
交换(我的意思是首先定义 LocalDebuggerEnvironment),显然这不起作用,所以如果是这种情况,只需手动交换那些2 用你喜欢的文本(或xml)编辑器定义,这样QTDIR就定义在前面了。
所以我建议使用这种方法,而不是使用 windeploy 作为自定义构建步骤的一部分,而是将 windeploy 用于生成(或准备文件)安装程序的脚本。
【讨论】:
谢谢!我会看看这个,但是从 VS 运行时我遇到的主要问题是平台 DLL 和插件,VS 没有正确找到它们。此外,在自动编译期间,一些自动化测试是从 VS 外部运行的。我想我对这个问题的了解不够。 使用这个VS会找到dll。至于自动化测试是所有开发人员在所有开发计算机上使用的测试吗?如果不是,那么也许那些自动化测试可以从构建路径中对 exe 进行分级,然后使用 windeploy(或其他带来依赖项的脚本),我不希望 windeploy 每次构建时都复制这些依赖项(更不用说 windeploy仅适用于 Qt,不会复制任何其他依赖项) 是的,每次完整编译时总是通过测试(可以跳过但通常不做)。关于其他依赖项,它们可以使用其他工具解决,windeployqt 的问题是它需要可执行文件,因此它必须在构建之后运行,而不是之前运行(就像其他只分析项目的那样)。关于复制的文件,(还)不是一个大问题,因为增加的时间几乎可以忽略不计,但同意这是一件需要考虑的事情。 另外,我们不提交 .user 文件,因为它们取决于每个用户配置,以某种方式在结帐时应用此更改(可能是针对不同的问题)? 是的,.user 文件不会受到版本控制(因为每个成员都可以在其他路径上具有依赖关系)。但是,每次构建后仍然复制依赖项是多余的。如果您不喜欢默认方式并且需要独立运行(用于测试),也许运行一次(python)脚本会更好以上是关于如何将 Qt 的 windeployqt 集成为 Visual Studio 构建工作流的一部分?的主要内容,如果未能解决你的问题,请参考以下文章
Qt官方开发环境生成的exe发布方式--使用windeployqt(windeployqt是单独的程序,放在低版本qt4目录下也可以运行的)