Qt 5.15.12 Windows 10下编译32位动态库完整指南

简介:面向Windows 10 32位应用开发的Qt 5.15.12动态库编译包,基于MSVC2019编译器构建,专为需要维护32位兼容性、或希望避开复杂编译配置的C++开发者准备。压缩包内共2000个文件,以Qt头文件(.h)为主,覆盖Core、Widgets、Network、GUI等核心模块的公共接口声明,整体大小约360.47MB;同时提供Debug与Release两种模式,分别用于调试期错误定位和发布期性能优化。动态库方式支持多个应用程序在运行时共享同一份代码,有效减少内存占用与重复拷贝,也便于按模块独立更新和维护。该版本未集成Qt WebEngine,但完整保留TLS加密支持,既缩小了库体量,又保障了网络传输过程中的数据安全。目前已有586人学习下载,可作为32位Qt环境配置、接口文档查阅以及旧项目迁移时的实用参考;借助这批头文件,开发者可以快速核对类定义与函数签名,理清模块依赖关系,在Windows 10 32位系统上更顺畅地构建轻量级、可维护的Qt应用程序。

1. Qt 5.15.12 在 Windows 10 下编译 32 位动态库:被很多人跳过却值得做的一件事

如果你手上还有老项目需要在 32 位 Windows 环境下运行,或者合作的某公司系统至今保留着 Win10 32 位终端,你一定遇到过这样的尴尬:新装的 Qt 预编译包是 64 位,跑几年前的 Win32 程序直接报“不是有效的 Win32 应用程序”。Qt 5.15.12 是 Qt 5 LTS 补丁序列里比较靠后的一个版本,它补了不少 5.15 早期版本在 Windows 上的问题,同时又保留了 Qt Widgets / Qt QML 的老接口,适合拿来做 32 位动态库的再编译。这篇文章记录的是我从空环境开始,把 Qt 5.15.12 源码编译成 32 位 DLL 动态库的完整过程,包括工具链选型、configure 参数、编译命令和四次翻车之后的排错思路。适合要把旧工程迁到新 Qt 版本、又必须继续支持 32 位系统的开发者;看完你能直接照着敲命令,不需要再去翻那堆零散的文档。

2. 编译工具链选型与 32 位环境搭建:MinGW 还是 MSVC

2.1 两条路线,一个终点:动态库与受控环境的差别

Qt 在 Windows 上做 32 位编译,工具链基本只有两选:MinGW(准确说是 MinGW-w64 的 i686 目标)和某个商业 IDE 自带的 MSVC 工具链。这两者的差别不在 Qt 本身,而在最终交付物依赖的运行环境和编译器的二进制接口。

MSVC 路线产出的 DLL 依赖 UCRT 和 VC 运行库,你的 Qt 程序部署到干净机器上时,通常要额外带上运行库安装包或者用部署工具把 msvcp140.dll 之类一起拷进应用目录。MinGW 路线用的是 GNU 工具链,产出的程序依赖 libgcc_s_dw2-1.dll、libstdc++-6.dll、libwinpthread-1.dll,这些 DLL 体积不大,windeployqt 部署时也会自动带出来,对老系统环境的侵入相对小。

如果只看“能不能编译出 32 位 Qt”,两条路都通。我的实际建议是:机器上已经装了商业 IDE、且后续项目都要用它的调试器时,走 MSVC;如果你只是想尽快拿到 32 位的 Qt5 动态库,Windows 又没有额外要求使用某个编译器的 ABI,MinGW 是更省事的一条路。以下主线就用 MinGW 的 32 位目标做演示,MSVC 的环境准备在 2.3 里单独列。

另外要提前想清楚“动态库”这个要求。Qt 默认 configure 出来的就是动态库,也就是每个模块一个 DLL,外加对应的小导入库文件。只有在 configure 时明确加了-static才会产出静态库。所以发布会上你只要别手滑加-static,最终结果就是带.dll的发布包。这一点后面在 configure 参数里会再讲。

2.2 安装 32 位 MinGW-w64 工具链:编译器与 make 的版本匹配

MinGW-w64 这个项目虽然名字里有 64,但它的 32 位目标同样存在,安装包通常在“i686”目录下。很多人翻车就是因为下载了名字里带 x86_64 的编译器,编译出来的 Qt 一看却是 64 位 DLL。

我一般把工具链单独放一个目录,比如D:\work\my_toolchain\mingw32,避免和装 Qt 预编译包自带的 MinGW 混在一起。解压后依次检查三个东西:gcc 目标架构、g++ 版本、mingw32-make 是否存在。

set PATH=D:\work\my_toolchain\mingw32\bin;%PATH% gcc -v g++ -v mingw32-make -v

