Running applications and unittests without "make install"

In our Akademy presentation, Kévin and I showed the importance for a better developer story to be able to work on a KDE module without having to install it. Running unittests and running applications without installing the module at all is possible, it turns out, it just needs a bit of effort to set things up correctly.

Once you require ECM version 5.38 (using find_package(ECM 5.38)), your libraries, plugins and executables will all go to the builddir's "bin" directory, instead of being built in the builddir where they are defined.
Remember to wipe out your builddir first, to avoid running outdated unit tests!
This change helps locating helper binaries, and plugins (depending on how they are loaded).

After doing that, see if this works:

  • make uninstall
  • ctest . (or run the application)

Oops, usually it doesn't work. Here's what you might have to do to fix things.

  • XMLGUI files: since KDE Frameworks 5.4, they can be embedded into a qrc file so that they can be found without being installed.
    The qrc should put the xmlgui file under ":/kxmlgui5/". You can use the script kde-dev-scripts/kf5/ to automate most of this change.
  • Uninstalled plugins can be found at runtime if they are installed into the same subdir of the "bin" dir as they will be in their final destination. For instance, the cmake line install(TARGETS kio_file DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kio) indicates that you want the uninstalled plugin to be in builddir/bin/kf5/kio, which can be done with the following line:
    set_target_properties(kio_file PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kio")
    Qt uses the executable's current directory as one of the search paths for plugins, so this then works out of the box.
  • If ctest complains that it can't find the unittest executable, the fix is very simple: instead of the old syntax add_test(testname myexec) you want to use the newer syntax add_test(NAME testname COMMAND myexec)
  • Helper binaries for libraries: look for them locally first. Example from KIO:
    QString kioexec = QCoreApplication::applicationDirPath() + "/kioexec";
    if (!QFileInfo::exists(kioexec))
        kioexec = CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kioexec"; // this was the original line of code
  • Helper binaries for unittests: an easy solution is to just change the current directory to the bin dir, so that ./myhelper continues to work. This can be done with QDir::setCurrent(QCoreApplication::applicationDirPath());

There are two issues I didn't solve yet: trader queries that should find uninstalled desktop files, and QML components, like in kirigami. It seems that the only solution for the latter is to reorganize the source dir to have the expected layout "org/kde/kirigami.2/*"?

Update: this howto is now a wiki page.