1. 项目概述:为什么在Win10上手动编译Qt的MySQL驱动不是“可选项”,而是“必修课”
在Qt开发中,数据库连接看似只是QSqlDatabase::addDatabase("QMYSQL")一行代码的事,但真正部署到客户机器上时,90%以上的崩溃、黑屏、报错“Driver not loaded”都源于一个被严重低估的事实:Qt官方预编译包(尤其是MinGW版本)默认不包含MySQL驱动插件,更不会自动打包libmysql.dll及其依赖。你用Qt Creator点运行能连上本地数据库,不代表打包后的exe能在另一台Windows 10电脑上打开——它大概率会静默失败,连错误提示都不给你。这不是Bug,是设计使然:Qt为了精简安装包体积、规避GPL传染风险、适配不同MySQL版本的ABI兼容性,把数据库驱动全部剥离为“按需编译”的独立模块。而Qt 5.14.1 + MinGW64这个组合,恰恰处于一个微妙的临界点:它既不支持新版MySQL 8.x的默认认证插件(caching_sha2_password),又对旧版MySQL 5.7的线程模型和SSL库链接方式极其敏感。我去年帮某高校实验室迁移一个十年老项目时,就卡在这个环节整整三天——他们用的是MySQL 5.7.33社区版,Qt 5.14.1 MinGW 64-bit,所有网上搜到的“复制dll”“改环境变量”方案全失效。最后发现根本原因:MinGW链接器找不到libmysql.dll导出的mysql_thread_init符号,因为MySQL 5.7.22之后默认启用了线程安全模式,而Qt源码里调用它的头文件路径和链接顺序没对齐。所以这个标题说的不是“怎么编译”,而是“如何让Qt和MySQL在Win10上真正握手成功”。它适合三类人:一是正在打包发布桌面数据库应用的开发者;二是需要对接老旧MySQL 5.7政企系统的集成工程师;三是被Qt Creator里那个灰色不可选的“QMYSQL”驱动折磨到怀疑人生的初学者。核心关键词就是Qt5.14.1、MinGW64、MySQL5.7、Win10、驱动编译——每一个词都踩在兼容性雷区的正中心。
2. 整体设计思路与关键决策逻辑:为什么必须自己编译,而不是复制dll或换MSVC
2.1 为什么“复制dll”方案注定失败
很多教程教你在Qt安装目录下找到plugins/sqldrivers/,然后把MySQL的libmysql.dll丢进去,再改PATH环境变量。这在Qt 5.9之前或许能蒙混过关,但在5.14.1+MinGW64环境下,它会触发三重校验失败:
ABI不匹配:MinGW64生成的是PE32+格式DLL,且使用GCC的C++ ABI(如
_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSt7__cxx1112basic_stringIS4_S5_T1_E这类符号),而MySQL官网下载的Windows版libmysql.dll是用Visual Studio编译的,使用MSVC ABI(符号名完全不同)。Qt加载驱动时会先解析DLL导出表,发现符号对不上,直接拒绝加载。依赖链断裂:MySQL 5.7.22+的
libmysql.dll依赖ssleay32.dll和libeay32.dll(OpenSSL 1.0.2),而Qt MinGW自带的libssl.dll是OpenSSL 1.1.1,两者不兼容。你复制了libmysql.dll,却漏掉对应版本的OpenSSL DLL,程序启动时会报“找不到指定模块”,但错误日志里只显示“QMYSQL driver not loaded”,根本不会告诉你缺的是哪个DLL。Qt插件机制拦截:Qt 5.12之后引入了插件元数据校验(
json描述文件),要求每个sqldrivers/qsqlmysql.dll必须配套qsqlmysql.json,里面声明了IID、className、version等字段。直接复制旧版驱动DLL,JSON文件版本号对不上,Qt在插件扫描阶段就会跳过它。
提示:你可以用
ntldd -R plugins/sqldrivers/qsqlmysql.dll(MinGW工具)或Dependencies.exe(GUI工具)查看DLL真实依赖树,而不是只看文件名。我实测过,网上流传最广的“Qt5.12+MySQL5.7一键包”,其qsqlmysql.dll实际依赖的是libcrypto-1_1-x64.dll,但包里附带的却是libeay32.dll,这就是典型版本错配。
2.2 为什么不能简单换成MSVC编译器
有人会说:“既然MinGW这么麻烦,我切到MSVC2019不就行了?”——这确实能绕过ABI问题,但会引入更隐蔽的工程管理成本:
工具链割裂:如果你整个项目(包括第三方库如OpenCV、FFmpeg)都是用MinGW64编译的,突然为数据库切到MSVC,意味着你要重新编译所有依赖库,工作量翻倍。而且MSVC生成的静态库(
.lib)和MinGW的静态库(.a)完全不兼容,无法混用。部署包体积爆炸:MSVC版Qt必须打包
vcruntime140.dll、msvcp140.dll等运行时,而MinGW版只需libgcc_s_seh-1.dll和libstdc++-6.dll,后者体积小50%以上。对于需要U盘分发的工业控制软件,这点很关键。调试体验降级:MinGW的GDB调试器对Qt信号槽、QVariant等类型有原生支持,而MSVC的CDB调试器在复杂模板展开时经常显示
<error reading variable>。我在调试一个涉及大量QSqlQueryModel嵌套的报表系统时,MSVC调试器根本无法查看查询结果集的内部结构,最后还是切回MinGW+Qt Creator的LLDB才搞定。
所以最终决策是:坚持MinGW64工具链,从Qt源码出发,完整编译MySQL驱动插件。这看似步骤多,但一劳永逸——编译出来的qsqlmysql.dll和你的主程序ABI完全一致,所有依赖DLL版本可控,打包时只需确认libmysql.dll和对应OpenSSL DLL在同目录即可。
2.3 为什么选择MySQL 5.7而非8.x
标题明确指向MySQL 5.7,这不是怀旧,而是现实约束:
认证协议鸿沟:MySQL 8.0.4+默认启用
caching_sha2_password认证插件,而Qt 5.14.1的MySQL驱动只支持mysql_native_password。你可以在MySQL里执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';临时降级,但这违反政企系统安全审计要求,且新用户创建时仍可能触发默认插件。SSL库版本锁死:MySQL 5.7.28+开始强制要求OpenSSL 1.1.1+,而Qt 5.14.1 MinGW构建时默认链接的是OpenSSL 1.0.2(因历史兼容性)。强行升级会导致Qt网络模块(QSslSocket)崩溃。MySQL 5.7.33则完美适配OpenSSL 1.0.2g,与Qt 5.14.1的SSL栈完全对齐。
线程模型稳定:MySQL 5.7的
mysql_thread_init()/mysql_thread_end()调用约定在所有小版本中保持一致,而8.x在5.7.30之后引入了新的线程局部存储(TLS)机制,Qt驱动源码未适配,编译时会出现undefined reference to 'mysql_thread_init'链接错误。
因此,整个方案的设计锚点就是:以Qt 5.14.1 MinGW64为基准,反向锁定MySQL 5.7.33 + OpenSSL 1.0.2u组合,确保从源码到二进制的全链路ABI、API、ABI三重一致。
3. 核心细节解析与实操要点:编译前必须搞清的五个致命细节
3.1 Qt源码版本与构建配置的精确对应关系
Qt 5.14.1有两个关键源码包:qt-everywhere-src-5.14.1.zip(完整源码)和qtbase-everywhere-opensource-src-5.14.1.zip(仅qtbase模块)。很多人误以为只要下载后者就够了,这是大坑。因为MySQL驱动位于qtbase/src/plugins/sqldrivers/mysql/,但它依赖qtbase/src/corelib/global/里的qglobal.h、qconfig.h等头文件,而这些头文件的宏定义(如QT_VERSION_STR、QT_COMPILER_SUPPORTS_CXX11)必须与你最终要链接的Qt库完全一致。如果你用预编译的Qt 5.14.1 MinGW64安装包(比如Qt5.14.1\5.14.1\mingw73_64\),那么你必须下载完全相同构建参数的源码包。Qt官方构建参数藏在qtbase/mkspecs/win32-g++/qmake.conf里,关键字段如下:
QMAKE_CC = gcc QMAKE_CXX = g++ QMAKE_LINK = g++ QMAKE_CFLAGS = -fno-keep-inline-dllexport -march=x86-64 -mtune=generic -O2 -pipe QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -fno-exceptions -fno-rtti QMAKE_LFLAGS = -Wl,-subsystem,windows -static-libgcc -static-libstdc++注意-static-libgcc -static-libstdc++这两项——它意味着Qt库本身是静态链接GCC运行时的,所以你编译的qsqlmysql.dll也必须用同样的链接方式,否则运行时会因libgcc_s_seh-1.dll版本冲突而崩溃。我踩过的坑是:用自己编译的MinGW73(带-shared-libgcc)去编译驱动,结果生成的DLL在客户机上闪退,用Process Monitor抓取发现它在疯狂搜索libgcc_s_seh-1.dll的多个版本,最后加载了系统PATH里的旧版,导致异常处理机制失效。
3.2 MySQL开发包的正确获取与解压姿势
MySQL官网提供的“Windows (x86, 64-bit), ZIP Archive”下载包(如mysql-5.7.33-winx64.zip)不能直接用。因为它只包含服务端二进制文件,没有libmysql.lib(MinGW需要.a静态库)和mysql.h头文件。你必须下载MySQL Connector/C 6.1.11(这是最后一个支持MySQL 5.7且提供MinGW兼容库的版本)。它的下载页在Oracle官网深处,路径类似/downloads/connector-c/,文件名是mysql-connector-c-6.1.11-winx64.zip。解压后,你会看到:
mysql-connector-c-6.1.11-winx64/ ├── include/ # mysql.h, mysql_version.h等头文件 ├── lib/ # libmysql.lib (MSVC), libmysql.dll (MSVC) └── libmysql/ # 这里才是关键!有 libmysql.a (MinGW静态库) 和 libmysql.dll (MinGW版)重点看libmysql/子目录下的libmysql.a——它是由MinGW GCC编译的静态库,导出符号与Qt驱动源码调用完全匹配。而lib/下的libmysql.lib是MSVC的,绝对不能用。我曾因手快复制了lib/下的库,导致链接时出现undefined reference to '_imp__mysql_init@4',因为MSVC的__imp__导入符号前缀和MinGW的_mysql_init@4不一致。
3.3 OpenSSL 1.0.2u的编译与路径绑定技巧
Qt 5.14.1 MinGW默认链接OpenSSL 1.0.2u,但这个版本早已停止维护,官网不再提供下载。你需要从OpenSSL的GitHub Release页找存档:openssl-OpenSSL_1_0_2u.tar.gz。解压后,进入目录,执行:
perl Configure mingw64 --prefix=/opt/openssl-1.0.2u no-shared make depend && make && make install注意--prefix参数:它决定了OpenSSL头文件和库的安装路径。这个路径必须与Qt configure时指定的-openssl-linked路径完全一致。比如你在configure Qt时写了-openssl-linked -I/opt/openssl-1.0.2u/include -L/opt/openssl-1.0.2u/lib,那么这里--prefix就必须是/opt/openssl-1.0.2u。否则Qt编译时会找不到openssl/ssl.h,报错fatal error: openssl/ssl.h: No such file or directory。更隐蔽的坑是:make install默认会把libcrypto.a和libssl.a安装到/opt/openssl-1.0.2u/lib/,但Qt驱动编译脚本qmake会优先查找/opt/openssl-1.0.2u/lib64/(因为64位系统惯例),所以你必须手动创建软链接:ln -s /opt/openssl-1.0.2u/lib /opt/openssl-1.0.2u/lib64。这个细节在Qt官方文档里只字未提,是我用strace -e trace=openat qmake ...跟踪文件打开路径才发现的。
3.4 环境变量设置的“最小必要集”
网上教程常让你设置一堆环境变量,其实真正必需的只有三个,且必须在qmake执行前生效:
MYSQL_PREFIX=C:/mysql-connector-c-6.1.11-winx64:指向MySQL Connector/C解压根目录,Qt的qmake会自动在$MYSQL_PREFIX/include找头文件,在$MYSQL_PREFIX/libmysql找库。OPENSSL_PREFIX=C:/opt/openssl-1.0.2u:同理,qmake会在$OPENSSL_PREFIX/include和$OPENSSL_PREFIX/lib找OpenSSL。PATH:必须把C:/Qt/Tools/mingw73_64/bin(MinGW编译器路径)和C:/mysql-connector-c-6.1.11-winx64/libmysql(MinGW版libmysql.dll所在目录)加到最前面。因为qmake在生成Makefile时会调用gcc -dumpmachine检查目标架构,如果PATH里有其他GCC(比如MSYS2的),会导致架构识别错误。
其他变量如QTDIR、QMAKESPEC都是Qt安装时自动设置的,无需手动干预。我见过最离谱的配置是有人把QT_PLUGIN_PATH设成C:/Qt/5.14.1/mingw73_64/plugins,结果qmake在编译驱动时误以为插件已存在,跳过了编译步骤,生成了一个空的qsqlmysql.dll。
3.5 驱动编译命令的逐参数解析
最终执行的编译命令是:
cd C:/Qt/5.14.1/Src/qtbase/src/plugins/sqldrivers/mysql qmake "INCLUDEPATH+=C:/mysql-connector-c-6.1.11-winx64/include" "LIBS+=-LC:/mysql-connector-c-6.1.11-winx64/libmysql -lmysql" "CONFIG+=sql_mysql" mysql.pro mingw32-make拆解每个参数的作用:
INCLUDEPATH+=...:显式添加MySQL头文件路径。虽然MYSQL_PREFIX已设,但qmake有时会忽略,显式声明更保险。LIBS+=-LC:/... -lmysql:-L指定库搜索路径,-lmysql告诉链接器链接libmysql.a(MinGW约定,-lxxx会找libxxx.a或libxxx.dll.a)。注意路径里是libmysql子目录,不是lib。CONFIG+=sql_mysql:这是关键开关!它会激活mysql.pro里sql_mysql条件块,里面定义了SOURCES += main.cpp(驱动入口)和HEADERS += qsql_mysql_p.h(私有头文件),没有它,qmake只会生成一个空Makefile。mysql.pro:这是驱动的项目文件,不是qtbase.pro。很多人cd错目录,跑到qtbase/根目录下执行qmake,结果编译的是整个Qt Base库,耗时2小时还失败。
执行完mingw32-make后,生成的qsqlmysql.dll在C:/Qt/5.14.1/Src/qtbase/src/plugins/sqldrivers/mysql/目录下,而不是plugins/sqldrivers/。你需要手动复制过去,并确保同目录有qsqlmysql.json文件(Qt 5.14.1源码里自带,内容固定,不用改)。
4. 实操过程与核心环节实现:从零开始的完整编译流水线
4.1 准备工作:工具链与目录结构标准化
首先,建立一个干净、无空格、无中文的根目录,比如C:/qt-build-env。所有后续操作都在此目录下进行,避免路径空格导致qmake解析失败。目录结构规划如下:
C:/qt-build-env/ ├── deps/ # 第三方依赖 │ ├── mysql-connector-c-6.1.11-winx64/ │ └── openssl-1.0.2u/ # 编译好的OpenSSL ├── qt-src/ # Qt 5.14.1 源码 │ └── qt-everywhere-src-5.14.1/ ├── build/ # 构建输出目录(避免污染源码) │ └── mysql-driver/ # 专门放MySQL驱动编译产物 └── tools/ # 工具链 └── mingw73_64/ # Qt官方MinGW73 64-bit(必须用这个版本!)为什么强调mingw73_64?因为Qt 5.14.1是用GCC 7.3.0编译的,ABI与GCC 8.1+不兼容。如果你用更新的MinGW(比如UCRT64),qmake会报错The target is not supported。Qt官方MinGW下载地址在https://download.qt.io/official_releases/cmake/附近,文件名类似mingw73_64-9.0.0-20200310.7z。解压到tools/mingw73_64,然后把tools/mingw73_64/bin加到系统PATH。
验证MinGW版本:
gcc --version # 输出应为:gcc.exe (Rev3, Built by MSYS2 project) 7.3.04.2 编译OpenSSL 1.0.2u:避坑指南与实测参数
进入deps/openssl-1.0.2u/,执行以下命令(注意路径用正斜杠):
# 1. 清理上次编译残留 make clean # 2. 配置,关键参数:no-shared(禁用动态库)、no-asm(禁用汇编优化,避免MinGW不兼容) perl Configure mingw64 --prefix=C:/qt-build-env/deps/openssl-1.0.2u no-shared no-asm # 3. 生成Makefile(这一步会检查Perl和gcc是否可用) make depend # 4. 编译(-j4表示4线程,根据CPU调整) make -j4 # 5. 安装到指定前缀 make install # 6. 创建lib64软链接(关键!) cmd /c "mklink /D C:\qt-build-env\deps\openssl-1.0.2u\lib64 C:\qt-build-env\deps\openssl-1.0.2u\lib"常见错误及解决:
Can't locate FindBin.pm:说明Perl环境缺失。下载Strawberry Perl(便携版),解压后把strawberry/perl/bin加到PATH。unable to load perl script:路径含空格或中文,重装到纯英文路径。make: *** No rule to make target 'depend':Configure执行失败,检查perl命令是否可用,以及当前目录是否正确。
编译完成后,检查deps/openssl-1.0.2u/lib/下是否有libcrypto.a和libssl.a,大小应在2MB和1MB左右。如果只有.dll文件,说明no-shared没生效。
4.3 配置Qt源码并编译MySQL驱动
进入qt-src/qt-everywhere-src-5.14.1/,执行Qt的全局配置(这步耗时约15分钟,但只需一次):
# 设置环境变量 set MYSQL_PREFIX=C:/qt-build-env/deps/mysql-connector-c-6.1.11-winx64 set OPENSSL_PREFIX=C:/qt-build-env/deps/openssl-1.0.2u set PATH=C:/qt-build-env/tools/mingw73_64/bin;%PATH% # 进入qtbase目录(必须!) cd qtbase # 执行configure,关键参数详解: configure -prefix C:/Qt/5.14.1/mingw73_64 \ -debug-and-release \ -platform win32-g++ \ -xplatform win32-g++ \ -opengl desktop \ -sql-mysql \ -openssl-linked \ -I C:/qt-build-env/deps/openssl-1.0.2u/include \ -L C:/qt-build-env/deps/openssl-1.0.2u/lib \ -no-icu \ -no-audio-backend \ -nomake examples \ -nomake tests \ -skip webengine \ -confirm-license \ -opensource参数说明:
-sql-mysql:启用MySQL支持,会自动在src/plugins/sqldrivers/启用mysql子目录。-openssl-linked:强制静态链接OpenSSL,避免运行时依赖DLL。-I和-L:显式指定OpenSSL头文件和库路径,覆盖OPENSSL_PREFIX的自动探测。-no-icu:禁用ICU国际化库,减少依赖,加快编译。-nomake examples:跳过示例编译,节省时间。
配置成功后,会生成Makefile。此时不要执行mingw32-make编译整个Qt——我们只需要驱动。执行:
# 回到驱动目录 cd ../src/plugins/sqldrivers/mysql # 执行qmake,生成驱动专用Makefile qmake "MYSQL_PREFIX=C:/qt-build-env/deps/mysql-connector-c-6.1.11-winx64" "OPENSSL_PREFIX=C:/qt-build-env/deps/openssl-1.0.2u" "CONFIG+=sql_mysql" mysql.pro # 编译驱动 mingw32-make -j4 # 复制产物到Qt插件目录 copy release\qsqlmysql.dll C:\Qt\5.14.1\mingw73_64\plugins\sqldrivers\ copy qsqlmysql.json C:\Qt\5.14.1\mingw73_64\plugins\sqldrivers\注意:
mingw32-make命令必须在mysql目录下执行,且qmake生成的Makefile里TARGET变量应为qsqlmysql。如果生成的是qsqlmysqld(带d后缀),说明CONFIG+=debug_and_release被继承了,需要在qmake命令里加CONFIG-=debug_and_release CONFIG+=release。
4.4 部署验证:四步法确认驱动真正可用
编译完不是终点,必须验证。新建一个最简Qt项目test-mysql.pro:
QT += core sql TARGET = test-mysql TEMPLATE = app SOURCES += main.cppmain.cpp内容:
#include <QCoreApplication> #include <QSqlDatabase> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 1. 检查驱动列表 qDebug() << "Available drivers:" << QSqlDatabase::drivers(); // 2. 尝试创建连接(不连接,只检查驱动加载) QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); qDebug() << "QMYSQL driver loaded:" << db.isValid(); // 3. 检查插件路径(关键!) qDebug() << "Plugin paths:" << QCoreApplication::libraryPaths(); return 0; }编译运行,正确输出应为:
Available drivers: ("QSQLITE", "QMYSQL", "QPSQL", "QODBC", "QOCI") QMYSQL driver loaded: true Plugin paths: ("C:/Qt/5.14.1/mingw73_64/plugins", ...)如果QMYSQL不在列表里,检查plugins/sqldrivers/目录下是否有qsqlmysql.dll和qsqlmysql.json;如果driver loaded为false,用Dependency Walker打开qsqlmysql.dll,看是否报libmysql.dll或libcrypto-1_0_0.dll缺失。
4.5 打包发布:最小化依赖清单与路径规范
最终发布的exe目录结构必须严格遵循:
your-app/ ├── your-app.exe ├── platforms/ # Qt平台插件(qwindows.dll) ├── plugins/ │ ├── sqldrivers/ │ │ ├── qsqlmysql.dll │ │ └── qsqlmysql.json │ └── imageformats/ # 其他必需插件 ├── libmysql.dll # MySQL Connector/C的MinGW版DLL ├── libcrypto-1_0_0.dll # OpenSSL 1.0.2u的DLL(注意文件名!) └── libssl-1_0_0.dll关键点:
libmysql.dll必须来自mysql-connector-c-6.1.11-winx64/libmysql/,不是lib/。- OpenSSL DLL文件名是
libcrypto-1_0_0.dll和libssl-1_0_0.dll,不是libcrypto.dll。Qt 5.14.1硬编码了这个文件名。 - 不需要
ssleay32.dll或libeay32.dll,那是OpenSSL 1.0.0时代的命名。
你可以用windeployqt --no-opengl-sw your-app.exe自动拷贝大部分Qt插件,但sqldrivers和MySQL相关DLL必须手动添加,因为windeployqt不认识自编译驱动。
5. 常见问题与排查技巧实录:那些文档里不会写的血泪教训
5.1 典型问题速查表
| 问题现象 | 根本原因 | 解决方案 |
|---|---|---|
QSqlDatabase: QMYSQL driver not loaded | qsqlmysql.dll未放在plugins/sqldrivers/,或QCoreApplication::addLibraryPath()未添加插件路径 | 用QApplication::addLibraryPath("plugins");在main()开头添加,或设置环境变量QT_PLUGIN_PATH=plugins |
undefined reference to 'mysql_thread_init' | MySQL Connector/C版本过高(>6.1.11),或libmysql.a是MSVC版 | 降级到mysql-connector-c-6.1.11,确认libmysql.a大小>1MB(MinGW静态库) |
SSL routines:SSL_CTX_new:library has no ciphers | OpenSSL DLL版本错配,libssl-1_0_0.dll与libcrypto-1_0_0.dll版本不一致 | 用dumpbin /headers libssl-1_0_0.dll | findstr "timestamp"对比两个DLL的时间戳,必须完全相同 |
QMYSQL: Unable to connect | MySQL服务未启动,或防火墙阻止3306端口,或用户权限不足 | 在命令行执行mysql -h127.0.0.1 -P3306 -uroot -p测试,确认能连上 |
Application failed to start because libgcc_s_seh-1.dll was not found | qsqlmysql.dll链接了动态libgcc,但发布目录没放 | 用ntldd -R qsqlmysql.dll检查依赖,如果输出含libgcc_s_seh-1.dll,则qmake时加CONFIG+=static_runtime |
5.2 独家避坑技巧:三个提升成功率的实战经验
技巧一:用qmake -query验证环境变量是否生效
在执行qmake前,先运行qmake -query,检查输出中MYSQL_PREFIX和OPENSSL_PREFIX是否为你设置的路径。如果为空,说明环境变量没生效,qmake会用默认路径(通常是C:/Program Files/MySQL),导致头文件找不到。
技巧二:编译时开启详细日志,定位链接失败点
在mingw32-make命令后加VERBOSE=1:
mingw32-make VERBOSE=1 -j1 \| findstr "mysql\|ssl\|crypto"-j1禁用并行,findstr过滤关键字符串。这样你能看到gcc实际执行的链接命令,比如:g++ -shared -o qsqlmysql.dll ... -LC:/.../libmysql -lmysql -LC:/.../lib -lssl -lcrypto
如果这里-L路径错了,一眼就能发现。
技巧三:用Process Monitor抓取文件访问失败
当程序启动报错但日志不明确时,用ProcMon.exe(Sysinternals工具)过滤进程名your-app.exe,操作类型选CreateFile,结果选NAME NOT FOUND。它会显示程序试图加载qsqlmysql.dll时,具体在哪些路径下搜索,比如:C:\your-app\plugins\sqldrivers\qsqlmysql.dll→ NOT FOUNDC:\Qt\5.14.1\mingw73_64\plugins\sqldrivers\qsqlmysql.dll→ SUCCESS
这能帮你快速定位插件路径配置错误。
5.3 版本迁移指南:Qt 5.15.x和6.x的适配要点
虽然标题是Qt 5.14.1,但实际工作中你很可能要升级。这里给出平滑迁移路径:
- Qt 5.15.2:基本兼容,只需将
mysql-connector-c-6.1.11升级到6.1.12,OpenSSL保持1.0.2u,qmake命令不变。 - Qt 6.2+:重大变化!MySQL驱动移至
qtbase/src/plugins/sqldrivers/mysql/,但qmake被cmake取代。编译命令变为:cd qtbase/src/plugins/sqldrivers/mysql cmake -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH=C:/Qt/6.2.0/mingw64 -DMYSQL_INCLUDE_DIR=C:/.../include -DMYSQL_LIBRARY=C:/.../libmysql/libmysql.a . cmake --build . --config Release - Qt 6.5+:官方宣布MySQL驱动进入“deprecated”状态,推荐迁移到
QODBC(通过MySQL ODBC驱动)或QSQLITE(本地嵌入)。如果你必须用原生MySQL,需自行维护驱动源码,因为Qt不再提供qsqlmysql的CI测试。
我个人在实际项目中发现,Qt 5.14.1 + MySQL 5.7.33这个组合的稳定性远超预期——我们一个电力监控系统已连续运行18个月无数据库连接异常。关键在于:所有二进制组件(Qt库、MySQL驱动、libmysql.dll、OpenSSL DLL)都来自同一构建工具链,版本号精确锁定,没有一个“大概能用”的侥幸。这种确定性,比任何新特性都珍贵。