[Development] Proposing CMake as build tool for Qt 6

Lisandro Damián Nicanor Pérez Meyer perezmeyer at gmail.com
Thu Jun 13 14:02:01 CEST 2019

Resending because I mistakenly replied just to Lars.

Lars: thansk for the heads up, and also note I rewrote a paragraph below,
hopefully to be more on point.

On 19/06/11 07:12, Lars Knoll wrote:
> Hi Lisandro,

Hi Lars!

> That thread doesn’t explain why qtchooser isn’t a solution. It does work
> without problems for all my use cases, and I certainly do have quite a few Qt
> versions installed in parallel.

Maybe my fault, I have discussed this in this mailing list before. The mail
also has a link to our bugs list, but let me try to write down it's pros
and cons here.

> Part of the problem simply stems from the fact that Linux distributions
> want to put all the binaries into /usr/bin. As long as you keep separate
> Qt versions in separate directories there’s no problem I know of.

Each operative system has it's design rules. We might or not like them, but if
we want Qt to be really a multi-platform code-once tool then we should accept
those rules and do our best to build upon them.

Let's try to put this into two three different points of view:

- A Qt-internals' developer
- A developer using Qt to create stuff
- A system developer/integrator (within this, distro maintainers).

> Giving our build tools different names depending on the version can create
> other problems for our users, especially those that use some hand rolled
> build systems (and we probably have lots of those as well).

And the above is clearly a thing a Qt-internals' developer should definitely
look to, so a very valid concern. But let's take the other's too.

I am taking maybe another approach to what Kevin already wrote in [a], but I do
agree to what he wrote there too.

[a] <https://lists.qt-project.org/pipermail/development/2019-June/036453.html>

# Problem 1: binary masking

At first I thought qtchooser might probe to be a nice tool for switching
versions much like Shawn wrote, but then experience showed us the contrary.

With "binary masking" I mean that qtchooser replaces the path for where a
binary should be with itself.

With this comes the following cases:

## Binaries that need to be accesible by "the user"

This are the ones that really need to be in $PATH because the normal user needs
it. We can't expect a normal user to add to $PATH a "weird" path of a specific
Qt version and change it every time it needs to switch versions. Let's add that
the user of that application might well be another application or
system library.

We can list qdbus and qdbusviewer as examples (perhaps not the best ones, but
will do for now). So let's say app4 is compiled against Qt4 (we still have
them around, sadly not every useful app was yet ported) and app5 is compiled
against Qt5. Take Qt 6 instead of Qt 4 if you like. Both where developed using
their own version's qdbus in mind.

As a packager my duty is to ensure that app4 has a strong dependency against
Qt4's qdbus and app5 has a strong dependency against Qt5's qdbus, so both
versions of qdbus will be installed.

Now both app4 and app5 developer's will probably not worry about qtchooser
because it's just a hack needed on Linux, so they won't be calling 'qdbus -qt5'
(which, as Kevin said, it's not even a standard) but just 'qdbus'. So with
qtchooser around app4 and app5 will receive both the same version of qdbus, be
it Qt 4's or 5's.

So, why it has not backfired yet? Because thanks Thiago (probably) qdbus behaves
the same in both Qt 4 and 5. Had they differed in the way they behave... kaboom.
We packagers would be probably needed to start patching applications to pass
proper qtchooser arguments, which is not something developers that use Qt like a

So the big question here is: can we *really* keep this applications
backward-compatible for the whole Qt 4, 5 and 6 and future versions?

## Binaries that need to be accesible by developers using Qt

These are moc, rcc, linguist, designer, uic, etc. Some of them really
need to be in
$libexecdir and ought to be found by way of the .cmake and .pc files
[1]. But then
there are the other tools that, once again, need to be readily accesible for a
developer user but in a much "normal" way. Let's say for example
linguist. Translators
are normally more in the "user" side of things than in the "developer" side.

assistant might probably be in this situation too.

[1] <https://lists.qt-project.org/pipermail/development/2018-November/034382.html>
[2] <https://lists.qt-project.org/pipermail/development/2018-November/034385.html>

And maybe lupdate is also an elegible example.

## Binary masking and dependency resolution

Now the user installs qt5's qdbus. Currently that will in turn install
qtchooser (there is currently no way around it except renaming binaries),
so /usr/bin/qdbus is taken.

Now the user needs qt5's qdbus, so he simply runs 'qdbus'. It will fail. Why is
that? Because in Qt 4 the concept of qtchooser did not exist, so the
default system
consiguration needs to be qt4 as long as there is any piece of it installed on
the system. So the user thinks it's a qdbus bug, but it's actually a
bad dependency
resolution due to qtchooser.

Note that this example is also valid in the Qt 4 case and will be in the Qt 6
case too because developers of Qt solutions do not take qtchooser into
account, so
they won't be calling "qdbus -qtfoo" from within their apps. And
that's what Qt has
told us all this time: "Code less, create more, deploy everywhere".

Now if we switched user-facing binaries to say qdbus6 the above motto
would still be
true for all aps written with Qt 6.

# Problem 2: masks user-facing applications that belong just to one
specific version

The easy example here is qtconfig. Right, one could easily say "hey, just let
/usr/bin/qtconfig be a symlink to qt4's $libexec's qtconfig". But then
what would
happen with a tool that ships in Qt 4 and 5 but not in Qt 6?

This is exactly Debian bug

# Seeing the problem as a Qt-internal's developer

I can see value in qtchooser for Qt-internal's developers. You can easily
switch between Qt versions without too much hassle.

I sincerely do not know how you manage to keep up with your desktop environment
in Linux as I'm pretty sure most of you are not using a GTK-based desktop :-)
 Why I say that? because even the smallest Qt-based desktop environment ships
theming which requires using Qt's private API, so it's tightly tied to a
specific ¡minor! version. And I'm pretty sure there are other cases which have
the same issue.

But let's go back to Lars' original mail, rewriting here for speeding up things:

> Giving our build tools different names depending on the version can create
> other problems for our users, especially those that use some hand rolled
> build systems (and we probably have lots of those as well).

This is comparable to people not using CMake, qmake or qbs to build Qt based
applications/libraries. If they do things by hand then they must understand
beforehand that things might break.

Note that even Qt-generated pkgconfig files had issues that took quite long to
fix. With this I want to emphasize that the *trully* supported build systems
are qmake, CMake and qbs, be it by Qt Co., any other company or the community.

# Proposed solution

All user-facing binaries that do not really belong to $libexec should be
suffixed, as explained in

- For integrators it will mean easily-deployable solutions without hacks.

- For Qt-internal's developers will certainly not affect them much once they
get used to the switch (yes, I understand a change sometimes brings discomfort).

- For developers using Qt it means they will directly understand that
the specific
user-faced tool is *specific* to the Qt version and it might change in future

**Pretty please** be sure to state if there is another thing I did not
consider. I'm pretty sure we can work out viable solutions.

Cheers, Lisandro.

Lisandro Damián Nicanor Pérez Meyer

More information about the Development mailing list