Deploying dynamically linked Qt 5.7 Widgets applic

2019-09-15 03:14发布

I'm trying to deploy a dynamically linked Qt 5.7 Widgets application on CentOS 7. It works on my machine without a problem, even though I don't copy libQt5Widgets.so to build directory. However, if I copy the application to another machine it says:

./Application: error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file: No such file or directory

When I check the dependencies with:

ldd ./Application

the result is:

linux-vdso.so.1 =>  (0x00007ffdb7126000)
libQt5Widgets.so.5 => /opt/Qt5.7.0/5.7/gcc_64/lib/libQt5Widgets.so.5 (0x00007f2d3f33e000)
libQt5Gui.so.5 => /opt/Qt5.7.0/5.7/gcc_64/lib/libQt5Gui.so.5 (0x00007f2d3eb95000)
libQt5Network.so.5 => /opt/Qt5.7.0/5.7/gcc_64/lib/libQt5Network.so.5 (0x00007f2d3e837000)
libQt5Core.so.5 => /opt/Qt5.7.0/5.7/gcc_64/lib/libQt5Core.so.5 (0x00007f2d3e11c000)
libGL.so.1 => /lib64/libGL.so.1 (0x00007f2d3de97000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f2d3dc7b000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f2d3d972000)
libm.so.6 => /lib64/libm.so.6 (0x00007f2d3d66f000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f2d3d459000)
libc.so.6 => /lib64/libc.so.6 (0x00007f2d3d098000)
libz.so.1 => /lib64/libz.so.1 (0x00007f2d3ce81000)
libicui18n.so.56 => /opt/Qt5.7.0/5.7/gcc_64/lib/libicui18n.so.56 (0x00007f2d3c9e7000)
libicuuc.so.56 => /opt/Qt5.7.0/5.7/gcc_64/lib/libicuuc.so.56 (0x00007f2d3c62f000)
libicudata.so.56 => /opt/Qt5.7.0/5.7/gcc_64/lib/libicudata.so.56 (0x00007f2d3ac4b000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f2d3aa47000)
libgthread-2.0.so.0 => /lib64/libgthread-2.0.so.0 (0x00007f2d3a845000)
librt.so.1 => /lib64/librt.so.1 (0x00007f2d3a63c000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f2d3a305000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2d3fb8e000)
libexpat.so.1 => /lib64/libexpat.so.1 (0x00007f2d3a0db000)
libxcb-dri3.so.0 => /lib64/libxcb-dri3.so.0 (0x00007f2d39ed7000)
libxcb-present.so.0 => /lib64/libxcb-present.so.0 (0x00007f2d39cd4000)
libxcb-randr.so.0 => /lib64/libxcb-randr.so.0 (0x00007f2d39ac6000)
libxcb-xfixes.so.0 => /lib64/libxcb-xfixes.so.0 (0x00007f2d398bd000)
libxcb-render.so.0 => /lib64/libxcb-render.so.0 (0x00007f2d396b3000)
libxcb-shape.so.0 => /lib64/libxcb-shape.so.0 (0x00007f2d394af000)
libxcb-sync.so.1 => /lib64/libxcb-sync.so.1 (0x00007f2d392a7000)
libxshmfence.so.1 => /lib64/libxshmfence.so.1 (0x00007f2d390a4000)
libglapi.so.0 => /lib64/libglapi.so.0 (0x00007f2d38e75000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f2d38c4d000)
libXext.so.6 => /lib64/libXext.so.6 (0x00007f2d38a3b000)
libXdamage.so.1 => /lib64/libXdamage.so.1 (0x00007f2d38838000)
libXfixes.so.3 => /lib64/libXfixes.so.3 (0x00007f2d38631000)
libX11-xcb.so.1 => /lib64/libX11-xcb.so.1 (0x00007f2d3842f000)
libX11.so.6 => /lib64/libX11.so.6 (0x00007f2d380f1000)
libxcb-glx.so.0 => /lib64/libxcb-glx.so.0 (0x00007f2d37ed6000)
libxcb-dri2.so.0 => /lib64/libxcb-dri2.so.0 (0x00007f2d37cd1000)
libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f2d37aaf000)
libXxf86vm.so.1 => /lib64/libXxf86vm.so.1 (0x00007f2d378a8000)
libdrm.so.2 => /lib64/libdrm.so.2 (0x00007f2d37699000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f2d37437000)
libXau.so.6 => /lib64/libXau.so.6 (0x00007f2d37233000)

To solve the problem, I've tried to deploy the following libraries:

