Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix 'Could not load the Qt platform plugin "xcb" in "" even though it was found.' after fixup_bundle macro?

I'm trying to setting up a standalone binary archive (.tar.gz) that can run on most Linux distros (ex. Blender). I'm still not familiar with CMake. As far as I know, all the dependencies can be resolved at the install step with fixup_bundle macro. And I assume that the install directory should become a standalone app that can be copied and run on other computers without Qt installed? I'm not sure about the role of CPack here.

What I've tried

My Qt installation path is /home/<user>/Qt5.12.2/5.12.2/gcc_64/qmake. I've followed some answers and have copied platform/libqxcb.so and libQt5XcbQpa.so.5 into the install directory. In order to test the standalone package, I change ~/Qt5.12.2 into ~/qt. And this is the error message when the executable run:

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: xcb.

[1]    25965 abort (core dumped)  ./<executable_name>

I've also tried qt.conf and set the Prefix and Plugin path to ./ but that didn't work. One interesting thing I found though is that when I set Plugins = /home/<user>/qt/5.12.2/gcc_64/plugins, a little Qt window shows, but comes with a bunch of error messages:

qrc:/main.qml:4:1: module "QtQuick.Dialogs" is not installed
qrc:/main.qml:1:1: module "QtQuick" is not installed
qrc:/main.qml:3:1: module "QtQuick.Controls" is not installed
......
qrc:/main.qml:3:1: module "QtQuick.Controls" is not installed
qrc:/main.qml:5:1: module "QtQuick.Controls.Styles" is not installed
qrc:/main.qml:2:1: module "QtQuick.Layouts" is not installed

Then, I found some information by testing the two libqxcb.so with ldd, although I'm not sure this is the actual cause.

ldd ~/qt/5.12.2/gcc_64/plugins/platforms/libqxcb.so shows that the original libqxcb.so links the libraries that come with the Qt installation:

        libQt5XcbQpa.so.5 => /home/giokka/qt/5.12.2/gcc_64/plugins/platforms/../../lib/libQt5XcbQpa.so.5 (0x00007ff8936d7000)
        libQt5Gui.so.5 => /home/giokka/qt/5.12.2/gcc_64/plugins/platforms/../../lib/libQt5Gui.so.5 (0x00007ff892d64000)
        libQt5DBus.so.5 => /home/giokka/qt/5.12.2/gcc_64/plugins/platforms/../../lib/libQt5DBus.so.5 (0x00007ff892ad8000)
        libQt5Core.so.5 => /home/giokka/qt/5.12.2/gcc_64/plugins/platforms/../../lib/libQt5Core.so.5 (0x00007ff892343000)
......
        libicui18n.so.56 => /home/giokka/qt/5.12.2/gcc_64/plugins/platforms/../../lib/libicui18n.so.56 (0x00007ff8914ee000)
        libicuuc.so.56 => /home/giokka/qt/5.12.2/gcc_64/plugins/platforms/../../lib/libicuuc.so.56 (0x00007ff891136000)
        libicudata.so.56 => /home/giokka/qt/5.12.2/gcc_64/plugins/platforms/../../lib/libicudata.so.56 (0x00007ff88f751000)
......

ldd <path_to_project>/build/install/platforms/libqxcb.so shows it links to the system Qt library, which is not the one my project built against on:

./platforms/libqxcb.so: /lib64/libQt5XcbQpa.so.5: version `Qt_5_PRIVATE_API' not found (required by ./platforms/libqxcb.so)
./platforms/libqxcb.so: /lib64/libQt5Gui.so.5: version `Qt_5_PRIVATE_API' not found (required by ./platforms/libqxcb.so)
        libQt5XcbQpa.so.5 => /lib64/libQt5XcbQpa.so.5 (0x00007f1d8ea75000)
        libQt5Gui.so.5 => /lib64/libQt5Gui.so.5 (0x00007f1d8e41e000)
        libQt5DBus.so.5 => /lib64/libQt5DBus.so.5 (0x00007f1d8e382000)
        libQt5Core.so.5 => /lib64/libQt5Core.so.5 (0x00007f1d8de62000)
