1. 为什么2024年还有人死磕Qt 5.12.11离线包
先说结论:如果你手头有工业控制、医疗设备、军工配套或者内网开发环境这类项目,Qt 5.12.11这个版本号大概率不是随便挑的。它是Qt 5.12 LTS系列的最后一个补丁版本,也是官方长期支持策略里被大量商业项目锁死的版本。很多做上位机、组态软件、仪器控制界面的团队,代码基线就卡在5.12.11上,往上跳5.15要改的东西太多,往下退5.9又缺特性,所以这个版本成了事实上的“钉子户”。
但问题来了——Qt官方从5.15开始对离线安装包做了限制,5.12.11的官方离线安装器虽然还能找到,可它默认走在线下载,一个模块一个模块地拉,网络稍微抖一下就得重来。更麻烦的是很多开发机根本连不了外网,或者公司网络策略把Qt的下载源给拦了。这时候3.7GB的完整离线包就成了刚需。
我这次要聊的就是把这个3.7GB的完整包在Windows 10上跑通,并且把MSVC和MinGW两套编译器都配好。为什么两套都要?因为实际项目里经常出现这种情况:主程序用MSVC编译,因为要链接某些Windows SDK或者第三方商业库;但某个小工具或者插件又用MinGW,因为开发者习惯或者依赖某个只有MinGW能编的库。两套环境共存不是炫技,是真实需求。
这篇文章适合谁看?如果你是刚接触Qt、准备在Windows上搭开发环境的新手,可以跟着走一遍,我会把每个选择背后的原因讲清楚。如果你是有经验的老手,直接跳到第3节的配置细节和第4节的踩坑记录,那些是我实际折腾出来的经验,文档里不会写。
提示:全文基于Qt 5.12.11官方离线包在Windows 10 22H2专业版上的实测,不同小版本号可能有细微差异,但整体思路通用。
2. 离线包获取与安装前的关键决策
2.1 3.7GB完整包到底包含什么
很多人拿到一个3.7GB的Qt离线包,第一反应是“这么大,里面塞了啥”。我拆开看过,这个体积主要由几块构成:Qt核心库和模块的预编译二进制、两套编译器的预编译版本(MSVC和MinGW各一套)、Qt Creator IDE、以及大量的示例代码和文档。其中文档和示例大概占了1GB左右,如果你磁盘紧张,安装时可以取消勾选,但我不建议——后面查API的时候离线文档比在线搜索快得多。
具体到模块层面,5.12.11的完整包默认包含Qt Core、Gui、Widgets、Network、Sql、Xml、Concurrent、PrintSupport这些基础模块,还有Qt WebEngine(这个是大头,Chromium内核就占了好几百MB)、Qt Multimedia、Qt SerialPort、Qt Bluetooth等。如果你做的是纯桌面工具,WebEngine可以不装,能省下将近800MB。
这里有个细节:离线包里的预编译二进制是分编译器版本的。MSVC版本又分msvc2015、msvc2017、msvc2019,5.12.11官方只提供到msvc2017的预编译包,但msvc2017的ABI和msvc2019、msvc2022是兼容的,所以用VS2019或者VS2022也能链接。MinGW版本则是mingw73_64和mingw73_32,对应GCC 7.3.0。
2.2 下载渠道与校验
官方离线包现在不太好找,Qt官网的下载页面默认引导你去在线安装器。我的做法是直接去Qt的归档服务器找,路径规律是/archive/qt/5.12/5.12.11/下面,文件名类似qt-opensource-windows-x86-5.12.11.exe。这个文件大概3.7GB,下载的时候建议用支持断点续传的工具,因为单线程下载中途断掉的概率不低。
下载完第一件事是校验哈希值。官方页面会提供SHA-256,用PowerShell的Get-FileHash命令算一下,对不上就重新下。我遇到过两次下载文件损坏的情况,安装到一半报错,排查半天才发现是包本身的问题。
Get-FileHash .\qt-opensource-windows-x86-5.12.11.exe -Algorithm SHA256校验通过后再运行安装程序。安装路径建议不要有空格和中文,比如D:\Qt\Qt5.12.11就很好。虽然Qt现在对中文路径的支持比以前好,但某些第三方库和构建工具还是会在中文路径上出幺蛾子,没必要给自己埋雷。
2.3 安装时的组件勾选策略
运行安装器后,第一步是登录Qt账号。离线安装器也会要求登录,这个绕不过去,没有账号就注册一个,免费的个人账号就行。登录后进入组件选择页面,这里的选择直接决定了你后面能不能顺利编译。
我的勾选策略是这样的:在Qt 5.12.11节点下,展开后你会看到按编译器分类的条目。MSVC 2017 64-bit必须勾,这是Windows桌面开发的主力。MinGW 7.3.0 64-bit也勾上,用于需要MinGW的场景。32位的版本看需求,如果要做兼容老系统的程序就勾上,否则可以省空间。
Tools节点下面,Qt Creator肯定要勾,版本选安装器自带的那个。MinGW 7.3.0这个工具链条目也要勾,它包含了GCC、GDB、make等工具,不勾的话MinGW编译器没法用。另外Qt Debugging Tools建议勾上,后面调试的时候用得到。
有个坑要注意:安装器里的组件依赖关系不是自动处理的。比如你勾了Qt的MinGW版本,但没勾Tools里的MinGW工具链,装完你会发现Qt Creator里能选MinGW编译器,但一编译就报找不到g++。所以勾完最好检查一遍。
注意:安装过程大概需要15到30分钟,取决于磁盘速度。安装路径所在分区至少留出8GB空间,因为安装过程中会有临时文件,装完清理后实际占用大概5GB左右。
3. MSVC与MinGW双编译器配置实操
3.1 MSVC编译器的配置与验证
装完Qt后,MSVC编译器本身是不在Qt安装包里的,你需要先装Visual Studio。这里有个版本对应关系:Qt 5.12.11的msvc2017预编译包,可以用VS2017、VS2019、VS2022来编译,因为微软保证了MSVC 2015到2022的ABI兼容性。我实测用VS2022社区版没问题。
装VS的时候,工作负载选“使用C++的桌面开发”,右侧的安装细节里确保勾上“MSVC v143 - VS 2022 C++ x64/x86生成工具”和“Windows 10 SDK”。SDK版本选最新的就行,Qt 5.12.11对SDK版本不挑。
装完VS后打开Qt Creator,进入“工具”->“选项”->“Kits”页面。在“编译器”标签页里,Qt Creator通常会自动检测到MSVC编译器。如果没有,手动添加,路径指向VS安装目录下的VC\Tools\MSVC\版本号\bin\Hostx64\x64\cl.exe。注意要选64位的cl.exe,32位的在Hostx86目录下。
然后到“构建套件”标签页,新建一个套件。编译器选刚配好的MSVC,Qt版本选D:\Qt\Qt5.12.11\5.12.11\msvc2017_64,调试器选VS自带的cdb.exe或者Windows SDK里的调试工具。这里有个细节:Qt Creator默认可能找不到cdb,需要手动指定路径,通常在C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe。
配置完后建一个空的Qt Widgets应用测试一下。如果编译通过并且能运行,说明MSVC环境没问题。如果报“LNK2019无法解析的外部符号”,大概率是链接器找不到Qt库,检查套件里的Qt版本路径是否指向了msvc2017_64目录。
3.2 MinGW编译器的配置与验证
MinGW的配置相对简单,因为Qt安装包里已经带了完整的工具链。打开Qt Creator的“编译器”标签页,应该能自动看到“MinGW 7.3.0 64-bit”这个编译器,路径指向D:\Qt\Qt5.12.11\Tools\mingw730_64\bin\g++.exe。
如果没有自动检测到,手动添加,类型选“GCC”,编译器路径选上述g++.exe。然后到“构建套件”页面新建套件,编译器选MinGW,Qt版本选D:\Qt\Qt5.12.11\5.12.11\mingw73_64,调试器选D:\Qt\Qt5.12.11\Tools\mingw730_64\bin\gdb.exe。
MinGW环境有个常见问题:编译时报“undefined reference to__imp_xxx”,这通常是因为链接了MSVC编译的库。MinGW和MSVC的库不能混用,这是ABI层面的不兼容。所以如果你项目里用了第三方库,必须确认它有MinGW版本,或者你自己用MinGW重新编译。
测试MinGW环境同样建一个空项目,编译运行。如果报“cannot find -lQt5Widgets”,检查套件里的Qt版本是否指向mingw73_64目录,以及该目录下的lib文件夹里是否有对应的.a文件。
3.3 两套环境共存的目录结构与切换技巧
MSVC和MinGW共存时,目录结构是这样的:
D:\Qt\Qt5.12.11\ ├── 5.12.11\ │ ├── msvc2017_64\ # MSVC版本的Qt库 │ └── mingw73_64\ # MinGW版本的Qt库 ├── Tools\ │ ├── mingw730_64\ # MinGW工具链 │ └── QtCreator\ # IDE两套环境的头文件是各自独立的,但内容基本一致。切换编译器时,Qt Creator会自动切换对应的Qt版本和库路径,你不需要手动改.pro文件。但如果你在.pro文件里写了硬编码的库路径,切换时就会出问题。所以我的建议是:.pro文件里只用QT +=这种模块声明,不要写绝对路径。
有个实用技巧:在Qt Creator的“项目”页面,你可以为同一个项目配置多个构建套件,然后一键切换。比如Debug用MinGW快速迭代,Release用MSVC出正式版。切换时Qt Creator会重新生成Makefile,不需要手动清理。
提示:如果你在命令行下用qmake,MSVC环境需要先运行VS的
vcvarsall.bat设置环境变量,MinGW环境需要把D:\Qt\Qt5.12.11\Tools\mingw730_64\bin加到PATH里。这个区别在写自动化脚本时特别重要。
4. 常见问题与排查技巧实录
4.1 安装与启动阶段的典型故障
问题一:安装器启动后白屏或者卡在登录界面。这个我遇到过好几次,原因是安装器的Qt WebEngine组件和某些显卡驱动不兼容。解决办法是给安装器加--no-opengl参数,或者右键属性里禁用显卡加速。如果还是不行,把安装器复制到另一个目录再运行,有时候是路径权限问题。
问题二:安装到一半报“写入文件失败”。九成是杀毒软件在捣乱。Qt安装器会释放大量小文件,某些杀毒软件的实时监控会锁文件。临时关闭杀毒软件,或者把安装目录加到白名单里。另外Windows Defender的“受控文件夹访问”也可能拦截,检查一下。
问题三:装完后Qt Creator启动报“could not find the Qt platform plugin windows”。这是环境变量冲突,通常是你之前装过其他版本的Qt,PATH里残留了旧版本的路径。检查系统环境变量,把旧Qt的路径删掉,只保留当前版本的。如果用的是MSVC套件,还需要确保VS的环境变量没有覆盖Qt的。
4.2 编译与链接阶段的典型故障
问题一:MSVC编译报“fatal error C1083: 无法打开包括文件: ‘QApplication’”。这是Qt版本没选对,套件里的Qt路径指向了MinGW版本。检查“构建套件”页面,MSVC套件必须配msvc2017_64的Qt版本。
问题二:MinGW编译报“cannot mix incompatible Qt library”。这个错误信息很明确,你链接了不同版本的Qt库。常见场景是系统PATH里有另一个Qt版本的bin目录,运行时加载了错误的DLL。解决办法是把当前Qt版本的bin目录加到PATH最前面,或者用windeployqt工具把依赖库复制到exe旁边。
问题三:链接时报“undefined reference to_imp__ZN7QStringC1Ev”之类的符号。这是MinGW链接了MSVC编译的库。检查你项目里引用的第三方库,确认它是用MinGW编译的。如果没有MinGW版本,要么找替代库,要么自己编译。
问题四:程序编译通过但运行崩溃,报“This application failed to start because no Qt platform plugin could be initialized”。这是运行时找不到平台插件。Qt的程序运行需要platforms\qwindows.dll这个插件。用windeployqt工具可以自动复制所有依赖,命令是windeployqt your_app.exe。如果手动复制,确保platforms文件夹和exe在同一目录。
4.3 双编译器切换时的注意事项
切换编译器时,最大的坑是中间文件不兼容。MSVC生成的.obj文件和MinGW生成的.o文件格式不同,切换时必须清理重新编译。Qt Creator在切换套件时会自动提示清理,但如果你用命令行,记得先make clean或者删掉build目录。
另一个坑是调试器不匹配。MSVC套件用cdb,MinGW套件用gdb,切换套件时Qt Creator会自动切换调试器。但如果你手动指定了调试器路径,切换后可能报“调试器无法启动”。检查套件配置里的调试器设置。
还有个细节:MinGW的gdb在Windows 10上有时会卡死,特别是调试多线程程序时。如果遇到,升级到更新的gdb版本,或者改用MSVC套件调试。我一般用MinGW编译快速验证,用MSVC做正式调试。
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 安装器白屏 | 显卡驱动不兼容 | 加--no-opengl参数 | 禁用显卡加速或换目录运行 |
| 写入文件失败 | 杀毒软件拦截 | 查看杀毒日志 | 关闭实时监控或加白名单 |
| 找不到平台插件 | 环境变量冲突 | 检查PATH | 清理旧版本路径 |
| 符号未定义 | 库ABI不匹配 | 确认库的编译工具 | 用对应编译器重新编译库 |
| 运行时崩溃 | 缺少依赖DLL | 用Dependency Walker查看 | windeployqt自动部署 |
4.4 离线环境下的依赖部署
离线环境下部署Qt程序,windeployqt是核心工具。它的用法很简单:
windeployqt --release --no-translations your_app.exe--release指定发布版,--no-translations跳过翻译文件(如果需要多语言支持就去掉这个参数)。工具会自动扫描exe的依赖,把需要的Qt DLL和插件复制到同目录。
但windeployqt有个局限:它只复制Qt自身的依赖,不复制第三方库。如果你用了OpenCV、FFmpeg之类的库,需要手动复制对应的DLL。另外VC运行时库(MSVC编译的程序需要)也不在复制范围内,目标机器没装VC运行时的话,需要把vcruntime140.dll、msvcp140.dll这些一起带上。
MinGW编译的程序依赖libgcc_s_seh-1.dll、libstdc++-6.dll、libwinpthread-1.dll这几个,windeployqt会自动复制。但如果你在目标机器上遇到“找不到libgcc_s_seh-1.dll”,检查一下是不是复制漏了。
注意:离线部署时,建议在干净的虚拟机里测试一遍。我遇到过开发机上跑得好好的,到客户机器上就报缺DLL,原因是开发机装了一堆运行时,掩盖了依赖缺失的问题。
5. 从安装到出包的完整流程复盘
5.1 环境搭建的时间线与检查点
我把整个流程的时间线整理一下,方便你对照自己的进度。第一步是下载3.7GB离线包,网速正常的话20到40分钟。下载完校验哈希,5分钟。运行安装器,选组件,15到30分钟。装VS2022,如果没装过,大概20到40分钟。配置Qt Creator套件,10分钟。建测试项目验证两套编译器,15分钟。总计大概一个半到两个小时。
检查点有三个:安装完成后Qt Creator能正常启动;MSVC套件能编译运行一个空窗口程序;MinGW套件能编译运行同样的程序。三个都过了,环境就算搭好了。
5.2 项目实战:一个窗口程序的双编译器验证
我建了一个最简单的Qt Widgets应用来验证环境。.pro文件内容如下:
QT += core gui widgets TARGET = EnvTest TEMPLATE = app SOURCES += main.cpp mainwindow.cpp HEADERS += mainwindow.hmain.cpp里就创建一个QApplication和MainWindow,显示一个带按钮的窗口。按钮点击弹出一个消息框,显示当前编译器的信息。用#ifdef _MSC_VER和#ifdef __GNUC__来区分编译器,这样运行时就能直观看到是哪个编译器编的。
MSVC套件下编译,输出目录是build-EnvTest-Desktop_Qt_5_12_11_MSVC2017_64bit-Debug,MinGW套件下是build-EnvTest-Desktop_Qt_5_12_11_MinGW_64bit-Debug。两个目录互不干扰,切换套件时Qt Creator自动切换输出目录。
运行MSVC版本,消息框显示“Compiler: MSVC”。运行MinGW版本,显示“Compiler: MinGW”。两个都正常,说明环境完全打通。
5.3 发布版本的构建与体积优化
出正式版的时候,用Release模式编译。MSVC的Release版比Debug版小很多,因为不包含调试符号。但即使Release版,Qt程序的体积也不小,一个空窗口程序大概10到15MB,因为要带Qt的核心DLL。
体积优化有几个方向:一是用-static静态链接Qt,但5.12.11的预编译包不提供静态库,需要自己编译,比较麻烦。二是用windeployqt的--no-opengl-sw参数跳过软件OpenGL渲染器,能省几MB。三是用UPX压缩exe和DLL,但压缩后启动会慢一点,看需求取舍。
我一般不做静态链接,因为动态链接的部署更灵活,更新Qt版本时只需要替换DLL。静态链接虽然单文件方便,但一旦Qt有安全更新,得重新编译整个程序。
5.4 我踩过的三个印象最深的坑
第一个坑是MSVC版本和Qt预编译包的对应关系。我一开始用VS2015配msvc2017的Qt包,编译报了一堆链接错误。后来查资料才知道,msvc2017的预编译包是用VS2017的编译器编的,虽然微软说ABI兼容,但某些C++标准库的细节还是有差异。换成VS2019后问题消失。所以建议用VS2017或更新的版本配msvc2017包。
第二个坑是MinGW的gdb在调试时卡死。调试一个多线程的网络程序,gdb在某个断点处卡了十几分钟没反应。换成MSVC的cdb后秒过。后来查到一个已知问题:MinGW 7.3.0自带的gdb 8.1在Windows 10上有线程调度相关的bug。解决办法是单独下载更新的gdb替换,或者调试时用MSVC套件。
第三个坑是离线部署时漏了VC运行时。给客户部署时,程序在开发机上跑得好好的,到客户机器上报“找不到VCRUNTIME140.dll”。原因是开发机装了VS,自动带了VC运行时,客户机器没装。后来把vc_redist.x64.exe一起打包,问题解决。这个教训是:离线部署一定要在干净的虚拟机里验证。
6. 关于版本选择与长期维护的个人建议
Qt 5.12.11这个版本,我的看法是:如果你的项目已经稳定运行在这个版本上,没必要为了追新而升级。5.12 LTS的支持周期到2021年,商业支持更长,很多工业项目到现在还在用。但如果你是新项目,可以考虑5.15 LTS,它的离线包虽然官方不直接提供,但社区有维护的版本,而且对新编译器的支持更好。
MSVC和MinGW的选择上,我的经验是:Windows桌面程序优先用MSVC,因为和Windows SDK的兼容性最好,调试体验也更好。MinGW适合跨平台项目,或者依赖某些GNU工具链的库。两套都配着,根据项目需求切换,这是最稳妥的做法。
最后分享一个实用技巧:把Qt的安装目录和VS的安装目录都加到系统环境变量里,但不要加bin目录到PATH,而是用Qt Creator的套件配置来管理路径。这样可以避免不同版本Qt之间的DLL冲突。如果需要在命令行用qmake,写个批处理脚本临时设置PATH,用完就恢复,比永久改PATH安全得多。
这个环境我用了两年多,中间升级过一次VS,Qt版本一直没动。稳定压倒一切,尤其是工业项目,环境一变,测试成本太高。所以我的建议是:环境搭好后,把安装包和配置文档存档,下次换机器直接照着来,别重新折腾。