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!

Professional CMake: A Practical Guide 16th Edition

Release Date: 25th October 2023

This is part of the change history for the book Professional CMake: A Practical Guide. The 16th Edition has been updated for the CMake 3.27 release. The main highlights for this edition include three new chapters:

  • Basic Testing And Deployment
  • Static Code Analysis
  • Dynamic Code Analysis

This edition also includes some structural improvements aimed at making things easier to find and more coherently grouped. Some of the larger chapters have been split up into smaller, more focused chapters that are easier to digest. The first part of the book (five chapters) is also now being made available as a free Getting Started guide.

Full details of the changes are given below.

Part And Chapter Reorganization:

A major focus for this release was to provide a Getting Started set of chapters at the beginning of the book, and to make those chapters freely available as a separate download. For any developer who has never used CMake before, this should provide the basics of using CMake, all the way up to producing simple packages. The first four chapters previously did this up to building simple targets, and a new chapter has been added in this edition to provide an introduction to testing, installing, and packaging.

A second major change with this edition was to split up the Testing chapter into a five separate chapters, group them under a new Testing And Analysis part, and add two completely new chapters on static and dynamic code analysis. Splitting up the existing chapter into smaller, more focused chapters makes each one less daunting, and the reader can more easily find and focus on just the aspect they are interested in learning about. The two new code analysis chapters are also a significant addition to the book, covering tools like clang-tidy, cppcheck, cpplint, include-what-you-use, sanitizers and code coverage.

As the book has grown with each edition, it has become quite large. The reader is now unlikely to want to work through the entire book in order, chapter-by-chapter. To help give clearer direction in guiding the reader, the BuildTypes and Compiler And Linker Essentials chapters have been moved to the Fundamentals part. All parts after that can now be seen as pick-and-choose chapters rather than “continue reading these in order”. It is anticipated that this will be further refined in subsequent editions to help make the book less daunting, but still be a rich resource for learning CMake.


  • Updated with a paragraph about consulting activities since the book was first published, and how they drive updates of the book and contributions to CMake itself.


  • Expanded and reformatted the list of individuals who have contributed to the book through reviews, corrections, and feedback. Please get in touch if you believe any names have been left out.