......
        libicui18n.so.63 => /lib64/libicui18n.so.63 (0x00007f1d8cf37000)
        libicuuc.so.63 => /lib64/libicuuc.so.63 (0x00007f1d8cd64000)
        libicudata.so.63 => /lib64/libicudata.so.63 (0x00007f1d8afd0000)
......

Source code

CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(OpenGLUnderQML LANGUAGES CXX)

set(CMAKE_PREFIX_PATH "$ENV{HOME}/Qt5.12.2/5.12.2/gcc_64/lib/cmake")
set(qt_lib_path "$ENV{HOME}/Qt5.12.2/5.12.2/gcc_64")

list(APPEND qt_modules
    Core
    Gui
    Quick
    DBus
)

foreach(module ${qt_modules})
    list(APPEND qt_libs "Qt5::${module}")
endforeach()

include(GNUInstallDirs)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")


find_package(Qt5 COMPONENTS ${qt_modules} REQUIRED)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

include_directories(include/)

list(APPEND headers
    include/Scene.hpp
    include/Renderer.hpp
    include/VertexArray.hpp
    include/VertexBuffer.hpp
    include/VertexLayout.hpp
    include/IndexBuffer.hpp
    include/Shader.hpp
)

list(APPEND qrc
    qml/qml.qrc
    res/fonts.qrc
    res/shaders.qrc
)

add_executable(${PROJECT_NAME}
    src/main.cpp
    src/Scene.cpp
    src/Renderer.cpp
    src/VertexArray.cpp
    src/VertexBuffer.cpp
    src/VertexLayout.cpp
    src/IndexBuffer.cpp
    src/Shader.cpp
    ${headers}
    ${qrc}
)

target_link_libraries(${PROJECT_NAME}
    PUBLIC
        ${qt_libs}
)


file(RELATIVE_PATH _rel "${CMAKE_INSTALL_PREFIX}/install" "${CMAKE_INSTALL_PREFIX}")
set(_rpath "\$ORIGIN/${_rel}")
file(TO_NATIVE_PATH "${_rpath}/install" app_RPATH)

