Hướng dẫn sửa lỗi “QMYSQL driver not loaded” khi lập trình kết nối C++ với MySQL qua Qt Creator trên Ubuntu

Vài lưu ý ban đầu

Đây là những dòng out ra của lỗi

Trường hợp 1 (available drivers nhiều hơn 1 driver):

QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QPSQL QPSQL7

Trường hợp 2 (available drivers chỉ có 1 driver):

QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: available drivers: QSQLITE

Để dễ thao tác và ít xảy ra lỗi mình khuyên các bạn nên cài Qt từ gói qt5-default.

  • Để gỡ bỏ gói Qt đã cài từ file .run thì các bạn vào thư mục cài đặt , tìm MaintenanceTool và chạy nó lên (Trình tự gỡ bỏ giống như gỡ phần mềm bên Window)
  • Tiếp theo cài Qt creator từ gói qt5-default

Install Qt

sudo apt-get install build-essential
sudo apt-get install qtcreator
sudo apt-get install qt5-default

Install documentation and examples

sudo apt-get install qt5-doc
sudo apt-get install qt5-doc-html qtbase5-doc-html
sudo apt-get install qtbase5-examples

Chúng ta bắt đầu vào vấn đề nhé:

Đây là source code của chương trình test.cpp

#include <QCoreApplication>
#include <QtSql/QSql>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <iostream>
#include <QtSql>

using namespace std;

int main(int argc, char *argv[])
{
 QCoreApplication a(argc, argv);

      QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
      db.setHostName("127.0.0.1");
      db.setDatabaseName("test");
      db.setUserName("root");
      db.setPassword("dangkhoa");
      if (db.open()){
      cout << "ket noi thanh cong" << endl;
 }
 db.close();
 return 0;
}

Trong đó :

  • db.setDatabaseName(“test”): là tên cơ sở dữ liệu
  • db.setUserName(“root”): tên người dùng
  • db.setPassword(“dangkhoa”): mật khẩu của người dùng

Tiếp theo là source của test.pro

QT += core
QT -= gui

CONFIG += c++11

TARGET = connectdb
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

SOURCES += main.cpp
QT +=sql
QTPLUGIN += qsqlmysql

Chú ý 2 dòng màu xanh là 2 dòng cực kỳ quan trọng, nếu không có sẽ bị lỗi undefined reference to QSqlDatabase::defaultConnection:

Mọi thứ có vẻ đã sẳn sàng nhưng khi chạy sẽ bung ra lỗi như ở đầu bài viết, và thật không thể biết được lý do là tại sao, vì rõ ràng driver đó đã được cài đặt nhưng không thể load được??!!!

Giải thích lỗi:

  • Nếu bạn cài phần mềm Qt trên linux theo file .run thì đường dẫn thư mục cài đặt sẽ là:
$QT_INSTALL_PLACE/$QT_VERSION_NUMBER/$COMPILE_TOOL_KIT_NAME/plugins

(Ví dụ: /opt/Qt5.1/5.1.0/gcc_64/plugins/ hoặc /home/khoahnd1996/Qt5.5.1/5.5.1/gcc_64/plugins/).
  • Nếu bạn sử dụng apt-get để cài đặt gói qt5-default, thì đường dẫn đến các plugins, thư viện cài là:
/usr/lib/i386-linux-gnu/$QT_VERSION/plugins/ nếu là ubuntu 32bits 
or
/usr/lib/x86_64-linux-gnu/$QT_VERSION/plugins/ nếu là ubuntu  64bits.

Giờ chúng ta sẽ bắt đầu kiểm tra nguyên nhân gây ra lỗi:

  • Đầu tiên các bạn vào đúng thư mục cài đặt như mô tả ở trên
  • Tiếp theo chuyển đến thư mục sqldrivers (cd sqldrivers)
  • Chúng ta tìm file thư viên động libqsqlmysql.so và tiến hành phân tích nó

Dùng lênh ldd libqsqlmysql.so để kiểm tra. Ở một số trường hợp, bạn sẽ không thể thấy file libqsqlmysql.so, trường hợp đó ta sẽ xử lý ở phần sau (file đó sẽ được tạo ra khi sài lệnh qmake và make ở phần sau). Giờ ta giả sử đang ở trường hợp có file libqsqlmysql.so trong thư mục sqldrivers.

