[Development] Qt5*Config.cmake files: _qt5_*_check_file_exists macros and plugins

Kevin Kofler kevin.kofler at chello.at
Fri Oct 17 17:02:04 CEST 2014


in Fedora, we have repeatedly had trouble with the following macro, defined 
in Qt5BasicConfig.cmake.in (and in some manually edited versions of it, e.g. 
macro(_qt5_$${CMAKE_MODULE_NAME}_check_file_exists file)
    if(NOT EXISTS \"${file}\" )
        message(FATAL_ERROR \"The imported target \\\"Qt5::
$${CMAKE_MODULE_NAME}\\\" references the file
but this file does not exist.  Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
but not all the files it references.

That macro is called in several places in Qt5*Config.cmake.in to check 
whether files mentioned in CMake configuration actually exist. The problem 
with this comes from plugins: Those plugins install a 
Qt5Sql_QMYSQLDriverPlugin.cmake, which allows client programs' 
CMakeLists.txt files to get some information about the plugin. So far this 
is also fine, but now e.g. Qt5SqlConfig.cmake imports all those *.cmake 
files and checks that all the mentioned files actually exist. This means 
that the plugin has now become a build-time dependency, even though it is 
not needed to compile the software at all, and even if the client program 
didn't ask for that particular plugin to begin with.

If the plugin is not present at build time, this results in a fatal error 
like the following:
CMake Error at /usr/lib/cmake/Qt5Designer/Qt5DesignerConfig.cmake:15 
  The imported target "Qt5::Designer" references the file

This is a problem for packaging, because we ship the plugins in subpackages, 
which carry dependencies, e.g. on the SQL backends. The .cmake files, on the 
other hand, go to a -devel subpackage that is used to compile software 
against the library. We don't want the -devel subpackage to require all the 
plugins, because of the dependencies they drag in, and because they aren't 
actually needed at build time (if at all, depending on the program).

Those _qt5_*_check_file_exists checks look unnecessary to me in the first 
place. At least for our Qt packages, they definitely are:
* If a file is actually required to build against the library, it will be in
  the same -devel package that carries the .cmake file (or in the main
  package that the -devel package Requires), and will thus always be there.
* If a file is NOT actually required to build against the library, then it
  should NOT be checked for (as is the case for those plugins).
But I also don't see the checks being useful for self-built Qt (where "make
install" will just install everything) nor your upstream binaries (which
also contain everything that is needed). So the question there is: Why were 
those checks added in the first place? Can they be removed in upstream Qt?

Packagers have come up with several solutions to this problem:
1. Have the -devel package Require (at RPM/dpkg/… level) all the plugin
   subpackages. That's what we are currently doing in Fedora, and I really
   don't like that approach, because those dependencies are actually
   unnecessary and drag in all the dependencies of every plugin. (E.g.,
   qt5-qtbase-devel currently transitively Requires all the SQL databases in
2. Delete the *Plugin.cmake files entirely. That's what Debian is currently
3. Put the *Plugin.cmake files into yet another subpackage. That's what Rex
   Dieter is proposing we do in Fedora. There are actually 3 ways to do
   3.a. One subpackage with all *Plugin.cmake files. That subpackage would
        then still have the same nasty dependencies as in 1. But most
        programs (or even all, if approach 2. is working) won't need it
        anyway. (But then, if they really don't, we could just go with 2.)
   3.b. One subpackage per *Plugin.cmake file, i.e. for every
        qt5-modulename-pluginname package, we'd have a
        qt5-modulename-pluginname-devel. That means many subpackages.
   3.c. Put the .cmake file into the regular qt5-modulename-pluginname
        package. That is frowned upon in distributions because it is a
        development file. There are also issues with the package ownership
        of the directory containing the file in that case. (/usr/lib/cmake/
        is owned by CMake, the subdirectory is owned by the -devel package.
        Neither should be a runtime dependency of the plugin.) But it can be
        done and is being considered in Fedora.
4. Remove the _qt5_*_check_file_exists checks. That's what I am proposing we
   do in Fedora. Again, there are 2 ways to do that:
   4.a. remove the calls to _qt5_*_check_file_exists and/or
   4.b. remove the contents of the _qt5_*_check_file_exists macro.

So, we would like some feedback from you, upstream Qt developers:
(i) Which of the above solutions would you prefer packagers to adopt for the
    currently released Qt 5 versions, and why?
(ii) Can you remove the _qt5_*_check_file_exists checks in the next
     release(s) of Qt? (If not entirely, at least for plugins?)

Kind regards,
        Kevin Kofler
        (volunteer Fedora Qt/KDE packager)

More information about the Development mailing list