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

Release Date: 28th March 2024

This is part of the change history for the book Professional CMake: A Practical Guide. The 18th Edition has been updated for the CMake 3.29 release. This is a fairly modest update, consisting mostly of incremental improvements and a few smaller new features. Full details of the changes are given below.


Flow Control chapter:

  • CMake 3.29 added new IS_READABLE, IS_WRITABLE, and IS_EXECUTABLE expressions for the if() command.

Functions And Macros chapter:

  • The Problems With Argument Handling section contains a small example highlighting the interaction between semicolons and quoting. That example block contained three similar someCommand() calls that earlier editions claimed all produced the same number of arguments, but the third one, someCommand(a;";";c) was in fact different to the other two. This third command has now been dropped from that example.

Language Requirements chapter:

  • The last example in the Setting The Language Standard Directly section contained an error. It was comparing CMAKE_CXX_STANDARD against the values 90 and 99, but those are for the C language, not C++. The example has been updated to compare CMAKE_CXX_STANDARD against 98 instead of those two values.

Custom Tasks chapter:

  • Starting with CMake 3.29, an alias target can now be passed to add_custom_command(TARGET...) when adding build events.
  • CMake 3.29 added a new cmake_language(EXIT) subcommand to immediately end execution. It can only be used in CMake script mode.

Toolchains And Cross Compiling chapter:

  • Starting with version 3.29, CMake now provides a set of CMAKE_<LANG>_COMPILER_LINKER... variables that give information about the linker.

Apple Features chapter:

  • The Xcode generator gained support for embedding XPC services with CMake 3.29.

Build Performance chapter:

  • Unity builds are supported for OBJC and OBJCXX languages starting with CMake 3.29.
  • CMake 3.29 gained a new abstraction for selecting the linker to use. A new CMAKE_LINKER_TYPE variable is the primary way to select the linker, with supporting variables that can be used to define custom linkers if required. Importantly, this new abstraction also supports the new mold linker.
  • The Alternative Linkers section was updated to drop the paragraph and supporting example that discussed using add_link_options() within a project to add raw flags for linker selection. Even with CMake 3.28 or older, that method fails to pass linker details to any try_compile() sub-builds, so it is not robust.

Testing Fundamentals chapter:

  • CMake 3.29 added support for specifying a file containing a list of test names to include or exclude. The Regular Expressions subsection was expanded to cover this new feature and the subsection was renamed to Test Names to reflect its broadened scope.
  • CMake 3.29 added a dedicated test launcher feature. The existing CROSSCOMPILING_EMULATOR property could previously have been repurposed to achieve a similar result, but that was not obvious nor originally intended. The new TEST_LAUNCHER test property has a clear responsibility and the behavior of CROSSCOMPILING_EMULATOR has been changed with policy CMP0158 for non-cross-compiling scenarios. The Cross-compiling And Emulators section was updated and renamed to Cross-compiling, Emulators, And Launchers to reflect these changes. The Recommended Practices section was also updated.

Test Resources And Constraints chapter:

  • Starting with CMake 3.29, the ctest -j and ctest --parallel options now accept the special value 0, or can be given with no value at all. These have special meaning and are intended primarily for situations where ctest is running as a subprocess under a make job server. The CTEST_PARALLEL_LEVEL environment variable support was also updated similarly.

Installing chapter:

  • CMake 3.29 added support for using a CMAKE_INSTALL_PREFIX environment variable to initialize the same-named CMake cache variable.
  • Two new Apple-specific commands, generate_apple_{platform,architecture}_selection_file(), were added to the CMakePackageConfigHelpers module in CMake 3.29. The commands are mentioned briefly at the end of the Config Files For CMake Projects subsection.

Package Generators chapter:

  • A paragraph was added to the WIX section to highlight a long-standing bug with installers generated by CMake 3.28 and earlier. The bug related to the installer only installing some things for the current user instead of all users. CMake 3.29 fixed the bug and also added a new CPACK_WIX_INSTALL_SCOPE variable to specify the type of install to allow.
  • CMake 3.29 changed the default for the CPACK_PRODUCTBUILD_DOMAINS variable via policy CMP0161. The new default enables domains, which avoids using deprecated methods and generates installers with more desirable behavior by default.

Project Structure chapter:

  • The various CMAKE_PROJECT_...INCLUDE... variables associated with the project() command can contain a list rather than just a file name starting with CMake 3.29. List items can also be CMake modules, not just file names.