Professional CMake:

A Practical Guide

Learn to use CMake effectively with practical advice from a CMake co-maintainer. You can also have the author work directly with your team!

 

CMake And C++ Consulting Services Now Available

Following the successful launch of my book Professional CMake: A Practical Guide last year and receiving positive feedback from readers, I’m pleased to announce that I’ve formed my own consulting company, Crascit Pty Ltd. An overview of the sort of consulting services I will be providing are available on the services page. The general intention though is to make myself available to clients to help them address their CMake, C++ and build/release challenges.

Read moreCMake And C++ Consulting Services Now Available

CMake Now Available As A Snap

Last week’s Snapcraft Summit in Montreal was a fantastic opportunity to work directly with staff from Canonical and Travis CI, experienced Snapcraft users and key people from other projects, all with the goal of getting more languages and build tools supported in the snap ecosystem. It was a privilege to attend and I’m pleased to announce that as a result of that summit, CMake can now be installed as a snap on all major Linux distributions.

Read moreCMake Now Available As A Snap

Forwarding Command Arguments In CMake

The previous article discussed an example from Dan Pfeifer’s popular Effective CMake talk. That article highlighted the dangers of trying to override a function and forward the call to the original implementation. We now look at a related but more subtle problem associated specifically with forwarding command arguments. The same example from the previous article will serve as our starting point:

macro(find_package)
  if(NOT "${ARG0}" IN_LIST as_subproject)
    _find_package(${ARGV})
  endif()
endmacro()

Read moreForwarding Command Arguments In CMake

Generated Sources In CMake Builds

Using a set of source files to build libraries and executables is about the most basic thing a build system needs to do. This is relatively easy with CMake, but things get more interesting when some of the source files need to be generated as part of the build. CMake provides a range of functionality which can be used to create files, but getting build dependencies correct is an area where many developers struggle or even simply give up. It doesn’t have to be that way!

Read moreGenerated Sources In CMake Builds

Test Fixtures With CMake/CTest

New test properties were added in CMake 3.7.0 to support test fixtures. Put simply, a fixture allows setup and cleanup tasks to be associated with a group of tests. On their own, fixtures are quite useful, but they also integrate well with the existing RESOURCE_LOCK and DEPENDS test properties to support some interesting use cases. This article explains the new fixture features and provides examples showing how they complement the existing resource and dependency functionality.

Read moreTest Fixtures With CMake/CTest

Using ccache with CMake

Updated 1st February 2017

Working with very large C/C++ code bases will sometimes test your patience. Build times in particular can be a sore point, especially if the development team do not have a great understanding of how to minimise dependencies between source files, headers, etc. The problem gets worse if the developer frequently switches between branches of their source control system, resulting in source files often changing their contents and/or timestamps. The ccache tool aims to minimise that pain by caching compilation outputs (i.e. object files) and reusing them instead of compiling the source again if it gets a compilation request it has seen before and cached. It supports GCC or any compiler that looks like GCC (eg clang). When rebuilding a large project that ccache has mostly compiled before already, the time saving can be significant, even sometimes reducing many minutes down to seconds.

Getting ccache to work with CMake is not overly complicated, but the way to do it is not always obvious. This is especially true with Xcode builds. This article demonstrates how to set up a CMake project to use ccache with Unix Makefiles, Ninja or Xcode generators, with Xcode receiving special attention. The techniques presented do not require any changes to the host system. Specifically, no symlinks need to be set up for ccache, making it suitable for use in CI systems, etc. where the developer may not be in control of how/where ccache is installed.

Read moreUsing ccache with CMake

Scripting CMake builds

Sometimes you just want a single way to build a software project, regardless of what platform or build tool you are using. The promise of CMake is that this should be possible, but in practice, it sometimes doesn’t always seem that way. One particular area where this becomes apparent is scripted builds, especially for things like continuous integration systems, automated testing processes, etc. Since each platform typically has its own commonly used build tool and developers tend to be more familiar with that tool than with CMake, the tendency is to invoke that tool directly in scripts. Unfortunately, this means such scripts end up handling each platform’s build tool separately. But it doesn’t have to be that way. This article will address this and a few other smaller details associated with setting up a platform independent scripted CMake build.

Read moreScripting CMake builds

Enhanced source file handling with target_sources()

Updated December 2018: Parts of this article have been reworked to account for improvements made with the CMake 3.13.0 release. Key updates are noted within the article.

In all but trivial CMake projects, it is common to find targets built from a large number of source files. These files may be distributed across various subdirectories, which may themselves be nested multiple levels deep. In such projects, traditional approaches usually either list all source files at the top-most level or build up the list of source files in a variable and pass that to add_library(), add_executable(), etc. With CMake 3.1, a new command target_sources() was introduced which provides the missing piece among the various target_... commands. While the CMake documentation succintly describes what target_sources() does, it fails to highlight just how useful the new command is and why it promotes better CMake projects:

  • It can lead to cleaner and more concise CMakeLists.txt project files.
  • Dependency information can be specified closer to where the actual dependencies exist in the directory hierarchy.
  • Source files gain the ability to become part of a target’s interface.
  • Source files can be added to third party project targets without having to modify the third party project files.

Read moreEnhanced source file handling with target_sources()