Meta(
    title: "Annoyed with Foss Desktops",
    summary: Some("Some interlinked issues are encountered while building packages using Pkgsrc on Linux using Musl libc"),
    published: Some(Time(
        year: 2023,
        month: 2,
        day: 26,
        hour: 16,
        minute: 44,
        second: 53,
    )),
    tags: [
        "linux",
        "musl",
        "pkgsrc",
        "rants",
    ],
)
---
I've pretty much finished rebasing HitchHiker Linux to use Musl libc now, verifying that builds work for all of the platforms I'm trying to support (x86_64,aarch64 and riscv64). I've been working slowly through building packages for it using NetBSD's Pkgsrc. As expected, there have been a lot of annoyances along the way. I'll be explicit in warning (in case you haven't already figured it out) this post is going to be a rant.

## The scope of the project
I'm not trying to build all of Pkgsrc. Not even close. Some of what's in there doesn't really make sense in 2023 anyway. For instance, Plasma desktop is stuck on the last KDE4 series release, and Gnome is also behind (while not as far). Those builds are also seriously broken. There simply aren't enough maintainers. Interestingly, the kde builds don't even have up to date url's for fetching the sources, as they are so old that they've been moved to an "attic" directory on the server. Note that I find this practice distasteful to begin with. If you make a source tarball available at a certain link when it is released then it's not good practice to move that link later.

My aims are to provide a halfway decent desktop on x86_64 with the choice of either Xfce4 or Mate, or a variety of lightweight Window Managers. I want to have a decent subset of common well known packages for common desktop uses like image editors, word processors, audio and video players and the like. For aarch64 I'm not planning to provide a desktop but a lot of home server options as that's what I tend to use my Arm boards for and suspect that a lot of other users do the same.

## Posix is great. Too bad it came late to the party.
Musl aims to be a standards compliant Libc implementation. Posix is the chosen standard. That makes Musl an almost drop in replacement for Glibc. It's the almost part that causes headaches. I have mad respect for the distros that have been doing this sort of thing for years such as Alpine and Void. The crux of the problem is that until Posix there was no agreement on what should go into Libc, so there was already a good bit of drift between what functions were available on Linux vs BSD vs the many commercial Unixes. This is exactly what Posix set out to address. A lot of their choices were sound, but there's a few that were questionable. For instance, the GNU function getline was included in Posix while the BSD fgetln was left out. Both functions read lines from a stream. The BSD function is far more ergonomic. The GNU getline comes loaded with lots of nice footguns in comparison.

There are also lots of cases of functions that most Unix systems have but which are not in the standard. And there are some things that were included in the standard but probably shouldn't have been, and thus were puposely omitted from Musl. One of those more glaring cases is the sys/queue.h header. This header contains almost all of the implementation via macros. Headers are not supposed to contain implementations, only signatures and things like constants. I can understand the decision to leave this out. Frankly there are better implementations of all of the interfaces provided by the header in third party libraries. I'll get to another troublesome omission in a bit.

## I hate suid binaries
Yeah, I know that seems like jumping around. I need it for background. I recently wrote my own small sudo replacement due to my long held belief that you probably don't want any more suid binaries on your system than neccessary, those binaries should be as simple as possible, and their inclusion should probably not be mandatory to get other things working. 99.9% of Unix users who have sudo installed use probably 5% of it's features. But sudo is just the tip of the iceberrg here.

I used to joke back when Gnome2 was the most common Linux desktop that the Gnome devs never met a daemon that they dodn't like. When you started up Gnome you wound up with dozens of background processes. It might have since gotten somewhat better, but then again it might be worse. I haven't tried to measure it. Anyway, we used to have a program called gksu and another called gksudo which were just graphical wrappers around su and sudo, respectively. They were used to run graphical programs with permissions other than what your user normally had. Things like running a graphical package manager. That code has been left to rot because we now have Polkit. Polkit runs a background process that you connect to using the included pkexec binary in order to accomplish those sorts of things. I could have easily predicted that someone would find some horrible vulnerability and sure enough we had in the fairly recent past an exploit known as pwnkit. I suspect there will be more.

