I'm mad about linux distros again today and I think I am realizing why this is so hard for me to write about systemically: I have a software engineer brain and so I try to model the various problems as technical problems. And there are numerous technical problems to think about (platform interfaces, ABI boundaries, release management, etc) but the core problem is a social one, which requires a social solution.
In short, all the volunteer-based distributions need to have a gigantic conference where they all come together and *agree to stop working on about 99% of them*, to pool efforts to make a real Linux platform. A lot of people will need to put their egos aside and decide to acquiesce to solutions they believe to be technically inferior, in order to be able to address the diffusion of labor into pointlessly recreating basically the same toolchain a thousand times.
This is a big problem because labor is not fungible and the reason that a lot of these people got involved in distro development *in the first place* is that those sorts of problems and systems are interesting and engaging for them to work on. They all want to have control over a packaging tool, or a build farm, or whatever. The redundancy is a huge problem and a huge waste but it's also the engine that powers the whole thing, to some extent.
Fixing the problem involves driving a truck through that load-bearing "to some extent". Doing a big ugly multi-party negotiation to figure out how we can EOL Qt, to replace it with Gtk everywhere, and get all the Gtk devs on board with being *extremely* nice to the Qt people as we sunset their work. (Did you feel a little thrill because I picked Gtk instead of Qt? Well, I flipped a coin. Imagine I said Qt wins instead of Gtk. You're gonna be that mad about *big* parts of this, no matter what.)

@glyph I mean, yes, but should I write my Windows app to use GDI, GDI+, WinForms, WPF, UWP, or whatever they're doing nowadays?

That only works on the corporate side because they throw oodles of money at propping up that hodgepodge of manager-getting-promotion frameworks, but yeah... that doesn't work so well when volunteer labor is fungible. Imitating corporate dysfunction without corporate resources is... suboptimal.

@xgranade on Linux this stuff matters because the user might be making choices about which ones are available. your package might arrive on a system without GTK, or without configuration for GTK. arguably on Windows making this choice is still a drain on your time and resources, but whichever choice you make the app still *works* and Microsoft has cleverly conditioned their user base to not care at all about how anything looks by using 15 different toolkits internally

@glyph I mean, yes, right up until an application doesn't work, and then "computers are just like that."

The number of times .NET Framework is the wrong version, or that .NET is missing entirely (Windows ships with .NET Framework, not with .NET, same problem as Windows PowerShell vs PowerShell and for the same reasons), or it's the wrong version of the C++ runtime, or or or.

@xgranade yeah windows is weird because you're really supposed to ship Windows to your Windows users as well, right? what if static linking, but in hell
@glyph .NET (not .NET Framework, because branding) is basically nodejs in terms of the static linking approach to packaging, yeah. You have to bring all your dependencies with you. This is a good idea, actually, for anyone used to Windows development back when you had to rely on a single fucking thing in C:\windows\system32. I have spent more hours in Dependency Walker than I ever care to admit.

@glyph I can't address macOS since I'm again entirely outside of that world, but IME, no matter how painful Linux dev is, it pales in comparison to Windows dev as soon as one single line of native code enters the chat.

Like, .NET applications that rely exclusively on .NET packages and so forth work *fine*. It's really once you try to interact with native code, appx publishing, or anything other than "run this NuGet command" that things break.

@xgranade @glyph Forgive me if I come off as a Rust fanboy, but Rust is pretty good about making it easy to ship a self-contained native executable on Windows. They just need to make the hybrid CRT (see my other post) the default. I guess I should open an issue and then a PR.

That also means it's easy to use Rust to build a native module in a larger Python or Node.js app. (Not sure about .NET; last time I tried, you were on your own for implementing and consuming a C API via P/Invoke.)