第一行命令执行后,注意看输出里“Target”字段。如果是i686-w64-mingw32,说明当前编译器是以 32 位为目标的;如果显示x86_64-w64-mingw32,那就是 64 位工具链,必须换掉。Qt 5.15.12 源码要求编译器支持 C++17,gcc 至少要到 7 以上,建议直接用和官方 Qt 5.15 离线安装包配套的 MinGW 8.1 版本,省得 configure 阶段因为语法特性报错。

这里要说一下mingw32-make和make的关系。MinGW-w64 发布的二进制里,make 的名字往往叫mingw32-make.exe,就是为了避免和同目录下的 Unix 工具冲突。编译 Qt 时你用它,不要习惯性敲make。

2.3 MSVC 2019 作为备选:vcvarsall.bat 与 x86 参数

如果你的机器上有 2019 或更新版本的商业 IDE,用它的 32 位命令提示符也行。关键是不要直接打开普通的 cmd 就去跑 configure,那样 cl.exe、nmake 都不在 PATH 里,configure 会报“compiler cannot create executables”。

我习惯的做法是用工具链安装目录里自带的vcvarsall.bat脚本,后面跟x86,然后才在当前会话里调用 cl 和 nmake。

call D:\myide\VC\Auxiliary\Build\vcvarsall.bat x86 cl nmake /?

注意参数是x86,不是amd64。32 位目标对应x86,x64对应的是 64 位目标。执行完 vcvarsall 后,cl 的输出版本信息能正常显示,说明当前 cmd 会话已经是 32 位 MSVC 环境。之后 configure 时要用-platform win32-msvc2019(根据你实际的 IDE 版本选择后缀),而不是-platform win32-g++。

MSVC 路线还有一个常见问题:默认的nmake是单线程的,编译 Qt 这种大工程会很痛苦。常见的做法是下载一个叫jom的并行构建工具,它兼容 nmake 的 Makefile,但能利用多核并行编译。如果你手头有这个工具,编译阶段用 jom 替代 nmake 即可。

3. configure 与源码编译:一条完整命令行跑出 32 位 DLL

3.1 源码解压与目录约定:路径是第一个隐藏条件

Qt 5.15.12 的源码包解压后,目录名是类似于qt-everywhere-src-5.15.12这样的一整包,里面同时包含了源码和构建系统文件。解压路径和安装前缀是两个概念:源码目录只负责构建过程,安装前缀是 make install 之后 Qt 库实际落盘的位置。

我建议把源码放一个尽量短的纯英文路径。不要放在带空格、带中文的目录下,虽然很多情况下也能编,但 configure 生成的 Makefile 里会含路径变量,某些模块会因为这些特殊字符报出莫名其妙的文件找不到错误。下面是我在这台模拟项目X机器上的目录布局:

C:\work\qt-everywhere-src-5.15.12 # 源码根目录,只读不解 D:\work\qt-out\5.15.12-mingw32 # make install 后的安装前缀

前缀目录D:\work\qt-out\5.15.12-mingw32就是以后 qmake、windeployqt、头文件和库文件的位置。源码目录建议保留干净,不要往里面塞东西,因为如果编译到一半失败需要重新 configure,源码树足够干净能省不少麻烦。

3.2 configure 命令的参数拆解:关键开关与含义

确认工具链没问题后进入源码根目录,执行 configure.bat。MinGW 路线下的完整命令大致是这样:

cd /d C:\work\qt-everywhere-src-5.15.12 set PATH=D:\work\my_toolchain\mingw32\bin;%PATH% configure.bat ^ -opensource -confirm-license ^ -release ^ -shared ^ -prefix D:\work\qt-out\5.15.12-mingw32 ^ -platform win32-g++ ^ -skip qtwebengine ^ -skip qtwebview ^ -nomake examples -nomake tests ^ -mp

先解释几个必选项。-opensource -confirm-license是确认采纳开源许可,不写这个会在配置中途停下来要你手动输入;-release表示只编 release 版,不加这个默认可能是 debug 和 release 都编,时间和磁盘占用翻倍;-shared是告诉构建系统输出动态库,对应我们标题里的“动态库”需求;-prefix指定最终 make install 的安装目录。

-platform win32-g++是 MinGW 路线绕不开的参数,它告诉 Qt 构建系统“我要用 GNU 工具链”。后面跟的^是 Windows cmd 的续行符。-skip qtwebengine和-skip qtwebview建议加上,这两个模块编译时间长、依赖多,如果不做基于 Chromium 的界面压根用不上;-nomake examples -nomake tests同样是为了缩减编译工作量。-mp让编译器在支持多核的机器上开启多进程编译。

3.3 编译过程:从 configure 到 make install

configure 正常结束后,屏幕最后会出现一段当前构建配置摘要,列出接下来会构建哪些模块,比如 qtbase、qtdeclarative、qtmultimedia 等。这时候再执行编译,MinGW 工具链对应的命令是:

