PDA

View Full Version : Qt 5 linux deployment - using qt.conf for dynamic linking



te777
30th March 2013, 13:18
I have a Qt 5 app that I don't want to opensource (so I don't want to do a static build of Qt 5 from source). I'm trying to dynamic link the required dependencies using the ldd command, and a qt.conf file in the same folder as the executable. Is this possible? I really would rather not do a static build of Qt 5 and opensource my app. I would like to offer my app as a tar.gz (with dependencies). Here's what I have in my qt.conf:

[Paths]
PrefixPath = data
LibrariesPath = libs_32
TranslationsPath = translations

And my folder looks like this:

Executable
qt.conf
data/libs_32/
data/translations/
platforms/

libs_32 contains the dependencies listed by the ldd command. Also, do I need translations?

The above configuration doesn't work. It only works with Qt 5 installed, which means it's looking for some hard-coded paths I'm missing or configuring incorrectly. Am I missing something or doing something wrong? Any input would greatly be appreciated. Thanks in advance.

ChrisW67
30th March 2013, 21:49
You do not need qt.conf to deploy using dynamic linking (it cannot be read until after QtCore loads anyway). Place the Qt libraries in the same folder as the program executable, the plugins in the relevant subfolder (sqldrivers, platform, imageformats etc.). On Windows that is sufficient, and on Linux you need a wrapper script as described in the deployment docs.
http://qt-project.org/doc/qt-5.0/qtdoc/deployment-windows.html
http://qt-project.org/doc/qt-5.0/qtdoc/deployment-x11.html

te777
31st March 2013, 01:39
I used the wrapper script. It didn't work. In my app folder I have:

myapp
myapp.sh
all dependencies fromm the ldd command
platforms/

Any ideas?

Added after 1 6 minutes:

The Qt libraries needed (libicuxxx, libQt5Corexxx, libQt5Guixxx, libQt5WidgetsXXX) are listed in the Qt 5 library as links to other versions of those files. Maybe resolving the dependencies is having a problem with that.

ChrisW67
31st March 2013, 09:28
The links in the installed Qt library typically look like this:

# These links all point to a real file
/usr/lib64/qt4/libQtGui.so -> libQtGui.so.4.8.4
/usr/lib64/qt4/libQtGui.so.4 -> libQtGui.so.4.8.4
/usr/lib64/qt4/libQtGui.so.4.8 -> libQtGui.so.4.8.4
# This is the real file
/usr/lib64/qt4/libQtGui.so.4.8.4

The application will be linked to a major Qt version, e.g. 4, and the linker will be instructed to look for libQtGui.so.4 (or 5). So you can either copy the real file as libQtGui.so.4, or copy libQtGui.so.4.8.4 as-is and also create libQtGui.so.4 as a symbolic link to it. The first approach is less verbose, the second more descriptive of exactly what Qt version is involved but limited to file systems that can maintain the symlink. The LD_LIBRARY_PATH set by the wrapper script ensures the copies on the local folder are found where they normally would not be.

te777
31st March 2013, 11:29
I tried both ways already. There seems to be a problem with dynamic linking with Qt 5. Do you have any Qt 4 apps you can build in Qt 5 try dynamic linking with it? I'll see if I can try building my app in Qt 4 and try the dynamic linking with it.

Added after 1 51 minutes:

I did a build in Qt 4.8.2 (installed from software manager in Linux Mint 14 32 bit) and everything works perfectly. I even used a qt.conf setup and that works too (not all those dependencies in the same folder as the executable). There's definitely a problem with dynamic linking with Qt 5. Thanks for the help. Much appreciated.

ChrisW67
1st April 2013, 04:55
There's definitely no problem with dynamic linking in Qt5.
main.cpp:


#include <QApplication>
#include <QWidget>

int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget w;
w.resize(640, 480);
w.show();
return app.exec();
}

test.sh straight from the docs:


#!/bin/sh
appname=`basename $0 | sed s,\.sh$,,`

dirname=`dirname $0`
tmp="${dirname#?}"

if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/$appname "$@"

Deployed files


./test
./test.sh
./libQt5Core.so.5 # required by test
./libQt5Gui.so.5 # required by test
./libQt5Widgets.so.5 # required by test
./libQt5DBus.so.5 # required by platform plugin
./libicuuc.so.49 # required by Qt5Core
./libicudata.so.49 # required by Qt5Core
./libicui18n.so.49 # required by Qt5Core
./platforms
./platforms/libqxcb.so # required for X11 on Linux

Check that it won't run without wrapper:


$ ./test
./test: error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file: No such file or directory
$ ldd test
linux-vdso.so.1 (0x00007fff7b3ff000)
libQt5Widgets.so.5 => not found
libQt5Gui.so.5 => not found
libQt5Core.so.5 => not found
libGL.so.1 => /usr/lib64/libGL.so.1 (0x00007fe8428c1000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe8426a4000)
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/libstdc++.so.6 (0x00007fe8423a0000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe8420aa000)
libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/libgcc_s.so.1 (0x00007fe841e94000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe841aea000)
libnvidia-tls.so.313.26 => /usr/lib64/libnvidia-tls.so.313.26 (0x00007fe8418e7000)
libnvidia-glcore.so.313.26 => /usr/lib64/libnvidia-glcore.so.313.26 (0x00007fe83f3e4000)
libX11.so.6 => /usr/lib64/libX11.so.6 (0x00007fe83f0a5000)
libXext.so.6 => /usr/lib64/libXext.so.6 (0x00007fe83ee93000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe83ec8e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe842be4000)
libxcb.so.1 => /usr/lib64/libxcb.so.1 (0x00007fe83ea6d000)
libXau.so.6 => /usr/lib64/libXau.so.6 (0x00007fe83e869000)
libXdmcp.so.6 => /usr/lib64/libXdmcp.so.6 (0x00007fe83e663000)

Run it with the wrapper:


./test.sh

Starts no problem.

te777
1st April 2013, 13:21
I was missing libQt5DBus. I didn't know I needed it thanks. Works now.

te777
1st April 2013, 18:36
ChrisW67, do you know to use qt.conf with a Qt 5 developed application. I can get qt.conf to work with a Qt 4.8.2 developed app, but not Qt 5.0.1

Here's my qt.conf:

[Paths]
Libraries = libs

Here's my app folder:

myapp
libs/
platforms/
qt.conf

The dependencies are in the libs folder. I know you already provided me a solution with a shell file, bit I'd like to know how to use a qt.conf file with a Qt 5 developed app. And thanks a lot for your help. I really appreciate it.

c1tru55
22nd May 2014, 14:45
Have tried exactly the same approach, but get next error, when trying to launch shell script:

./test: symbol lookup error: /home/user/test/./libQt5Widgets.so.5: undefined symbol: _ZTI15QGuiApplication

How fix it?

anda_skoa
23rd May 2014, 16:40
Do you have the QtGui library?

Cheers,
_