Issues with CMake


This document is known to be out-of-date. A number of problems cited below are reportedly fixed with more recent versions of CMake.

CMake has gotten a lot of buzz over the past few years in the open-source world, especially with its adoption by the KDE project, for their fourth major release. And because of the growing pains of using the old autotools (the autoconf, automake and libtool).

The autotools certainly have a steep learning curve. They are also a pain to debug, due to the intricate interdependencies between M4 macros, shell scripting, automake and make constructs. And of course, automake is horribly slow when dealing with a large numbers of targets, as is common with large projects. Yet, if you actually try CMake, you'll realize it is not all that great either.

In practice, CMake not only lacks a rich platform tests suite, compared to autoconf, it also lacks a lot of features from automake and libtool.

So why should you not switch an autotools-based project over to CMake?

Tedious
First and foremost, your configure.ac script may be large. Porting to CMake can be a time consuming and not so funnny task when it comes to the long tail.
iconv support missing
There are no standard tests for iconv(), neither for finding the compiler flags, nor whether it takes a const pointer.
pkg-config support broken
pkg-config support is reportedly broken as of cmake 2.4 patch 8.
Exported symbols list not implemented
There are no documented ways to specify the list of exported symbols for a shared libraries, so your libraries will unconditionnaly expose all their non-static APIs (libtool can use a flat list or a regular expression).
C99 compiler check missing
There is no built-in support to enable C99 support in the C compiler.
Objective-C flags not supported
You can add flags for the Objective-C compiler, but they propagate to C compilation as well.
Compiler feature checks missing
There are no built-in checks for any of the C99 features, such as variable-sized arrays, restricted pointers, macros with variable number of arguments, etc. nor for GCCisms.
Monolithic installation prefix
There is only one global installation prefix. So the typical Linux distro cannot set the global prefix to /usr while the system configuration (automake's sysconfdir) would be /etc. Very nice for "downstream" Linux packagers...
Installation paths hard-coding
As a consequence of the single prefix, you need to hard-code all paths from the prefix. Instead of ${docdir}, you need to hard-code ${prefix}/share/doc/${package} (${CMAKE_INSTALL_PREFIX}/share/doc/foobar in CMake parliance) and so on and so forth. BSD porters are going to have fun tweaking the paths manually...
Uninstallation not supported
There is sipport for uninstalling. That is a design choice. You'd better never ever try to install a package straight from the build tree, without a proper packaging system.
Installation testsuite not supported
Since there is no uninstallation, there is no of course no distcheck target either. How often did you get your source tarball right from the first attempt before a new release?
No cross-compilation
There is no documented support for cross-compilation. This is scheduled for a future release.
Limited documentation
Compared to autotools, the documentation feels a bit light. At least, there is a wiki, but that cannot replace a good offline reference.
Limited executable renaming
CMake is not quite as powerful as automake (with program-prefix, program-suffix and program-transform-name) when it comes to on-the-fly executable renaming. This little-known feature of automake can be extremely useful when building an operating system distribution with possibly conflicting executable names from different projects. For instance, it is very conveniant along with the Debian alternatives system.
No source tarball packaging
There is no built-in support for making a tarball (make dist). Some Version Control Systems can do it themselves (git does, Subversion does not). This is quite critical a feature for open-source projects.
No source tarball testing
As there is no replacement for make dist, there is no replacement for make distcheck either. From my not-so-humble experience, that is tremendously useful before doing a new release. (NOTE: when I write distcheck, I mean distcheck. I don't mean check which becomes test with CMake)
No gettext integration
Gettext is not supported. Targets for .po and .mo files must be added manually. Nevermind that this is the most widely used localization subsystem in the open-source community.
Awkward feature listing
Whereby ./configure --help gives the list of build option, cmake --help prints the CMake options only. Instead, it seems you have to run cmake in "interactive" mode and answer a question for each and every setting (much like Linux kernel make config).

Of course, many of these issues could be fixed if someone bothered to provide the necessary support to future main-line CMake releases. Then again, unless you want to be hacking CMake instead of your own project, I can only recommend you wait and suffer the autotools for a while longer. And should you decide to go for CMake anyway, please do ensure that you don't remove a feature which your "downstream" packagers or -do I need to mention it- fellow developers (if any) were relying upon.

To me, this is very reminiscent of the problems I had when I tried to use autopackage (disclaimer: things may have changed since then). Both projects are trying to address annoying short-comings of two different critical widely used pieces of the open-source development world: CMake aims at fixing the build process, the autotools, and provides better support for OSX and Windows in the process. Autopackage wans to fix the binary release and installation, which are usually devoted RPM and dpkg, hence distro-specific.

To succeed in replacing such critical, widely deployed and supported components, one must make a huge effort in making the migration as painless as possible, and preserving as many of the features as you can. Providing a cool well-thought framework is not sufficient, nor does being more performant. The long-tail set of features matters as much, if not more.