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 10th Edition

Release Date: 2nd August 2021

This is part of the change history for the book Professional CMake: A Practical Guide. The 10th Edition has been updated for the CMake 3.21 release. The more substantial changes for this edition include new sections on installing runtime dependencies and new output control capabilities for ctest (e.g. JUnit, per-test measurements and attachments). As usual, a range of smaller updates and clarifications have also been made. The main changes in this edition are listed below.

NOTE: As foreshadowed in the previous release, the MOBI format is no longer provided. The kindlegen tool used to create it previously was withdrawn from public distribution last year and Amazon has officially dropped support for creating reflowable MOBI files. The EPUB format continues to be provided.

Variables chapter:

  • CMake 3.21 improved the behavior of the set() command such that it no longer discards a non-cache variable of the same name when setting a cache variable. This makes it more consistent with similar changes made to the option() command in CMake 3.13. Special cases are noted.

Flow Control chapter:

  • Corrected a minor error. The if(...IN_LIST...) command was added in CMake 3.3, not 3.5 as previously claimed.

Using Subdirectories chapter:

  • CMake 3.21 added a new PROJECT_IS_TOP_LEVEL variable, along with related project-specific variables.

Language Requirements chapter:

  • CMake 3.21 added support for specifying C17 and C23 by setting CMAKE_C_STANDARD to 17 or 23 respectively.

Custom Tasks chapter:

  • CMake 3.21 extended add_custom_command() to add DEPFILE support for Xcode and Visual Studio.

Working With Files chapter:

  • CMake 3.21 added a new file(COPY_FILE) subcommand, intended to provide a simpler, more familiar syntax for more common basic file copy operations.
  • CMake 3.21 added a new EXPAND_TILDE option for the file(REAL_PATH) sub-command.
  • CMake 3.21 added new RESULT and NO_REPLACE options for the file(RENAME) sub-command. It is now possible to detect when the operation fails and provide alternative behavior instead of CMake halting with a fatal error.
  • Material relating to renaming files and making directories was re-ordered to improve the logical flow.

Toolchains And Cross Compiling chapter:

  • CMake 3.21 added a new --toolchain option for the cmake command. This is a convenience and is equivalent to setting the CMAKE_TOOLCHAIN_FILE cache variable. Support for a CMAKE_TOOLCHAIN_FILE environment variable was also added.
  • Some minor corrections were added for when toolchain files could be re-read during a configure run.

Apple Features chapter:

  • Added a brief note for the new XCODE_EMBED_APP_EXTENSIONS target properties added in CMake 3.21, mostly just to raise awareness.

Finding Things chapter:

  • find_file(), find_path(), find_library() and find_program() gained a new NO_CACHE option in CMake 3.21. The behavior of these commands also changed with regard to when a non-cache result variable already exists at the time of the call. Implications of both are discussed.

Testing chapter:

  • Embedding <DartMeasurement> and <DartMeasurementFile> tags in test output is now officially documented as of CMake 3.21. Material related to this has been updated, including the newly documented (but still always supported) BaselineImage as a synonym for ValidImage measurement type.
  • CMake 3.21 added the ability to attach arbitrary files to a test using <DartMeasurementFile>, not just images. Previously, this resulted in files that were not accessible from CDash, but it now works and is officially documented.
  • CMake 3.21 now supports overriding the Details field of a test by including a <CTestDetails> tag in its results.
  • A new Output Control section was added to this chapter. The new section covers how to use the new JUnit XML format output functionality added in CMake 3.21. It also discusses variables that can be used to override the limits on how much test output is recorded in the CDash and JUnit results.

Installing chapter:

  • CMake 3.21 added some significant capabilities associated with installing runtime dependencies of targets. New options were added to the install(TARGETS) command and two new install() subcommands were also added. The book contains two new sections, Installing Imported Targets and Runtime Dependency Sets which discuss the new capabilities.
  • Advice on choosing between the different methods (old and new) for installing runtime dependencies has been updated.
  • The install(SCRIPT) and install(CODE) sub-commands gained a new ALL_COMPONENTS keyword in CMake 3.21.
  • One of the main examples in the Config Files For CMake Projects section was expanded to demonstrate how to safely handle the use of if(...IN_LIST...) in config files when processed by an older version of CMake that doesn’t supported it.

Packaging chapter:

  • CMake 3.21 added the ability to use component and group names containing hyphens when using cpack wth QtIFW 3.1 or later.
  • The .dmg file system type can now be specified for the DragNDrop CPack generator using a new CPACK_DMG_FILESYSTEM variable.

Project Organization chapter:

  • Presets gained a new version 3 schema in CMake 3.21, expanding the capabilities of the previous schema version. Some of the more significant changes include the binaryDir and generator no longer being compulsory for configure presets and the ability to enable a preset only if certain conditions are met (e.g. the host platform matches a given string). The Presets section was expanded to cover the more important new features, with examples.


  • The index was expanded to cover individual sub-commands for some of the more complex built-in commands. This includes cmake_language(), file(), install(), list() and string().