linux-vdso.so.1 =>  (0x00007fff457d9000)
libmysqlclient_r.so.16 => not found libQt5Sql.so.5 => /opt/Qt5.1/5.1.0/gcc_64/lib/libQt5Sql.so.5 (0x00007ff9ad66b000) 
libQt5Core.so.5 => /opt/Qt5.1/5.1.0/gcc_64/lib/libQt5Core.so.5 (0x00007ff9acfe2000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff9accde000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff9ac915000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff9ac6f8000)
libicui18n.so.51 => /opt/Qt5.1/5.1.0/gcc_64/lib/libicui18n.so.51 (0x00007ff9ac2df000)
libicuuc.so.51 => /opt/Qt5.1/5.1.0/gcc_64/lib/libicuuc.so.51 (0x00007ff9abf58000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff9abd54000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007ff9abb52000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff9ab949000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007ff9ab64d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff9ab348000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff9ab131000)/lib64/ld-linux-x86-64.so.2 (0x00007ff9adaec000)
libicudata.so.51 => /opt/Qt5.1/5.1.0/gcc_64/lib/libicudata.so.51 (0x00007ff9a99e8000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007ff9a97a8000)

Rõ ràng chúng ta thấy có dòng libmysqlclient_r.so.16 => not found tức là thư viện này hiện đang thiếu.

Okay, chúng ta bắt đầu giải quyết nhé

Đầu tiên các bạn theo link qt-project  để tải một project của Qt (Tên của nó dạng như: “qt-everywhere-opensource-src-version”.tar.gz các bạn có thể tìm trên google cho nhanh)

Các bạn có thể truy cập vào đây cho nhanh (Lưu ý là chọn project phải đúng với phiên bản Qt bạn đã cài).

Mục đích của công việc này là chúng ta sẽ tạo ra thư viện libqsqlmysql.so mới.

  1. Giải nén và di chuyển đến thư mục qtbase/src/plugins/sqldrivers/mysql/
  2. qmake "INCLUDEPATH+=/opt/lampp/include" "LIBS+=-L/usr/local/lib -lmysqlclient_r" mysql.pro
  3.  Trong đó /opt/lampp/include là thư mục chứa phần cài đặt MySQL Server
  4. make
  5. Nếu thành công sẽ có dạng như bên dưới và file thư viện sẽ được tạo trong thư mục qtbase/plugins/sqldrivers/ :
/opt/Qt5.7.0/5.7/gcc_64/bin/moc -DQT_NO_MTDEV -DQT_NO_LIBUDEV -DQT_NO_TSLIB -DQT_NO_LIBINPUT -DQT_NO_CAST_TO_ASCII -DQT_NO_CAST_FROM_ASCII -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_PLUGIN -DQT_...
...
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/main.o .obj/qsql_mysql.o .obj/moc_qsql_mysql_p.o -L/usr/local/lib -L/usr/lib64/mysql -lmysqlclient_r -lz -lcrypt -lnsl -lm -lssl -lcrypto -L/opt/Qt5.7.0/5.7/gcc_64/lib -lQt5Sql -lQt5Core -lpthread 
mv -f libqsqlmysql.so ../../../../plugins/sqldrivers/

Chúng ta sẽ di chuyển đến thư mục như trên để kiểm tra

cd ../../../../plugins/sqldrivers/
ldd libqsqlmysql.so

Nếu output như bên dưới là bạn đã thành công và chỉ cần copy ghi đè lên file thư viện cũ trong đường dẫn như bên dưới

