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
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
The exact mapping of names can be found in files
There are some conventions particular to the KDE ports
- 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
- 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.
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.