Guidelines and HOWTOs/Making apps run uninstalled
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/bundle_data_files.pl 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. Note: this is not necessary if you are creating the plugin with kcoreaddons_add_plugin.
- 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());
- QML Components. For the unittests to find them, organize your source directories like the install directory, and provide qmldir files in there with a "module" directive. See the kirigami framework for a working example.
Note that shared libs are correctly picked up from the builddir automatically - as long as you don't set LD_LIBRARY_PATH.
There are two issues that aren't solved yet: trader queries that should find uninstalled desktop files, and servicetype desktop files that define the type of service properties.