Packaging software is a colossal waste of time. Take that however you will; I’ll write about some time-wasting I’ve undertaken this week to reduce time-wasting by others (mostly users of KDE Frameworks on FreeBSD) in future.

Almost all KDE software uses CMake; in CMakeLists.txt in the source of each package / product the direct dependencies are known and expressed through find_package(). In the kdesrc-build configuration files and metadata there is dependency data, and yet each packaging system has to go out and re-discover and re-write the dependency information one more time (for good luck).

FreeBSD Dependencies (ports)

FreeBSD writes these things out in “ports Makefiles”. For KDE-related ports, and KDE Frameworks in particular, there are two important expressions of those dependencies that come from the Qt / KDE stack:

USE_KDE=  coreaddons \
          ecm_build
USE_QT=   core declarative gui network opengl \
          buildtools_build linguisttools_build

These two lines express that the package depends on KDE components coreaddons and ecm, and on seven Qt components. The names of the components can be mapped back to source-packages with some educated guesswork (ecm means “Extra CMake Modules”, and that is FreeBSD package devel/kf5-extra-cmake-modules). The exact mapping of names can be found in files Mk/Uses/qt.mk and Mk/Uses/kde.mk.

There are some conventions particular to the KDE ports Makefiles:

  • dependency components for Qt and KDE are sorted alphabetically within three groups: needed both at build- and at run-time, needed at build-time, and needed at run-time.
  • build dependencies (expressed through the suffix _build) are sorted after all of the regular dependencies (the “both” kind), and the list of build-dependencies starts on a new continuation line in the Makefile.
  • run dependencies (expressed through the suffix _run, not visible in the example here) are sorted after regular and build dependencies, and start a new line as well.

It turns out that a-lot-a-lot of ports name some build-only dependencies in the “both” group. Two that crop up all the time are ecm and doctools. Now, ECM isn’t all that big (2.0MiB on disk), but it’s just not needed at runtime except for specialised applications (like KDevelop). Doctools (2.3MiB) has some hefty(-ish) dependencies (60MiB) of its own, simply because it’s the tooling that generates the documentation. But once the documentation is generated, we don’t need that at runtime, either.

On my personal workstation, which has everything KDE-related installed anyway, and builds packages regularly, and also has 424GB of ISO images (all related to Calamares testing) kicking around, none of this matters particularly. For live CDs, though, or people who want that one cool KDE application (kdenlive!), extra cruft is extra cruft.

So if we can lose the 2MiB, or 60MiB, or whatever worth of cruft on the end-user machine without impacting functionality or FreeBSD’s “batteries included” philosophy (where generally installing a package means you can build the package, too) then that’s a little win.

What I’ve Done

I’ve been building things in a loop, basically:

  • Go through a bunch of ports, turn ecm and doctools into build-dependencies, it they are present.
  • Make Qt’s testlib a build-dependency as well, if it’s present.
  • Remove listed dependencies if they look silly (e.g. Qt Widgets dependencies in pure QML frameworks).
  • Build stuff and deal with the fallout.

The “build stuff” part is really simple in FreeBSD thanks to awesome local tooling like poudriere (I gush about it here), so running clean builds isn’t an issue. Doing the updates and shuffling some dependencies around isn’t hard either, a minute per port and then letting it grind away. A half hour later I can find a dozen failures and fix them and try again. In the meantime I can read mail and do KDE e.V. things or install KDE neon again in a VM.

Takeaway

The dependency information in the KDE FreeBSD ports was pretty crappy, actually: lots of implicit dependencies . Which is nice, in a way: if some tier-1 framework drags in ECM and doctools, you can get away with not mentioning those two as dependencies and everything still works! So cleaning up them frameworks also meant then adding explicit dependencies in lots of Plasma and KDE Gear ports that didn’t bother to mention ECM.

So while it’s a colossal waste of time – editing and compiling – in many ways, the end result is a set of FreeBSD packages that is a much better match for the original idea of KDE Frameworks: lightweight, single-purpose libraries that extend Qt in various ways and that build together in tiers (1 through 4) of increasing complexity and interdependence. Which, for that one cool KDE application (konsole!) is a good thing.