mingw32-make -j8

-j8中的 8 是并行执行的编译任务数,通常设置为 CPU 物理核心数的 1.5 到 2 倍。如果不想手算,可以直接写mingw32-make -j%NUMBER_OF_PROCESSORS%,Windows 系统变量里一般存了当前处理器的逻辑核心数。

这里有个容易被忽略的操作:不要把编译输出直接打到屏幕上,一是滚动太快看不出问题,二是后面排查时没有日志可翻。我一般先重定向一份日志:

mingw32-make -j8 > build.log 2> build.err

编译完成后再执行安装,把产物放到前面指定的前缀目录:

mingw32-make install > install.log 2> install.err

install 阶段主要是把 DLL、lib、头文件、mkspec 和工具拷贝到D:\work\qt-out\5.15.12-mingw32下。整个过程在 8 核机器上通常要一小时到数小时不等,取决于你保留的模块数量。编译 Qt 不像编译普通应用,期间最好别开太多重型程序,内存不足时编译器子进程会被系统杀掉,日志里就会莫名出现“killed”或者“out of memory”字样。

3.4 编译产物解析:DLL、导入库与 bin 目录

make install 完成后,进入安装前缀目录,你会看到一个比较熟悉的 Qt 布局:

D:\work\qt-out\5.15.12-mingw32 ├── bin │ ├── qmake.exe │ ├── windeployqt.exe │ └── Qt5Core.dll ... ├── lib │ ├── libQt5Core.a # MinGW 风格的导入库 │ └── cmake ... ├── include └── mkspecs

其中lib下面的libQt5Core.a不是静态库,而是导入库(import library)。动态库的导出函数信息记录在 DLL 里,导入库的作用是链接时告诉链接器“这个符号在哪个 DLL 里、序号是多少”。MinGW 工具链产出的导入库命名是libQt5Core.a,而同路径下生成的Qt5Core.dll才是运行时真正加载的文件。这也就是 windeployqt 部署时既要带 DLL、又要把导入库链接进可执行文件的原因。

你可以抽查一下 DLL 的目标架构,确认确实是 32 位。MinGW 工具链没有 dumpbin,可以这样确认:

objdump -f D:\work\qt-out\5.15.12-mingw32\bin\Qt5Core.dll | findstr /i "file format"

输出如果显示pei-i386,说明是 32 位 PE 格式,目标架构对了;要是显示pei-x86-64,说明工具链选错,回去换 i686 版本再编。

4. 避坑记录:32 位 Qt 编译与运行中的五次排错

4.1 编出来的 Qt5Core.dll 一看是 64 位

现象:configure 和编译都正常通过,install 也顺利,结果检查 Qt5Core.dll 的格式时发现是 64 位,32 位程序加载它直接报0xc000007b。

原因:工具链下载错了。MinGW-w64 的压缩包分 i686 和 x86_64 两套,i686 才是 32 位目标;部分下载站把名字简化成“mingw32”包装 64 位编译器,骗过了人眼。

解决:编译前先用gcc -v看输出里的 Target,必须是i686-w64-mingw32,不能只凭目录名字判断。如果不确认当前 PATH 里先命中哪个版本,执行where gcc把实际路径打出来。

4.2 编译到中段报 “cannot find -lstdc++”

现象:Qt 编译到某个模块的链接阶段,屏幕输出cannot find -lstdc++,定位不到标准 C++ 库。

原因:-lstdc++是 GNU C++ 库的链接名,找不到它说明g++的库搜索路径没配置好。在一些精简的 MinGW 安装包里,libstdc++-6.dll 存在但对应的导入库libstdc++.a缺失,或者工具链的 lib 目录在 PATH 之外。

解决:检查D:\work\my_toolchain\mingw32\lib下有没有libstdc++.a;没有的话回到完整的编译器分发包里找。另外确认 PATH 里gcc.exe与g++.exe在同目录,不能混用两个不同版本的 bin 目录。

4.3 链接时报 “Unsupported or malformed archive”

现象:用 MSVC 工具链编译 Qt 时,链接阶段突然报LNK1103或 GCC 侧中文提示“不支持的或格式错误的存档”,怀疑是导入库文件损坏。

原因:多半是把 MinGW 生成的.a导入库拿给 MSVC 链接器用了,或者反过来把.lib拿给 MinGW 的链接器用。两种工具链的导入库格式并不完全兼容,MSVC 用的是 COFF 格式的.lib,MinGW 用的是 GNU 格式的.a。

解决:按工具链分类隔离开导入库文件。如果项目里同时装了 Qt5 的 MinGW 版和 MSVC 版,链接参数里要用与编译器同源的 qmake,不能跨编译器指定-L路径。检查实际链接命令里的LIBS参数,确认指向前缀目录的lib而不是另一个前缀。

