You know that I’m an “autotools lover” in the sense that i prefer having to deal with autotools-based buildsystem that most custom build-system that are as broken as they can possibly be. Or with cmake.
But I’m definitely not saying that autotools are perfect, far from it. I’m pretty sure that I said before that there are so many non-obvious tricks around that confuse most people and cause lots of confusion out there. The presence of these non-obvious tricks is due partly to the way autoconf tarted in the first place, partly into the fact that it has to generate standard
sh scripts for compatibility with older systems, and partly because upstream is not really helping the whole stack to maturate.
One of the most non-obvious, but yet common, macros out there is definitely the
AC_ARG_ENABLE (and its cousin
AC_ARG_WITH obviously), as I’ve blogged and documented before. The main issue with those macros is that most people expect them to be boolean (
--without) even though it’s quite freeform (
--enable-errors=critical). But also the sheer fact that the second parameters need to be returned by another different macro (
AS_HELP_STRING) is quite silly if you think of it. And, if you look at it, the (likely more recent)
AC_ARG_VAR macro does not require a further macro call for the help string.
It gets even wilder: a lot of the
AC_ARG_WITH calls are, further down, wrappers around calls to
pkg-config support macro). How is this worse? Well, you end up repeating the same code between different projects to produce, more or less, the same output. To at least reduce the incidence of this, Luca wrote a set of macros that wrap around and perform these common tasks. The result is that you have to provide a lot less details; you lose some flexibility of course, but it produces a much neater code in your
Now, as I said, autoconf upstream is partly responsible for this: while the new versions have been trying to reduce the possible misuse of macros, they are bound to a vast amount of compatibility. You don’t see the kind of changes that happened with the 2.1x → 2.5x version jump, nowadays. The result of this is that you cannot easily provide new macros, as they wouldn’t be compatible with older versions of autoconf, and that would be taken as mostly bad.
And the reason for that can be found in the reason why libvirt’s configure is still stuck with compatibility toward autoconf 2.59. While autotools are designed to not require their presence on either the host or build system (unlike CMake, imake, qmake, scons, …), developing for, and checking compatibility with, older systems require to have the tools at hand to rebuild
configure and company. I solve this myself by just using NFS to pass the code around the various (real and virtual) machines, after regenerating it on my Gentoo box, but I admit it’s definitely not sleek enough. In this case, libvirt is also developed against RHEL-5, and in that system the only autoconf available is 2.59.
One problem to solve this kind of problem would be to have a single, main repository of macros, that everybody could use to perform the same task. Of course this would also mean standardising on some sort of interface for macros, and for the build systems themselves, and this is easier said than done. While we’re definitely not to the point Ruby is we still aren’t really that standard. Many packages handled by more or less the same people tend to re-use the same code over and over, but that only builds a multiple amount of similar, but still half-custom build systems.
There are only two, as far as I know, efforts that ever tried extending autoconf in a “massive” way: KDE (and the results are, well, let’s just say that I can’t blame for trying to forget about KDE3’s build system), and GNOME. The latter is still alive, although it isn’t concerned with giving more generic macro interfaces to common tasks.
There is the autoconf macro archive but there is one catch with it: some of the macros submitted there have GPL or GPL-affine licenses (as long as they are compatible); that means that you might not be able to use them in MIT-licensed systems. While it even says that FSF does suggest using more open licenses for macro files, it does not require the submissions to be. Which can get quite messy on the long term, I’m afraid, for those projects.
At any rate, this post should show that I don’t really think that autotools are error-safe, but at the same time, I don’t think that creating a totally new language to express these things (like CMake does) is the solution. If only Rake was parallel-capable (which is unlikely to happen as long as Ruby cannot seriously multithread), then it would probably be, in my opinion, a better replacement for autotools than what we have now. That is, if the presence of Ruby is not a problem.
I used to hate autotools, not because I liked something else better, but because I didn’t understand why it was all necessary and why simple Makefiles were insufficient. I largely have you to thank for opening my eyes to the issues and finally taking the time to understand it properly. You’re right that it isn’t perfect, especially with respect to the default actions doing bad things like AC_CHECK_LIB adding to the global LIBS variable. You made me aware of these issues too. So thanks. 🙂
> developing for, and checking compatibility with, older systems require to have the tools at hand to rebuild configure and company. I solve this myself by just using NFSAnd this is what in my opinion a lot of people simply get wrong. Version control is to be used for any files that are not easy to recreate.As you here admit, autotools configure is _not_ easy to recreate, thus the generated configure belongs in your version control! Please everyone using autotools, do your users a favour and check in the configure (unless you really intend to check it works flawlessly on all significant systems and auto* versions generally in use).
Reimar, I don’t even trust the configure script that I’m given by upstream in tarballs most of the time.The @configure@ script is so obfuscated that it’s definitely easy to sneak in unwarranted code paths in it.
Reimar: configure is easy to recreate. Putting ./configure into a VCS just asks for bad, uninformative, and sometimes extraneous diffs when configure.ac is edited or the person checking out your projects decides to run autoreconf instead of automake (which should be automatically handled by the Makefiles…).configure is a generated file. Such files don’t belong in VCSes IMO.I think that autoconf-archive is a good and valid attempt at attempting to provide common and useful macros for all programs to use. However, certain macros are broken (e.g., the boost-related ones don’t work with gentoo’s boost installation).However, one problem I feel I’m seeing is lack of support from the libraries for which these macros are being written. Projects that provide libraries need, nowadays, to do something as simple as providing a pkgconfig compatible metadata file. This reduces the overal complexity of the configure.ac of a project using that lib and is buildsystem-indifferent.