linux-vdso.so.1 =>  (0x00007fff5d3fe000)
libmysqlclient.so.18 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 (0x00007f98f988d000)
libQt5Sql.so.5 => /opt/Qt5.1/5.1.0/gcc_64/lib/libQt5Sql.so.5 (0x00007f98f964d000) 
libQt5Core.so.5 => /opt/Qt5.1/5.1.0/gcc_64/lib/libQt5Core.so.5 (0x00007f98f8fc4000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f98f8cc0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f98f88ca000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f98f86b3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f98f84af000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f98f8291000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f98f7f8c000)
libicui18n.so.51 => /opt/Qt5.1/5.1.0/gcc_64/lib/libicui18n.so.51 (0x00007f98f7b73000) 
libicuuc.so.51 => /opt/Qt5.1/5.1.0/gcc_64/lib/libicuuc.so.51 (0x00007f98f77ec000) 
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f98f75ea000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f98f73e2000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f98f70e5000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f98f6ecf000)
lib64/ld-linux-x86-64.so.2 (0x00007f98f9dda000) 
libicudata.so.51 => /opt/Qt5.1/5.1.0/gcc_64/lib/libicudata.so.51 (0x00007f98f5785000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f98f5546000)
Đường dẫn file thư viện sẽ được chép đến và ghi đè lên.
$QT_INSTALL_PLACE/$QT_VERSION_NUMBER/$COMPILE_TOOL_KIT_NAME/plugins
hoặc
/usr/lib/i386-linux-gnu/$QT_VERSION/plugins/
hoặc
/usr/lib/x86_64-linux-gnu/$QT_VERSION/plugins/

Hoặc có thể dùng lệnh sudo make install để chương trình tự copy.

Trở về với thư mục như ban nảy (sourcepackagedir/qtbase/src/plugins/sqldrivers/mysql)

sudo make install

Output như bên dưới là okay

install -m 755 -p ../../../../plugins/sqldrivers/libqsqlmysql.so /opt/Qt5.7.0/5.7/gcc_64/plugins/sqldrivers/libqsqlmysql.so
strip --strip-unneeded /opt/Qt5.7.0/5.7/gcc_64/plugins/sqldrivers/libqsqlmysql.so
install -m 644 -p /home/chadrick/Downloads/qt-everywhere-opensource-src-5.7.0/qtbase/lib/cmake/Qt5Sql/Qt5Sql_QMYSQLDriverPlugin.cmake /opt/Qt5.7.0/5.7/gcc_64/lib/cmake/Qt5Sql/

Ở một số trường hợp sau khi thực hiện lệnh qmake và make vẫn còn lỗi

  • qmake "INCLUDEPATH+=/opt/lampp/include" "LIBS+=-L/usr/local/lib -lmysqlclient_r" mysql.pro
  • make

File thư viện tạo ra vẫn bị lỗi  libmysqlclient_r.so.16 => not found hoặc libmysqlclient_r.so.18 => not found thì các bạn vào đường dẫn sau:

/opt/lampp/lib để copy file libmysqlclient_r.so.18 hoặc libmysqlclient_r.so.16 vào /usr/lib/x86_64-linux-gnu/ hoặc /usr/lib/i386-linux-gnu/ hoặc nơi chứ thư viện khi cài Qt theo file .run

  • /opt/lampp/lib là đường dẫn nơi chứa thư viện của MySQL Server
sudo cp libmysqlclient.so.18 /usr/lib/x86_64-linux-gnu/

Sau khi copy qua thì mọi thứ đã okay.

screenshot-from-2018-04-14-21-14-56.png

Screenshot from 2018-04-14 21-15-10

Các lỗi thường gặp phải:

Lỗi 1

Lệnh:

qmake "INCLUDEPATH+=/usr/local/include" "LIBS+=-L/usr/local/lib -lmysqlclient_r" mysql.pro

Lỗi

Project ERROR: Could not find feature framework.
Project ERROR: Could not find feature c++11.

Nguyên nhân:

Qt version mismatch: có nghĩa là bạn tải Project ở qt-project  không đúng với phiên bản Qt của bạn.

Hướng giải quyết:

Kiểm tra phiên bản qmake của bạn:

qmake --version

Output của lệnh:

QMake version 3.0
Using Qt version 5.7.0 in /opt/Qt5.7.0/5.7/gcc_64/lib

Lên google gõ “qt everywhere opensource src [version Qt của bạn]” => Vào trang đầu tiên để tải về nhé (khoảng hơn 450MB, và hơn 2GB sau khi giải nén)

Lỗi 2: (chỉ bị lỗi khi bạn bài Qt từ file .run)

 qmake Error: qmake: could not exec '/usr/lib/x86_64-linux-gnu/qt4/bin/qmake': No such file or directory

