prt-get/doc/i3-softdeps.md

6.8 KiB

Followup on installing i3 with the softdeps-aware fork of prt-get

(Was: Re: prt-get nicetohave)

2023-08-25

The "Optional" metadata field stirred up some controversy when first proposed. At the time, it was preferred to write Pkgfiles whose build() functions contain no branching logic to customize the build for the host machine. Maintainers would even try to suppress the branching logic hidden inside the autotools ./configure script using command-line switches to hard-code the desired defaults [1]. Peer pressure eventually wore away at the resistance to this new metadata field, so it is now in widespread use despite there being no official mandate for contributors to test their ports under all possible configurations. Whenever a port can adapt to a variety of use-cases, maintainers try to document that versatility in the "Optional" field. But our package management tools remain unable to use that data! At present, it requires a human reading the Pkgfile, for the data in the "Optional" field to affect the order in which ports are built. Thankfully, sorting with optional dependencies taken into account is now possible in prt-get itself, either with the softdeps or the mixed-upinst branch of the fork by farkuhar.

Respecting the limitations of a prt-get that only knows about hard dependencies would entail following the old practice and hard-coding the configure options in each port. This example of letting our tools dictate how we work (rather than updating the tools to fit a new workflow) would encourage a portdb more like the AUR, with a seemingly endless variety of dups that all have their own particular combination of configure options. Thankfully the unwieldiness of this prospect was enough to deter maintainers from clinging to an outmoded interpretation of KISS [3], and they adopted the new norm of "fluid Pkgfiles" (FS#1576) even as prt-get remained unable to incorporate this fluidity in its operations.

As recently as November 2021, users of CRUX could still have noticed a remnant of the historical preference for non-fluid Pkgfiles, illustrated by the coexisting pair harfbuzz and harfbuzz-icu. These ports differed from each other only in the configuration option that enables linking to icu. A port that depends on the icu-linked harfbuzz would list harfbuzz-icu among its dependencies, while a port that did not require such linking would only list harfbuzz.

Such dups in the portdb, all using the same upstream tarball, inevitably have overlapping footprints, and it becomes impossible to avoid filesystem collisions if a user running prt-get depinst foo triggers an attempt to pkgadd a variant of an already-installed port. Once the set of installed ports is sufficiently diverse, maintaining prt-get.aliases so as to avoid such collisions becomes an impossible task.

Nix (and GoboLinux even earlier) solves the overlapping footprint problem by giving each package its own separate directory in the filesystem. This solution arguably fits quite well with the historical CRUX preference for rigid Pkgfiles, offering a one-to-one correspondence between a repository of non-fluid ports, and the filesystem where built packages are unpacked. But CRUX was reluctant to impose an additional layer of complexity on top of the Filesystem Hierarchy Standard, and so the Nix and GoboLinux solution never gained serious consideration in the CRUX community.

As the last vestige of a historical preference for non-fluid ports, harfbuzz and harfbuzz-icu persisted alongside each other until surprisingly recently, only getting merged into one fluid port with commit b2e30dbf8c96e03f4fe4b39b1e5ffbecd8372787. This merge allowed users to simplify prt-get.aliases, removing harfbuzz-icu: harfbuzz (if they had ever added such an entry to avoid filesystem collisions).

Equipping prt-get with softdeps awareness is just letting our tools evolve to match the trend toward fluid Pkgfiles. If the new prt-get capabilities are deemed to violate the CRUX Mantra [2], then the same criticism can be leveled against fluid Pkgfiles. Such criticisms were in fact expressed (by Anton most stridently, and by Tilman and Juergen in a gentler tone) during the discussions of USE flags and "prt-get nicetohave" [3,4]. But the resistance to fluid Pkgfiles has diminished over the years, to such an extent that nobody has seriously proposed crafting the dependency graph so that prt-get depinst i3 is impossible to fail [5], say by making i3 depend on a duplicate port libxkbcommon-x11 (which would differ from libxkbcommon only by hard-coding the meson option "-D enable-x11" and by listing xkeyboard-config as a hard dependency --- similar to how harfbuzz-icu differed from harfbuzz).

A duplicate port of libxkbcommon is indeed a KISS solution, with prt-get in its present state. That nobody bothered to propose such a dup is a clear indication that we are not going back to non-fluid Pkgfiles anytime soon. So either our Pkgfiles have irrevocably become "just a bit" more complex (and therefore no longer "simple"), or they are in fact the simplest way to accommodate the modern software landscape. In the latter case, a KISS objection to any new logic in prt-get is hypocritical. In the former case, it could be argued that two wrongs do not make a right, and the trend away from KISS Pkgfiles does not justify making prt-get "just a bit" more complex. But then we would have an awkward mismatch between the capabilities of prt-get, and the ports that it has to handle. This mismatch is only a slight annoyance at present (the experienced users that make up the CRUX target audience can usually diagnose the problem themselves if they encounter a build failure like [5]), but before the software landscape becomes even more convoluted and such build failures harder to avoid, we should have the discussion on adding new logic to prt-get.

[1] It should be noted that the autotools ./configure script (or its meson or cmake counterpart) might not actually expose all compile-time options via command-line switches. Hence some testing of the host environment is unavoidable, unless the port maintainer performs substantial downstream patching of the source tree.

[2] We do not want to prepare for all necessities and build a complex system which in 90% of all cases is overkill ... making something "just a bit" more complex is not "simple" anymore. (https://crux.nu/Main/Mantra)

[3] https://lists.crux.nu/pipermail/crux-devel/2006-August/001912.html

[4] https://lists.crux.nu/pipermail/crux-devel/2008-May/003366.html

[5] The possibility of this command failing was first noted by jaeger in https://libera.irclog.whitequark.org/crux/2023-08-21 (16:36)