ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Qt 5.15.12 32位动态库编译实战:工具链匹配与configure参数详解

Qt 5.15.12 32位动态库编译实战:工具链匹配与configure参数详解 简介Qt5.15.12 32位动态库版本专为Windows 10平台上的Qt应用开发准备基于MSVC2019构建适用于需要兼容32位系统或维护旧工程的开发者。包内包含2000个头文件涵盖Widgets、Network、Core等核心模块并附带对应的动态链接库与库文件同时支持Debug和Release模式便于调试与部署。该版本未集成Qt WebEngine但完整支持TLS安全通信可满足不依赖Web组件的桌面应用开发场景。压缩包整体约360.47MB已有584人在线学习浏览。借助此套库文件开发者可直接配置32位Qt开发环境省去自行编译的耗时与踩坑快速启动GUI或网络应用项目。 先说结论Qt 5.15.12 这套源码包在 Windows 10 上折腾 32 位动态库难点不在“编译”本身而在“工具链匹配”和“configure 参数”。我试过 MinGW 和 MSVC 两条路线也踩过不少坑这篇直接把流程、参数和排查经验摊开来说。很多人拿到 Qt 第一反应是用在线安装器直接装装上确实快但开源版在线安装器默认只给 64 位预编译包想要 32 位动态库就得自己编。更何况像 5.15.12 这个版本号正常开源通道能下载到的源码其实是 5.15.2 之后就不再公开更新能拿到 5.15.12 基本意味着你走的是商业更新渠道或者特殊来源。不管来源是哪既然要自己编译那这篇就是给你准备的。这篇内容适合这几类人被 32 位旧项目绑住手脚的 C 开发者、需要给客户交付 32 位 DLL 的嵌入式/工业软件工程师、以及想在 Win10 上构建一套 Qt 32 位运行库做二次开发的同学。读完你不仅能编译出一套能用的 Qt 5.15.12 32 位动态库还能知道编译过程中那些莫名其妙的报错到底怎么解决。1. 为什么要自己编译 32 位 Qt 动态库1.1 版本溯源5.15.12 到底算什么Qt 5.15 是 Qt 5 系列里的 LTS长期支持版本官方策略是 LTS 版本持续发布补丁但补丁周期和发布渠道有讲究。开源用户能免费拿到的源码通常停在 5.15.2之后的补丁版本 5.15.3 到 5.15.12 主要面向商业授权用户。我的理解是你手上既然有 5.15.12 的源码包那大概率是公司买过 Qt 商业授权或者从其他渠道拿到的源码。这个版本号本身不需要过度解读它就是 5.15 分支的最后一个补丁版本修复了之前一大批已知 bug尤其是 QtWebEngine、QML 相关的问题。但对于动态库编译这件事来说版本号的差异影响不大configure 流程和 5.15.2 几乎完全一样。真正需要关心的是为什么非要用 32 位。在新项目里64 位已经是绝对主流但现实世界里大量旧系统、旧驱动、旧动态库还在用 32 位。比如很多工业相机 SDK、指纹识别 SDK、老版本数据库驱动只提供 32 位 DLL你主程序哪怕是 64 位想进程内调用这些库整个进程架构就得是 32 位。这就是你绕不开 32 位 Qt 的最直接理由。1.2 动态库与静态库为什么 DLL 方案更实用编译 Qt 时有“动态库shared”和“静态库static”两个选项默认就是动态库。动态库的优点是显而易见的多个程序可以共享同一份 Qt5Core.dll、Qt5Widgets.dll升级时不重新编译整个程序发布时体积也小几十个 DLL 远比一个几十 MB 的 exe 好管理。更重要的是Qt 采用 LGPL 授权动态链接可以让你合法的闭源发布商业软件静态编译则意味着你的 exe 里嵌了 Qt 源码的编译产物需要遵守更严格的许可证义务。所以如果只是内部工具静态库也行但给客户交付或者作为公共 SDK动态库方案永远是首选。另外要注意Windows 下“动态库”听到最多的是 DLL但在 MinGW 工具链里还有个概念叫“导入库import library”也就是编译 Qt 时会在 lib 目录下生成一批 .a 文件MSVC 下是 .lib。链接时编译器用的正是这些导入库运行时才去找真正的 DLL别把 .a 和 .lib 当成库本身。一句话总结编译 32 位动态库本质上就是配置出一套 x86 架构、DLL 方案的 Qt 运行环境。配置过程中位数选错是最隐蔽、最坑的问题后面会专门讲。2. 工具链选型与环境准备2.1 MinGW 还是 MSVC一次选定的关键决策动手之前必须先定工具链两条路我都走过直接说结论。MinGW 路线用的是 GCC 编译器优点是环境轻量、不依赖 Visual Studio、配置简单下载一个 Qt 官方维护的 MinGW 8.1.0 32 位版本就够用。问题是调试体验一般GDB 对 Qt 某些类型支持不如 Visual Studio 那套好。如果你的目标只是编译出一套库自己用或者配合 Qt Creator 做开发MinGW 完全够。MSVC 路线用的是 Visual Studio 的 C 工具集优点是调试强大、性能通常比 MinGW 编译出来的稍好、与 Windows SDK 集成本身就是一家人。缺点是环境重要装 Visual Studio Build Tools而且 configure 必须在 MSVC 的命令行环境里进行如果忘了加载 x86 环境配置出来就是 64 位。我的个人倾向是如果后续项目要跟 Visual Studio 生态深度集成或者要用到 MSVC 特有的调试功能直接选 MSVC如果只是自己编译完给 Qt Creator 用MinGW 能省掉很多麻烦。下面两套命令都会给出按自己的实际需求挑一套执行。工具链版本上我强烈建议不要用最新版编译器来编译 5.15.x 源码GCC 12 以上和非常新的 MSVC 都可能导致一些兼容性问题。稳妥的组合是MinGW 用 Qt 官方仓库里的 8.1.0 32 位版本MSVC 用 Visual Studio 2019 的 x86 工具集。这套组合经过大量人验证踩坑概率最小。对比维度MinGW 路线MSVC 路线编译器GCC 8.1.0 (32位)MSVC v142 (x86)配置命令configure.bat mingw32-make先调用 vcvarsall.bat x86再 configure nmake导入库格式.a.lib调试体验一般强环境成本低高需要 VS Build Tools推荐场景Qt Creator 独立开发VS 生态集成开发2.2 环境配置的硬性要求64 位的 Windows 10 完全可以编译 32 位程序所以系统上不需要纠结关键是安装好正确的工具链依赖。整个编译过程的内容包含源码包解压后大约 7~10 GB编译中间文件会膨胀到 20 GB 以上加上安装到目标目录的产物我建议你预留至少 35~40 GB 磁盘空间。内存 16 GB 以上如果只有 8 GB编译时建议 -j4更少核数并行否则内存耗尽直接报错这会让你崩溃。编译之前还需要装两个辅助程序Perl 和 Python。ActivePerl 或者 Strawberry Perl 都可以Python 用 3.x。Qt 5.15 里的一些模块比如 QtWebEngine 的构建脚本依赖它们缺了会在 configure 阶段报错。如果不打算编译 QtWebEngine 可以加 -skip qtwebengine 跳过但我仍然建议装好 Perl因为有些小模块也会用到。下载源码包后解压务必注意一点解压路径不要带中文、不要带空格。这个老生常谈的问题每年还是坑掉一批人。路径不要有空格和中文否则后面编译时很难排查出问题。我习惯放在 D:\Qt\qt-everywhere-src-5.15.12 这种纯英文短路径下。3. 从 configure 到 install32 位动态库编译全流程3.1 configure 参数背后的逻辑编译 Qt 的核心第一步是 configure.bat这一步决定了你整个 Qt 的架构、模块、调试选项。参数很多但常用的就那几个我挑重要的说-prefix指定安装路径编译完的产物会复制到这里。比如-prefix D:\Qt\Qt5.15.12\mingw73_32后面开发环境里 Qt 版本就指向这个目录。注意 configure 时用 prefix 指定的路径以后就是你 Qt Creator 里的 Qt 版本路径写死之后尽量别移动否则一堆路径问题。-shared或者-static决定动态库还是静态库。默认就是 -shared动态库。如果看到什么奇怪版本的库默认是 static用 -shared 强制指回去。-debug-and-release会同时产出 debug 版和 release 版 DLL体积大、编译时间翻倍但开发时很方便。如果嫌慢可以只编译-release。内部调试手段丰富的人可以只 release反正大多数问题用 qDebug 打印也能定位。-opensource -confirm-license表示接受开源协议如果不加会交互式确认每次 configure 都卡在那里等输入建议直接写上。-platform参数指定目标平台。MinGW 写win32-gMSVC 从 VS 命令行环境编译时通常会自动识别为win32-msvc。32 位 MSVC 环境的关键点在于你的命令行环境必须是 x86 的因为 MSVC 工具链默认环境是 x64直接 configure 配出来的就是 64 位版本。-nomake examples -nomake tests跳过示例和测试的编译能省大量时间。-skip qtwebengine跳过 WebEngine 这个重量级模块它要下载额外的依赖、编译极其耗时非必要不编。-openssl-runtime或者-openssl-linked是配置 OpenSSL 支持。如果项目用到 HTTPS比如 QNetworkAccessManager 访问 HTTPS 接口需要编译 OpenSSL 相关模块。手头有 OpenSSL 32 位 DLL 并且希望 Qt 运行时直接加载用-openssl-runtime想链接到 libssl/libcrypto 静态库用-openssl-linked。没有这个需求就跳过后续需要时再补编也来得及。3.2 两条完整的编译命令行MinGW 路线假设你装了 Qt 官方下载的 MinGW 8.1.0路径比如D:\Qt\Tools\mingw810_32。打开命令行先设置 PATH让编译器可用然后进入源码目录set PATHD:\Qt\Tools\mingw810_32\bin;%PATH% cd /d D:\Qt\qt-everywhere-src-5.15.12 configure.bat -prefix D:\Qt\Qt5.15.12\mingw73_32 -debug-and-release -opensource -confirm-license -shared -platform win32-g -nomake examples -nomake tests -skip qtwebengine -openssl-runtime mingw32-make -j8 mingw32-make install-j8表示 8 个并行编译任务根据你 CPU 核心数调整。如果内存只有 8 GB建议降成-j4不然很容易在某个大模块编译时内存溢出导致崩溃。整个编译过程大概 1~2.5 小时取决于硬件和是否 -skip qtwebengine。MSVC 路线需要以管理员身份打开 “x86 Native Tools Command Prompt for VS 2019” 或手动加载 vcvarsall.bat。如果是 VS Build Tools手动加载的命令是call D:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat x86 cd /d D:\Qt\qt-everywhere-src-5.15.12 configure.bat -prefix D:\Qt\Qt5.15.12\msvc2019_32 -debug-and-release -opensource -confirm-license -shared -nomake examples -nomake tests -skip qtwebengine -openssl-runtime nmake nmake install注意vcvarsall.bat x86这一句少了这个参数环境就是 x64编译出来的还是 64 位版本。为啥很多人在 MSVC 下 “明明选了 32 位还是编译出 x64”十有八九就是这里出问题。configure 完成后留意最后输出的摘要会明确写 “Building Qt for: win32-msvc”以及架构是 x86如果看到 x64 而不是 x86赶紧 CtrlC 重新配置。3.3 部署与验证用 windeployqt 收尾编译安装完成后在D:\Qt\Qt5.15.12\mingw73_32\bin下能看到一排 exe 和 DLL其中最重要的有 Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll以及配套的工具windeployqt.exe、assistant.exe等。在lib目录下能找到导入库 .a 或 .lib 文件include目录下是头文件。到这里一套干净的 32 位 Qt 动态库就算建好了。验证有没有编成功最快捷的方式是打开 Qt Creator添加 Kit选择 Qt Versions 指向D:\Qt\Qt5.15.12\mingw73_32\bin\qmake.exe新建一个 QWidget 小项目构建并运行一个带按钮的窗口。如果窗口能弹出来说明动态库能正常链接和加载。但本地能跑不代表拷给别人就能跑因为你的 exe 依赖 Qt5Core.dll 等一堆 DLL。这时候用 windeployqt 处理它会自动把 exe 依赖的 Qt DLL、插件比如 platforms/qwindows.dll和运行库都拷贝到同一个目录windeployqt.exe --release --no-translations D:\build\demo.exe这里有几个细节--release要和编译时的版本对应如果项目是 debug 编的就要用--debug--no-translations可以省掉翻译文件如果是 MinGW 编译器建议再加--compiler-runtime让 windeployqt 顺便带上 libgcc_s_dw2-1.dll 和 libwinpthread-1.dll 这些 GCC 运行时 DLL不然换一台没装 MinGW 的机器程序双击后没反应。4. 常见问题与独家排查手册4.1 运行时崩溃no qt platform plugin could be initialized这个错误是 Qt 开发中最常见的坑。完整报错一般是 “qt.qpa.plugin: Could not find the Qt platform plugin “windows” in “””或者 “no qt platform plugin could be initialized, reinstalling the application may fix this problem”。原因不是没装对 Qt而是运行时找不到platforms/qwindows.dll。解决办法就是用 windeployqt 部署。如果手动拷贝记住插件目录结构是exe 同级目录下建一个platforms文件夹里面放qwindows.dll。另外务必要检查位数32 位的 qwindows.dll 配 32 位 exe64 位的配 64 位 exe混用会让程序直接无法启动。我在调试时见过很多人拿 64 位 Qt 编出来的 exe配 32 位程序折腾一天才发现是位数不对。如果你确认插件文件都在但还是报这个错那就有可能是插件文件的 DLL 依赖不全。用 Process Explorer 或者 Everything 看一下进程加载的 Qt5Core.dll 路径确认程序加载的不是系统目录里的残留版本。4.2 configure 阶段找不到 Perl 或 Python报错类似于 “Cant locate file stripped in INC” 或者直接提示找不到 Python。原因很简单Qt 源码的某些模块构建时需要 Perl/Python 执行脚本。解决办法是安装 Strawberry Perl 和 Python 3.x并确保它们加入了 PATH。如果安装了 Perl 还是报错注意一下 MSYS2 环境下可能路径问题建议直接在 cmd 下运行 configure别用 Git Bash 或者 MSYS2 shell路径解析方式不同会引发各种奇怪的找不到文件问题。4.3 编译中期语法错误与工具链版本不匹配如果你看到一堆 C 编译报错比如某个.cpp文件里的标准库类型不认识、某个模板特化失败而且你用的是最新版 GCC 12 或 MSVC 2022那大概率是工具链版本太新。Qt 5.15 的源码是 2020 年代的代码部分写法在新编译器下不再编译通过。最省心的做法是回退到我建议的版本组合MinGW 8.1.0 或 MSVC 2019。不要问为什么新编译器不能编问就是兼容性的历史包袱。若坚持用新编译器那就得自己修源码了耗时不可控不推荐。这个坑还衍生出一个常见问题是“报各种各样的宏未定义错误”比如API_EXPORT、Q_DECL_EXPORT之类。这往往不是编译器问题而是 configure 没跑完就中断了导致头文件生成不完整。老老实实重新跑一遍 configure。4.4 DLL 版本冲突与排查思路32 位程序在一台机器上同时跑多个 Qt 应用时偶尔会出现某个程序字体不对、风格怪异甚至闪退这可能是因为它加载了另一个程序目录下的 Qt5Core.dll。Windows 加载 DLL 的顺序是exe 所在目录优先于系统目录你的程序目录里如果有旧版本的 Qt5Core.dll就会覆盖其他位置的同名 DLL。排查思路很简单用 Process Explorer 打开目标进程查看 Qt5Core.dll 的路径是不是程序目录下如果不是比如是 C:\Windows\System32 下的说明你装过某个软件自带的 Qt DLL 污染了系统目录。解决方法是把程序改成免安装版确保所有 DLL 都放在 exe 同目录下或者把必要的 Qt5Core.dll 放到程序目录里优先级最高的就是 exe 同级目录。另一个很隐蔽的问题是配置 -prefix 路径时如果选的路径太深在编译安装阶段会产生路径过长问题Windows 默认路径限制是 260 个字符超过会报错。解决办法是启用 Windows 10 的 Long Path 支持或者把 prefix 路径尽量缩短。5. 32 位动态库在项目中的几个典型扩展5.1 QCustomPlot 时域转频域显示不少做采集、信号处理的朋友编译 Qt 是为了做波形显示QCustomPlot 是一个常用的单文件绘图库配合 FFT 可以做时域图和频域图的切换显示。QCustomPlot 的接入本身很简单只要把 qcustomplot.h 和 qcustomplot.cpp 加入你的工程在 .pro 里加上QT widgets printsupport即可。但需要注意QCustomPlot 内置了kissfft的实现如果你在项目里还有其他 FFT 代码尽量不要同时包含两份 kissfft否则会冲突。一个简单做法是利用 QCustomPlot 的 QCPGraph 来画原始时域曲线同时自己用 kissfft 算出频谱数据再开一个 QCPGraph 画频域曲线。32 位动态库环境下QCustomPlot 这类纯源码库不需要特殊配置但如果你要跟其他 32 位库比如采集卡 SDK混用记得把所有依赖库的位数对齐到 32 位否则会在链接或加载阶段报 “module machine type mismatch”。5.2 与第三方 32 位库协同编译编译好 32 位 Qt 动态库后后面你的项目里可能会接入各种第三方库文本编辑器可以用 QScintilla算法库可以接 onnxruntime 动态库工业视觉场景要接 Halcon 的 32 位 SDK。这些库的位数必须保持 32 位一致否则在链接时会出现 “LNK1112: module machine type x64 conflicts with target machine type x86”MSVC或者 “skipping incompatible” 之类的错误。我的习惯是给每个公共依赖库单独建一个目录比如D:\libs\onnxruntime-x86、D:\libs\halcon-x86在 .pro 或 CMake 里统一引用免得以后升级库版本时改来改去。还有尽量让第三方库和 Qt 使用同一个编译模式release 引用 release 库debug 引用 debug 库混合引用在 MSVC 下很容易因为运行库不一致而崩。实际项目里QScintilla 就特别适合做成动态库它本身编译出来就是一个 DLL放在 Qt 的 lib 目录里作为插件用这样代码更新时只要替换 DLL 而不用重编整个应用。QScintilla 的源码里也带 .pro 文件编译时注意目标位数别用错了 qmake要用 32 位的 qmake.exe。最后分享两个我在试验中沉淀下来的习惯确实能让你省掉不少麻烦。第一每次 configure 完立刻看输出摘要确认 x86/x64 和 shared/shared 的状态别等编译完了再去“考古”。第二编译的机器最好固定一个生成环境别频繁换因为编译过程中 toolchain 的自动检测结果是带路径记忆的换目录会导致以后无法增量编译。这两条帮你避开我踩过的大部分坑。本文还有配套的精品资源点击获取
返回列表