Lỗi này xuất hiện khi bạn dùng lệnh qmake mà khi lệnh này chưa được khai báo trong đường dẫn PATH.

Hướng giải quyết (export từng lệnh nhé)

Lưu ý: đây chỉ là export tạm thôi nên chỉ có chính terminal thực hiện export mới có thể thực thi được lệnh qmake sau khi khai báo.

export PATH="$QT_INSTALL_PLACE/$QT_VERSION_NUMBER/$COMPILE_TOOL_KIT_NAME/bin/":$PATH 
exportLD_LIBRARY_PATH="$QT_INSTALL_PLACE/$QT_VERSION_NUMBER/$COMPILE_TOOL_KIT_NAME/lib/":$LD_LIBRARY_PATH
exportLD_LIBRARY_PATH="$QT_INSTALL_PLACE/$QT_VERSION_NUMBER/$COMPILE_TOOL_KIT_NAME/plugins/":$LD_LIBRARY_PATH
exportLIBRARY_PATH="$QT_INSTALL_PLACE/$QT_VERSION_NUMBER/$COMPILE_TOOL_KIT_NAME/lib/":$LIBRARY_PATH
export LIBRARY_PATH="$QT_INSTALL_PLACE/$QT_VERSION_NUMBER/$COMPILE_TOOL_KIT_NAME/plugins/":$LIBRARY_PATH

Ví dụ:

exportPATH="/opt/Qt5.1/5.1.0/gcc_64/bin/":$PATH
exportLD_LIBRARY_PATH="/opt/Qt5.1/5.1.0/gcc_64/lib/":$LD_LIBRARY_PATH
exportLD_LIBRARY_PATH="/opt/Qt5.1/5.1.0/gcc_64/plugins/":$LD_LIBRARY_PATH
exportLIBRARY_PATH="/opt/Qt5.1/5.1.0/gcc_64/lib/":$LIBRARY_PATH 
exportLIBRARY_PATH="/opt/Qt5.1/5.1.0/gcc_64/plugins/":$LIBRARY_PATH

Lỗi 3:

make: Nothing to be done for `first'.
Lỗi này xuất hiện khi thực hiện lệnh make nhiều lần.
Hướng giải quyết:
make clean
Output
rm -f .moc/moc_qsql_mysql_p.cpp
rm -f .moc/main.moc
rm -f .obj/main.o .obj/qsql_mysql.o .obj/moc_qsql_mysql_p.o
rm -f *~ core *.core

Lỗi 4: (thư viện khi thực hiện qmake)

fatal error: mysql.h: No such file or directory

Lỗi này do đường dẫn đến nơi cài MySQL bị sai do đó chương trình không thể tìm thấy file mysql.h.

Hướng giải quyết:

Thực hiện lại lệnh

qmake "INCLUDEPATH+=[đường dẫn tới thư mục cài MySQL Server]" "LIBS+=-L/usr/local/lib -lmysqlclient_r" mysql.pro

Lỗi 5:

fatal error: QtSql/private/qsqldriver_p.h: No such file or directory

Hướng giải quyết:

sudo apt-get install qtbase5-private-dev

Lỗi 6: (Makefile)

/usr/bin/ld.gold: error: cannot find -lmysqlclient_r
/usr/bin/ld.gold: error: cannot find -lmysqlclient
....

Lỗi này do đường dẫn trong file make bị sai.

Hướng giải quyết:

  • Vào thư mục …../qtbase/src/plugins/sqldrivers/mysql (Ví dụ: /home/khoahnd1996/Downloads/qt-everywhere-opensource-src-5.5.1/qtbase/src/plugins/sqldrivers/mysql)
  • Mở Makefile lên và tìm dòng LIBS = $(SUBLIBS) -L[đường dẫn tới thư viện MySQL Server] -lmysqlclient_r -lmysqlclient -lz -lm -lrt -ldl -lQt5Sql -lQt5Core -lpthread
  • Sửa đường dẫn cho đúng và lưu lại.

screenshot-from-2018-04-14-21-56-19.png

Chúc các bạn thành công!

khoahnd1996

Bình luận