Gentoo has an amazingly awesome feature where you can maintain your own patches against packages in the Gentoo package system [1]. This feature can be useful when the corresponding upstream project is on life support, obstinate, you have eccentric desires, or otherwise your (or someone else's) patch has not been accepted upstream. The patched package will still continue to automatically receive updates with the patch automatically applied over time (at least as long as the patch can be applied without errors -- some maintenance may be required).
NixOS—or more properly Nixpkgs—certainly does. (I expect Guix does as well, I’ve just never used it.) It’s even cooler when the distro being essentially a build system with an artifact cache means you can still use premade binaries for anything that you haven’t patched.
This falls out as a composition of two features. First, the default package build scripts support (and it’s a good practice to make your customization also support) an attribute called “patches”, containing, well, the patches that are applied to the unpacked source before configuring it. Second, Nixpkgs allows you to reach down into any package and mess with its attributes; NixOS further wires that up to a composable option. The result looks something like this:
(Here `prev` is the package set just before the customization in question is applied, useful for obvious reasons; while `final` is the package set after all the customizations have been applied, courtesy of lazy evaluation. Why’s that useful? Suppose you want to refer to some other package, say to add it as a dependency, and don’t want to depend on any customizations to it being applied before yours. What happens if you mess up and the customizations depend on each other? Well, what do you think happens when you mess up recursion in a huge chunk of pervasively recursive, pervasively lazy code, most of which you haven’t read. Ugh.)
Can’t say anything about Gentoo, but am a former Arch user that’s migrated to NixOS, so probably still close enough for your question. I’d say there are nevertheless advantages to Arch as both are now:
- The build-system joints which Nixpkgs exercises to separate things into package-specific directories... They technically exist, I guess, at least in the GNU standards and their implementations such as CMake’s GNUInstallDirs, but they have seriously rusted after three decades of no innovation in putting together a Unix-like.
Many simple things do build with minimal effort, don’t get me wrong, but that is achieved through a fair bit of magic in the shell scripts that mkDerivation pulls in, and when that doesn’t work things get really gnarly, with little systematic documentation as to which specific compat problems the relevant tooling does or does not solve and how. This is nowhere near the ease of throwing together a PKGBUILD—and the peace of mind of knowing that you’ll be able to do that even if it’s a Python Qt5 app or whatnot.
And I shudder to even think about what it takes to run a preexisting GUI binary on NixOS.
- NixOS is much closer to the Debian or Red Hat school of configuring things, in the vein of update-alternatives, /etc/default, and various other ways of dressing up the realities of the underlying programs and configuration files, than it is to Arch’s (and, I presume, Gentoo’s) way of having you just write whatever configuration you want directly.
There are upsides and downsides to both approaches (there are a lot of places where my Arch server hardcodes its own public IPv4 address), but overall the NixOS way is seriously leaky. When you dive into it, it also confronts you with the settings and accompanying config generators for everything. Not everything you have installed, like the dozen configs you have to write when installing Arch and some people already find overwhelming. Everything it knows about. Everything.
NixOS’s module system is still amazingly clever, mind you. It is the only config generator I know that’s capable of convincingly supporting interdependent configuration options, multiple levels of abstraction, all that stuff which either prevents others from scaling or has them lock you up in their way of thinking. The only other approach that I’d assume to even be theoretically capable of this is CUE, and even that’s purely a theoretical assumption—nobody’s tried.
But the blob of a codebase that obtains when you plonk every config option in the system in one place is just as awful as you’d expect. [Not incidentally, the configuration.nix(5) man page is a usability disaster simply due to its sheer size, and I’ve seen project members recommend a web-based service(!) over it.] This is made worse by years and years of support for superseded options and obsolete coding techniques, which are in part consciously maintained and in part just left there because nobody could possibly know whether they’re still necessary or even remember they exist.
I understand why this particular kind of project would need such discipline, but still, the implementation of the module system and the root tying-the-recursive-knot business is the best (concise) argument for breaking backwards compat that I’ve ever seen. It’s very simple at its core, and could’ve been really beautiful and the first (non-trivial) thing you showed anybody interested in learning the distro and the language. Instead, you get... that.
Why haven’t I gone back then? I can’t! I just bloody can’t! I imagine poking around random files in /etc and not being able to rebuild every part of my system from a version-controlled config, and I can’t do it. It’s like I’m using the PHP MySQL binding again, where everything seems to conspire to swallow every error and silently propagate wrong or null values to random places in your code unless you’re really really paranoid about checking absolutely everything, and even then it still slips thr...
As the original announcement (linked in a sibling) stated, Gentoo has shipped binaries for some time now for some of the packages that take longer to build (Chromium, LibreOffice) and when source isn't available (firmware, Nvidia drivers).
The difference now is that they are shipping binaries for all packages.
I was going to say, I remember getting KDE and OpenOffice pre-compiled 15 years ago. I made the mistake of building them from source on my Pentium 4 exactly once.
10 comments
[ 2.9 ms ] story [ 37.3 ms ] thread[1] https://wiki.gentoo.org/wiki//etc/portage/patches
I wish I knew more about NixOS or Guix -- do they have an equivalent feature?
This falls out as a composition of two features. First, the default package build scripts support (and it’s a good practice to make your customization also support) an attribute called “patches”, containing, well, the patches that are applied to the unpacked source before configuring it. Second, Nixpkgs allows you to reach down into any package and mess with its attributes; NixOS further wires that up to a composable option. The result looks something like this:
(Here `prev` is the package set just before the customization in question is applied, useful for obvious reasons; while `final` is the package set after all the customizations have been applied, courtesy of lazy evaluation. Why’s that useful? Suppose you want to refer to some other package, say to add it as a dependency, and don’t want to depend on any customizations to it being applied before yours. What happens if you mess up and the customizations depend on each other? Well, what do you think happens when you mess up recursion in a huge chunk of pervasively recursive, pervasively lazy code, most of which you haven’t read. Ugh.)- The build-system joints which Nixpkgs exercises to separate things into package-specific directories... They technically exist, I guess, at least in the GNU standards and their implementations such as CMake’s GNUInstallDirs, but they have seriously rusted after three decades of no innovation in putting together a Unix-like.
Many simple things do build with minimal effort, don’t get me wrong, but that is achieved through a fair bit of magic in the shell scripts that mkDerivation pulls in, and when that doesn’t work things get really gnarly, with little systematic documentation as to which specific compat problems the relevant tooling does or does not solve and how. This is nowhere near the ease of throwing together a PKGBUILD—and the peace of mind of knowing that you’ll be able to do that even if it’s a Python Qt5 app or whatnot.
And I shudder to even think about what it takes to run a preexisting GUI binary on NixOS.
- NixOS is much closer to the Debian or Red Hat school of configuring things, in the vein of update-alternatives, /etc/default, and various other ways of dressing up the realities of the underlying programs and configuration files, than it is to Arch’s (and, I presume, Gentoo’s) way of having you just write whatever configuration you want directly.
There are upsides and downsides to both approaches (there are a lot of places where my Arch server hardcodes its own public IPv4 address), but overall the NixOS way is seriously leaky. When you dive into it, it also confronts you with the settings and accompanying config generators for everything. Not everything you have installed, like the dozen configs you have to write when installing Arch and some people already find overwhelming. Everything it knows about. Everything.
NixOS’s module system is still amazingly clever, mind you. It is the only config generator I know that’s capable of convincingly supporting interdependent configuration options, multiple levels of abstraction, all that stuff which either prevents others from scaling or has them lock you up in their way of thinking. The only other approach that I’d assume to even be theoretically capable of this is CUE, and even that’s purely a theoretical assumption—nobody’s tried.
But the blob of a codebase that obtains when you plonk every config option in the system in one place is just as awful as you’d expect. [Not incidentally, the configuration.nix(5) man page is a usability disaster simply due to its sheer size, and I’ve seen project members recommend a web-based service(!) over it.] This is made worse by years and years of support for superseded options and obsolete coding techniques, which are in part consciously maintained and in part just left there because nobody could possibly know whether they’re still necessary or even remember they exist.
I understand why this particular kind of project would need such discipline, but still, the implementation of the module system and the root tying-the-recursive-knot business is the best (concise) argument for breaking backwards compat that I’ve ever seen. It’s very simple at its core, and could’ve been really beautiful and the first (non-trivial) thing you showed anybody interested in learning the distro and the language. Instead, you get... that.
Why haven’t I gone back then? I can’t! I just bloody can’t! I imagine poking around random files in /etc and not being able to rebuild every part of my system from a version-controlled config, and I can’t do it. It’s like I’m using the PHP MySQL binding again, where everything seems to conspire to swallow every error and silently propagate wrong or null values to random places in your code unless you’re really really paranoid about checking absolutely everything, and even then it still slips thr...
Gentoo goes Binary - https://news.ycombinator.com/item?id=38804135 - Dec 2023 (272 comments)
The difference now is that they are shipping binaries for all packages.