Deploying to Linux with CMake
December 22, 2022 by Jörg Bornemann | Comments
A while ago, I blogged about our CMake deployment API that allows you to enhance the cmake --install
step with instructions that deploy Qt libraries, plugins and assets. At the time of writing, Linux was not supported yet. But not anymore: Qt 6.5 comes with deployment support for Linux!
Quick recap how it looks like to deploy a simple Qt application. Consider the following project.
cmake_minimum_required(VERSION 3.22)
project(MyApp)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()
qt_add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE Qt::Widgets)
Now, we install the application and enhance the installation step. Our goal is to have a (mostly) self-contained directory after installation.
# Install the executable into "${CMAKE_INSTALL_PREFIX}/bin".
install(TARGETS MyApp
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# Generate the deployment script for the target MyApp.
qt_generate_deploy_app_script(
TARGET MyApp
FILENAME_VARIABLE deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)
# Call the deployment script on "cmake --install".
install(SCRIPT ${deploy_script})
We build and install the project:
$ qt-cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/my-application ..
[output omitted]
$ cmake --build .
[output omitted]
$ cmake --install .
-- Install configuration: "Release"
-- Installing: /tmp/my-application/bin/myapp
-- Set runtime path of "/tmp/my-application/bin/myapp" to "$ORIGIN:$ORIGIN/../lib"
-- Writing /tmp/my-application/bin/qt.conf
-- Running generic Qt deploy tool on /home/someone/playground/myapp/build/myapp
-- Installing: /tmp/my-application/lib/libQt6Core.so.6
-- Installing: /tmp/my-application/lib/libQt6Core.so.6.6.0
-- Installing: /tmp/my-application/lib/libQt6DBus.so.6
-- Installing: /tmp/my-application/lib/libQt6DBus.so.6.6.0
-- Installing: /tmp/my-application/lib/libQt6EglFSDeviceIntegration.so.6
-- Installing: /tmp/my-application/lib/libQt6EglFSDeviceIntegration.so.6.6.0
-- Installing: /tmp/my-application/lib/libQt6EglFsKmsSupport.so.6
-- Installing: /tmp/my-application/lib/libQt6EglFsKmsSupport.so.6.6.0
-- Installing: /tmp/my-application/lib/libQt6Gui.so.6
-- Installing: /tmp/my-application/lib/libQt6Gui.so.6.6.0
-- Installing: /tmp/my-application/lib/libQt6OpenGL.so.6
-- Installing: /tmp/my-application/lib/libQt6OpenGL.so.6.6.0
-- Installing: /tmp/my-application/lib/libQt6Widgets.so.6
-- Installing: /tmp/my-application/lib/libQt6Widgets.so.6.6.0
-- Installing: /tmp/my-application/lib/libQt6XcbQpa.so.6
-- Installing: /tmp/my-application/lib/libQt6XcbQpa.so.6.6.0
-- Installing: /tmp/my-application/plugins/egldeviceintegrations/libqeglfs-emu-integrat...
-- Installing: /tmp/my-application/plugins/egldeviceintegrations/libqeglfs-kms-egldevic...
-- Installing: /tmp/my-application/plugins/egldeviceintegrations/libqeglfs-x11-integrat...
-- Installing: /tmp/my-application/plugins/imageformats/libqgif.so
-- Installing: /tmp/my-application/plugins/imageformats/libqico.so
-- Installing: /tmp/my-application/plugins/imageformats/libqjpeg.so
-- Installing: /tmp/my-application/plugins/xcbglintegrations/libqxcb-egl-integration.so
-- Installing: /tmp/my-application/plugins/xcbglintegrations/libqxcb-glx-integration.so
-- Installing: /tmp/my-application/plugins/platforms/libqxcb.so
After the myapp
executable is installed into /tmp/my-application/bin/
, the deployment script handles the following tasks:
- Create a
qt.conf
file next to the executable that contains information about the directory layout. This is needed at runtime to find the plugins and assets. See the qt.conf documentation for details. - Inspect the executable and used Qt plugins with CMake's built-in file(GET_RUNTIME_DEPENDENCIES) to determine which Qt libraries to deploy.
- Install the necessary Qt plugins and Qt libraries.
The installation directory can now be copied to a different machine, and the application should still work.
Packaging the installation folder
After installation, we have a nice self-contained directory that can be packaged and shipped. For the sake of example, we'll create a .deb
package using cpack
.
Add the following at the end of the project file:
set(CPACK_PACKAGE_NAME my-app)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My amazing application")
set(CPACK_PACKAGE_VENDOR "My Company")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_VERBATIM_VARIABLES ON)
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/myapp")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Manfred Maintainer <mm@example.com>")
set(CPACK_DEBIAN_PACKAGE_DEPENDS libc6 libstdc++6 libgcc-s1)
include(CPack)
Re-configure the project and run cpack
:
$ cpack -G DEB
CPack: Create package using DEB
CPack: Install projects
CPack: - Install project: MyApp []
CPack: Create package
CPack: - package: /home/someone/projects/myapp/build/my_app-1.0-Linux.deb generated.
That's already it. The package has been wrapped and is ready to be shipped.
You can inspect the content of the package with dpkg -c my_app-1.0-Linux.deb
and install with
.
sudo dpkg -i my_app-1.0-Linux.deb
Summary
We have seen how to deploy a simple Qt application on Linux using Qt 6.5's CMake deployment API. There's no dedicated linuxdeployqt tool. The current solution wholly relies on CMake's built-in functionality.
These are the platforms that are covered by Qt's CMake deployment API:
- Windows
- macOS
- Linux
For Android and iOS there's still the need to call androiddeployqt / macdeployqt manually - or you let Qt Creator handle these details.
The relocatable installation folder can be conveniently wrapped into a package using tools like cpack
.
Please report any issues you find while playing with this at our bug tracker.
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.4 Now!
Download the latest release here: www.qt.io/download.
Qt 6 is the productivity platform for the future, with next-gen 2D & 3D UX and limitless scalability.
Explore Qt World
Check our Qt demos and case studies in the virtual Qt World
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Näytä tämä julkaisu Instagramissa.Henkilön Qt (@theqtcompany) jakama julkaisu