The long-awaited build systems post (part 1, maybe)

I call this “long-awaited” because I promised Donnie to write about this a few months ago, but I haven’t had time to work on it in quite a while. Since today it should be an holiday, yet I’m still working on a few things, I’m going to try filling the hole.

I have been criticising CMake quite a bit on my blog, and I have been trying with all my strength to show that autotools aren’t as bad as they are made appear since I think that is still the best build system framework we have available at the moment. But in all this, I’m afraid the wrong message was sent somehow, so I want to clear it up a bit.

First of all, CMake isn’t as bad as, say, scons or imake; it’s also not as bad as qmake under certain circumstances. I don’t think that CMake is bad in absolute; I just think it’s bad as an “universal” solution. Which I have to admit autotools are bad for too, to an extent. So let me explain what my problem is.

For Free Software for a long time the autotools framework was the almost de-facto standard for lots of packages; switching away from that to CMake just because “it’s cool” or it seems easier (it does seem easier, mostly because the autotools documentation and examples are full of particularly bad code), it’s not the right thing to do since it increases the work for packages, especially because for some things CMake isn’t yet particularly polished.

I blame KDE for the CMake tide not much because I don’t think it was the right choice for them, but rather because they seem to pinpoint the reasons to the change to autotools defects when they are, actually, making a pragmatic choice for a completely different reason: supporting Microsoft Visual C++ compiler. As I have already expressed more than a couple of time, the autotools-based buildsystem in KDE 3 is a real mess, a bastardised version of autotools. Blaming autotools in general for that mess is uncalled for.

It’s also not only about Windows support; you can build software under Windows with just autotools, if you use cygwin or msys with GCC, what you cannot do is building with Microsoft’s compiler. Since GCC objectively still lacks some features needed or highly desired under Windows, I can understand that some projects do need Microsoft’s compiler to work. I’m not sure how true that is for KDE, but that’s their choice to desire Microsoft’s compiler. And CMake allows them to do that. More power to them.

But in general, I’m very happy if a project whose build system is custom-made, or based on scons or imake, gets ported to CMake, even if not autotools, since that would mean having a somewhat standard build system, which is still better than the other options. And I’m totally fine if a project like libarchive gets dual build system to build on Unix and Windows with the “best” build system framework available on those systems.

Still, I think CMake has a few weak spots that should be taken care of sooner rather than later, and which are shared with autotools (which is what I usually point out when people say that it’s always and only better than autotools; while it’s actually making similar mistakes).

The first is the fact that they seem to have moved (or people claim they moved) from an actual build system solution to a “framework to build build systems” which is more or less what autoconf basically can be said to be and what scons always have been. This is particularly bad because it ensures that there is no standard way to build a package without actually having to check the definition files for that particular release: scons provides no standard options for flags handling, feature switching and similar; autotools can be messed up since different packages will use the same variable names for different meanings. If CMake were to provide just a framework, it’s have the same exact problem. I think somewhat this was supposed to be limited, from what I read when I tried to learn CMake, but the results now don’t seem to be as good.

The second problem is slightly tied to the one above, and relates to the “macro hell”. One of the worse issues with autoconf is that beside the set of macros provided with autotools itself, there are basically no standard macros. Sure there is the Autoconf Macro archive but even I fail at using it (had some problems before with the license handling, should probably try to use it again), and the result is that you end up copying forking and modifying the same macros over a series of projects. Some of the macros I wrote for xine are now used in lscube and also in PulseAudio .

CMake provides a set of modules to identify the presence of various libraries and other software packages; but instead of using it as an official repository for these macros, I’ve been told that they are “just examples” of how to write them. And some of them are very bad examples. I already ranted about the way the FindRuby module was broken and the issue was ignored until a KDE developer didn’t submit his version. Unfortunately there are still modules that are just as broken. The CMake developers should really look into avoiding the “macro hell” problem of autotools by integrating the idea of a macro archive with CMake itself, maybe having an official “CMake modules” package to install to the side to provide the package search macros, which can be updated independently from the actual CMake package.

I have lots of reserves about CMake, but I still think it’s a better alternative than many others. I also have quite a few problems with autotools, and I know they are far from perfect. Both build systems have their area of usefulness, I don’t think either can be an absolute replacement for the other, and that is probably my only problem with all this fuzz over CMake. Also, I do have an idea of what kind of buildsystem framework could hopefully replace both of them, and many other, but I still haven’t found anything that comes near it; I’ll leave that description for part two of this post, if I can find time.