Some doubts about Linux deployment
-
I read a lot of threads and tutorials about the Linux deployment of Qt6 but still I have a couple of doubts I cannot answer by myself.
-
Out of curiosity, if I want to link my application statically, do I need to build the Qt libraries from sources or is there a way to install them using the Qt installer? I don't find anything related in the available items and in the installation folder I just find few *.a files
-
I'm able to collect all the needed shared libraries but when I deploy them along the executable on the target device (Ubuntu 24.04 like my dev machine) it still does not find the libraries. I need to put them in a system folder or set
LD_LIBRARY_PATH
to the current folder. Either way it's not acceptable.
I just want to place all the files inside a folder and running the executable it should work... is it possible?
I mean, is there a way to configure the executable to search the libraries in the current folder? -
-
-
I believe nobody supplies static libraries for Qt and you have to build them yourself.
-
Did you do your own "deployment" or did you use linuxdeployqt as you ought do? If the latter does not help (don't know, never used it) then you need to either add
.
toLD_LIBRARY_PATH
outside of your program e.g. in a "wrapper" which sets that and runs your program or you might change the rpath in the executable at link time viag++ -Wl,-R.
or-Wl,-rpath -Wl,'$ORIGIN'
.
https://stackoverflow.com/questions/41074720/why-linux-doesnt-search-for-shared-libraries-in-the-same-folder
https://unix.stackexchange.com/questions/22926/where-do-executables-look-for-shared-objects-at-runtime
-
-
@Mark81
If for some reason you cannot run linuxdeployqt (I do not know why, but never tried it) then you might have a problem if your own deploy does not do what it does.If
QMAKE_LFLAGS_RPATH
exists it might be a good thing to use. See if it generates the right link line, if it does you're good and if it does not you're not! Assuming you're still using qmake not cmake for Qt6. -
I tried both solutions, but it seems they don't work (or I'm missing something).
The executable still searches for system libraries first:$ ldd MyApp ./MyApp: /lib/x86_64-linux-gnu/libQt6Core.so.6: version `Qt_6.8' not found (required by ./MyApp) linux-vdso.so.1 (0x00007d3eaa232000) libQt6Widgets.so.6 => /lib/x86_64-linux-gnu/libQt6Widgets.so.6 (0x00007d3ea9a00000) libQt6Gui.so.6 => /lib/x86_64-linux-gnu/libQt6Gui.so.6 (0x00007d3ea9200000) libQt6SerialPort.so.6 => /lib/x86_64-linux-gnu/libQt6SerialPort.so.6 (0x00007d3eaa1d7000) libQt6Core.so.6 => /lib/x86_64-linux-gnu/libQt6Core.so.6 (0x00007d3ea8c00000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007d3ea8800000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007d3eaa1a7000) ...
even if I put the shared libraries in the same directory:
$ tree . . ├── libQt6Core.so -> libQt6Core.so.6 ├── libQt6Core.so.6 -> libQt6Core.so.6.8.0 ├── libQt6Core.so.6.8.0 ├── libQt6Gui.so -> libQt6Gui.so.6 ├── libQt6Gui.so.6 -> libQt6Gui.so.6.8.0 ├── libQt6Gui.so.6.8.0 ├── libQt6SerialPort.so -> libQt6SerialPort.so.6 ├── libQt6SerialPort.so.6 -> libQt6SerialPort.so.6.8.0 ├── libQt6SerialPort.so.6.8.0 ├── libQt6Widgets.so -> libQt6Widgets.so.6 ├── libQt6Widgets.so.6 -> libQt6Widgets.so.6.8.0 ├── libQt6Widgets.so.6.8.0 ├── MyApp └── platforms ├── libqeglfs.so ├── libqlinuxfb.so ├── libqminimalegl.so ├── libqminimal.so ├── libqoffscreen.so ├── libqvkkhrdisplay.so ├── libqvnc.so ├── libqwayland-egl.so ├── libqwayland-generic.so └── libqxcb.so
Here my
.pro
file:QT += core gui serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 #QMAKE_LFLAGS_RPATH += g++ -Wl,-R. or -Wl,-rpath -Wl,'$ORIGIN' QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN'" TARGET = MyApp TEMPLATE = app SOURCES += main.cpp \ mainwindow.cpp \ femtoserial2.cpp HEADERS += mainwindow.h \ femtoserial2.h FORMS += mainwindow.ui target.path = /home/user/bin INSTALLS += target
-
@JonB said in Some doubts about Linux deployment:
If for some reason you cannot run linuxdeployqt (I do not know why, but never tried it) then you might have a problem if your own deploy does not do what it does.
This is quite annoying: You need to use the oldest still supported Linux version instead of the most current one to be able to use linuxdeployqt. The reasoning behind that is that the generated AppImage should work on all currently maintained Linux versions. If you compile on a newer Linux version your app might not run on older version. I haven't found an easy way to circumvent this restriction of linuxdeployqt.
@Mark81 one common solution to your problem is to not run your program directly, but wrap it into a small script. The script can then first set LD_LIBRARY_PATH and after that launch your program (with all the provided command line parameters). Just name the program e.g.
MyApp.bin
and the scriptMyApp
and nobody will notice that they are running a script instead of the program directly when launching MyApp. -
@hskoglund said in Some doubts about Linux deployment:
As a last resort, you can try installing chrpath and patch it manually like this:
chrpath -r "$ORIGIN" MyApp
I get this error:
no rpath or runpath tag found
-
@SimonSchroeder said in Some doubts about Linux deployment:
Just name the program e.g. MyApp.bin and the script MyApp and nobody will notice that they are running a script instead of the program directly when launching MyApp.
That's a good hint!
-
@Mark81 said in Some doubts about Linux deployment:
no rpath or runpath tag found
Ok, I think this did the trick:
patchelf --set-rpath '$ORIGIN' MyApp
Now it looks in the current directory:
$ ldd MyApp linux-vdso.so.1 (0x0000737d573d7000) libQt6Widgets.so.6 => /home/mark/MyApp/dist/./libQt6Widgets.so.6 (0x0000737d56c00000) libQt6Gui.so.6 => /home/mark/MyApp/dist/./libQt6Gui.so.6 (0x0000737d56000000) libQt6SerialPort.so.6 => /home/mark/MyApp/dist/./libQt6SerialPort.so.6 (0x0000737d56bdc000) libQt6Core.so.6 => /home/mark/MyApp/dist/./libQt6Core.so.6 (0x0000737d55800000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x0000737d55400000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x0000737d56b90000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000737d55000000 ...
so far so good, but I have a last issue. When I run the executable I get:
./MyApp ./MyApp: symbol lookup error: /home/mark/MyApp/dist/libQt6Gui.so.6: undefined symbol: _Zls6QDebugRK15QDBusObjectPath, version Qt_6
but I copied the libraries from my Qt 6.8.0 installation, from
/home/mark/Qt/6.8.0/gcc_64/lib/
ThatDebug
looks suspicious: I set the build as release and also the libraries are the release versions. -
@hskoglund said in Some doubts about Linux deployment:
And you copied libQt6DBus.so.6 as well? (maybe a stupid question :-)
It's not a stupid question! I didn't copy this library! Good catch!
-
@SimonSchroeder said in Some doubts about Linux deployment:
This is quite annoying: You need to use the oldest still supported Linux version instead of the most current one to be able to use linuxdeployqt. The reasoning behind that is that the generated AppImage should work on all currently maintained Linux versions. If you compile on a newer Linux version your app might not run on older version. I haven't found an easy way to circumvent this restriction of linuxdeployqt.
Just in case it helps, while I've never had any success with
linuxdeployqt
, I have had success with (and regularly use for FLOSS projects)linuxdeploy
together with thelinuxdeploy-plugin-qt
andlinuxdeploy-plugin-appimage
plugins.ie
linuxdeployqt
is not the same as (linuxdeploy
+linuxdeploy-plugin-qt
) - they are quite separate projects, and personally I can only recommend the latter, which might solve yourlinuxdeployqt
issues too.Cheers.
-
@Paul-Colby I didn't know that
linuxdeploy
had plugins. We are currently usinglinuxdeploy
to create the AppDir and thenlinuxdeployqt
to add the Qt dependencies. However, if I'm not mistakenlinuxdeploy
also requires an older Linux version. (But, as you can see from my example we also didn't manage to create an AppImage withlinuxdeployqt
alone.) -
@SimonSchroeder said in Some doubts about Linux deployment:
@Paul-Colby I didn't know that
linuxdeploy
had plugins. We are currently usinglinuxdeploy
to create the AppDir and thenlinuxdeployqt
to add the Qt dependencies. However, if I'm not mistakenlinuxdeploy
also requires an older Linux version. (But, as you can see from my example we also didn't manage to create an AppImage withlinuxdeployqt
alone.)Actually, I was able to deploy a working appimage using the three tools above! With the "low-level " approaches I still had problems.
I'm pretty new to these tools, but as far as I understand they can work together as plugins or just as three separate calls. I'm using Ubuntu 24.10 right now so they work on pretty modern systems (I didn't test the appimage on older systems because I don't need to support them).