With the advent of the Qt Installer FrameWork (QtIFW), it has never been easier to provide installers for your Qt based applications. Such installers can be either online (i.e. they fetch contents from the internet from repositories during the installation process, thus allowing updates), or offline (i.e. all the contents is bundled into the installer). QtIFW allows installers to be built for different platforms including Windows, MacOS and Linux.
However, it is not always easy to produce an install tree that is standalone so that it can be moved from one build machine to another production machine, especially when using dynamic linking and possibly third party plugins.
This post will not focus on QtIFW but introduces some methods to prepare its contents so that it is ready for deployment.
To help deploying applications, Qt comes with a set of tools, namely macdeployqt
and windeployqt
(there is one for android as well). They bundle the Qt libraries used by your application, patching them recursively in some occasions (using install_name_tool
on mac) so that their encoded run time path can be correctly resolved.
However, Qt is not only a set of libraries or frameworks, it comes with different kinds of plugins:
- platform plugins: they contain the platform abstraction (QPA) code for the target platform
- helper plugins: they contain various support implementations e.g. for audio, printing, databases, image formats etc.
And other material:
- imports: QML plugins
- qml: QML implementations
- translations: .qm files for internationalization.
The deployment tools handle these different types of plugins and material to make your installation tree consistent, as far as Qt is concerned. It does not handle third party libraries your program may require.
However, no such tool is provided for Linux, for many variants exist, and the philosophy to resolve run time path is not always consistent from a distribution to another.
For example, many applications are launched with the help of a script that sets LD_LIBRARY_PATH
to the correct value before invoking the application’s binary. This is difficult to maintain and sometimes confusing for the users.
Another example is, package maintainers build software with system installed Qt distributions that come in turn as a package. This has the major drawback of sticking developers with the very version of Qt that is maintained as a package, which version can be sometimes too old and not contain all the features you may need for your implementation.
There is a trick that consists of setting rpath
when linking your binaries that is often criticised for the provided path have to exist on the target system, and may require root privileges to be created otherwise.
Here comes $ORIGIN
, a token that refers to the application’s binary location. It can be used at link time or set later on, using either chrpath
or the most recent and maintained patchelf
tools.
dtk comes with dtkDeploy
, a fork of macdeployqt
that handles third party libraries in addition to the Qt ones, as well as the possibility to inject third party plugins.
In the near future, we intend to extend this tool so that it handles linux and windows as well.