10 Cmake Tips & Tricks

Let us first get to understand what a buildsystem is?

Rohan Krishnamurthy
Mar 29 · 4 min read

In simple words, a buildsysytem describes how to build the project executables and the associated libraries from the codebase using a build tool that automates the process.

For example, a Makefile is a buildsystem that is used as a command-line make tool or a project file for an Integrated Development Environment (IDE). In order to avoid maintaining multiple such buildsystems, a project may specify its buildsystem abstractly using files written in the CMake language.

Cmake simple flowchart

Build stages

An entire CMake build consists of the following stages:

  1. Configure: CMake executes the CMake code itself to create a build configuration.
  2. Generate: CMake generates a concrete build system (for example GNU Makefiles or a Visual Studio solution with related project files) out of the configuration.
  3. Compile: Apply the generated build system to finally compile and link the sources. Usually, CMake itself is not involved in this stage, but the generated build system checks if any relevant CMake code was altered and triggers another CMake configure run if required.

TIPS & TRICKS

  1. add_subdirectory: According to documentation, add_subdirectory should only be used for subdirectories of the current CMakeLists’ directory. But with special considerations, you may apply it to sources outside of the current directory, see here for things to consider. Attention: add_subdirectory behaves in terms of scope exactly like a macro. So pay attention to which variables of the calling CMakeLists might be altered by the added CMakeLists.
  2. aux_source_directory: aux_source_directory adds the found source files to the list in the passed variable. Source files already in the variable’s list are untouched. This has to be considered particularly if you add another CMakeLists with add_subdirectory that uses the same variable in its aux_source_directory calls. In that case, the variable accumulates all source files, because add_subdirectory does not have its own scope. In addition, note that aux_source_directory does not add header files. That could be a problem for example if you want to apply qt5_wrap_cpp to call moc for the header files. As a workaround use file(GLOB_RECURSE … to search directly for header files.
  3. Call function or macro with an arbitrary number of arguments: It is possible to call a function or macro with an arbitrary number of arguments, which are passed as a list by using the predefined variables ${ARGV} or ${ARGN}. ${ARGV} contains all arguments as a list while ${ARGN} contains only the arguments not assigned to a named parameter
  4. Select architecture(x86orx64) for Visual Studio build: If you call cmake without any further options on a Windows with installed Visual Studio 2010 (for example) it creates project files for a 32-bit build (x86).

To create 64-bit executables, set option -G accordingly:

cmake -G "Visual Studio 10 2010 Win64" ..

Since CMake 3.13 there is the alternative and preferred option -A to select the platform architecture:

cmake -G "Visual Studio 10 2010" -A x64 ..

It is not possible to create a VS project for both architectures. If you need both you should create two build folders and setup each with a different architecture.

5. “if” command does not work: An if command to determine if a Visual Studio build system should be generated (if(MSVC)) did not work as expected. It turned out that this needs a prior project command to work correctly. Thus, the project command should be put before any include commands (but behind the cmake_minimum_required command).

6. Terminate CMake run due to an error: CMake does not come with an exit command to terminate the CMake run after a fatal error. To terminate the CMake run call message(FATAL_ERROR “…”) with an appropriate message. This terminates the CMake run with the clearly highlighted message in the console.

7. Add a general option to the CMakeGUI: The option command allows to add a boolean option to the CMake GUI, but not an option with an arbitrary value. Adding a non-boolean option is done with the set command with its CACHE flag as described in section Set Cache Entry on the set docs page. Besides general strings, such an option might be a directory (PATH) or file (FILEPATH) type. In those cases, the CMake GUI offers a directory/file selection dialog. It is also possible to offer a selection of possible string values to choose from.

8. Debugging tips: Linux with GNU Makefiles :

A global make clean causes a complete rebuild. If you want to rebuild only a subdirectory, change to the respective subfolder in your build folder and execute make clean there, or simply delete that subfolder of the build folder. Passing VERBOSE=1 to the make call gets “make” to print out all compiler and linker calls.

9. An include guard: Include guards avoid to execute an included file multiple times if the file is included at several places. CMake 3.10 and newer provide the include_guard command for that. In case of an older CMake, the following trick helps. Targets are globally defined. If the included file defines a target called MyTarget put the following code at its top:

if(TARGET MyTarget)
return()
endif()

If the file does not define a target you can add one with add_custom_target. If that is not used anywhere else it won’t harm.

10. CMake and VisualStudio: See here for a mapping of Visual Studio terms onto CMake terms.

References:

  1. An Introduction to Modern CMake
  2. CMake reference documentation
  3. Effective modern CMake
  4. CMake Tutorial

I hope at least some of these tips offered some help if not all. Drop-in some more tips in the comments section below. Thank you for reading and do clap if this article was useful.

CodeX

Everything connected with Tech & Code

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store