Hi,
for my Qt6 Qml Application I want to create installers for all major platforms (Linux, Mac Os, Windows).
I do already have a working cmake files which handles the non Qt6 part of my application. Additionally I also managed to deploy an application, which uses the core part of Qt6 (such as QStandardPaths) for instance.
It looks like this:
// Install some Runtime Dependencies
install(TARGETS BeansClient COMPONENT Beans
RUNTIME_DEPENDENCIES
PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-"
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
DIRECTORIES $<TARGET_FILE_DIR:Qt6::Core>
FRAMEWORK DESTINATION Beans.app/Contents/Frameworks
)
// Install shared libraries of manually listed dependencies
foreach(lib IN ITEMS CLI11::CLI11 sqlpp11::sqlite3 spdlog::spdlog)
get_target_property(target_type ${lib} TYPE)
if (target_type STREQUAL SHARED_LIBRARY)
get_target_property(real_lib ${lib} ALIASED_TARGET)
install(TARGETS ${real_lib} COMPONENT Beans)
endif ()
endforeach()
But yeah for Qt6 with GUI and qml in particular everythings seems to be more involved. Simply adding for instance
DIRECTORIES $<TARGET_FILE_DIR:Qt6::Core> $<TARGET_FILE_DIR:Qt6::Quick>
helps a little bit. But is not enough. Currently I get the following error message on startup of my app:
qt.core.plugin.factoryloader: checking directory path "/opt/BeansClient 0.3.0/bin/platforms" ...
qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
fish: Job 1, '"/opt/BeansClient 0.3.0/bin/Bea…' terminated by signal SIGABRT (Abort)
A recent blog entry (Qt's CMake deployment API) already suggest that depoying Qt application and QML applications in particular is a little bit more involved. Maybe @jobor can help here, as you are the author of this article and seem to be very involved in the project. Hope it’s okay that I tag you!
So from my understanding for Windows / Mac Os something like
qt_generate_deploy_qml_app_script(TARGET BeansClient FILENAME_VARIABLE deploy_script)
install(SCRIPT ${deploy_script})
would work but well it’s only working on Windows and Mac Os. So I still need a solution for Linux. How can I currently do it on Linux?
And I also wonder what are the general steps making this works / what makes Qt6 difficult to deploy. The first step getting the shared libs installed did seem quite easy:
// Install some Runtime Dependencies
install(TARGETS BeansClient COMPONENT Beans
RUNTIME_DEPENDENCIES
PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-"
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
DIRECTORIES $<TARGET_FILE_DIR:Qt6::Core> $<TARGET_FILE_DIR:Qt6::Quick>
FRAMEWORK DESTINATION Beans.app/Contents/Frameworks
)
This install stuff like libQt6QmlModels.so.6 libQt6QmlModels.so.6 libQt6QmlModels.so.6 …
From the blog post I got that qml files need to be installed as well. Although I don’t quite understand why. Aren’t qml files compiles in Qt6 in the application?
What else needs to be done? Some Input would be great.
Do you have a timeline when Qt6 deployment will work out of the box for Linux as well? So I can see if it’s even worth the effort to come up with my own solution right now.