Qt6 + CMake migration
Requires the updater-wip branch from https://github.com/slipher/fluid.
There are two branches. This one, slipher/qt6, includes only the commits that are supposed to be related to Qt6 migration. The other one slipher/qt6-combined represents the actual working copy I am using which includes some other commits.
Upgrade from Qt 5.14 to 6.8; migrate from qmake to cmake; update Fluid by a lot which requires some migrations; also update Quazip which didn't require any migrations.
Current issues:
- [ ] Implement MacOS
- [ ] Fix release mode build for Windows
- [ ] Update codeql workflow
- [x] The Linux executable is a PIE
- [ ] (Linux) File dialog that should should be modal fails to control focus (maybe missing some x11 lib?)
- [x] Missing date strings in file dialog. The date strings are hardly needed, but their absence causes warning spam in the terminal.
-
D-Bus is disabled. I think we use that for having the task icon blink when the download finishes. - [x] Hard dependency on obscure XCB libraries
- [x] (Linux) examine xkb library dependencies
- [x] Restore basic text editing functionality, for command line editor? (copy and paste, undo)
- [x] Custom CMake for Fluid
- [x] Doesn't exit when all windows are closed
- [ ] Fluid "ripple" animations when clicking a button not working?
It now depends on libxcb-cursor.so.0 and I had to install libxcb-cursor0 on my end, meaning no one of the applications I use requires that, meaning that dependency is very rare.
Edit: I forgot to say I'm running Ubuntu 24.04.3 LTS Noble Numbat.
I get this:
In file included from /updater/downloadworker.cpp:20:
/updater/downloadworker.h:25:10: fatal error: QStandardItemModel: No such file or directory
25 | #include <QStandardItemModel>
| ^~~~~~~~~~~~~~~~~~~~
I get this:
In file included from /updater/downloadworker.cpp:20: /updater/downloadworker.h:25:10: fatal error: QStandardItemModel: No such file or directory 25 | #include <QStandardItemModel> | ^~~~~~~~~~~~~~~~~~~~
I guess the "remove an unused include" commit from slipher/qt6-combined is needed.
That was that, thanks!
Out of curiosity, I tried building Qt without OpenGL, to see if that would save space. The updater builds and runs this way but that looks ugly: curves are aliased, and some background color on configuration dialog is wrong.
It now depends on
libxcb-cursor.so.0and I had to installlibxcb-cursor0on my end, meaning no one of the applications I use requires that, meaning that dependency is very rare.Edit: I forgot to say I'm running Ubuntu 24.04.3 LTS Noble Numbat.
That's annoying: when that dependency isn't there, Qt6 doesn't build, but we cannot ship an updater requiring it.
On Ubuntu 24.04 that dependency is not installed by default, and is required by only 8 softwares! That means no one have this dependency installed on Ubuntu LTS! Maybe we will have to build it statically.
Out of curiosity, I tried building Qt without OpenGL, to see if that would save space. The updater builds and runs this way but that looks ugly: curves are aliased, and some background color on configuration dialog is wrong.
The Qt Quick documentation says that some effects are expected not to display if software rendering is used. Also I get high CPU usage in that mode (for me it happens when I run the app from a container that lacks some support libs).
It now depends on
libxcb-cursor.so.0and I had to installlibxcb-cursor0on my end, meaning no one of the applications I use requires that, meaning that dependency is very rare. Edit: I forgot to say I'm running Ubuntu 24.04.3 LTS Noble Numbat.That's annoying: when that dependency isn't there, Qt6 doesn't build, but we cannot ship an updater requiring it.
On Ubuntu 24.04 that dependency is not installed by default, and is required by only 8 softwares! That means no one have this dependency installed on Ubuntu LTS! Maybe we will have to build it statically.
Ouch. It seems Qt 6 has the opposite problem of Qt 5, which had too few hard requirements and ended up not displaying properly on the initial attempt to upgrade to Bullseye. There is an extensive list of libs for the test named xcb_syslibs in the build system which are required all or nothing. But recently I saw somewhere an option for using an internal xcb that we should try out. I forgot what the option is called but I can see the code in there at qtbase src/3rdparty/xcb/.
I now have a version that statically links against the libxcb-XXX libraries from Debian.
Excellent!
Some minor changes that live in a local branch of mine:
- The install command looks like this way on my end:
RUN apt-get update \
&& apt-get install -y \
autoconf \
autopoint \
ca-certificates \
curl \
gettext \
git \
g++ \
libgl1-mesa-dev \
libtool \
libx11-xcb-dev \
libxcb-glx0-dev \
libxkbcommon-x11-dev \
make \
ninja-build \
perl \
p7zip-full \
pkg-config \
python \
xz-utils \
zlib1g-dev \
$XCB_MINIMUM_PACKAGES \
&& echo 'deb https://archive.debian.org/debian bullseye-backports main' > /etc/apt/sources.list.d/backports.list \
&& apt-get update \
&& apt-get install -y \
cmake/bullseye-backports \
&& apt-get clean
It installs explicitely ca-certificates because that's needed for the archive depot. It worked before because a package pulled it (probably curl), but it's not bad to be explicit.
It runs apt-get clean at the end in hope the snapshotted docker step is smaller on disk.
The backport repository url is made a bit smaller.
Also, just as a style concern, I put the && at the beginning of the line so it makes more obvious to my eyes it's a command and not an argument.
I also have a patch that moves the Aria build before the Qt build, so anytime Qt changes are made, the whole build is faster because modifying the Qt build doesn't invalidate the Aria build because of ordering.
I had a third patch adding ENV LANG=C.UTF-8 before anything else, but you already implemented the same yourself.
I don't know if that's bad or not, but Qt links against libxcb-xkb.a while also linking against libxkbcommon-x11.so.0 which is linked against libxcb-xkb.so.1, meaning we link against two libxcb-xkb, and one of them will be the static one from the Debian docker, while the other one will be the shared one from the user's computer.
Doing this makes sure the shared lib is always used for xcb-xkb while others are linked statically:
RUN ls /usr/lib/x86_64-linux-gnu/libxcb-*.so | grep -v xcb-xkb | xargs rm -v
The input part is where Qt has a bundled one that we can try. -qt-xkb or something in the configure args
The backports list file was removed:
E: Release 'bullseye-backports' for 'cmake' was not found
Also I noticed the backport url could use http, making it possible to be fetched before installing ca-certificates. Debian does it own crypto thing and doesn't need to trust the carrier as it can validate the package whatever the way it was sourced. This makes possible to do a single apt update.
That ca-certificates package is likely needed for the curl download, but then keeping it implicit from curl now sounds fine.
That's doable:
RUN echo 'deb http://archive.debian.org/debian bullseye-backports main' > /etc/apt/sources.list.d/backports.list \
&& apt-get update \
&& apt-get install -y \
autoconf \
autopoint \
curl \
gettext \
git \
g++ \
libgl1-mesa-dev \
libtool \
libx11-xcb-dev \
libxcb-glx0-dev \
libxkbcommon-x11-dev \
make \
ninja-build \
perl \
p7zip-full \
pkg-config \
python \
xz-utils \
zlib1g-dev \
$XCB_MINIMUM_PACKAGES \
&& apt-get install -y \
cmake/bullseye-backports \
&& apt-get clean
The commit spam no-pie/no-pic mistakenly deletes this line from the OpenSSL build:
RUN ./config --prefix=/openssl --openssldir=/dev/null no-shared no-apps no-autoload-config no-capieng no-dso no-dynamic-engine no-engine no-loadereng no-module -Os
The commit
spam no-pie/no-picmistakenly deletes this line from the OpenSSL build:RUN ./config --prefix=/openssl --openssldir=/dev/null no-shared no-apps no-autoload-config no-capieng no-dso no-dynamic-engine no-engine no-loadereng no-module -Os
Fixed
There is now a Windows build, which seems to work in non-release mode. (But if you pass release=1, you get an internal compiler error.)
Fixed issue with the app not exiting when all windows are closed.
Also added the toolchain file for MinGW which I forgot to add before.
Fixed issue with the app not exiting when all windows are closed.
Thanks a lot!
Added customized fluid.cmake and cleaned up the load-bearing posters. Now you can use the submodule references as-is.
I don't know if that's bad or not, but Qt links against
libxcb-xkb.awhile also linking againstlibxkbcommon-x11.so.0which is linked againstlibxcb-xkb.so.1, meaning we link against twolibxcb-xkb, and one of them will be the static one from the Debian docker, while the other one will be the shared one from the user's computer.
Patched Qt to always disable the XKB extension to x11. The point is to get rid of the libxkbcommon-x11 dependency. It has a drawback that while editing text, selection via Shift + arrow keys no longer works, but I think we can live with that.
Patched Qt to always disable the XKB extension to x11.
Did you forgot that commit? I still some xkb stuff with ldd when I rebase my branch over yours:
$ ldd updater | grep xkb
libxkbcommon.so.0 => /lib/x86_64-linux-gnu/libxkbcommon.so.0 (0x00007075929da000)
libxkbcommon-x11.so.0 => /lib/x86_64-linux-gnu/libxkbcommon-x11.so.0 (0x00007075929d0000)
libxcb-xkb.so.1 => /lib/x86_64-linux-gnu/libxcb-xkb.so.1 (0x000070759252a000)
Patched Qt to always disable the XKB extension to x11.
Did you forgot that commit? I still some xkb stuff with
lddwhen I rebase my branch over yours:
Yeah I forgot to update slipher/qt6, it was only in slipher/qt6-combined.
I think D-Bus is not actually needed for anything so we can leave it disabled.
I'm having trouble now with the modal dialog thing. The file dialog does not grab focus like it should. It works when built with Debian Trixie's Qt distro packages, though the app uses the "native" file dialog which is not the same one we get in our build. It also works when built with Arch Linux's distro packages, which do give the same dialog as our build. (In the Arch case it's running in a Distrobox container so some sort of black magic is used to connect the WM with the host system.) In both cases I made sure to test with QT_QPA_PLATFORM=xcb so it does not use Wayland. I tried removing the big block of feature settings base_features='...' in the build script and also installing all the (dev versions of) packages that are dependencies of libqt6gui6 but that didn't help.
Something that is broken is the render of the “Continue reading” link, the HTML code explicitly says this should be cyan and aligned to the right, while it is rendered as white and aligned to the left. Actually that look isn't that bad, and we may decide to do it purposely, but that's not what the code is asking for.
Finally got the modal dialog thing. Turns out it is not implemented for "non-native" dialogs until Qt 6.10. The Debian distro libraries used "native" dialogs so that's why the problem could not be reproduced there. I tried building with version 6.10 but then the dialog wouldn't open at all. So I backported the commit to 6.8.
Something that is broken is the render of the “Continue reading” link, the HTML code explicitly says this should be cyan and aligned to the right, while it is rendered as white and aligned to the left. Actually that look isn't that bad, and we may decide to do it purposely, but that's not what the code is asking for.
Fixed
You may be interested in my build-qt: per-module patch application patch to simplifies the application of patches, this is something I wrote when I added a patch for qtshadertools but I rebased it and rewrote it to be even more generic so it could handle without custom code the qtdeclarative patch you added.
I see no difference with “Continue reading”.
Maybe it would be better to just test slipher/qt6-combined since I keep forgetting to update the slipher/qt6 pointer.
Maybe it would be better to just test
slipher/qt6-combinedsince I keep forgetting to update theslipher/qt6pointer.
Never mind, I don't think it was in there either. Pushed both
This is starting to look (the PR) very good!