A Minimal Project chapter:

  • Updated the Commenting section to also discuss block comments (#[==[ ... ]==]).

Building Simple Targets chapter:

  • The discussion and code examples in the Recommended Practices section have been updated to more clearly highlight appropriate and inappropriate ways to specify project and target names.

Basic Testing And Deployment chapter:

  • This is an entirely new chapter. Its purpose is to give a basic introduction to testing, installing, and packaging so that the reader can start experimenting with these much earlier in their learning path. It is also included as part of the new Getting Started guide, which is freely available as its own separate download.

Generator Expressions chapter:

  • Added a note that $<PATH:subcommand,...> expressions accept a list of paths with CMake 3.27 or later.
  • Added a new List Expressions section covering the $<LIST:...> expressions added in CMake 3.27.

Debugging And Diagnostics chapter:

  • A new Interactive Debugging section was added to briefly discuss the new support added in CMake 3.27 for the Debug Adapter Protocol. This is mostly for awareness of the feature, not to explain how to use it, since its use is primarily implemented by IDEs.

Build Type chapter:

  • Moved to the Fundamentals part of the book, since the build type is something every developer needs to know about and understand.
  • The Custom Build Types section previously contained examples and advice showing the Profile custom build type’s flags being set in CMake cache variables. That doesn’t work in all cases because the cache variables may already be defined by the time the project was trying to set them. The advice has been updated to use regular non-cache variables instead, with the discussion also mentioning the potential drawbacks of this for developers.

Compiler And Linker Essentials chapter:

  • Moved to the Fundamentals part of the book, since almost every project will use some of the commands, properties and variables discussed in this chapter.
  • A new Target Property Contexts section has been added to provide an expanded discussion of how generator expressions like $<BUILD_INTERFACE:...> and $<INSTALL_INTERFACE:...> affect the way properties are set and used. The expressions $<BUILD_LOCAL_INTERFACE:...> (added in CMake 3.26) and $<COMPILE_ONLY:...> (added in CMake 3.27) are now also discussed, with examples.

Language Requirements chapter:

  • This is now the first chapter in the Builds In Depth part of the book. It was moved one chapter earlier before the Advanced Linking chapter, since it is likely to be more relevant to a wider cross-section of readers. It is also a more logical next step after the Compiler And Linker Essentials chapter.

Target Types chapter:

  • Updated the first main example in the Interface Libraries section to use a $<BUILD_INTERFACE:...> generator expression around the path specified in the call to target_include_directories().

Custom Tasks chapter:

  • Updated the opening paragraph of the Commands That Generate Files section with clearer wording and an example scenario where the OUTPUT form of add_custom_command() is useful.
  • Updated the discussion of relative path handling for the output files in add_custom_command(OUTPUT). The text now advises always using absolute paths for these instead.
  • CMake 3.27 added support for a new DEPENDS_EXPLICIT_ONLY keyword for add_custom_command(OUTPUT). This is discussed briefly in this chapter, with a cross-reference to a more detailed discussion in the Build Performance chapter.

Specifying Version Details chapter:

  • One example was updated to wrap a target_include_directories() path in a $<BUILD_INTERFACE:...> generator expression.

Libraries chapter:

  • A paragraph was added to the Linking Static Libraries section to mention where $<LINK_ONLY:...> may be used by CMake when exporting targets.
  • CMake 3.27 added support for a new DLL_NAME_WITH_SOVERSION target property. The Shared Library Versioning section was updated to cover this, with an example.
  • Paths in target_include_directories() calls have been wrapped in $<BUILD_INTERFACE:...> expressions in the chapter’s examples.

Build Performance chapter:

  • This chapter was moved earlier to the end of the Builds In Depth part of the book. It is squarely focused on build details, so it more logically belongs there rather than near the end of the book.
  • The Optimizing Build Dependencies section was expanded to cover the new DEPENDS_EXPLICIT_ONLY option for add_custom_command(). A paragraph was also inserted at the beginning of that section to make clear it focuses on reducing conservatism in the dependencies.

Testing Fundamentals chapter:

  • This chapter is a reduced version of the Testing chapter of the previous edition. It is more focused on everyday testing needs, with more specialized topics moved out to their own dedicated chapters. It is much shorter and less daunting for the reader as a result.
  • CMake 3.27 added TIMEOUT_SIGNAL_NAME and TIMEOUT_SIGNAL_GRACE_PERIOD test properties. This chapter explains their use, including an example scenario showing how they can help with investigating flaky tests in continuous integration jobs.

Test Resources And Constraints chapter:

  • This new chapter is essentially existing material split out to its own dedicated chapter.

Build And Test Mode chapter:

  • This new chapter is also mostly existing material split out to its own dedicated chapter. The main change is the addition of a new Alternatives section which highlights how CDash scripts or workflow presets may be better alternatives, especially the latter.

Test Frameworks chapter:

  • The existing material for GoogleTest was split out to this chapter.
  • New Catch2 and doctest sections were added, showing how they follow similar setup and usage to GoogleTest (for the CMake-related aspects).

CDash Integration chapter:

  • This new chapter is essentially existing material split out to its own dedicated chapter.

Static Code Analysis chapter:

  • This new chapter contains entirely new material. It covers CMake’s support for the clang-tidy, cppcheck, cpplint, and include-what-you-use code analysis tools, along with a broader discussion of some tools’ usage. This chapter and the next are the most significant updates for this new edition.

Dynamic Code Analysis chapter:

  • This new chapter also contains entirely new material. It goes into a fair amount of detail about how to set up sanitizers and code coverage. Along with the previous chapter, this is one of the most significant updates in this new edition. A full sanitizers example is included as an appendix.

Finding Things chapter:

  • A paragraph was added to the Finding Packages section for the new <PACKAGENAME>_ROOT environment and CMake variables (uppercase versions). Support for these was added in CMake 3.27.

Installing chapter:

  • Some of the material from the Interface Properties sub-section and the Installing Exports section was moved to the new Target Property Contexts section of the Compiler And Linker Essentials chapter. The material that was left behind from the Interface Properties sub-section was absorbed into its parent Installing Project Targets section, and its examples were updated for improved consistency and continuity.

Packaging chapter:

  • The sections covering each individual package generator were moved out to their own dedicated chapter. The remaining sections now focus on packaging concepts and techniques, leaving the generator-specific aspects to that new separate chapter.
  • The discussion of the CPACK_PACKAGE_VERSION_... variables was reworded. It now highlights that CPACK_PACKAGE_VERSION is not accessible in the project’s CMakeLists.txt file.
  • The Components section has been updated and given more structure with sub-sections. It now includes a sub-section on downloadable components. Previously the downloadable component support was only discussed as part of the IFW generator. This edition corrects a long-standing error where past editions previously claimed IFW was the only generator that supported this, but NSIS and the new Inno Setup generators also support downloadable components.

Package Generators chapter:

  • This new chapter contains all the sub-sections previously found in the Package Generators section of the Packaging chapter.
  • A new section was added covering the new Inno Setup CPack generator, which was added in CMake 3.27.
  • Most of the discussion of downloadable components in the IFW generator section was moved to a sub-section of the Components section in the Packaging chapter.
  • The NSIS section was updated to mention that it supports downloadable components.

ExternalProject chapter:

  • Corrected an error in the second example of the Configuration Step section. The PDF version of the book incorrectly used CMAKE_ARGS instead of CMAKE_CACHE_ARGS in previous editions.

Presets chapter:

  • Updated the table in the High Level Structure section to account for the new version 7 presets schema added in CMake 3.27.
  • Added a note to the Test Presets section that they are useful for setting run-time options for sanitizers and code coverage. The section’s example was updated to demonstrate this.

Project Structure chapter:

  • The book’s chapters were split up into a few more parts, and one of those new parts is named Project Organization. This chapter was renamed to avoid confusion with that part name, but its content is mostly the same as the previous edition.
  • The Windows-specific Issues section was updated to mention the new CMAKE_VS_DEBUGGER_... variables added in CMake 3.27.

Working With Qt chapter:

  • The Moc sub-section was updated to discuss the new INTERFACE_AUTOMOC_MACRO_NAMES target property, including a motivating example. This property was added in CMake 3.27.
  • Updated the statement that qt_add_translations() is still in tech preview as of Qt 6.6.


  • A new appendix was added with a complete, working sanitizers example.