4 ms·
In decades past, if you were developing software for Unix you would inevitably run across compatibility problems. Even with the POSIX standard, every Unix was t
by db48x 3y ago
In decades past, if you were developing software for Unix you would inevitably run across compatibility problems. Even with the POSIX standard, every Unix was trying new things, inventing new things, or just implementing the same thing in slightly different ways. So your programs had to have a bunch of macros to switch between different variations. Some API would have two arguments on Unix A but three on Unix B, so you would have to turn that api call into a macro that would insert the missing third argument or whatever. But now your users needed to know which configuration of your software to use. You could try documenting all the little knobs and switches and make them choose the correct values, but someone hit on a clever idea.
Just write a little program that tries calling the API with two arguments, and see if it compiles. If it does, you could automatically define THAT_API_HAS_TWO_ARGS and your code will do the right thing. If it fails to compile, then define something else.
So you start writing a shell script that will run through all of these tests and dump out a header containing all of these configuration choices. Call the script `configure` and the header `config.h` and you are good.
Except that actually writing a shell script that is really actually POSIX correct is pretty hard. And the code is pretty repetitive. Mistakes start to creep in, bashism break things when it’s actually run under `sh` and so on. And it turns out that all the little tools we rely on, like find and grep and sed and awk, are all different on different platforms too! Turns out that nice option you were passing to grep is just an extension, only present on your specific flavor of unix.
So the next clever idea was to write a program that generates the configure script. The repetitive bits can mostly be solved by text substitution, so someone had the bright idea to use M4. Thus autoconf was born.
Autoconf solved a lot of problems. It ensured that the configure script was actually POSIX correct. It did this even though the generated script was even more complex than ever, with extra logging and tracing and debug output that most people never look at, but which is actually super useful for debugging. The configure script you had written by hand didn’t have any of that!
And autoconf came with baked–in knowledge about all the things you might need to test for. Any time someone discovered some new difference between Unices, new tests were added to autoconf for it. Autoconf users hardly had to do any more work than to look up the name of the macro that it would define for you.
Of course, M4 causes actual brain damage in regular practitioners, and nobody cares to write software for any Unix except Linux these days. Even the BSDs are an afterthought. Technically OpenSolaris is still out there, with superior features like ZFS and Zones and whatnot, but that’s a lot of extra work. So autoconf is a dinosaur, solving problems that nobody really has any more.
Rachel is not wrong that it’s crazy to rerun the same configure script over and over, but really only developers have to do that. Most people just run the thing once when they install your software, and never see it again. And most people don't even do that any more, because they download binaries from their package manager most of the time. It’s just the distro packagers that actually run your configure script.
And she’s right that the answers configure gets should be cached system–wide. Autoconf does support that, but it’s harder to do correctly than she remembers. And by the time it was possible usage was already waning in practice.
- cpeterso 3y agoIt always seemed to me that most of these differences and macros could be defined in a static header file that has a million #ifdefs for different OS and compiler versions. That seems simpler and more reliable, and usable for cross compiling, than running dynamic checks with autoconf.
- smackeyacky 3y agoHmmm. Nope. The file would be near unusable and contain a pile of things you don’t care about where autoconf can cope with the one or two cases you are trying to manage. Despite the description above of the genesis of autoconf, at the time when there were dozens of nearly compatible unices, it was a key enabling technology for free software to be distributed and shouldn’t be discounted just because it’s a little hard to understand.
- db48x 3y agoIt was absolutely a boon to all developers who used it. If you didn’t use it you were doing things the hard way. Just don’t look too hard at the implementation, because like I said M4 causes actual brain damage.
- darnir 3y agoThat's a very nice summary. But you're missing one crucial point. These are GNU tools and if you use them within that ecosystem, you also often use gnulib. Gnulib is effectively the GNU Portability Library. Your fancy, new, auto generated configure script can find all the differences, but someone still needs to account for them and write alternative code to support the various platforms. This is where gnulib comes into play. It reads all the configure checks and plugs in replacements / stubs for whatever is different. This allows you, the developer to simply target GNU/Linux in your code while gnulib handles everything else (and pretty automatically) making is portable across all the unices and even non UNIX systems.
- fanf2 3y agoYeah, there’s a lot of software that uses autoconf without gnulib. It’s common to include a load of default platform tests in the configure script that are used by gnulib, but without gnulib the software never uses the results of the tests. All these futile tests are an appalling waste of time and energy.