Qt5.7.0/5.7/gcc_64/lib/libicui18n.so.56
Qt5.7.0/5.7/gcc_64/lib/libicuuc.so.56 
Qt5.7.0/5.7/gcc_64/lib/libicudata.so.56 
Qt5.7.0/5.7/gcc_64/lib/libQt5Core.so.5.7.0
Qt5.7.0/5.7/gcc_64/lib/libQt5Widgets.so.5.7.0
Qt5.7.0/5.7/gcc_64/lib/libQt5Gui.so.5.7.0
Qt5.7.0/5.7/gcc_64/lib/libQt5Network.so.5.7.0

with the application. Also, I've created symbolic links

libQt5Core.so.5
libQt5Widgets.so.5
libQt5Gui.so.5
libQt5Network.so.5

to libQt5Widgets.so.5.0.7 and the other Qt 5.7 libraries. The remaining shared libraries exist in the other machine too. But it still doesn't work.

It is related to the following topics: Qt project release ubuntu - error while loading shared libraries: libQt5Widgets.so.5 and QT5.7 How to deploy Qt Application on Linux. But they don't have a solution.

  1. What can be the problem?
  2. How do I solve it?

Thanks in advance.

1条回答
smile是对你的礼貌
2楼-- · 2019-09-15 03:42

As it is stated here: Qt for Linux/X11 - Deployment (Creating the application package)

... but the main issue with shared libraries is that you must ensure that the dynamic linker will find the Qt libraries. Unless told otherwise, the dynamic linker doesn't search the directory where your application resides.

There are 3 solutions to overcome this problem:

  • You can install the Qt libraries in one of the system library paths (e.g. /usr/lib on most systems).
  • You can pass a predetermined path to the -rpath command-line option when linking the application. This will tell the dynamic linker to look in this directory when starting your application.
  • You can write a startup script for your application, where you modify the dynamic linker configuration (e.g., adding your application's directory to the LD_LIBRARY_PATH environment variable.

  1. I don't prefer the first option not to pollute /usr/bin directory for a simple application.

  2. In Qt Creator's Build & Run tab, the option to Add build library search path to LD_LIBRARY_PATH is checked by default. (Also, in the contents of the Makefile (in the build directory), -rpath option is specified for LFLAGS.) I don't know why but this option does not work for me.

  3. I've prefered the third option. In the link I've provided, there is a script ready to use for this.

Application.sh

#!/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 "$@"

But the documentation warns that:

Note: If your application will be running with "Set user ID on execution," and if it will be owned by root, then LD_LIBRARY_PATH will be ignored on some platforms. In this case, use of the LD_LIBRARY_PATH approach is not an option).

Also, you should beware that according to the documentation, you have to include The Qt xcb platform plugin in platforms/libqxcb.so in your application's directory. You can find it in:

Qt5.7.0/5.7/gcc_64/plugins/platforms/libqxcb.so

After doing these, you'll still have a problem. It will complain that:

This application failed to start because it could not find or load the Qt platform plugin "xcb"
in "".

Available platform plugins are: xcb.

Reinstalling the application may fix this problem.
./Application.sh: line 12:  3783 Aborted (core dumped) $dirname/$appname "$@"

This is because libqxcb.so has other dependencies (you can check it with the command: ldd libqxcb.so):

libQt5XcbQpa.so.5
libQt5DBus.so.5

To solve it, you have to copy the shared libraries from:

Qt5.7.0/5.7/gcc_64/lib/libQt5XcbQpa.so.5.7.0
Qt5.7.0/5.7/gcc_64/lib/libQt5DBus.so.5.7.0

and create the corresponding symbolic links:

libQt5XcbQpa.so.5
libQt5DBus.so.5

in the directory where other shared libraries, your executable and the script resides. It is important that you create the symbolic links for the shared libraries starting with the name libQt5. Otherwise, it still won't be able to open them.

Briefly, your directory content will be as follows:

Application (The executable)
Application.sh (The script you will execute to run your application)
libicudata.so.56
libicui18n.so.56
libicuuc.so.56
libQt5Core.so.5 -> libQt5Core.so.5.7.0
libQt5Core.so.5.7.0
libQt5DBus.so.5 -> libQt5DBus.so.5.7.0
libQt5DBus.so.5.7.0
libQt5Gui.so.5 -> libQt5Gui.so.5.7.0
libQt5Gui.so.5.7.0
libQt5Network.so.5 -> libQt5Network.so.5.7.0
libQt5Network.so.5.7.0
libQt5Widgets.so.5 -> libQt5Widgets.so.5.7.0
libQt5Widgets.so.5.7.0
libQt5XcbQpa.so.5 -> libQt5XcbQpa.so.5.7.0
libQt5XcbQpa.so.5.7.0
platforms/libqxcb.so
查看更多
登录 后发表回答