Qt5.10.0编译MYSQL(Mariadb)驱动

最近安装了新版本的Qt,当连接MySQL数据库时,又出现那个似曾相识的错误 QSqlDatabase: QMYSQL driver not loaded.知道后就赶紧去编译源码.然而你以为真的就那么一帆风顺吗?

问题

测试环境:

  • Linux
  • Qt 5.10.0
  • MariaDB 10.1.29

出现问题:
我是新换成了MariaDB,比起之前传统MySQL,相应的文件路径也发生了变化.而其结果时导致后面一连串的问题.
现在网上大部分都是以前的MySQL驱动编译教程,关于MariaDB数据库(本质上也是MySQL)的资料很少,所以这里就总结一下期间遇到的问题……

终端下输入: $ locate mysql.h
在我这里输出

/usr/include/mariadb/mysql.h
/usr/include/qt4/Qt/qsql_mysql.h
/usr/include/qt4/QtSql/qsql_mysql.h

注意了没,就这里注定编译MySQL驱动会失败!因为默认的搜索路径为 /usr/include/mysql.h

接下来我们来看看 libqsqlmysql.so 这个库文件
$ ldd libqsqlmysql.so
img

他说 libqsqlmysql.so.18 这个库文件没有找到,那么就只能重新编译了…

尝试成功

但是这里我还是讲一下我第一次尝试的方法(就是把 mariadb 的库链接到 libqsqlmysql.so.18)

$ locate libmariadb|grep so 查看 mariadb库文件的路径

/usr/lib/x86_64-linux-gnu/libmariadb.so
/usr/lib/x86_64-linux-gnu/libmariadb.so.2
/usr/lib/x86_64-linux-gnu/libmariadbclient.so.18
/usr/lib/x86_64-linux-gnu/libmariadbclient.so.18.0.0

接着我再找下是否还存在之前的 libmysqlclient.so
$ locate libmysqlclient.so

/usr/lib/libmysqlclient.so

$ ls -l /usr/lib/libmysqlclient.so 发现 libmysqlclient.so 是个软链接

lrwxrwxrwx 1 root root 43 9月 17 08:01 /usr/lib/libmysqlclient.so -> /usr/lib/x86_64-linux-gnu/libmysqlclient.so

接着 $ ls -l /usr/lib/x86_64-linux-gnu/libmysqlclient.so

ls: 无法访问’/usr/lib/x86_64-linux-gnu/libmysqlclient.so’: 没有那个文件或目录

what!居然不存在!?所以赶紧把那链接删了

那么接下来就是给 libmariadbclient.so 设个软链接

ln -s /usr/lib/x86_64-linux-gnu/libmariadbclient.so.18 /usr/lib/libmysqlclient.so
ln -s /usr/lib/x86_64-linux-gnu/libmariadbclient.so.18 /usr/lib/libmysqlclient.so.18

最后看看 $ ldd libqsqlmysql.so

libmysqlclient.so.18 => /usr/lib/libmysqlclient.so.18 (0x00007fdf1a1df000)

……居然成功了!!那还用编译个毛啊??然而这不是本文重点蛤……

重点(编译MySQL驱动)

这里所说的驱动其实也不过就是一个链接库罢了……

首先进入该源代码目录下 $ cd ${QTDIR}/5.10.0/Src/qtbase/src/plugins/sqldrivers/mysql

一般正常来讲接下来就是 qmake mysql.pro,make
不过这里会出现一个错误
img

这就要修改 mysql.pro

1
2
3
4
5
6
7
8
TARGET = qsqlmysql
HEADERS += $$PWD/qsql_mysql_p.h
SOURCES += $$PWD/qsql_mysql.cpp $$PWD/main.cpp
QMAKE_USE += mysql
OTHER_FILES += mysql.json
INCLUDEPATH += /usr/include/mariadb
PLUGIN_CLASS_NAME = QMYSQLDriverPlugin
include(../qsqldriverbase.pri)

注意我添加了 INCLUDEPATH += /usr/include/mariadb

接着 qmake;make 恭喜,特么的又出现了个错误.不急找找看那出了问题…

/opt/Qt5.10.0/5.10.0/gcc_64/bin/qmake -o Makefile mysql.pro
rm -f libqsqlmysql.so
g++ -Wl,–no-undefined -Wl,-O1 -Wl,–enable-new-dtags -Wl,-z,origin -Wl,-rpath,$ORIGIN/…/…/lib -Wl,-rpath,$ORIGIN/…/…/lib -shared -o libqsqlmysql.so .obj/qsql_mysql.o .obj/main.o .obj/moc_qsql_mysql_p.o -L/opt/Qt5.10.0/5.10.0/gcc_64/lib -lQt5Sql -lQt5Core -lmariadbclient -lpthread -lz -lm -ldl
/usr/bin/ld: 找不到 -lmariadbclient
collect2: error: ld returned 1 exit status
Makefile:80: recipe for target ‘…/plugins/sqldrivers/libqsqlmysql.so’ failed
make: *** […/plugins/sqldrivers/libqsqlmysql.so] Error 1

其实问题很简单,就是一个链接名字.在链接库时,默认匹配的为 libxxx.so ; 而后面的数字,如: libxxx.so.1.1.1 表示库的版本.

$ locate libmariadbclient.so 看到,少了一个 libmariadbclient.so

/usr/lib/x86_64-linux-gnu/libmariadbclient.so.18
/usr/lib/x86_64-linux-gnu/libmariadbclient.so.18.0.0

瞬间问题简单化了,so,直接添加一个软链接就行了

ln -s /usr/lib/x86_64-linux-gnu/libmariadbclient.so.18.0.0 /usr/lib/x86_64-linux-gnu/libmariadbclient.so

再一次 qmake;make……

rm -f libqsqlmysql.so
g++ -Wl,–no-undefined -Wl,-O1 -Wl,–enable-new-dtags -Wl,-z,origin -Wl,-rpath,$ORIGIN/…/…/lib -Wl,-rpath,$ORIGIN/…/…/lib -shared -o libqsqlmysql.so .obj/qsql_mysql.o .obj/main.o .obj/moc_qsql_mysql_p.o -L/opt/Qt5.10.0/5.10.0/gcc_64/lib -lQt5Sql -lQt5Core -lmariadbclient -lpthread -lz -lm -ldl
mv -f libqsqlmysql.so …/plugins/sqldrivers/

成功编译!

现在 $ ../plugins/sqldrivers
$ ldd libqsqlmysql.so

libmariadbclient.so.18 => /usr/lib/x86_64-linux-gnu/libmariadbclient.so.18 (0x00007f1bf7414000)

现在可以把这个文件复制到 /opt/Qt5.10.0/5.10.0/gcc_64/plugins/sqldrivers 目录下了

结束语

基本上到此为止了吧……顺带提下,用C写的程序链接MySQL数据库时,传统的做法就是

gcc xxx.c -o xxx -lmysqlclient

换成MariaDB后就成了

gcc xxx.c -o xxx -lmariadb

这一点要特别注意啊!

bye


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!