I don't want to come across as disrespectful to my elders but in many ways I feel that certain kinds of nostalgia like this are holding open source back. One of my favorite pieces of software is GNU Make. Having read the codebase, I get the impression that its maintainer might possibly be a similar spirit to the OP. The kind of guy who was there, during the days when computers were a lot more diverse. The kind of guy who still boots up his old Amiga every once in a while, so he can make sure GNU Make still works on the thing, even though the rest of us literally would not be able to purchase one for ourselves even if we wanted it.
It's a pleasure I respect, but it's not something I'll ever be able to understand because they're longing for platforms that got pruned from the chain of direct causality that led to our current consensus (which I'd define more as EDVAC -> CTSS -> MULTICS/CPM -> SysV/DOS/x86 => Windows/Mac/Linux/BSD/Android/x86/ARM).
My point is that open source projects still maintain all these #ifdefs to support these unobtainable platforms. Because open source is driven by hobbyism and passion. And people are really passionate about the computers they're not allowed to use at their jobs anymore. But all those ifdefs scare and discourage the rest of us.
For example, here's a change I recently wrote to delete all the VAX/OS2/DOS/Amiga code from GNU Make and it ended up being 201,049 lines of deletions. https://github.com/jart/cosmopolitan/commit/10a766ebd07b7340... A lot of what I do with Cosmopolitan Libc is because it breaks my heart how in every single program's codebase we see this same pattern, and I feel like it really ought to be abstracted by the C library, since the root problem is all these projects are depending on 12 different C libraries instead of 1.
> I recently wrote to delete all the VAX/OS2/DOS/Amiga code from GNU Make and it ended up being 201,049 lines of deletions.
That commit 10a766eb you linked to appears to have significantly more than removal of those architectures -- you also appear to have deleted all the tests, documentation, and support for multiple (human) languages. Of the portions of diff which aren't deleted files, many of the deletions seem to be around code reformatting (i.e. they add a line for each line they remove), and removal of includes which your libc doesn't need / support. I do see that you have removed several #ifdef VMS (and similar) stanzas, but the vast bulk of the changes are either removal of, or modifications to, unrelated files.
Although I agree instinctively that we shouldn't expect to run the latest version of Make on the VAX in our basement, this diff doesn't make that argument very well and IMO borders on disingenous.
Or, to put it another way, after looking at your diff, I feel much happier about your hypothetical make-on-Amiga afficionado, because I know that they also care about i18n, documentation, and testing!
Identifying the moment we need to stop supporting a platform is frequently non-obvious. Unisys still supports MCP (as Clearpath OS), VMS is supported and was ported to x86, Atos supports GECOS, and some people are making CP/M fit inside dedicated word processors. A couple months back there was a report of ncurses failing on Tandem NonStop OS (still supported, IIRC, by HPE). As long as something works, we'll never hear about all those wonderful exotic platforms people still use for various reasons. There must be a lot of PCs controlling machinery doing GPIO through parallel ports while emulating PDP-8's with some poor intern having to figure out how to make changes to that code.
There should be a foreseeable date when we can say, "OK the Amiga maintainers have added a feature that lets us use '.' as a directory so we can now delete that #ifdef". But that day is guaranteed to never come, because the Amiga project is disbanded. So should we keep that until the heat death of the universe?
I would propose that we instead say, if you use Amiga, there's great support for it in versions of GNU Make up until x.y.z. So if you love old Amigas, you'll be well served using an older version of GNU Make. I think it's straightforward.
This kind of thing shows why ifdefs are usually the wrong tool for multi-target projects.
There should be a platform adapter API instead that defines a shared header with function names for these actions, multiple platform-specific implementation files, and only one of them gets compiled.
That way you could simply ignore the existence of "filesys_amiga.c", and then maybe delete it 50 years from now.
(I realize it's probably not realistic to do such major internal surgery on Make at this point.)
This was one of the brilliant aspect of Knuth's web system: You could have change files that would be applied to the immutable source to manage ports to individual platforms.¹ I really wish that this sort of patching had spread to other programming paradigms.
⸻
1. It works even on somewhat actively developed code since the likely to require porting parts of the program could be clumped together in a web source file and, once isolated, generally saw few if any changes. I remember maintaining the public domain vms change files for the TeX 2–3/MF 1–2 upgrades and as I recall, even with these significant changes to the programs, no updates for the change files were necessary.²
2. Most of the work that I did back then in maintenance was centered around enhancements to the VMS-specific features. For example, rather than having iniTeX be a special executable, instead, iniTeX features could be enabled/disabled at runtime from a single executable.³ Similarly with debug code.
3. This feature appeared soon after in the web2c port of TeX and friends, but I think that Tom Rokicki might have got the idea from me (or else it was a case of great minds thinking alike in the late 80s).
I respectfully disagree to this very common argument against ifdefs, and will also point out that developers who hold this anti-ifdef belief hold it quite strongly! I generally prefer the ifdef-style.
> But that day is guaranteed to never come, because the Amiga project is disbanded. So should we keep that until the heat death of the universe?
Surely there are more options "keep that until the heat death of the universe" and "remove that the moment its platform is out of production". A more practical metric for free/open software, I think, would be "is there still someone maintaining this software on this platform": every major release (e.g., 5.x -> 6.0) could be a time to do a sanity check, documenting ports that don't have an active maintainer as "deprecated". At the next major release, if nobody's stepped up to maintain it, then it gets removed. (One could argue even that's too draconian, because there may be people still using the port even if it's not maintained.)
Surely this is a problem of source code organisation not multi-platform support? A better model would be having clearly articulated platform/arch specific files doing all the per-platform/arch defines, which then get included for the target specific build. However, reorganising a code-base this way when it wasn't like that at the outset is can be a fraught (and hard to justify) exercise.
A good example of source code organisation that does a decent job of separating per-platform concerns, is the Nethack code base.
Maybe because tons and tons of software build with GNU make, not with Ninja, and if you want to be able to build that software, you need GNU make?
Also, Ninja by itself is not really a replacement for GNU make. Rather it's a tool one can build such a replacement on, so the comparison is a bit off to start with...
The Cosmopolitan Libc repo uses GNU Make. It builds 672 executables, 82 static archives, and 17,637 object files and runs all unit tests in under 60 seconds on a $1000 PC. How fast would Ninja do it?
While I agree that having one library could be a good solution, I don't think all those #ifdefs are wasted. There are a lot of legacy tech programs that use systems way older than I ever imagined would still be in use. There was a minor crisis at for an org I was working at one time where they were going to need to flip a multimillion dollar system because the only source of replacement parts was a hobbyist in his garage and for new gov compliance purposes that guy was going to need to become a cleared contractor supplier...which can be problematic if the person in question is an open source advocate whose main purpose in running this business in retirement is supplying enthusiasts rather than government departments or contractors.
I'm sure some of those systems and ones like it make plenty of use out of those #ifdefs though, and it's not just a handful of old fogey enthusiasts cramping everyone elses style. Established systems can't always evolve as fast as the general market.
Because open source is driven by hobbyism and passion. And people are really passionate about the computers they're not allowed to use at their jobs anymore. But all those ifdefs scare and discourage the rest of us.
Isn't this the same process you yourself referenced? There's nothing stopping people from forking and building leaner versions of these programs, but it turns out that projects with those passionate, nostalgic developers are more successful even with the support burden than that same project without them. That backwards-support might be a cost rather than a waste.
Scaring new talent away from spending their precious time on a solved problem like GNU make is a feature not a bug. Work on something more relevant to today's challenges.
There's plenty of things "holding open source back", this isn't a significant one of them IMNSHO.
Saying make is a solved problem is a real failure of imagination. I used to do a lot of work on Blaze and Bazel. I intend to add support for a lot of the things it does to GNU Make. Such as using ptrace() to make sure a build rule isn't touching any files that aren't declared as dependencies. I can't do that if our imagination is stuck in the 80's with all this DOS and Amiga code.
I wrote Bazel's system for downloading files. https://github.com/bazelbuild/bazel/commit/ed7ced0018dc5c5eb... So I'm sympathetic to your point of view. However some of us feel like people should stop reinventing Make and instead make Make better. That's what I'm doing. I'm adding ptrace() support. That's something I asked the Bazel folks to do for years but they felt it was a more important priority to have Bazel be a system for running other build systems like Make, embedded inside Bazel. So I asked myself, why don't we just use Make? It's what Google used to use for its mono repo for like ten years.
"You can't have systemd in Debian, what about kFreeBSD"
"You can't use Rust until it supports DEC Alpha"
...there are no shortage of examples where open and free software is held back by hyper-niche interests, where our pet twenty and thirty year old, long-dead projects and processor architectures create absurd barriers to improve anything.
NetBSD is so cool, and I have so many machines sitting around I need to get running on (SGI, Alpha, Dreamcast, etc.)
Sadly I’ve heard it can be rough on older architectures still. I’ve been told, that at least on VAX, for example is not in the best of states because usermode dependencies on Python. From what I was told, Python currently doesn’t have a VAX port due to the architectures floating point design.
The weird thing I keep seeing is that many C libraries still define their own integer types for some reason instead of just using the ones from stdint.h. Even new ones, that certainly didn't ever need to support ancient platforms and ancient compilers, like libopus.
> instead of just using the ones from stdint.h. Even new ones, that certainly didn't ever need to support ancient platforms and ancient compilers, like libopus.
But stdint.h is from C99, and AFAIK there are non-ancient compilers for non-ancient platforms that still don't fully support C99.
> many C libraries still define their own integer types for some reason instead of just using the ones from stdint.h
Many C developers in my experience (as recent as 5 years ago) haven't really adapted to C99. This is in part because some platforms (Microsoft, I'm looking at you) resisted adopting it for quite some time and partly because a lot of C development is carried out by older developers who have long given up on keeping up with new developments. And I say that as a dev in my 40s.
I think stdint etc are great, but for some people the start of any 'serious' C codebase still requires a whole load of int and pointer type redefinitions.
I agree. That's why the Cosmopolitan Libc repository includes support for C++ as well as a JavaScript interpreter. It has Python 3. You can build Python 3 as a 5mb single file Actually Portable Executable that includes all its standard libraries! Then you put your Python script inside the executable using a zip editing tool and it'll run on Mac, Windows, Linux, name it. You can also build Actually Portable Lua too. More are coming soon.
Make is a very old codebase that you shouldn’t change in dramatic way anyway. It’s in itself an outdated piece of software which has far better and more modern replacements.
Everything I do, I do for you. I don't expect you to use it or thank me or pay me. All I'm saying is I could have more impact serving the community with fewer ifdefs.
And if you cut down every #ifdef in the code base, would you be able to stand in the winds that would blow then?
It's not just GNU make. Lots of GNU software is as you describe, because the GNU project took on the burden of abstracting the mess that was interoperating across many very different platforms -- many of which have far less capability than a modern or even decade-old x86-64 box -- and so became an internal reflection of that mess. It's not pleasant, I wish I could chuck autotools into the fucking sun, but it gets GNU going on a variety of exotic platforms that still run and are made more pleasant by the presence of GNU there. This effort is not helped by you going in and trying to yeet all the code you personally have decided is obsolete and gets in your way. GNU Make doesn't need such a "service", it's not "held back" by refusing it, and if you want a build tool that runs on and helps you build your little inner-platform effect without considering anything you personally deem irrelevant, write your own! Maybe start with Plan 9's mk as a base, it's tiny and comes from a somewhat similar philosophy.
Sheesh. Terry Davis believed he was important enough to be gangstalked by the CIA, and even he took a hobbyhorse, take-it-or-leave-it approach to TempleOS.
I don't have any authority over the GNU project. The things I do in the Cosmopolitan Libc repo have no bearing on them. They're free to keep doing what they're doing. However I'm willing to bet that once I add ptrace() support, it'll be attractive enough that folks will be willing to consider the equally libre copy of the GNU Make software that I intend to distribute instead. Just as they'll be free to copy what I did back into their own den of #ifdefs if they want to compete. Competition is good. Open source is good. It's all done with the best intentions. We're going to end up with a better Make once I've contributed this feature.
No worries friend. Not the first time I've gotten the Terry Davis treatment. Didn't Gandhi or someone say first they ignore, then laugh, then fight, and you win? Changing the world one line of code at a time!
It's a pleasure I respect, but it's not something I'll ever be able to understand because they're longing for platforms that got pruned from the chain of direct causality that led to our current consensus (which I'd define more as EDVAC -> CTSS -> MULTICS/CPM -> SysV/DOS/x86 => Windows/Mac/Linux/BSD/Android/x86/ARM).
My point is that open source projects still maintain all these #ifdefs to support these unobtainable platforms. Because open source is driven by hobbyism and passion. And people are really passionate about the computers they're not allowed to use at their jobs anymore. But all those ifdefs scare and discourage the rest of us.
For example, here's a change I recently wrote to delete all the VAX/OS2/DOS/Amiga code from GNU Make and it ended up being 201,049 lines of deletions. https://github.com/jart/cosmopolitan/commit/10a766ebd07b7340... A lot of what I do with Cosmopolitan Libc is because it breaks my heart how in every single program's codebase we see this same pattern, and I feel like it really ought to be abstracted by the C library, since the root problem is all these projects are depending on 12 different C libraries instead of 1.