简介:面向Windows 10平台32位应用开发者的Qt5.15.12动态库编译包,基于MSVC2019构建,适合需要在Win32架构下维护或迁移项目的C++开发者使用。资源同时提供Debug与Release两种模式库,支持TLS安全通信,但不含Qt WebEngine模块,可减轻包体与编译复杂度。压缩包约360.47MB,共2000个文件,以头文件为主,涵盖Widgets、Network、Core等核心模块及OpenGL相关扩展声明,便于在工程中直接引用与配置。已有586人学习下载,可作为32位Qt项目搭建与依赖排查的参考素材,帮助读者快速定位所需头文件、理解模块划分,并配合动态库完成运行环境的部署与调试。
1. Qt5.15.12 在 Win10 上编 32 位动态库:为什么这件事值得单独写一篇
上周有个做工业上位机的朋友找我,说他手上一个老项目必须跑在 32 位进程里,因为对接的采集卡驱动只有 x86 版本,而界面层想用 Qt5.15.12 重写。他以为装个 Qt 就能直接编,结果折腾两天,编出来的 DLL 要么是 64 位、要么缺 debug 版、要么链接时一堆 unresolved external。这不是他水平问题,是 Qt 在 Windows 上编 32 位动态库这件事,坑集中在“环境选型”和“编译配置”两个环节,官方文档不会把每一步的失败现象写给你看。
这篇就围绕 Qt5.15.12 + Windows10 + 32 位动态库这条线,把从装工具链、配 configure 参数、编出 DLL、到验证位数和依赖的完整流程拆开。适合两类人:一是被 32 位驱动或老系统绑死、不得不用 x86 的从业者;二是想搞清楚 Qt 源码编译到底在干什么、以后遇到版本切换不慌的开发者。读完你应该能自己从源码编出一套可用的 32 位动态库,并且知道哪几个参数改了就翻车。
2. 编译前的选型与工具链:为什么必须是 MSVC 而不是 MinGW
2.1 32 位动态库的两种路线,先想清楚再动手
Qt 在 Windows 上编 32 位,工具链无非两条:MSVC 和 MinGW。很多人图省事用 MinGW,因为安装包自带、不用装 Visual Studio。但如果你的目标是“动态库给别的 32 位程序调用”,尤其是对方是 VS 工程或者要跟 C++ 接口混编,MinGW 编出来的 DLL 在 ABI 层面跟 MSVC 不兼容,C++ 类、STL 容器跨编译器传递基本是灾难。血泪经验是:只要下游有一方用 MSVC,你就老老实实走 MSVC 路线,别给自己埋雷。
MSVC 路线的前提是装对 Visual Studio 版本。Qt5.15.12 官方支持的编译器里,MSVC2019 是稳妥选择,32 位对应的是x86工具集,不是x64。这里第一个容易翻车的点:很多人装了 VS2019 但只勾了“使用 C++ 的桌面开发”里的默认组件,结果vcvarsall.bat调x86时报找不到编译器。正确做法是在 VS Installer 里确认勾选了 MSVC v142 生成工具(x86 和 x64 都要),以及 Windows 10 SDK。
工具链确认可以用一条命令验证,别急着编 Qt:
:: 打开 "x86 Native Tools Command Prompt for VS 2019" :: 或者手动初始化环境 call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86 clcl输出里如果显示的是x86版本、版本号是 19.2x,说明 32 位编译器就位。如果显示 x64,说明你进错了命令提示符或者vcvarsall参数写成了x64。这一步看着简单,但后面 configure 报“无法检测编译器”十有八九是这里没对。
2.2 源码、路径与依赖:三个不能带空格的硬约束
Qt5.15.12 的源码包从官方归档拿qt-everywhere-src-5.15.12.zip或.tar.xz都行,解压后目录里应该有configure.bat、qtbase、qtsvg这些。这里有个老生常谈但每年都有人踩的坑:源码路径、编译输出路径、安装路径,三者都不能有空格和中文。Windows 下C:\Users\张三\Desktop\qt source这种路径,configure 阶段可能勉强过,到 nmake 阶段某个子模块的路径拼接就断了,报错信息还特别隐晦,比如找不到某个.pri文件。
我一般会固定成这样的结构,干净利落:
D:\qt-build\ ├── src\ # 解压后的 qt-everywhere-src-5.15.12 ├── build\ # 影子编译目录,configure 在这里跑 └── install\ # 最终安装目录影子编译(shadow build)是必须的,别在源码目录里直接 configure,否则编完想换参数重编时,残留的 Makefile 和中间文件会让你怀疑人生。依赖方面,Qt5.15 编动态库本身不需要额外装 OpenSSL、ICU 这些,除非你要开对应特性;默认配置下 Windows 10 SDK 自带的头文件和库够用。如果你打算开-openssl,那要提前准备好 32 位的 OpenSSL 库并指定路径,这个后面参数章节再说。
2.3 configure 参数逐条拆:哪些必须写,哪些写了会出事
进入D:\qt-build\build,用刚才那个 x86 命令提示符跑 configure。下面这套是我在 32 位动态库场景下验证过多遍的配置,逐条解释:
D:\qt-build\src\configure.bat ^ -prefix D:\qt-build\install ^ -platform win32-msvc ^ -debug-and-release ^ -shared ^ -opensource ^ -confirm-license ^ -nomake examples ^ -nomake tests ^ -no-opengl ^ -qt-zlib ^ -qt-libpng ^ -qt-libjpeg-platform win32-msvc是核心,它决定了目标架构是 32 位;如果你写成win32-msvc2019之类,要看对应 mkspec 是否存在,5.15.12 里win32-msvc是通用入口,实际编译器由当前环境变量决定,所以前面vcvarsall x86不能省。-shared明确要动态库,对应生成.dll和.lib;-debug-and-release同时出 debug 和 release 两套,工业项目经常 debug 版调试、release 版交付,分开编两次太浪费时间。-nomake examples -nomake tests是省时间的关键,全量编 examples 能多花一两个小时,对只要库的人毫无意义。
-no-opengl这条要单独说:如果你的 32 位程序不需要 OpenGL 渲染(很多工控界面确实不需要),关掉能避开一堆显卡驱动相关的编译依赖;但如果你的界面用了 Qt Quick 或者 QOpenGLWidget,这条就不能加,否则运行时报找不到上下文。-qt-zlib这类是让 Qt 用自带的第三方库,避免去系统里找,32 位环境下系统库路径容易混进 64 位版本,用自带的更稳。
configure 跑完会打印一份摘要,重点看三行:Build type是不是debug and release、Architecture是不是x86、Shared是不是yes。这三行不对,后面全白搭。
3. 从 nmake 到 DLL:编译、安装与位数验证
3.1 编译与安装:jom 还是 nmake,以及中断了怎么办
configure 成功后,编译命令二选一。nmake是 VS 自带,稳但慢;jom是 Qt 官方推荐的多核 make 替代,快很多,需要单独下载放到 PATH 里。我一般用 jom:
:: 在 build 目录下,确保仍是 x86 环境 jom -j8 jom install-j8是并行任务数,按你 CPU 核数给,别贪多,32 位编译某些模块内存吃得凶,开太大反而容易在链接阶段被系统杀掉进程。jom install会把编好的库、头文件、工具按-prefix指定的路径铺好。如果中途断了(断电、误关窗口),重新进 x86 环境、回到 build 目录再跑一次jom即可,make 体系会跳过已完成的目标;但如果你改过 configure 参数,务必先jom distclean或者干脆删掉 build 目录重来,残留配置是玄学错误的温床。
安装完成后,D:\qt-build\install\bin下应该能看到Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll这些,lib下是对应的.lib导入库。注意 debug 版文件名带d后缀,比如Qt5Cored.dll,两套并存是正常的。
3.2 验证位数与依赖:别等交付了才发现是 64 位
编完第一件事不是写代码,是验证产物到底是不是 32 位。最直接的办法是用 dumpbin:
dumpbin /headers D:\qt-build\install\bin\Qt5Core.dll | findstr machine输出里如果是machine (x86),说明是 32 位;如果是machine (x64),那你前面某一步环境串了,常见原因是 configure 时用的命令提示符其实是 x64 的,或者 PATH 里混进了别的编译器。这个检查我建议对Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll各跑一遍,别只查一个。
依赖检查同样用 dumpbin:
dumpbin /dependents D:\qt-build\install\bin\Qt5Core.dll正常情况下它依赖KERNEL32.dll、USER32.dll、msvcrt或VCRUNTIME140.dll这类系统库。如果看到依赖里出现了某个你机器上特定路径的 DLL,说明编译时链接了不该链接的东西,换台机器部署就会缺库。Qt 官方动态库在 Windows 上通常还依赖platforms\qwindows.dll这个插件,部署时plugins\platforms目录要跟着 exe 走,这是另一个高频翻车点,后面避坑章节细说。
3.3 用最小工程验证:能编过不等于能用
库编出来了,拿一个最小 Qt Widgets 工程验证链接和运行。用 qmake 建个main.cpp:
#include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label("32-bit Qt5.15.12 OK"); label.show(); return app.exec(); }配套.pro文件:
QT += core gui widgets TARGET = bitcheck TEMPLATE = app SOURCES += main.cpp用刚编出来的 qmake 生成 Makefile,注意要用install\bin\qmake.exe,并且仍在 x86 环境里:
D:\qt-build\install\bin\qmake.exe bitcheck.pro nmake编出来的 exe 再用dumpbin /headers bitcheck.exe | findstr machine确认是 x86,然后直接双击运行。如果窗口能弹出来,说明动态库链接、插件加载这条链路是通的;如果报“无法定位程序输入点”或者“找不到 Qt5Core.dll”,先查 PATH 和 exe 同目录有没有把 DLL 拷过去。这一步别省,我见过库编得没问题、但 qmake 用错版本导致链接到系统里另一套 Qt 的情况,最后查了半天。
4. 避坑与排查:五条真实踩过的记录
4.1 现象:configure 报 “Cannot detect the compiler”,但 cl 明明能用
原因通常是命令提示符环境不对。vcvarsall.bat x86必须在同一个cmd 窗口里先执行,再跑 configure;如果你开了新窗口、或者用 PowerShell 跑 bat,环境变量不会继承。另一个可能是 VS 安装时没勾 x86 工具集,vcvarsall x86静默失败但没报错。解决:在 cmd 里先call vcvarsall.bat x86,再where cl确认路径指向Hostx86\x86目录,然后同窗口继续 configure。
4.2 现象:nmake 编到一半报 “fatal error C1060: 编译器堆空间不足”
32 位编译器本身有地址空间限制,并行开太大或者某个模块模板展开过深就会撞上。原因不一定是内存不够,而是 32 位 cl.exe 的堆上限。解决:把jom -j8降到-j4甚至-j2,单独重跑失败模块;如果还不行,在 configure 时加-no-pch关掉预编译头,能降低单次编译的内存峰值,代价是编译慢一些。
4.3 现象:程序在开发机跑得好好的,拷到目标机报 “This application failed to start because no Qt platform plugin could be initialized”
这是部署时插件没带。Qt 动态库运行时要去 exe 同目录或QT_PLUGIN_PATH找platforms\qwindows.dll,只拷Qt5Core.dll这些是不够的。原因是你只复制了 bin 下的 DLL,没复制plugins目录。解决:把install\plugins\platforms\qwindows.dll按platforms\子目录结构放到 exe 旁边;更省事的做法是用windeployqt.exe(install\bin 下有 32 位版)对 exe 跑一遍,它会自动补齐插件和依赖,但注意 windeployqt 也要用 32 位那个,别拿错。
4.4 现象:链接时报 “unresolved external symbol”,符号名带@@QAE之类
这是 32 位和 64 位库混链的典型症状,或者 debug/release 混用。原因可能是.lib路径里同时有 x86 和 x64 的库,链接器先找到了错的;也可能是工程配了 release 却链了带d后缀的 debug 库。解决:在 VS 工程里检查附加库目录,确保只指向install\lib这一处;用dumpbin /headers对.lib对应的 DLL 再确认一次位数;debug 配置链Qt5Cored.lib,release 链Qt5Core.lib,别交叉。
4.5 现象:编译成功但运行崩溃在QApplication构造,无具体报错
这种黑匣子问题常见于插件路径冲突:机器上装了别的 Qt 版本,运行时先加载了那套的qwindows.dll,跟当前 DLL 版本不匹配。原因是 PATH 或系统里存在多个 Qt 的 bin 目录。解决:用 Process Monitor 看进程加载了哪个路径的 Qt5Core.dll 和 qwindows.dll;临时把 PATH 里其他 Qt 路径去掉;部署时尽量让 exe 同目录的 DLL 优先,Windows 的 DLL 搜索顺序里 exe 所在目录优先级高于 PATH,把依赖拷到 exe 旁边是最稳的隔离手段。
5. 进阶技巧:把 32 位 Qt 编译做成可复现的批处理
编一次 Qt 要几十分钟,换台机器或者换版本又要重来,靠记忆敲参数迟早出错。我的习惯是把整个流程固化成批处理脚本,参数集中在一个地方改,这样下次编 5.15.x 的其他小版本或者切 debug-only 都只是改几行。下面这个build_qt32.bat是我常用的骨架:
@echo off setlocal :: ===== 可改参数区 ===== set QT_SRC=D:\qt-build\src set QT_BUILD=D:\qt-build\build set QT_INSTALL=D:\qt-build\install set VS_VCVARS=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat set JOM_JOBS=4 :: ===================== :: 初始化 32 位编译环境,失败则直接退出 call "%VS_VCVARS%" x86 if errorlevel 1 ( echo [ERROR] vcvarsall x86 failed exit /b 1 ) :: 清理旧构建目录(按需注释掉以增量编译) if exist "%QT_BUILD%" rmdir /s /q "%QT_BUILD%" mkdir "%QT_BUILD%" cd /d "%QT_BUILD%" :: configure,参数与正文一致 call "%QT_SRC%\configure.bat" ^ -prefix "%QT_INSTALL%" ^ -platform win32-msvc ^ -debug-and-release ^ -shared ^ -opensource ^ -confirm-license ^ -nomake examples ^ -nomake tests ^ -no-opengl ^ -qt-zlib ^ -qt-libpng ^ -qt-libjpeg if errorlevel 1 ( echo [ERROR] configure failed exit /b 1 ) :: 编译并安装 jom -j%JOM_JOBS% if errorlevel 1 ( echo [ERROR] build failed exit /b 1 ) jom install if errorlevel 1 ( echo [ERROR] install failed exit /b 1 ) :: 自动验证核心 DLL 位数 for %%f in (Qt5Core.dll Qt5Gui.dll Qt5Widgets.dll) do ( echo [CHECK] %%f dumpbin /headers "%QT_INSTALL%\bin\%%f" | findstr /i "machine" ) echo [DONE] Qt 32-bit build finished at %QT_INSTALL% endlocal脚本里几个设计点值得说。if errorlevel 1在每个关键步骤后做短路,避免 configure 失败还继续 nmake 浪费时间;rmdir /s /q那行默认清空构建目录,保证可复现,如果你要增量编译就注释掉,但改过参数时千万别增量。最后的for循环自动对三个核心 DLL 跑 dumpbin,把“验证位数”从人工检查变成流程的一部分,这一步是我踩过 4.2 和 4.4 之后加的,从那以后每次编完先看这三行输出,machine (x86)全绿才往下走。
还有一个进阶用法:如果你只需要 debug 版做联调,把-debug-and-release换成-debug,编译时间能砍掉近一半;反过来交付前再跑一次 release-only。两套分开编、分开装到不同 prefix,比一套混装更不容易在链接阶段拿错库。另外,-no-opengl在需要 Qt Quick 的项目里要去掉,去掉后如果编译报 OpenGL 头文件缺失,检查 Windows 10 SDK 是否完整安装,这个依赖是 SDK 带的,不是 Qt 自己的。
最后说个习惯:每次编完,我会把configure的摘要输出和 dumpbin 的位数检查结果一起存到install\build-info.txt,下次有人问“这套库到底什么配置”,直接甩文件,不用回忆。Qt 源码编译这件事,参数就那些,难的是每次都确认环境没串、位数没混、插件没漏。希望帮到你。
本文还有配套的精品资源,点击获取