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

Release Date: 28th April 2020

This is part of the change history for the book Professional CMake: A Practical Guide. The 6th Edition has been updated for the CMake 3.17 release and includes a substantial amount of new material. Major highlights of this edition are a new chapter on Qt support and an expansion of the topics covered in the Apple chapter. The following lists the main changes in this edition.

General presentation:

  • Conventions used for upper/lowercase naming of targets and tests has been made more consistent throughout the book.
  • An updated syntax highlighting scheme has been defined to improve consistency and reduce questionable highlighting in some code samples.

Introduction chapter:

  • Replaced mention of the CMake users mailing list with a link to the CMake forums.

Setting Up A Project chapter:

  • Updated generator examples table to mention Visual Studio 16 2019 and the new Ninja Multi-Config generator.

A Minimal Project chapter:

  • Replaced comments about when to call the project() command and toolchain configuration with cross-references to other chapters which cover the equivalent material in more detail. In particular, removed the ambiguous statement about calling project() “early enough”.

Variables chapter:

  • CMake 3.17 added the ability to set a default log level with the new CMAKE_MESSAGE_LOG_LEVEL cache variable.
  • Fixed some operators being listed twice in the description of the math() command.

Flow Control chapter:

  • CMake 3.17 added a new IN ZIP_LISTS form for the foreach() command.

Using Subdirectories chapter:

  • Added a new subsection When To Call project(). This expands on the previously ambiguous “calling project() early enough” comment in the A Minimal Project chapter. It also adds new material related to calling project() in subdirectories and calling it more than once, with particular reference to Visual Studio and Xcode projects.
  • Added advice to the Recommended Practices section discouraging calling project() in every subdirectory.

Functions And Macros chapter:

  • CMake 3.17 added a number of new variables that provide information related to the currently executing function. These are CMAKE_CURRENT_FUNCTION, CMAKE_CURRENT_FUNCTION_LIST_FILE, CMAKE_CURRENT_FUNCTION_LIST_DIR and CMAKE_CURRENT_FUNCTION_LIST_LINE. A common use case for CMAKE_CURRENT_FUNCTION_LIST_DIR is presented.

Properties chapter:

  • Added an example showing how to set source file properties.

Modules chapter:

  • Fixed the check_c_source_compiles() example which would previously have always returned the same result due to the name of the output variable always matching the regular expression.

Build Type chapter:

  • CMake 3.17 added a new Ninja Multi-Config generator. Some brief comments have been added to mention its support for specifying a default build type with the new CMAKE_DEFAULT_BUILD_TYPE variable.
  • Fixed the examples where the CMAKE_STATIC_LINKER_FLAGS_PROFILE variable was being given flags that are not relevant for a library archive tool.

Language Requirements chapter:

  • CMake 3.17 added the ability to directly specify compile features for CUDA rather than having to rely on a fallback to C or C++ compile features (this is only a brief note, CUDA is not covered in any great detail).
  • Condensed the discussion of compile features in the Recommended Practices section to give less prominence to granular compile features. Granular features are of decreasing importance, being restricted to C++11 and C++14 only and are no longer being added for later language standards. The standard meta features (e.g. cxx_std_17) continue to be added for each standard version.

Custom Tasks chapter:

  • CMake 3.17 added a new cmake -E rm command as a replacement for the now deprecated cmake -E remove and cmake -E remove_directory commands.
  • Added a paragraph to the Recommended Practices section briefly discussing use cases that the new Ninja Multi-Config generator uniquely supports. Comments are fairly restricted at this time due to the relatively new status and limited real-world experience with this generator.

Working With Files chapter:

  • Updated examples and discussion for cmake -E commands related to removing files and directories. The motivation for why cmake -E rm was added in CMake 3.17 is briefly discussed.

Libraries chapter:

  • Briefly mentioned the new MACHO_COMPATIBILITY_VERSION and MACHO_CURRENT_VERSION target properties added in CMake 3.17. They are discussed in more detail in the Apple Features chapter.

Toolchains And Cross Compiling chapter:

  • Fixed non-generator expression example in Tool Selection section where CMAKE_CXX_COMPILER_ID and CMAKE_CXX_COMPILER_VERSION variables were missing their CMAKE_ prefix.

Apple Features chapter:

A number of sections in this chapter were significantly reworked for this edition. Some sections were restructured to improve discoverability and navigation, while others are entirely new. Updates to account for changes with Xcode 11 have also been made.

  • Added a brief example showing how to obtain a summary of a project’s build settings from the command line.
  • Highlighted the change to using Apple Development as the default signing identity from Xcode 11, regardless of the target platform. Examples have been updated to use this identity where relevant.
  • The Application Bundles section has been divided into subsections to make it easier to quickly find information on specific aspects. Some content was reordered to improve the flow, especially with regard to the examples.
  • A more detailed discussion has been added around how to add resources and other files to an application bundle. The differences in behaviour between RESOURCE target property and the MACOSX_PACKAGE_LOCATION source property are now more clearly presented, particularly with regard to resources that need to be compiled before being added to the bundle. The main example also now includes an asset catalog to briefly show how they can be added too.
  • The Frameworks section has also been divided into subsections to improve discoverability and navigation.
  • The Build Settings section received a number of updates and has also been divided into subsections with a clearer, more coherent flow. The SDK subsection now shows how to select the simulator SDK when building from the command line. A significant new subsection Compiler Test Workarounds was added to address very common problems related to changes with Xcode 11, preventing code signing during compiler checks or try_compile() calls, and avoiding checks failing due to the use of an inappropriate target type for the chosen platform.
  • The Code Signing section has been divided into subsections and advice has been updated for signing-related changes that came in with Xcode 11 (mostly related to the new Apple Development identity being applicable across all target platforms). All examples in this section now use CMake 3.14 as their minimum CMake version. Comments regarding sign-on-copy for shared frameworks have been updated.
  • A significant new Universal Binaries section has been added. Both regular builds and archive actions are covered. Universal binaries can be device-only or device-and-simulator. This section discusses areas that are often unnecessarily over-constrained or misconfigured by many users.
  • Another new section Linking And Embedding Frameworks has been added. This section shows how to link to frameworks in a way that works for both archive actions and regular builds. It also presents techniques for copying frameworks into application bundles, including sign-on-copy if required.
  • The Limitations section has been updated to account for the techniques presented in the newly added sections.
  • The Recommended Practices section has been updated to account for the various changes to the rest of the chapter.

Finding Things chapter:

  • A new section Debugging find_…() Calls was added to cover the new --debug-find option and its associated CMAKE_FIND_DEBUG_MODE variable. This functionality is new for CMake 3.17.

Testing chapter:

  • CMake 3.17 added a new CMAKE_CTEST_ARGUMENTS variable, which is used by the test or RUN_TESTS build targets when invoking ctest.
  • Added subsections to the Test Grouping And Selection section for improved navigation and discoverability.
  • CMake 3.17 added support for Dr Memory to the MemCheck action (CDash scripts).

Installing chapter:

  • Updated discussions related to linking, copying and embedding of frameworks when targeting Apple platforms. The example for RPATH handling with app bundles was also updated.
  • Moved and slightly expanded the comments regarding the check_required_components() command in the Custom Install Logic section.

Packaging chapter:

  • CMake 3.17 added more customization options for the NSIS package generator related to user-visible installer and uninstaller aspects.
  • Added a note highlighting the increased minimum NSIS version from 2.09 to 3.0 with CMake 3.17, including a bug related to this change in CMake 3.17.0 which was fixed in CMake 3.17.1.
  • CMake 3.17 added support for per-component file names with the DragNDrop package generator.
  • Mentioned that CMake 3.17 officially deprecated the PackageMaker generator.

Build Performance chapter:

  • Added note that it may be desirable to add include_file_mtime to the CCACHE_SLOPPINESS options for improved cache hit rate.
  • Fixed typo in two examples CACHE_SLOPPINESS –> CCACHE_SLOPPINESS.

Working With Qt chapter:

This is an entirely new chapter dedicated to the CMake support provided for Qt. It covers basic setup such as how to correctly find Qt and make it available to the build. Some less obvious build configuration points-of-care are highlighted. Each of the essential moc, uic and rcc tools are also discussed, including both automatic and manual handling. The steps needed to incorporate translations into a CMake project are presented, including their deployment. Deploying Qt applications in general using tools like windeployqt and macdeployqt is also discussed.


The index has been converted to a single column and no longer has numerous cases of long keywords being broken up through line wrapping.