4.4 程序拷到干净机器上运行提示缺少 api-ms-win-crt-runtime-l1-1-0.dll

现象:Qt 程序在开发机上正常跑,复制到没有安装过任何运行库的 Win10 32 位终端上,启动时弹窗说找不到 API 集 DLL。

原因:MSVC 工具链编译出来的 Qt 依赖通用 C 运行时,API 集 DLL 属于系统组件。老版本 Win10 或未开启自动更新的终端上,UCRT 组件不完整。MinGW 路线一般不带这个坑,MSVC 路线基本躲不开。

解决:部署阶段使用部署工具时加上--compiler-runtime参数,强制把 VC 运行库对应的 DLL 一并复制到程序目录。如果目标机器是 Win10 早期版本,也可以直接在资源包里带上 UCRT 更新包,安装一次就好。

4.5 windeployqt 跑完程序还是提示缺少 Qt5Core.dll

现象:用 windeployqt 部署之后,双击程序仍然提示缺少Qt5Core.dll。

原因:windeployqt 是依靠调用目标程序所在路径的 Qt 来定位依赖的。如果你 PATH 里先命中了一个 64 位 Qt 的 bin 目录,部署的结果很可能是带出了一堆 64 位 DLL,或者部署进程自己崩溃。

解决:先执行set PATH=D:\work\qt-out\5.15.12-mingw32\bin;%PATH%再执行windeployqt,并且部署完用 4.1 里的手段抽查Qt5Core.dll是否与目标应用同为 32 位。更稳的做法是调用带完整路径的windeployqt.exe,彻底避开 PATH 干扰。

5. 把编译好的 Qt 固化成可持续用的工具链:验证与后续用法

编译完成的 32 位 Qt 动态库不仅是这一次的产物,它还能继续作为工具链被重复使用。安装目录下的 qmake、windeployqt 都是独立可执行程序,只要整个前缀目录不被破坏,后续工程甚至不需要重新编译 Qt。

我一般会让新工程走一遍“验证三连”:先用前缀目录下的 qmake 生成 Makefile,再用它编一个空的 Win32 Widgets 程序,最后用 windeployqt 部署并检查 DLL 位深。

set PATH=D:\work\qt-out\5.15.12-mingw32\bin;%PATH% qmake -v windeployqt --release --no-translations D:\test\app32.exe objdump -f D:\test\app32.exe | findstr /i "file format"

这里qmake -v输出中会包含一个带Qt 5.15.12的版本行,同时还能看到编译器说明是MinGW还是MSVC;--no-translations表示跳过翻译文件,可以缩短部署时间;最后一条命令用于验证 app 文件头里是pei-i386而不是pei-x86-64。部署目录下会多出一批 32 位 DLL,把它们和 exe 一起复制到干净的 Win10 32 位终端跑一遍,确认无运行库报错后再交付。

从那以后我每次拿到新环境的 32 位 Qt 需求,都强制先走一遍这套“源码目录、工具链目标、前缀目录”的验证流程。编译 Qt 本身没什么玄学,绝大多数问题都出在工具链混用和路径指向错误上。希望这篇记录能帮你少走一次弯路。

本文还有配套的精品资源,点击获取

相关新闻

机械臂正运动学入门:从旋转矩阵到DH参数解析

机械臂正运动学入门:从旋转矩阵到DH参数解析

机械臂这个东西,入门时最容易迷惑的不是电机怎么转,而是“我要它去的点”和“它实际到的点”之间到底隔着什么。我刚开始折腾机械臂时,以为把每个舵机角度调到某个值就行,结果想让它末端走一条直线,它硬是在空中画了个…

2026/10/21 7:59:12 阅读更多 →
Java设计模式速通:场景+实战,快速掌握核心模式

Java设计模式速通:场景+实战,快速掌握核心模式

不是每一行代码都值得背下来,但设计模式是少数值得花时间想清楚的东西。尤其是Java生态里,框架源码、中间件、业务系统到处都嵌着这些模式,看不懂它们,读源码就像看天书;看懂了,重构和扩展的底气完全不一样…

2026/10/21 7:59:12 阅读更多 →
zzcms8.3建站系统实战:环境搭建、代码审计与二次开发改造指南

zzcms8.3建站系统实战:环境搭建、代码审计与二次开发改造指南

简介:ZZCMS 8.3 是一套开源内容管理系统源码,面向希望入门代码审计与 PHP 架构的开发者、安全学习者及建站人员。它既可用于搭建动态网站,也是一份可动手剖析的实战样本,帮助读者在真实项目中理解安全编码与设计模式。压缩包为 zi…

2026/10/21 7:59:12 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/21 9:32:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/21 9:31:32 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →