ubuntu18.04.2 LTS 系统关于Qt5.12.3 无法加载mysql驱动,需要重新编译MYSQL数据库驱动的问题以及解决方案

环境:ubuntu18.04.2 LTS + QT5.12.3 + MySQL5.7.26

geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ cat /proc/version
Linux version 4.15.0-50-generic (buildd@lcy01-amd64-013) 
(gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #54-Ubuntu SMP Mon May 6 18:46:08 UTC 2019
geek@geek-ubuntu:~/software/$ sudo mysql --version
mysql  Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using  EditLine wrapper

问题描述:

QSqlDatabase: MYSQL driver not loadedQSqlDatabase: 
available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7

问题定位:

(1)查看目前安装的QT中MYSQL数据库驱动的共享库依赖关系

geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ ldd libqsqlmysql.so
	linux-vdso.so.1 (0x00007ffcef589000)
	libmysqlclient.so.18 => not found
	libQt5Sql.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Sql.so.5 (0x00007fc71a7d6000)
	libQt5Core.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Core.so.5 (0x00007fc71a043000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fc719cba000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc7198c9000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc7196ac000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc7194a8000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc719289000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc718eeb000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc718cd3000)
	libicui18n.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicui18n.so.56 (0x00007fc71883a000)
	libicuuc.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicuuc.so.56 (0x00007fc718482000)
	libicudata.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicudata.so.56 (0x00007fc716a9f000)
	libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007fc71689d000)
	libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007fc716586000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fc71b243000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fc716314000)

(2) 查看本地安装的MYSQL数据库驱动共享库版本

geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ cd /usr/lib/x86_64-linux-gnu/
geek@geek-ubuntu:/usr/lib/x86_64-linux-gnu$ ll | grep mysqlclient
-rw-r--r--   1 root root   5733812 4月  26 02:10 libmysqlclient.a
lrwxrwxrwx   1 root root        20 4月  26 02:10 libmysqlclient.so -> libmysqlclient.so.20
lrwxrwxrwx   1 root root        25 4月  26 02:10 libmysqlclient.so.20 -> libmysqlclient.so.20.3.13
-rw-r--r--   1 root root   4244768 4月  26 02:10 libmysqlclient.so.20.3.13

注意:对比1和2的结果,发现本地的libmysqlclient.so 和qt mysql驱动库依赖的版本不一致,是导致其无法正常运行的原因。网上有很多基于现有的libmysqlclient.so 创建libmysqlclient.so.18软链接的方案,其实都是错误的做法。

解决方案:

1. 安装QT源代码。

QT安装包提供了源代码,安装QT时可以选择安装源代码,也可以单独到QT官方网站下载源代码。

2. 安装依赖库

sudo apt-get install mysql-client libmysqlclient-dev

这一步是为了安装MYSQL的头文件和libmysqlclient.so库,如果系统有安装过mysql,可能以上依赖已经安装在系统中。安装完成以后mysql的头文件位置一般在/usr/include/mysql, 而共享库在下面几个目录其中:/usr/lib/mysql/ ,/usr/local/lib,/usr/liib/x86_64-linux-gnu。

可通过以下命令定位libmysqlclient.so的位置:

sudo updatedb #更新ubuntu的文件数据库,it may take a long time
sudo locate libmysqlclient.so

3. 编译安装QT MySQL驱动包

(1)进入qt源代码路径下的mysql目录(这里的目录因人而异,是你本地安装QT源代码的目录,我这里是/home/geek/software/Qt5.12.3/5.12.3/Src/qtbase/src/plugins/sqldrivers/mysql,其中/home/geek/software/Qt5.12.3是QT的安装目录)。

(2)使用QT自带的qmake命令编译该工程。

sudo /home/geek/software/Qt5.12.3/5.12.3/gcc_64/bin/qmake "INCLUDEPATH+=/usr/include/mysql" "LIBS+=-L/usr/lib/x86_64-linux-gnu/ -lmysqlclient" mysql.pro

make && make install

注意:这里可能遇到两类问题,如下:

(i)类似于qtsqldrivers-config.pri文件找不到的问题:eg.  Cannot read /home/geek/software/Qt5.12.3/5.12.3//Src/qtbase/src/plugins/sqldrivers/qtsqldrivers-config.pri: No such file or directory.

解决方案:修改上一层目录(这里也就是/home/geek/software/Qt5.12.3/5.12.3/Src/qtbase/src/plugins/sqldrivers)的qsqldriverbase.pri文件中的内容,如下:

QT  = core core-private sql-private

