PDA

View Full Version : Link problems with static MySQL plugin



nurtsi
15th September 2007, 10:32
I have a little app that uses the SQL module from qt. I can compile (and run) this app fine on Ubuntu (where the qt lib is apparently built without plugins).

When I first tried my app in Gentoo, it compiled fine, but didn't find the SQL drivers during run-time (since they are compiled as plugins in Gentoo). I tried to convert my app to use the plugin approach (Added Q_IMPORT_PLUGIN to my code and QTPLUGINS to project), but now I get this error during linking:



g++ -o ../../logind Main.cpp -L../../lib -L/usr/lib/qt4 -lsockets -lssl -lcommon -lsrp -ldotconfpp -L/usr/lib/qt4/plugins/sqldrivers/ -lqsqlmysql -lQtSql -L/usr/lib/mysql -L/usr/lib/qt4 -lQtCore -lz -lm -lrt -ldl -lpthread
Main.o: In function `StaticqsqlmysqlPluginInstance':
Main.cpp:71: undefined reference to `qt_plugin_instance_qsqlmysql()'
collect2: ld returned 1 exit status
make: *** [../../logind] Error 1


The offending line in Main.cpp is:



Q_IMPORT_PLUGIN(qsqlmysql);


My project file for the app is:



SOURCES += Main.cpp
INCLUDEPATH += ../

LIBPATH += ../../lib
LIBS += -lsockets -lssl -lcommon -lsrp -ldotconfpp

QT = core sql
QTPLUGIN += qsqlmysql

CONFIG += debug

TARGET = ../../logind


I have libqsqlmysql.so in /usr/lib/qt4/plugins/sqldrivers.

For what it's worth, I use qt 4.3.1 and it was configured with the following:



./configure -stl -verbose -largefile -confirm-license -platform linux-g++ -xplatform linux-g++ -no-rpath -prefix /usr -bindir /usr/bin -libdir /usr/lib/qt4 -datadir /usr/share/qt4 -docdir /usr/share/doc/qt-4.3.1-r1 -headerdir /usr/include/qt4 -plugindir /usr/lib/qt4/plugins -sysconfdir /etc/qt4 -translationdir /usr/share/qt4/translations -examplesdir /usr/share/qt4/examples -demosdir /usr/share/qt4/demos -reduce-relocations -no-accessibility -cups -no-xinerama -opengl -no-nis -qt-gif -system-libpng -system-libjpeg -system-libtiff -system-zlib -no-libmng -release -no-separate-debug-info -plugin-sql-mysql -I/usr/include/mysql -L/usr/lib/mysql -no-sql-psql -no-sql-ibase -no-sql-sqlite -no-sql-sqlite2 -no-sql-odbc -qdbus -no-glib -no-qt3support -openssl -no-pch -no-tablet -xrender -xrandr -xkb -xshape -sm -nomake examples


From what library should `qt_plugin_instance_qsqlmysql()' come from? Or is there something else wrong in my approach?

wysota
19th September 2007, 10:40
Your Qt is compiled in shared mode, so you can't use static plugins. You have to use regular plugins. First verify if you have them in your sqldrivers directory. If so, check if you have libmysqlclient installed as the driver won't work without it.

nurtsi
20th September 2007, 13:30
I have the plugin:



$ ls /usr/lib/qt4/plugins/sqldrivers/
libqsqlmysql.so


And I have libmysqlclient:



$ ls /usr/lib/libmysqlclient*
/usr/lib/libmysqlclient.so /usr/lib/libmysqlclient.so.15.0 /usr/lib/libmysqlclient_r.so /usr/lib/libmysqlclient_r.so.15.0
/usr/lib/libmysqlclient.so.15 /usr/lib/libmysqlclient.so.15.0.0 /usr/lib/libmysqlclient_r.so.15 /usr/lib/libmysqlclient_r.so.15.0.0


I re-read the plugins-howto and found some stuff I missed earlier. Do I actually need to load the plugin manually (instead of just linking against it) with QPluginLoader by declaring an interface and writing some wrapper class to it?

I made this very simple test which I want to get working.

Test.cpp:


#include <QSqlDatabase>

int main(int argc, char** argv)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
return 0;
}


Test.pro:


SOURCES += Test.cpp
QT = sql
QTPLUGIN = qsqlmysql
TARGET = test


It compiles fine but I run it and it doesn't find any SQL drivers:



$ ./test
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers:

nurtsi
20th September 2007, 13:45
I actually managed to get it working. Apparently you need to instantiate QApplication (or in this case QCoreApplication) which actually loads the plugins. Nothing in the plugin documentation explicitly states this, but anyhow this works:



#include <QSqlDatabase>
#include <QCoreApplication>

int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

return 0;
}

wysota
20th September 2007, 15:32
Yes, plugins are loaded in QCoreApplication constructor (I must have missed the lack of QApplication in your previous code, sorry). By the way ".so" is a shared object, not a static plugin, therefore you're using real plugins, not static ones now.