CMake support for Qt5's external resources
When writing a Qt5 application there is often a need to include graphical
resources inside the application binary. As Qt is a portable framework, it
doesn't use platform-specific solutions for resource storage like the Resource
section in PE files on Windows systems. Qt has its own mechanism which is
possible for use with the help of the rcc
tool.
Normally the rcc
tool will generate c++
source files which contain selected
resources as simple arrays, together with some control structs. Your build
system takes this autogenerated source file, compiles it to a normal object file
with your C++ compiler, and links it into the final executable. CMake supports
that without any problem.
The problem started when I wanted to create an application which loads a plugin.
I wanted the plugin to use Qt5 code, but also I wanted to put some resources
into the plugin itself, not to the host application that loads the plugin. This
resulted in a problem, because the resources linked to the plugin shared object
are not registered to the Qt Resource subsystem, which results in inability to
load them through normal loading mechanisms, like QPixmap(":/resource.jpg")
.
Fortunately Qt's rcc
tool also supports external resources, which are compiled
binaries, that are meant to be put in an external *.rcc
file instead of linked
into the application binary. It's possible to generate this kind of resources by
adding the -binary
option to rcc
:
$ rcc res.qrc -o res.rcc -binary
$ file res.rcc
res.rcc: Qt Binary Resource file
Normally I am using a combo of CMake and Ninja to manage the build process, and
unfortunately CMake doesn't support generation of external resource files. CMake
seems to support qt5_add_resources
function, but it's designed to generate
source files that are later linked into the application. Even if forcing this
function to pass the -binary
option to rcc
tool, which is possible, the
result is that the linker tries to link also these binary resource files, which
obviously is not a good idea.
However, I've managed to create a small CMake script that should add support for
this. My function is based on original qt5_add_resources
in the sense that it
tries to parse the qrc
file to extract the external file references. These
file references are added to a list of dependencies, so CMake knows that it has
to rebuild the rcc
file if any of the referenced resource files will change.
It rebuilds the rcc
file also when the qrc
file will change.
The function works in both make
and ninja
generators. It has been tested on
gcc only, and I have no idea if it will work on Visual Studio or not.
You can use this support in your projects by checking out this repository on GitHub:
This repository contains a small example application that will help you understand how the CMake function should be called and how to load an external resource from your application.