# For QMAKE_USE in the parent projects.
#include($$shadowed($$PWD)/qtsqldrivers-config.pri)
include($$shadowed($$PWD)/configure.pri)
PLUGIN_TYPE = sqldrivers

(ii)类似于mysql 库文件找不到的问题,eg:project ERROR: Library 'mysql' is not defined.

解决方案:修改当前目录(这里也就是/home/geek/software/Qt5.12.3/5.12.3/Src/qtbase/src/plugins/sqldrivers/mysql)的mysql.pro文件内容,如下:

TARGET = qsqlmysql

HEADERS += $$PWD/qsql_mysql_p.h
SOURCES += $$PWD/qsql_mysql.cpp $$PWD/main.cpp

#把mysql.pro中的 QMAKE_USE += mysql用#注释掉
#QMAKE_USE += mysql

OTHER_FILES += mysql.json

PLUGIN_CLASS_NAME = QMYSQLDriverPlugin
include(../qsqldriverbase.pri)

(3)如果遇到步骤2中遇到的问题,解决完以后重新执行步骤1的编译命令。最后会在QT的plugins/sqldrivers目录下(这里是/home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers)找到编译好的mysql共享库文件。

geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ ll
总用量 2668
drwxrwxr-x  2 geek geek    4096 5月  18 12:30 ./
drwxrwxr-x 34 geek geek    4096 5月  17 11:38 ../
-rwxrwxr-x  1 geek geek 1239408 4月   9 16:22 libqsqlite.so*
-rwxr-xr-x  1 geek geek  103168 5月  18 12:29 libqsqlmysql.so*
-rw-r--r--  1 geek geek 1138264 5月  18 12:29 libqsqlmysql.so.debug
-rwxrwxr-x  1 geek geek  119352 4月   9 16:21 libqsqlodbc.so*
-rwxrwxr-x  1 geek geek  112440 4月   9 16:21 libqsqlpsql.so*

(4)查看编译完成的最新版本的mysql驱动库的依赖树结构,如下:

geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ ldd libqsqlmysql.so
	linux-vdso.so.1 (0x00007ffdef9d6000)
	libmysqlclient.so.20 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20 (0x00007f44af9ce000)
	libQt5Sql.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Sql.so.5 (0x00007f44af786000)
	libQt5Core.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Core.so.5 (0x00007f44aeff3000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f44aec6a000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f44ae879000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f44ae65c000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f44ae458000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f44ae239000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f44ade9b000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f44adc83000)
	libicui18n.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicui18n.so.56 (0x00007f44ad7ea000)
	libicuuc.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicuuc.so.56 (0x00007f44ad432000)
	libicudata.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicudata.so.56 (0x00007f44aba4f000)
	libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f44ab84d000)
	libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f44ab536000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f44b01f3000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f44ab2c4000)

和系统版本的libmysqlclient.so 一致。

至此,基于QT源代码编译出适合本地环境的mysql驱动包操作完成。

下面贴上main.cpp测试代码,仅供参考:

// main.cpp
#include 
#include 
#include 
#include 
#include 
#include 


int main(int argc, char *argv[]) {
    std::cout << "Hello, World!" << std::endl;
    qDebug() << QCoreApplication::libraryPaths();
    QCoreApplication app(argc, argv);
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("hotel");
    db.setUserName("geek");
    db.setPassword("geek");
    if (!db.open()) {
        qDebug() << "Failed to connect to mysql";
    } else {
        qDebug() << "open success!";
    }

    //create the query object
    QSqlQuery query(db);
    query.exec("create table student(id int primary key, name varchar(20))");
    query.exec("insert into hotel.student values(1, 'first')");
    query.exec("insert into hotel.student values(2, 'second')");

    query.exec("update hotel.student set name='zhang' where id=1");
    query.exec("delete from hotel.student where id >= 2");

    query.exec("alter table hotel.student add address varchar(60)");
    query.exec("alter table hotel.student add address123 varchar(100)");
    query.exec("alter table hotel.student add age tinyint unsigned after name");
    query.exec("alter table hotel.student drop address123");
    query.exec("alter table hotel.student change name name  varchar(30)");
    query.exec("alter table hotel.student rename hotel.student1");
    query.exec("alter table hotel.student1 rename hotel.student");

    query.exec("select * from hotel.student where id > 0");
    while (query.next()) {
        quint32 id = query.value(0).toInt();
        QString name = query.value(1).toString();
        QString age = query.value(2).toString();
        QString address = query.value(2).toString();
        qDebug() << id << " ," << name << " ," << age << " ," << address;
    }

    query.exec("drop table hotel.student");
    db.close();

    return app.exec();
}

 

你可能感兴趣的:(操作指南)