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

Release Date: 9th May 2023

This is part of the change history for the book Professional CMake: A Practical Guide. The 15th Edition has been updated for the CMake 3.26 release, although the majority of the changes actually relate to updating material for other third-party tools and packages. The main highlights for this edition include:

  • The Apple Features chapter was significantly revised and updated for Xcode 14.
  • The Working With Qt chapter was also significantly revised and updated for Qt 6.
  • Improved flow and structure in some chapters based on reader feedback.

Full details of the changes are given below.

Variables chapter:

  • The chapter underwent some reorganization to improve the flow and keep related content together. In particular, the Cache Variables section now includes the material about surprising behavior of variables and CMake GUI tools, both of which closely relate to cache variable usage. The Scope Blocks section now follows the Cache Variables section instead of interrupting the material primarily about cache variables.

Using Subdirectories chapter:

  • Improved a comment in one of the examples of the Ending Processing Early section, clarifying how return(PROPAGATE) interacts with a surrounding block().

Modules chapter:

  • Replaced mention of FindCUDA with FindCUDAToolkit, since FindCUDA has been deprecated since CMake 3.10.

Debugging And Diagnostics chapter:

  • CMake 3.26 added a new configure log, replacing the CMakeOutput.log and CMakeError.log files, and providing an improved ability to check the steps performed during a CMake configure step.
  • The Perfetto performance tracing tool ( is now mentioned, which is the modern replacement for the legacy about:tracing tool built into some web browsers.

Compiler And Linker Essentials chapter:

  • Briefly mention the new $<BUILD_LOCAL_INTERFACE:...> generator expression added in CMake 3.26.

Custom Tasks chapter:

  • Added discussion of the ENCODING option for execute_process(). Also added a missing note that the RESULTS_VARIABLE requires CMake 3.10 or later.
  • COMMAND_ERROR_IS_FATAL is now used to simplify the archiver.cmake example in the Combining The Difference Approaches section.
  • Updated the guidance in the Recommended Practices section for a number of cases:
    • When to use COMMENT or cmake -E echo in custom commands.
    • Mention using BYPRODUCTS for intermediate files in add_custom_output().
    • Mention using COMMAND_ERROR_IS_FATAL as an alternative way of checking that an execute_process() call was successful.

Working With Files chapter:

  • CMake 3.26 added support for a -t option when using cmake -E copy.
  • CMake 3.26 also added a new cmake -E copy_directory_if_different subcommand.

Toolchains And Cross Compiling chapter:

  • CMake 3.26 added a new CMAKE_VS_VERSION_BUILD_NUMBER variable, available when using a Visual Studio toolchain.

Apple Features chapter:

  • This chapter was significantly revised and updated for Xcode 14. The recommended minimum CMake and Xcode versions have been updated, and some of the techniques and workarounds for much older versions have been significantly condensed or removed.
  • Some restructuring was performed to allow most of the Info.plist material to be presented together in one place, a new Info.plist Files sub-section under Build Settings.
  • The new XCODE_EMBED_EXTENSIONKIT_EXTENSIONS... target properties added by CMake 3.26 are mentioned. The Embedding Frameworks section of the previous edition was renamed to Embedding Frameworks, Plugins And Extensions to more accurately reflect that it covers all supported XCODE_EMBED_... properties.

Installing chapter:

  • Explain the purpose and usage of the new $<BUILD_LOCAL_INTERFACE:...> generator expression added in CMake 3.26.

ExternalProject chapter:

  • CMake 3.26 added support for a new INSTALL_BYPRODUCTS keyword for ExternalProject_Add(). This is an alternative to the existing BUILD_BYPRODUCTS keyword, allowing more accurate and granular dependencies to be specified.

FetchContent chapter:

  • Added sub-headings to the Other Uses For FetchContent section to provide a clearer structure.
  • Expanded the discussion of sharing toolchain files from a separate repository. An example was added to show how to structure the separate toolchains repository’s CMakeLists.txt to provide some simple smoke tests.

Making Projects Consumable chapter:

  • Removed stray closing parenthesis from the end of the first example in Use Project-specific Names section.

Project Organization chapter:

  • Mention that CMake 3.26 added policy CMP0143, which sets the USE_FOLDERS global property to true by default.
  • Fixed wrong target property name for specifying the compile PDB (should be COMPILE_PDB_NAME and COMPILE_PDB_NAME_<CONFIG>, not COMPILE_PDB and COMPILE_PDB_<CONFIG>).
  • Mention that using a compile PDB typically defeats compiler caching, so they are usually something to be avoided.

Build Performance chapter:

  • Added discussion of how /Z... and -Z... forms of compiler flags for Visual Studio compilers are equivalent, but the -Z... form is generally preferred. Also highlight that using -Z7 doesn’t prevent a PDB file being generated for executables and shared libraries (that is controlled by a linker option).

Working With Qt chapter:

  • This chapter was significantly revised and updated to focus on Qt 6. A significantly improved CMake API is available with Qt 6, and the way CMake targets and files are handled has changed considerably. Resource handling, translations and deployment all underwent substantial revision for this update.