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

Release Date: 11th April 2022

This is part of the change history for the book Professional CMake: A Practical Guide. The 12th Edition has been updated for the CMake 3.23 release. A significant new feature covered in this update is the new file sets capabilities. The Compiler And Linker Essentials, Installing and Project Organization chapters all underwent substantial changes to account for the new functionality. Presets have also been given more prominence with their own dedicated chapter. As usual, a range of smaller updates and clarifications have also been made. The main changes in this edition are listed below.


Properties chapter:

  • CMake 3.23 added a new INITIALIZE_FROM_VARIABLE keyword for the define_property() command. Almost any target property (including custom properties) can now be initialized from a nominated variable when a target is created.
  • The BRIEF_DOCS and FULL_DOCS options of define_property() became optional with CMake 3.23 or later.

Compiler And Linker Essentials chapter:

  • The Target Properties section gained a Sources sub-section that introduces the SOURCES and INTERFACE_SOURCES properties.
  • The Target Property Commands sub-section was pulled up one level to improve discoverability and navigation. Sub-sections were then added for each target property command.
  • The target_sources() command is now introduced in its own sub-section under the Target Property Commands section. Previously, most of this material was found in the Project Organization chapter, but it had been harder to find and was introduced very late in the book. New features added by CMake 3.23 and covered in the Installing chapter mean it is more important to learn about target_sources() earlier.
  • Mention that target_link_libraries() could not be called on a target defined in a different directory until CMake 3.13. Previously, this wasn’t mentioned until the Project Organization chapter.
  • CMake 3.23 added support for a new IMPORTED_NO_SYSTEM target property, primarily aimed at use with imported targets. It is discussed along with the existing NO_SYSTEM_FROM_IMPORTED property as part of the explanation of the SYSTEM keyword of the target_include_directories() command.
  • A new Advanced Linking Relationships section was added to cover the new LINK_LIBRARIES_ONLY_TARGETS target property added in CMake 3.23. The new property can be used to enforce linking only against CMake targets, which can help catch project errors. An example is given for how to mask non-target libraries with a CMake target of the same name to assist with transitioning older projects to the new feature.

Target Types chapter:

  • The Interface Imported Libraries section now covers the IMPORTED_LIBNAME target property. That property is more relevant now, given its potential use with the new LINK_LIBRARIES_ONLY_TARGETS feature.

Libraries chapter:

  • The discussion about setting header search paths when using generate_export_header() now cross-references the new file sets feature added in CMake 3.23.

Apple chapter:

  • CMake 3.23 added a new XCODE_EMBED_PLUGINS target property. Mention this briefly in the existing discussion covering the other closely related XCODE_EMBED_... target properties.
  • Update the discussion about PUBLIC_HEADERS and PRIVATE_HEADERS to cross-reference the moved sub-section about them in the Installing chapter.

Finding Things chapter:

  • A new Ignoring Search Paths section was added. It expands the existing discussion about CMAKE_IGNORE_PATH and CMAKE_SYSTEM_IGNORE_PATH, covering in more detail how they affect the various find_...() commands. The section also covers the new CMAKE_IGNORE_PREFIX_PATH and CMAKE_SYSTEM_IGNORE_PREFIX_PATH variables added in CMake 3.23. The search path re-rooting of all four variables is now also covered. Guidance is given to highlight when these two new variables should be preferred over the other two existing ones, both in the new section and in the Recommended Practices section.
  • The Debugging find_…() Calls section was updated to cover the new cmake command line options --debug-find-pkg and --debug-find-var added in CMake 3.23.

Testing chapter:

  • Discussion of the ENVIRONMENT and ENVIRONMENT_MODIFICATION test properties was moved to its own dedicated Test Environment section to improve discoverability and navigation.
  • Errors in examples related to the handling of semicolons in the ENVIRONMENT test property have been corrected. Discussion in the Test Environment section was expanded to cover the subtle problems underlying those errors.
  • The Recommended Practices section was updated to recommend using the more robust ENVIRONMENT_MODIFICATION test property rather than the ENVIRONMENT property.

Installing chapter:

CMake 3.23 added a significant new feature called file sets. These provide a much stronger abstraction for associating files of a particular type with a specific target. The primary use for file sets in the 3.23 release is to associated headers with a target and install them as part of the target via install(TARGETS). A key benefit is the ability to preserve relative paths to the files from a set of base directories. Material in this chapter has been restructured to account for this significant new feature.

  • The Installing Files And Directories section of previous editions has been renamed to just Installing Files. It now has a number of sub-sections covering the different ways files can be installed.
  • A new sub-section dedicated to file sets has been added. This covers the new syntax of the target_sources() command for defining file sets, as well as the changes to install(TARGETS) for installing them as part of the target they are associated with.
  • The material covering how PUBLIC_HEADERS and PRIVATE_HEADERS can be used to install headers and how they relate to frameworks was moved out of Apple-specific Targets and into another sub-section under Installing Files. Discussion has been expanded to highlight the conventional way headers are included from frameworks and how these two properties are subject to path stripping.
  • Material covering how to install a whole directory tree of files was also moved into a new sub-section under Installing Files.
  • A new paragraph was added to the Recommended Practices section to provide guidance on how to choose between the different methods for installing headers.

Packaging chapter:

  • CMake 3.23 added a number of new variables and capabilities for the IFW generator. CPACK_IFW_PACKAGE_RUN_PROGRAM and related variables can be used to optionally run a program upon successful completion of an install. CPACK_IFW_PACKAGE_PRODUCT_IMAGES can provide a list of PNG images to show in a cycle while an installation is in progress. On macOS, CPACK_IFW_PACKAGE_SIGNING_IDENTITY can provide an identity to use for signing the installer. The Qt Installer Framework (IFW) section has been updated to discuss these new variables and capabilities.
  • CMake 3.23 also added a number of new variables and capabilities for the productbuild generator. CPACK_PRODUCTBUILD_DOMAINS and related variables now control where the installer may be allowed to install to. A key benefit of this new capability is that installers can now potentially install to a user’s home directory, which doesn’t require administrative privileges.
  • CMake 3.23 essentially deprecated the use of CPACK_RESOURCE_LICENSE_FILE with the DragNDrop generator. A new variable CPACK_DMG_SLA_USE_RESOURCE_FILE_LICENSE controls whether to use or ignore CPACK_RESOURCE_LICENSE_FILE for this generator only.

Presets chapter:

  • The material covering presets was moved out of the Project Organization chapter into its own dedicated chapter. This was done to improve discoverability and navigation, and to tighten the focus of the Project Organization chapter.
  • CMake 3.23 added a new presets schema version (4). The main addition is a new include field, which enables preset files to include other files. A new ${fileDir} macro was also added to support that use case. The new Presets chapter covers these new capabilities, including their impact on preset inheritance.
  • The Configure Presets section now has sub-sections to provide better navigation.
  • The Build Presets section now mentions that the available build presets can also be obtained with the alternative command line cmake --list-presets build.
  • The Build Presets and Test Presets sections now mention the problem of combinatorial explosion of presets when they are over-used.

Project Organization chapter:

  • Some of the material from the Target Sources sub-section under Defining Targets has been moved to earlier chapters. The remaining material has a tighter focus, and the section has been renamed to Building Up A Target Across Directories.
  • Discussion and examples in the Windows-specific Issues and Recommended Practices sections were updated to address errors relating to the handling of semicolons and the ENVIRONMENT test property. The ENVIRONMENT_MODIFICATION property is now recommended and used in the examples instead.
  • The entire Presets section was moved to its own separate chapter.