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!

Build Performance Insights

From time to time, people ask me whether it is possible to gain insight into the build performance of a C++ project. Using a tool like Ninja to efficiently build in parallel is usually an easy first step. The next focus is usually how to improve the efficiency of the parallel build. Developers are usually interested in which files are taking longer than expected to compile or link. Such files may be good candidates for reducing build time through refactoring or reducing header includes. Custom tasks might also be taking longer than expected, but this can be hard to spot in the build output in highly parallel builds. There are tools which can make this task much less daunting. This article briefly introduces some techniques and tools which can provide considerable insight with fairly minimal effort.

Estimated reading time: 4 minutes

Read more

Quoting In CMake

Let’s be honest, CMake’s syntax is not one of its most popular characteristics. This article isn’t going to try to convince you otherwise. Rather, it focuses on how quoting in CMake works. Its goal is to help you avoid common problems and write clearer, more robust CMake code. You’ll find no long-winded history lessons here, just the essential info you need.

Estimated reading time: 10 minutes

Read more

CppCon 2019: Deep CMake For Library Authors

This talk presents a road map for C++ library authors grappling with cross-platform aspects of library development and deployment. It highlights key CMake features that every cross-platform library project should be using and digs deeper into the platform-specific quirks and conventions behind them. The material presented will give library authors more robust control over their API, smoother integration with major platforms and packaging systems, and more convenient inclusion by other projects.

The presentation will firstly examine how symbol visibility, library versioning and API evolution can be handled coherently across all major platforms and compilers. CMake provides dedicated features for these that are easy to use, but with the deeper understanding provided by this talk, library authors will be able to make these areas work together more seamlessly and avoid future maintenance and compatibility issues.

We will then explore how platform and vendor differences affect the installed directory layout for projects with libraries. CMake features for transparently handling the different conventions and policies will be presented, including recent CMake improvements which simplify this task. The importance of RPATH/RUNPATH functionality for improved runtime robustness and ease of use will also be explained, along with some associated support CMake provides.

Along the way, the talk will mention a number of specific things that CMake library projects should do or avoid to make themselves easy for other projects to consume. This will include versioning support for CMake config package files, guidance on defining install components and accounting for the different ways that projects may incorporate yours into their build.

Read more

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 more

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 more

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 more

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 more

Avoiding Copies And Moves With auto

When C++11 introduced auto, it opened up a whole range of useful techniques and improved the life of C++ developers in a variety of ways. There’s no shortage of simple examples and tutorials teaching how to start using auto, but as is often the case, many of these well intentioned examples have left readers with an incomplete picture of how to use auto effectively and in some cases have resulted in poor habits becoming common practice. Since auto essentially hides away some of the details of how objects are created, there is a risk that developers don’t think as carefully about what is actually taking place. This article aims to arm the reader with information often omitted so that common pitfalls can be avoided.

Read more

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 more