[SOLVED] Problems with setting paths to libs and plugins in Qt app's executable file
-
Hello,
I would like to run my Qt application (let's call it "MyApp") on Ubuntu without Qt installed by putting folders with all necessary Qt libs and plugins in the same directory with the executable file. My app's directory looks like this:
MyAppDeployment ├── lib ├── plugins ├── qml └── MyApp*
While testing the app, I was using a simple bash script to change variables with paths and run the executable file with these new values. The script was like this:
#!/bin/sh export LD_LIBRARY_PATH=`pwd`/lib export QT_PLUGIN_PATH=`pwd`/plugins export QML2_IMPORT_PATH=`pwd`/qml ./MyApp
With the script I was able to run the app on Ubuntu without Qt, but now I would like to do this directly from the executable file, without any scripts. So, I've added to recourses of my app a qt.conf file:
[Paths] Prefix=./ Libraries=lib Plugins=plugins Qml2Imports=qml
I've build the app with this file included and when I tried to run it on Ubuntu WITH Qt installed I've got an error:
This application failed to start because it could not find or load the Qt platform plugin "xcb". Reinstalling the application may fix this problem.
So, I've put the new executable file to the folder with lib, plugins and qml subdirectories and tried to run it from there - everything was working good just as I expected. But when I try to run this executable file with all necessary subdirs on Ubuntu WITHOUT Qt, I was still getting the error message about xcb plugin. I've also tried putting qt.conf in the same folder with executable, but it haven't helped me.
So, why Qt app sees libs and plugin by paths from qt.conf on Ubuntu with Qt, but doesn't do it on Ubuntu without it? Thanks in advance for your answers!
-
Hi, the reason your Qt app is able to load the "xcb" plugin on a PC with Qt installed, is that there is a hardwired path to the plugins (written by the installer) in your libQt5Core.so.5.5.0 file.
There are 7 different ways for Qt to load the plugins (I've written more about it here but in almost all cases the libqxcb.so file needs to be in a subdirectory called platforms for Qt to be happy. You can change the name/place of the directory above it, as you do in your qt.conf file, but the name "platforms" is pretty hardwired :-) -
@hskoglund Thank your for your answer. The problem is that I already have libqxcb.so in a folder called "platforms" (path is "MyApp/plugins/platforms/"). Here is full information about all subdirs:
MyApp/ ├── lib │ ├── libicudata.so.54 │ ├── libicui18n.so.54 │ ├── libicuuc.so.54 │ ├── libqgsttools_p.so.1 │ ├── libQt5Core.so.5 │ ├── libQt5DBus.so.5 │ ├── libQt5Gui.so.5 │ ├── libQt5Multimedia.so.5 │ ├── libQt5MultimediaWidgets.so.5 │ ├── libQt5Network.so.5 │ ├── libQt5Qml.so.5 │ ├── libQt5Quick.so.5 │ ├── libQt5Widgets.so.5 │ └── libQt5XcbQpa.so.5 ├── plugins │ ├── imageformats │ │ └── libqjpeg.so │ ├── mediaservice │ │ └── libgstmediaplayer.so │ ├── platforms │ │ ├── libqlinuxfb.so │ │ ├── libqminimal.so │ │ ├── libqoffscreen.so │ │ └── libqxcb.so │ └── xcbglintegrations │ └── libqxcb-glx-integration.so ├── qml │ ├── QtQuick │ │ └── Window.2 │ │ ├── libwindowplugin.so │ │ ├── plugins.qmltypes │ │ └── qmldir │ └── QtQuick.2 │ ├── libqtquick2plugin.so │ ├── plugins.qmltypes │ └── qmldir └── MyApp
I've also made some experiments with this bash run script:
#!/bin/sh export LD_LIBRARY_PATH=`pwd`/lib export QT_PLUGIN_PATH=`pwd`/plugins export QML2_IMPORT_PATH=`pwd`/qml ./MyApp
I was trying to run MyApp executable file built including qt.conf with this script and everything was running well. Then I started deleting different lines from the script to discover, which subdir executable cannot find. So, I received "xml" error only when I deleted this line:
export LD_LIBRARY_PATH=`pwd`/lib
And executable was running well with script, containing only this lines:
#!/bin/sh export LD_LIBRARY_PATH=`pwd`/lib ./VeniceClassicRadioPlayer
So without the run script executable can successfully load plugins and qml subdirs. It only cannot load libs from lib subdir without script's "help". How can I solve this problem?
-
Hi @Eyeless,
Using a bash script, qt.conf, and custom subfolders seems a bit overcomplicated. Why not follow the tutorial in @hskoglund's blog? using RPATH only requires one extra line in your .pro file.
-
Indeed RPATH is exactly what the doctor ordered!
So in your case, to test, you could type:
chrpath -r \$ORIGIN/lib VeniceClassicRadioPlayer
Note: my blog is not yet updated for Qt 5.5. At least 2 errors: the path setting hardwired into Qt5Core.so is now called qt_prfxpath e.g. "qt_prfxpath=/home/henry/Qt/5.5/gcc_64" and my "grapefruit" stunt doesn't work anymore, i.e. in 5.5 Qt pays attention to the chrpath setting in libqxcb.so.
Edit: forgot, as JKSH suggests, try adding a line to your .pro file, like this:
QMAKE_LFLAGS += -Wl,-rpath,"'$$ORIGIN/lib'" -
I think I have a variation on the above.
We have an application that uses Qt 5.12 and we include the Qt 5.12 libs, plugins it was built against as part of the distribution. On Ubuntu 22, the native version of QT is 5.15 however, and that causes the application to segfault when the GUI window is laucnhed.
I tried the following environment variable settings,
$ env | grep -i "^qt"
QT_ACCESSIBILITY=1
QT_IM_MODULE=ibus
QT_DEBUG_PLUGINS=1
QTDIR=/usr/local/my_distro/revision/lib/qt
QT_QPA_PLATFORM_PLUGIN_PATH=/usr/local/my_distro/revision/lib/qt/plugins/platforms
QT_PLUGIN_PATH=/usr/local/my_distro/revision/lib/qt/plugins/platformsAmong the debug output messages, is the repeated notification that various libwayland libs cannot be found under the system path: /usr/lib/x86_64-linux-gnu/qt5/plugins. The same hapopens for the plugin libraries like libxcb.
In /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqwayland-xcomposite-egl.so: Plugin uses incompatible Qt library (5.15.0) [release] "The plugin '/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqwayland-xcomposite-egl.so' uses incompatible Qt library. (5.15.0) [release]" not a plugin QFactoryLoader::QFactoryLoader() looking at "/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqwayland-xcomposite-glx.so" Found metadata in lib /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqwayland-xcomposite-glx.so,
Yet those libraries exist under /usr/local/my_distro/revision/lib/qt/plugins/platforms but are ignored even with the environment variable settings above.
$ ls /usr/local/my_distro/revision/lib/qt/plugins/platforms/*wayland* /usr/local/my_distro/revision/lib/qt/plugins/platforms/libqwayland-egl.so /usr/local/my_distro/revision/lib/qt/plugins/platforms/libqwayland-xcomposite-egl.so /usr/local/my_distro/revision/lib/qt/plugins/platforms/libqwayland-generic.so /usr/local/my_distro/revision/lib/qt/plugins/platforms/libqwayland-xcomposite-glx.so
The only environment variable setting that seems to allow the GUI window to launch is,
LD_LIBRARY_PATH=/usr/local/my_distro/revision/lib/qt/lib
Even then, the system path /usr/lib/x86_64-linux-gnu/qt5 is still always searched. We prefer not to set LD_LIBRARY_PATH since it can ovveride RPATH. I've run "ldd -r" on every library and binary in the distribution, and there are no instances of "not found" for a library or listing for an unresolved symbol. RAPTH appaers to be set corretly in the GUI application and in the Qt libraries included in our distribution.
Please advise as to the variable(s) and/or other setting(s) to defeat searching the system path /usr/lib/x86_64-linux-gnu/qt5 such that LD_LIBRARY_PATH does not have to be used.
-
Hi, your env settings for the plugin paths seem a bit fishy, usually the QT_QPA_PLATFORM_PLUGIN_PATH points to a directory one level below QT_PLUGIN_PATH (assuming you're doing a standard deployment of the plugins where libqxcb.so is residing in a subdirectory called platforms).
You could try:
QT_QPA_PLATFORM_PLUGIN_PATH=/usr/local/my_distro/revision/lib/qt/plugins/platforms
QT_PLUGIN_PATH=/usr/local/my_distro/revision/lib/qt/pluginsAlso you could try setting the plugin path explicitly in your main.cpp before calling QApplications's ctor, say like this:
... QCoreApplication::setLibraryPaths("/usr/local/my_distro/revision/lib/qt/plugins"); QApplication a(argc, argv); ...
This will override env settings for the plugin paths.
To debug when the bad 5.15.0 dlls/plugins are pulled in, open a Terminal and type "lsof -c yourappname" to see what dlls are loaded.