At any rate, I would love it if I could run a full desktop without Polkit and pkexec. But both Mate and Xfce4 have grown hard dependencies on Polkit, as it just "how it's done now". To add insult to injury, the version of Polkit that is in Pkgsrc won't compile without that non-posix functions setnetgrent, endnetgrent, getnetgrent, and innetgr. And of course none of those functions are included in Musl. This has actually been a known problem for some years now, and searching for a solution on DuckDuckGo eventually led me to several variants of a three year old patch set that exists in Gentoo's portage, Alpine's apkbuilds and the issue tracker for Polkit itself. The original patch languished on their tracker until 7 months ago when someone took it upon themselves to rebase it against the current source and get it merged.

The patch itself is all preprocessor directives. If `HAVE_GETNETGRENT` is not defined it replaces the offending blocks of code with an error, so that if a user configures Polkit to use Unix netgroups support it will fail with an error. Since they've been using it in Alpine and Gentoo for quite a while without anyone complaining it makes one wonder how often anyone actually needs netgroup support in Polkit. I'd take that as a strong case to just rip it out entirely and thus simplify the codebase.

## Git web forges kinda suck
Having found said patches, it would really have been nice if there was a way to have GitLab shit out a patch from the pull request so that I could apply it and send the patch upstream to the Pkgsrc guys. If there's a way to do this I never found it. I wound up cloning the repository and just using the git command manually. At any rate I did get Polkit to compile, and have resumed building Xfce. I'll have to backtrack through the Mate dependencies as I had found ways of turning off Polkit dependency in a few of it's dependencies until I reached a point in the process where it was definitely going to be a hard requirement.

## WTF Samba?
I was getting persistent errors trying to build Samba4. The Samba devs chose `waf` as their build system some time ago, and I was first attempting to figure out if there was a way to turn off a feature that depended on the code which was failing to compile. But I have neither the time nor the patience to learn `waf`, on top of all of the time I've spent mucking around with autotools and meson. There wasn't an answer readily visible. The error messages were also nowhere near informative, obscuring the actual commands being run and their error messages. What I did find is that you can run `waf` with a verbose flag and it will stop obscuring that information. So I manually went into the source directory and did just that, expecting to have to read the errors and do a bit of hacking. But wow, fuck me gently with a chainsaw it compiled with no errors. I expect something in the environment being passed from Pkgsrc was causing it to shit the bed but I'm not going to try to figure it out. I backed up two directories and did a `bmake package install clean clean-depends` and moved on.

Note that there are several pet peaves at work here. Someone at some point was fed up with autotools and decided to reinvent a build engine. Then several hundred other people followed suit. There's a great XKCD panel about this sort of thing. The Samba devs chose `waf` out of tthe mess because it works for them. Fair enough but Samba4 is a major project with a lot of infrastructure depending on it. For all the unlucky SOB's who have to package Samba this is a headache. Lastly, if you think it's better to show a progress bar than the commands being run along with their error messages, then please don't write a build system. Some unlucky SOB in the future is going to run into problems and they are only going to be annoyed at the pretty yet uninformative output.

## Yeah, I'm going to rant about C again
A lot of these issues feed right into my main complaint with C as a programming language and ecosystem. Since C sort of grew organically over the years a piece at a time, largely coded by well meaning guys who nevertheless had no clear idea of the big picture, what resulted is an ecosystem with an exception to every rule and an embarrassing lack of standardization. Does C have standards? Yes. Pick one. Then pull your hair out because something you're depending on follows a different standard.

This problem infects every aspect of the C ecosystem, from Libc to build systems to methods of generating documentation. Everything past compiling an object file is a tacked on extra for which you have multiple competing ideas on how to do it best. If it were that bad it would already be bad, but that's just scratching the surface. You can't really even depend on the sizes of integers being the same from implementation to implementation. And while the action of standards committees has helped somewhat to clarify some of the most difficult low level issues, every proposed fix breaks someone's implementation and you often wind up with a deadlocked committee that makes the decision to not decide, kicking the can further down the road.

sed '^RantMode s/on/off/'