First, caveat: this is for C++.<p>I wrote a major part of a complex build system in autoconf[1,2]. I gotta say, just about ANYTHING would be better. There's no abstraction; at no point can you forget you're writing m4sugar (implemented on top of m4) that is writing bourne shell code. There's no indication if you screw up in subtle ways except an sh parse error when you run configure. I've had to run configure with sh -x more times than I can count. EVERY SINGLE autoconf release changes the interface, and there's no reasonable way to detect the autoconf version to work around it. Every autoconf release requires hours of tinkering. Autoconf 2.65 changed the quoting rules for m4_upper and m4_lower; making those work reliably on old and new versions is obnoxious.<p>I've spent many, many hours working on autoconf code. I consider myself an expert at it. And yet, I'm willing to throw it all away and replace it with ANY build system that isn't a pile of junk. I just haven't found one yet :(<p>The only ones that rise above the noise are scons, waf, and cmake. (No, I'm not using jam/bjam or ant. DIAF.) CMake does most of what I want, except they invented a completely idiotic new programming language. Waf and CMake both provide me with a system to make a build system instead of a build system itself (screw that). SCons reinvents make... poorly and slowly. Of these, only cmake handles windows without forcing me to sit in front of a windows machine for hours. (Autoconf, obviously, falls over hardcore on windows unless you set up a Unixy build environment on it. Not The Point.)<p>Anyway, that was a cathartic rant. (No, but seriously. I'm up for more suggestions, or you can try to convince me that my opinions of the above tools are wrong. I really do want to switch away, I just haven't found anything that's a big enough improvement to justify it.)<p>1) <a href="http://github.com/visionworkbench/visionworkbench/tree/master/m4/" rel="nofollow">http://github.com/visionworkbench/visionworkbench/tree/maste...</a><p>2) <a href="http://github.com/visionworkbench/visionworkbench/blob/master/configure.ac" rel="nofollow">http://github.com/visionworkbench/visionworkbench/blob/maste...</a>
Unfortunately most of his "rant" is justified.<p>Autotools are exceptionally bad for several reasons:<p>- They are difficult and not at all intuitive to learn and use. As another poster noted, there are no abstractions whatsoever, so what's stopping me from just writing a shell script that will check for the location of libparadise v3.1.6? This may be a subjective issue, so please check out gtkpod's CMakeLists.txt and configure.in and tell me with a straight face that you'd pick autotools.<p>- They are well-documented and easily extendable...Oops, no they're not!<p>- They aren't backward or forward compatible, and almost every other major version has serious regressions. This is a big whoop if you claim to want to produce portable software.<p>- Configuration is scattered around the build tree instead of one file. Seriously, I don't need this. I have enough of an issue with my current project's 400+ modules, thank you very much.<p>- Slow. They're beautified shell scripts, after all. But also, they check for unneeded dependencies and antiquated features (checking for an ANSI-C conforming const...OK).<p>- And last but not least, its "<i>caching</i>" is the most braindead half-implemented feature I've ever encountered since 1984. It's literally cost me hours to discover problems caused by caching the config files.<p>On the other hand, there aren't any better alternatives, so I'll just go cry for a bit.
It's hard to criticize their design decisions at the time. For instance, "m4" and "sh" were likely chosen because they <i>exist</i> on all systems, and "perl" and "python" were not yet ubiquitous.<p>I have never seen "configure" work particularly badly, and I've had to build some pretty hairy, dependency-ridden crap on Linux, Solaris and Mac OS X. It has held up remarkably well, and many projects are good about providing useful "configure" options. <i>Usually</i> fixing something requires an environment variable or configure option, and not a makefile hack.<p>There is no question the generated code is practically indecipherable. But you have to treat it like a compiler; no one goes leafing through the ".o" that GCC generates on a regular basis, so why worry about what "autoconf" and "automake" produce? Like any widely-used tool (such as a compiler), you can put a fair amount of trust in the maintainers to not make anything too broken; and if you see a problem, you can file a bug report.<p>It is also somewhat reassuring that even if the generated result is wrong, it is at least theoretically possible to fix it; just try fixing something that goes wrong in Visual Studio.<p>I will allow that "m4" is showing its age, and these days it's a heck of a lot easier to Google some examples and adapt them, than it is to figure out how to add a custom rule from scratch. The big challenge for the GNU Build System is to create a modern version that makes new assumptions (e.g. "perl" always exists), and update their methods accordingly.
Since some here are suggesting to just use `uname -s` as an autoconf
replacement. I thought I'd provide some data for that. The Git project
is a very good showcase, because it can do both.<p>Git can optionally use autoconf. To do this you can run make configure
&& ./configure which'll use this configure.ac file to generate the
configure script: <a href="http://github.com/git/git/blob/pu/configure.ac#L1" rel="nofollow">http://github.com/git/git/blob/pu/configure.ac#L1</a><p>Autoconf will then write out a config.mak file, which is generated
from this template: <a href="http://github.com/git/git/blob/pu/config.mak.in#L1" rel="nofollow">http://github.com/git/git/blob/pu/config.mak.in#L1</a><p>That's where autoconf's involvement ends. All it's doing is turning
simple macros like this:<p><pre><code> # Define NO_GETTEXT if you don't have libintl.h
AC_CHECK_HEADER([libintl.h],
[NO_GETTEXT=],
[NO_GETTEXT=YesPlease])
AC_SUBST(NO_GETTEXT)
</code></pre>
Into this:<p><pre><code> NO_GETTEXT=
</code></pre>
Or, if libintl.h doesn't exist:<p><pre><code> NO_GETTEXT=YesPlease
</code></pre>
Which you would otherwise need to specify manually as arguments to the
Makefile when building the program:
<a href="http://github.com/git/git/blob/pu/Makefile#L37" rel="nofollow">http://github.com/git/git/blob/pu/Makefile#L37</a>, after checking if you
have libintl.h on your system or not.<p>Autoconf can certainly get hairy, but in most cases using it is a lot
easier than not doing it. Consider this definition:<p><pre><code> AC_CHECK_LIB([curl], [curl_global_init],
[NO_CURL=],
[NO_CURL=YesPlease])
</code></pre>
That's doing a lot of work checking if there's a libcurl on your
system, and making sure it has a curl_global_init function.<p>Also note that the autotools are more than just autoconf. You <i>can</i>
stop here, but you can also generate your makefiles with automake, and
create your libraries with libtool.
Clearly autoconf isn't so unremittingly horrible that he doesn't use it in Varnish :)<p>autoconf is a bit of a Faustian bargain though - it promises a quick and easy solution to the labour-intensive and mindlessly boring task of managing all the microscopic differences between (and within!) Unix variants. Unfortunately it brings its own complexity, fragility and bugs along with it. It also encourages a programming style best described as "#ifdef hell" which is just poison to good maintainability.
I had real trouble using autoconf back when the documentation wasn't very good (it may have become more newbie friendly but I'm not sure). In the end I wrote my own configure script in bourne shell. The shell script suited my needs fine and was much faster.<p>The selling point of the autoconf tools is that writing your own shell script is tedious and error prone. This was not my experience.
Back in '02 I wrote a C program called "clump" that compiles and links C code, detecting dependencies automatically by scanning for "includes".<p><a href="http://github.com/chkoreff/Clump/blob/master/src/README" rel="nofollow">http://github.com/chkoreff/Clump/blob/master/src/README</a><p>People have been downloading it consistently ever since, and I know some of them like it a lot.<p>So with this program you just cd into your code directory, type "clump", and it builds your executable program in ../bin.<p>One current limitation: it expects all the .h and .c files to be in a single directory. I could enhance it to walk through a directory structure, but I haven't gotten around to it. Yeah I know, even after 8 years. :)
Hmm.. autotools work and they actually work quite well.<p>Besides - most the replacements that have been written eventually end up even more complicated than autotools..
I'm thinking of switching to waf (<a href="http://code.google.com/p/waf/" rel="nofollow">http://code.google.com/p/waf/</a>) for future projects. Node.js and a few other projects use it currently. Does anyone have any good/bad reviews? It seems to be a fork of SCons but stripped to the bare minimum.
Is it just me who read the last line and thought of this?<p><a href="http://www.thinkgeek.com/tshirts-apparel/unisex/frustrations/374d/" rel="nofollow">http://www.thinkgeek.com/tshirts-apparel/unisex/frustrations...</a>
He doesn't mention automake or libtool; he must be saving them for a separate rant :P<p>Much of what he says is fair. Many decisions made way back when would be different now. But the autotools are well-documented, well-maintained, and they do work.<p>The way forward (for the autotool-friendly audience anyway) is likely something like Tromey's quagmire -- <a href="http://code.google.com/p/quagmire/" rel="nofollow">http://code.google.com/p/quagmire/</a>.
I don't think a single person here has mentioned cross-compiling. As someone who maintains a cross-compiled distribution of Unix (for the iPhone), when someone writes software that involves anything remotely complex (maybe shared libraries), if you aren't using autoconf and libtool you are a cruel sadistic bastard (and if you think uname is /ever/ appropriate to use in a build environment, you are simply naive).
I've come to a conclusion: good build tools simply don't exist. Most of the time, build tools are good when run under the intended use-case, but if you stray from that, everything comes crumbling down.
What technology are you folks using that forces you to look at (and actually <i>edit</i>) a configuration file just to build your project? Are there actually still well-used languages that don't have a development environment that takes care of this for you? (serious question).<p>Granted, we have an automated build system that requires hand tweaking from time to time, but that's something we introduced ourselves. If I wanted I could still hit shift-ctrl-b on any box and have a working version of the project. (And in all the flavor-of-the-month web techs it's usually just a matter of pointing a browser at the source.)
I remember the first time I installed the ODE dynamics library on a Windows machine. "What do you mean, I need GNU Make?" Then the configurator ran, or rather tried to, and my jaw just hung open for the rest of the afternoon.<p>At that point I understood why Microsoft still has a positive balance sheet.