Large Unix programs were historically not all that portable between Unixes
utcc.utoronto.ca
utcc.utoronto.ca
It wasn't uncommon for the wrong block of code to get included so you had to figure out how the compile target's system call worked, how your system's system call worked and modify the code accordingly to get it to compile (and hope it worked). This was the 1990s so getting code to compile on Linux wasn't a high priority (since Linux was still in its infancy).
Fun times.
Fast forward to present: programs can target 10+ different Linux systems.
Fast forward 30 years to the future: programs can target 10+ different Ubuntu systems.
The device driver code had a shared component that supported the hardware, via an OS abstraction layer over top of the various OS specific ways to do things. The driver did fun things, like pin userspace memory for RDMA, which was often outside of supported driver interfaces.
The Windows, and the closed source commercial UNIXes were a PITA to bring up initially (AIX was the WORST). But once supported, they were easy to maintain because the interfaces never changed. Linux was fairly easy to write, but a PITA to maintain because the kernel interfaces changed so much. We had a configure style shell script to probe the kernel headers and detect how many args certain functions took on this particular linux version, etc. That script by itself was larger than the entire FreeBSD driver. (and FreeBSD was as easy as linux to write, and as easy as a commercial UNIX to maintain, since the interfaces we used didn't change).
One interesting thing that fell out of it is that we used ioctl interfaces everywhere (even Windows and MacOS). Since this was an HPC device, latency was critical and the Mac ioctl routines were painfully slow (like 4x slower than Linux/FreeBSD on the same hardware). So I tried switching to the Mach based IOKit IPC that Apple wants you to use, and that was twice as slow as ioctls!
I think I can imagine your pain.
Also "This program posts news to thousands of machines throughout the entire civilized world. You message will cost the net hundreds if not thousands of dollars to send everywhere. Please be sure you know what you are doing."
Uname -a having a build hash, and an index of hash to settings would have done better. Think of all the wasted CPU cycles computing how this chip orders a long long and testing POSIX compliance one function at a time.
Autoconf only fixes the apparent problem. Not the underlying disease.
At least X11 tried encoding the known patterns.
so whenever you upgrade the kernel or change CPU all your programs need manual patching? you may answer, "well uname -a was a joke, you would actually check the libc version". this worked alright in a very specific time period with a couple of big vendors with nigh-unmodifiable toolchains with well-defined release versions. it became increasingly awful when people started making their own toolchains with free software and had to patch every single piece of software to properly detect their new libc. sitting through an hour of autoconf sucks, but slogging through ten hours of patching poorly written bespoke configure scripts is a hundred times worse.
edit: not to mention cross-compiling where you can't even run uname -a, and which was almost universally broken before autoconf, which, despite being painful, made cross-compiling mostly work everywhere.
At one point in our project we had a lot of arguments about build systems and software repositories (there were times when we had to stop talking about it), then at some point John Ellson said, look, everyone else is using autotools, so do you want them to use your software? We realized he was right.
Individuals in the software community are capable of building a lot of amazing tools. The difficulty is persuading the community and teaching non-specialists to use them. They already know how to run make, or ./autogen.sh; ./configure --prefix=$HOME
Despite this Graphviz still has 3 or 4 build systems: autotools, Visual Studio (probably 90% of our audience is on Windows though we try not to think about it), Xcode (needed for an under-maintained MacOS app), and Magnus Jacobsson and Matthew Fernandez have a lot of a Cmake build working, though not yet complete.
Apologies for rambling a little off topic.
https://github.com/Perl/perl5/blob/perl-4.0.36/Configure#L10...
Alas - this was extra work on the developer, and at the time there were a zillion variations, which a developer had to deal with.
Back in 1999 - 2003 I had lots of fun porting code between AIX, Solaris, HP-UX and Red-Hat Linux.
A decade earlier the fun was with Xenix, DG/UX, and early GNU/Linux flavours.
And it wasn't only the OS specific APIs, each OS SDK had their own glitches and deviations from C standard.
More than once got sat down and told to connect to their HP-UX, AIX, Solaris, Linux, etc box and setup things up.
Would have to go back and explain that particular server was actually something different and I'd put the appropriate build on it.
Of course, every system had to have it's own build, and own scripts to accommodate all the differences mentioned here. University CS courses had definitely not covered things like GNU vs BSD tools, and various other differences.
I remember being advised early on in that job to learn vi, not because it's the best editor, but just because it's the only one you can rely on being everywhere, on every server. There were other discussions in the office about which editor for actual dev work, but for client visits on random servers - vi is always there.
I agree that to take a program from one unix and make it work on another is a tedious task, but the difference is minimal when you compare portability of architecture specific assembly language code. It is the reason "portable" languages like C were created.
Porting programs to Windows still remains a challenge.
Just to make the problem more clear, add:
Irix, Ultrix, SunOS, DG/UX, Pyramid OSX, NCR Unix, Xenix, A/UX, Bull DPX, EP/IX, ISC, MachTen, NeXT, Dynix, UnixWare, ConvexOS, Coherent, DomainOS and more...
See the supported platforms for something like Kermit or Pine to see this isn't just piling on. Some real and popular software had to support huge lists like this. Perl's CPANTS testing network was neat for stuff like this, you could write a module (including C code), and watch all the various ways your code would bomb on other platforms without having direct access to them.
http://www.columbia.edu/kermit/unix.html
http://www.mit.edu/afs.new/athena/astaff/source/src-9.0/thir...
Not quite that, but there are certainly a lot fewer with notable amounts of use. Which means, in turn, fewer compilers with unique flags...you can get away with supporting just gcc/clang.
And there are fewer machines that are big endian, or have unusual byte alignment, or have a buggy built-in malloc, or don't have off_t defined, or have unusual flags to link to pthreads. And so on...all the stuff things like Configure test for.
But as the essay notes:
> they gave you the tools that you could use to sort out how to achieve that, and to automatically detect various things you needed to do to adopt to the local Unix
autoconf doesn't do much on its own, it's more of a toolbox, if you don't leverage the tools it gives you, you won't achieve any sort of significant portability.
Firefox is portable and it's a large program, but a LOT of effort went into that.
That's irrelevant whataboutism.
TFA is very specifically in response to one pining about older unix ecosystems and seeing them as havens of portability, and explains that that was not the case at all.
Was that in absolute, or relative terms? Since portability between OS/360 and TOPS-10, for example, was non-existent.
Which - of course - varied somewhat different across different models.
Windows NT POSIX subsystem was for ticking check box on DoD contracts.
Had Microsoft been half serious about POSIX in NT like they are nowadays with WSL, Linux would never had taken off.