set_target_properties(${PROJECT_NAME}
    PROPERTIES
        SKIP_BUILD_RPATH OFF
        BUILD_WITH_INSTALL_RPATH OFF
        INSTALL_RPATH ${app_RPATH}
        INSTALL_RPATH_USE_LINK_PATH ON
)

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_BINARY_DIR}/install)
install(
    CODE "
include(BundleUtilities)
fixup_bundle(\"${CMAKE_BINARY_DIR}/install/${PROJECT_NAME}\" \"\" \"\")
"
    DESTINATION ${CMAKE_BINARY_DIR}/install
    COMPONENT Runtime
)

install(FILES "$<TARGET_FILE:Qt5::QXcbIntegrationPlugin>" DESTINATION ${CMAKE_BINARY_DIR}/install/platforms)

qt.conf

[Paths]
Prefix = ./
Plugins = /home/giokka/qt/5.12.2/gcc_64/plugins

Update01:

This is my qt.conf file, but it doesn't work.

[Paths]
Prefix = .
Libraries = lib
Qml2Imports = qml
Plugins = plugins

However, this script works on my compiling computer but not on the other computer:

export LD_LIBRARY_PATH=`pwd`/lib
export QML_IMPORT_PATH=`pwd`/qml
export QML2_IMPORT_PATH=`pwd`/qml
export QT_QPA_PLATFORM_PLUGIN_PATH=`pwd`/plugins/platforms
./OpenGLUnderQML

My bundle package content:

lib
OpenGLUnderQML (the executable)
plugins
qml
qt.conf
startapp.sh (the script above)

lib, plugins, and qml are fully copied from QTDIR (about 500 MB), so there should be no library or plugin missed.

like image 238
Luis Kao Avatar asked Aug 05 '19 15:08

Luis Kao


People also ask

How do you fix no QT platform plugin could be initialized error this application failed to start?

Sometimes corrupted system files can trigger various errors and issues when running your apps such as the “no Qt platform plugin could be initialized” error. So, we recommend you run an SFC scan or DISM to check system files.

What is Qt platform plugin Linux?

On Linux, the xcb QPA (Qt Platform Abstraction) platform plugin is used. It provides the basic functionality needed by Qt GUI and Qt Widgets to run against X11. Its library dependencies are described the following table.

What is Qt platform plugin windows?

Qt is a C++-based framework that is designed to create applications on Windows, Android, Linux, and other platforms. While it is not a programming language on its own, apps that are based on it need to have the framework installed on their machines to be able to run.

What is Qt platform Abstraction?

The Qt Platform Abstraction (QPA) is the platform abstraction layer for Qt 5 and replaces Qt for Embedded Linux and the platform ports from Qt 4. QPA plugins are implemented by subclassing various QPlatform* classes.


3 Answers

You have multiple questions here so I'll address them separately.

1. CMake uses wrong Qt installation.

The entry point for CMake here is the find_package function. This function is using heuristics when searching for libraries. Here's a fragment of the documentation:

<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/                 (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/                       (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/         (U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/         (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/               (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (W/U)

So your prefix path should be

set(CMAKE_PREFIX_PATH "$ENV{HOME}/Qt5.12.2/5.12.2/gcc_64")

In most cases this should be enough. If this is not enough then the goto way is to modify the PATH variable before executing your CMake command like so:

export PATH=~/Qt5.12.2/5.12.2/gcc_64:$PATH
cmake .. # do your cmake stuff

A good practice here is to have a system-wide environment variable called QTDIR pointing to the proper installation of Qt (e.g. export QTDIR=/Qt5.12.2/5.12.2/gcc_64 in your .bash_profile) and use it instead.

2. CMake can not find the plugins.

The fixup_bundle command from BundleUtilities module is only changing the dynamic library load paths and copying the necessary to the bundle. There's more to building a distributable Qt application than just changing the libraries - see documentation. For Windows and MacOS Qt provides a special tools: windeployqt and macdeployqt. For Linux however there's no official tool but you can take a look at the unofficial linuxdeployqt. In any case the most important guide for you would be "Qt for Linux/X11 - Deployment". The fixup_bundle can not fix the plugins because the mechanism of loading plugins is different - they are loaded dynamically from code and on demand.

To put it simple you need to know which plugins you use and which resources the Qt modules require apart from them. Once you figure that out - copy them to your bundle. The mentioned tools do exactly that (on top of fixing the dynamic libraries).

like image 99
Teivaz Avatar answered Nov 24 '22 06:11

Teivaz


I am working on Pop!_OS a Linux variant of Ubuntu 21.04 trying to build a QT5 app in Pycharm. It took me 1 day to finally find this solution for me:

There seems to be a conflict between cv2 (opencv-python) and QT5 that causes this error. I had to uninstall opencv-python and install opencv-python-headless to resolve the issue:

pip uninstall opencv-python
pip install opencv-python-headless
like image 25
ZiglagTheOrc Avatar answered Nov 24 '22 06:11

ZiglagTheOrc


I ran into a very similar problem with the same error message. First, debug some by turning on

export QT_DEBUG_PLUGINS=1

and rerun the application. For me this revealed the following:

"Cannot load library /home/.../miniconda3/lib/python3.7/site-packages/PyQt5/Qt/plugins/platforms/libqxcb.so: (libxkbcommon-x11.so.0: cannot open shared object file: No such file or directory)"

"Cannot load library /home/.../miniconda3/lib/python3.7/site-packages/PyQt5/Qt/plugins/platforms/libqxcb.so: (libxkbcommon-x11.so.0: cannot open shared object file: No such file or directory)"

Indeed, I was missing libxkbcommon-x11.so.0 and libxkbcommon-x11.so.0. Next, check your architecture using dpkg from the linux command line. (For me, the command "arch" gave a different and unhelpful result)

dpkg --print-architecture #result for me: amd64

I then googled "libxkbcommon-x11.so.0 ubuntu 18.04 amd64", and likewise for libxkbcommon-x11.so.0, which yields those packages on packages.ubuntu.com. That told me, in retrospect unsurprisingly, I'm missing packages called libxkbcommon-x11-0 and libxkbcommon-0, and that installing those packages will include the needed files, but the dev versions will not. Then the solution:

sudo apt-get update

sudo apt-get install libxkbcommon0

sudo apt-get install libxkbcommon-x11-0

like image 26
Schroeder Avatar answered Nov 24 '22 07:11

Schroeder