6-Minute Read

How to build KDE APP on Qt6

With the Qt6.4 release last month and the ongoing porting of most KDE Frameworks and Applications to Qt6, it’s time to write a post about how to build KDE applications on Qt6. This guide is intended for developers who want to port their own applications build on KDE frameworks.

I’ll use the porting of KWeather as an example. KWeather is a weather forecasting App build on top of Kirigami, it also relies heavily on KWeatherCore framework for its core functionality. So I’ll also cover the porting of KWeatherCore.

KDESRC-BUILD

KDESRC-BUILD is the tool that allows you to build any KDE software. If you don’t have KDESRC-BUILD installed yet, follow the link above and install it.

KDESRC-BUILD Configuration

After installing the KDESRC-BUILD and copying the sample configuration file to ~/.config/kdesrc-buildrc, we will edit some lines to make KDESRC-BUILD link Qt6 by default. First, we want create a separate folder to store the source files, build directories, and install root. We’ll choose ~/kde/qt6 as the root directory.

global

    # Install directory for KDE software
    kdedir ~/kde/qt6/usr

    # Directory for downloaded source code
    source-dir ~/kde/qt6/src

    # Directory to build KDE into before installing
    # relative to source-dir by default
    build-dir ~/kde/qt6/build

    ...
end global

Then we need to change the include of the KDE Frameworks 5 and Qt5 configuration files to the corresponding KF6 and Qt6 ones.

    ...
end global
# Common options that should be set for some KDE modules no matter how
# kdesrc-build finds them. Do not comment these out unless you know
# what you are doing.
include /home/hany/kde/src/kdesrc-build/kf6-common-options-build-include

...

# KF5 and Plasma :)
include /home/hany/kde/src/kdesrc-build/kf6-qt6-build-include

# To change options for modules that have already been defined, use an
# 'options' block. See kf5-common-options-build-include for an example

That’s all for the KDESRC-BUILD configuration.

Try to build KWeather

Since we’re porting our app, it is very likely that the first build will fail, so it is advisable to pull all the source code first.

kdesrc-build --src-only kweather will do just that.

Then we try to build by running kdesrc-build --refresh-build --no-src kweather. And as we expected, the build failed. but don’t worry, let’s investigate the cause.

Building kweathercore from _cmdline (8/11)
        Source update complete for kweathercore: Skipped
        Preparing build system for kweathercore.
        Removing files in build directory for kweathercore
        Old build system cleaned, starting new build system.
        Running cmake targeting Unix Makefiles...
        Unable to configure kweathercore with KDE CMake

kweathercore didn't build, stopping here.

<<<  PACKAGES FAILED TO BUILD  >>>
kweathercore - file:///home/hany/kde/qt6/src/log/2022-10-05-01/kweathercore/cmake.log
        * Installing "sample-kde-env-master.sh" would overwrite an existing file:
        *  /home/hany/.config/kde-env-master.sh
        * If this is acceptable, please delete the existing file and re-run,
        * or pass --delete-my-settings and re-run.

