Build Systems

While interpreted languages such as Python have been steadily gaining popularity, compiled languages such as C and Fortran are still prevalent and many new software projects even choose to mix compiled and interpreted languages. Compiled software generally requires a build system to manage internal and external dependencies and to automate most of the tedious process of generating libraries and executables. The popular standards for build systems have shifted over the years, from Makefiles, to GNU Autotools, and in recent years to CMake. While there are modern competitors such as Meson, we recommend the use of CMake for all build systems, as new users and developers are more likely to be familiar with it and more likely to have it already installed on their computers. CMake is a flexible build system that makes it straightforward to implement simple build systems for new projects that can be arbitrarily extended to handle growing project complexity and more diverse needs. CMake is also actively supported and responsive to emerging software and hardware trends in computing.

There is an abundance of online information, documentation, and examples regarding CMake. Its developers provide a tutorial that is good for guiding unfamiliar developers through the implementation of a simple CMake build system, and the main documentation is versioned and clearly delineates the version requirements of specific features.

An important consideration in using CMake is what minimum version to require, which is a decision that every project needs to make for itself, although it can certainly be changed with time. Using older CMake versions makes it more likely that users will already have a compatible version of CMake installed on their computers, but it will also prevent the use of newer features. Our recommendation is to use the minimum version of CMake that contains all of the features that are actively being used by a project and increase the minimum version requirement as more recent features become necessary. We do however recommend starting with CMake 3.x rather than CMake 2.x, and using a target-based build system.

The main use cases of CMake are (1) developers building a project, (2) users building a project, (3) automated builds for continuous integration, and less commonly (4) automated builds as part of building a dependent project and (5) packaging a project for distribution. Ideally, a project should compile and build without any custom arguments to CMake in a properly set up software environment, and any necessary, non-standard arguments should be clearly articulated in a project’s documentation. These different use cases can each introduce complications into a build system, and it is important to keep track of and document which features are serving which use cases.