Windows平台部署:MinGW vs MSVC、静态编译与动态编译、打包工具与安装包制作
Windows部署,说实话是Qt开发里最让人头疼的一环。我刚开始做跨平台项目时,在Mac和Linux上顺风顺水,一到Windows就各种缺DLL、崩溃、路径不对。后来摸爬滚打几年,总算把这条路走通了。今天我把这些经验掰开揉碎讲给你听。
编译器之争:MinGW还是MSVC?
很多新手会问:Qt Creator里这两个选项到底选哪个?我直接说结论——看你的目标用户。
核心区别一句话:MinGW是GCC的Windows移植版,MSVC是微软自家的编译器。两者生成的二进制不兼容。
| 对比项 | MinGW | MSVC |
|---|---|---|
| 调试器 | GDB | WinDbg / VS调试器 |
| STL兼容性 | 较好(GCC风格) | 与Windows API更贴合 |
| 性能 | 中等 | 较高(微软优化) |
| 第三方库 | 需自行编译 | 很多库直接提供MSVC版 |
| 部署难度 | 相对简单 | 需注意CRT运行时 |
我个人习惯:给企业内部用选MSVC,因为性能好、调试方便;给普通用户用选MinGW,部署起来省心。为什么?你想想看,MSVC编译的程序需要安装VC++运行库,用户电脑上没有就得弹窗报错。MinGW则没这个烦恼。
我的经验:有一次给客户做演示,MSVC编译的程序在对方Win7上直接崩溃,就是因为缺少VC++ 2015运行库。后来换成MinGW编译,一把过。从那以后,对外发布我优先用MinGW。
静态编译 vs 动态编译
这是个老生常谈的问题。说白了:动态编译生成小exe + 一堆DLL;静态编译生成一个大exe。
动态编译(默认方式)
- exe只有几百KB到几MB
- 运行时需要Qt的DLL(QtCore.dll、QtGui.dll等)
- 更新时只需替换exe
- 多个Qt程序可以共享DLL
静态编译
- exe有几十MB甚至上百MB
- 不需要额外DLL,直接双击运行
- 更新需要重新编译整个exe
- 每个程序都包含一份Qt库副本
我遇到过最尴尬的事:用动态编译给客户发了个工具,结果对方把exe拷走了,DLL全留在压缩包里。打开软件直接报错。嗯,从那以后,给非技术人员用的工具,我全用静态编译。
注意:Qt官方安装包默认不支持静态编译。你需要自己编译Qt源码,配置时加上-static参数。而且静态编译后,插件(如数据库驱动、图片格式插件)也需要静态链接,配置起来比较麻烦。
静态编译的配置命令示例:
configure -static -prefix C:\Qt\Qt5.15.2_static -opensource -confirm-license
mingw32-make -j4
这个过程大概要编译1-2小时,我建议你泡杯咖啡等着。
打包工具:windeployqt
这是Qt官方提供的部署工具,能自动找出程序依赖的DLL、QML文件、插件等。用法极其简单:
windeployqt.exe your_app.exe
它会扫描exe的依赖,把需要的文件全部复制到exe所在目录。我常用的完整命令:
windeployqt --release --no-translations --no-system-d3d-compiler your_app.exe
参数说明:
--release:只复制release版DLL--no-translations:不复制翻译文件(省空间)--no-system-d3d-compiler:不复制Direct3D编译器(大多数场景用不到)
避坑指南:我曾经遇到windeployqt漏掉某些插件的情况,比如数据库驱动。这时候手动把plugins\sqldrivers目录下的qsqlmysql.dll等复制过去就行。另外,如果你用了第三方库(如OpenCV),windeployqt不会帮你处理,得自己手动复制。
运行完windeployqt后,你的发布目录大概长这样:
your_app.exe
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
...
platforms/
qwindows.dll
styles/
qwindowsvistastyle.dll
...
安装包制作:NSIS vs Inno Setup
打包完一堆文件后,总不能给用户发个文件夹吧?这时候就需要制作安装包了。我常用的两个工具:NSIS和Inno Setup。
| 对比项 | NSIS | Inno Setup |
|---|---|---|
| 脚本语言 | 类汇编风格 | 类Pascal |
| 学习曲线 | 较陡 | 平缓 |
| 功能 | 极其强大 | 足够用 |
| 压缩率 | 高(LZMA) | 高(LZMA) |
| 界面 | 默认简陋 | 默认美观 |
我个人推荐:新手用Inno Setup,半小时就能上手。下面给个Inno Setup的示例脚本:
[Setup]
AppName=我的Qt应用
AppVersion=1.0.0
DefaultDirName={pf}\MyQtApp
DefaultGroupName=MyQtApp
OutputDir=.\installer
OutputBaseFilename=MyQtApp_Setup
[Files]
Source: "release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
[Icons]
Name: "{group}\MyQtApp"; Filename: "{app}\your_app.exe"
Name: "{commondesktop}\MyQtApp"; Filename: "{app}\your_app.exe"
这个脚本做了三件事:
- 指定安装路径和输出文件名
- 把release目录下所有文件复制到安装目录
- 创建开始菜单和桌面快捷方式
我的习惯:用Inno Setup配合windeployqt,写一个批处理脚本一键完成。先运行windeployqt收集依赖,再调用Inno Setup编译器生成安装包。整个过程自动化,省时省力。
NSIS虽然难学,但功能确实更强。比如要做多语言安装包、自定义安装界面、写注册表等,NSIS更灵活。不过说实话,大部分Qt应用用Inno Setup就够了。
知识体系总览
下面这张图帮你理清Windows部署的完整流程:
整个流程走下来,就是从源码到安装包的一条完整链路。每一步都有坑,但踩过一次就记住了。
最后分享个小技巧:写一个deploy.bat脚本,把windeployqt和安装包制作串起来。以后每次发布,双击一下就行。我团队现在就是这么干的,省去了大量重复劳动。
可可精品资料库