:-(
Your logs are saved in file:///home/hany/kde/qt6/src/log/2022-10-05-01

By examining the /home/hany/kde/qt6/src/log/2022-10-05-01/kweathercore/cmake.log we found out the exact error is

-- Configuring done
CMake Error: The INTERFACE_QT_MAJOR_VERSION property of "Qt6::Core" does
not agree with the value of QT_MAJOR_VERSION already determined
for "KF5KWeatherCore".

At first glance, this error seems confusing. In reality, it says that the project (in this case KF5KWeatherCore) is still linked to Qt5, even though we have specified to link against Qt6. So we need to take a look at KWeatherCore. It turns out that KWeatherCore still hardcodes Qt5 in CMakeList, so a change needs to be made to make KWeatherCore Qt6 compatible.

Make CMakeList Qt6 compatible

Qt’s cmake-qt5-and-qt6-compatibility is a good place to start. In our case, we should first include Extra-CMake-Modules (which should already have been done for existing KDE software) and then replace any hardcoded reference to Qt5 with Qt${QT_VERSION_MAJOR}. To see why, Volker Krause has an excellent post about it.

Edit KDESRC-BUILD configuration to specify Qt6

Now it is time to tell KDESRC-BUILD that KWeatherCore should be linked to Qt6. We simply set ${QT_VERSION_MAJOR} cmake variable to 6 by adding a section to ~/.config/kdesrc-buildrc

options kweathercore
    cmake-options DQT_MAJOR_VERSION=6
end options

Fix build issue for dependencies

Shortly after we had a build error with kemoticon, we found out after looking at the source code that kemoticon does not support Qt6. A search on KF6 workboard shows that kemoticon is deprecated in KDE Frameworks 6. Now it is time to determine exactly where kemoticon is located in our dependency tree. kdesrc-build --dependency-tree kweather shows that KWeatherCore depends on kf5umbrella, which in turn depends on kemoticon.

KDE manages project dependency data (along with much other metadata) in (repo-metadata)[https://invent.kde.org/sysadmin/repo-metadata/-/tree/master/dependencies]. The files we are insterested in are dependency-data-stable-kf5-qt5 and dependency-data-kf5-qt5, in particular dependency-data-kf5-qt5 since this is the file used to determine dependencies in KDESRC-BUILD. A quick search revealed that neither KWeather nor KWeatherCore depends on kf5umbrella. Here’s the kicker: any project not included in frameworks implicitly depends on kf5umbrella unless explicitly stated otherwise. Since both KWeather and KWeatherCore are in extragear category, they implicitly depend on kf5umbrella. The solution is simple: edit dependency-data-kf5-qt5 in our local repository (the repo is located in ~/kde/qt6/src/sysadmin-repo-metadata) to remove the dependency.

extragear/libs/kweathercore: -frameworks/kf5umbrella
extragear/utils/kweather: -frameworks/kf5umbrella

Later in the build process, kirigami also fails. We found out that kirigami has a working Qt6 CI, so we open one of the (succeeded pipeline jobs)[https://invent.kde.org/frameworks/kirigami/-/jobs/508706] to see which option needs to be enabled for Qt6.

A look at the top of the raw log shows that the calling command is

$ python3 -u ci-utilities/run-ci-build.py --project $CI_PROJECT_NAME --branch $CI_COMMIT_REF_NAME --platform Linux --extra-cmake-args=-DBUILD_WITH_QT6=ON --extra-cmake-args=-DEXCLUDE_DEPRECATED_BEFORE_AND_AT=5.94.0 --extra-cmake-args=-DQT_MAJOR_VERSION=6

So we copy the cmake options to our KDESRC-BUILD config file.

options kirigami
    cmake-options -DBUILD_WITH_QT6=ON --extra-cmake-args=-DEXCLUDE_DEPRECATED_BEFORE_AND_AT=5.94.0 --extra-cmake-args=-DQT_MAJOR_VERSION=6
end options

For projects that a have working Qt6 CI, it is always easier to copy the CI commands than to try to debug it yourself.

You may wonder why kirigami as a KDE framework still needs manual intervention to build on Qt6? Well, when the KDE developers ported a framework to Qt6, they added required option to the (kf6-qt6 config files in KDESRC-BUILD)[https://invent.kde.org/sdk/kdesrc-build/-/blob/master/kf6-frameworks-build-include]. As for kirigami, it iss still in the process of being ported (but it compiles on Qt6). So if a framework doesn’t work right away, it either means that it is deprecated (kemoticon) or hasn’t been fully ported.

The End

To build app on Qt6 with KDESRC-BUILD, you should:

  • change KDESRC-BUILD config file
  • apply cmake options on dependencies that failed to build
  • change your app’s cmake file to make it Qt6 compatible

Since Kirigami has not yet been fully ported to Qt6, KWeather crashes on startup even though it can be built successfully on Qt6. But this should be a pretty complete example of how to build KDE app on Qt6 with KDESRC-BUILD.

Resource

Recent Posts

Categories

About

A young developer who loves Linux.