One of the things I’ve been asked recently quite often is about where’s the information regaring the needed port to KF5. I’ll use this blog post as reference.
Documentation
We have quite some documentation set up already to find your stuff. The ones I use the most are:
- api.kde.org: The API documentation, the frameworks section. There you can find most classes documented, within its own module.
- Porting notes: Whenever developing KF5, each not obvious decision we took was documented either here or in the api documentation. It’s especially interesting to look at this when hitting a deprecated class. If it’s not here, check the API documentation, if it’s still not there tell us and we’ll fix it.
- Already ported code: We have a good set of ported projects, it can be interesting to look at them and see how things have been resolved. Look for a frameworks branch.
- People: As a last resource, there’s always the community to give you a hand, notably in the #kde-devel IRC channel in freenode and the kde-frameworks-devel@kde.org mailing list.
How to get started
When it comes to porting, we can have a bit of a stress at start, I recommend to take it quietly and to take any step forward as a success. 🙂
For frameworks and libraries, look here, a template for creating KDE Frameworks.
For applications, what works the best is to port first the root CMakeLists.txt file, it should look like this:
find_package(ECM 0.0.11 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(FeatureSummary)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
find_package(KF5 REQUIRED COMPONENTS CoreAddons Solid)
add_subdirectory(src)
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
There’s not much more to change further than that. To make it a bit faster, you can use the spartan script, to port some simple and tedious changes to the new cmake names used in KF5. Note that it’s not perfect and we don’t ensure it’s going to work, but so far it has been of good help to me.
A good way to figure out if the porting is acceptable, is to run the unit tests of your application. If you don’t have, then remember that making unit tests is fun.
Things to look into
CMake
- Adopted the cmake idioms: We don’t use anymore kde4_* macros to create targets, but the cmake macros, e.g. kde4_add_executable -> add_executable.
- Dependencies: Where we used to have ${KDE4_KDEUI_LIBS}, now we have KF5::WidgetsAddons. Note it’s not a variable anymore and if you use cmake 3.0 you’ll get a warning if it wasn’t found. Furthermore, now each target already pulls the include directories. We don’t need to keep adding include_directories() with each of the dependencies.
- Extra-cmake-modules: Look at what’s in there, there’s interesting things you’ll have to use at some point, also it’s targetted as a cmake extension, you might want to use it even though Qt or C++ isn’t used in your project.
C++
In reality, this is probably the easiest part. You need to keep trying to make it compile, and when it doesn’t then you look at the API and porting notes until it does, then goto “C++”.
To get the port started, it’s usually best to rely on KDELibs4Support framework in the beginning. It’s a framework with all the modules we decided to deprecate, because we moved the functionality to Qt5 mostly. It will help get to a point where everything is building then you can start removing deprecated dependencies 1 by 1. It’s also good to use it when there’s development still in the Qt4 branch of the project, because merging back will be easier.
If you’re planning to keep developing in Qt4 for a while, some porting beforehand can be useful, like KIcon -> QIcon::fromTheme, this way you also reduce the divergence between branches. Another idea to do before porting is to do unit testing, so you don’t need to test by hand every feature while porting.
QML
Porting QML is not trivial, but then there were only few projects actually using it seriously. All the underlying technology changed, so it can get tricky. At the moment, in Qt5 there are 2 QML implementations, QtQuick 1, which is the one we used in Qt4 and QtQuick 2 which is the one you want to be on, which uses Qt Scene Graph and does voodoo with the GPU.
One thing you get to decide is to stay in QtQuick 1. That is, only if everything it depends on is ported to QtQuick 1. For that matter, the PlasmaComponents were ported directly to QtQuick 2, so you’ll have to make the full change.
If you need to port to QtQuick 2, there’s also some scripts you can use to ease the change. You’ll want to basically change all the classes starting with QDeclarative* to QQml* and QQuick*, they usually keep the same name. If you were using QGraphicsView features, then you’re screwed.
In the actual qml/js side, when porting to QtQuick 2, you’ll want to update all imports. All Qt imports versions were bumped, so now you’ll have to change “import QtQuick 1.1” to “import QtQuick 2.2”. In the same direction, “import org.kde.plasma.components 0.1” now becomes “import org.kde.plasma.components 2.0”
Final considerations
I recommend people to do their porting, I think it’s a solid step forward for the project and will help you clean up parts of it and start thinking future.
Qt 5 provides many interesting new concepts. I’m thinking of QtWebSockets, QtWayland, QtWebEngine and I hear Qt3D is getting really interesting. Additionally, it enables your project from letting the Qt code integrate properly in the new C++11 concepts.
Porting to KF5 will also help your project become more portable and reach out to different platforms.
Finally, if you think this is interesting for KDE but you can’t find time or energy to dedicate it, please take a look at the Randa pledge, where we will push together to get KDE to embrace fully the KDE Frameworks 5.