Skip to content

Cmake best practices and guidelines

Paul Fultz II edited this page Jun 22, 2017 · 4 revisions

Cmake best practices and guidelines

This goes over cmake best practices and guidelines from Daniel Pfeifer's talks on cmake: Effective cmake and Cmake introduction and best practices

cmake_minimum_required

  • Prefer the latest version of CMake.
  • Please don’t set 2.8 as the minimum.
  • If you use 2.6 or 2.4, God kills a kitten.

project

  • Make sure that all your projects can be built both standalone and as a subproject of another project
  • Don’t assume that your project root is the build root.
  • Don’t modify global compile/link flags.
  • Don’t make any global changes!

find_package

  • Finds preinstalled dependencies
  • Can set some variables and define imported targets.
  • Use a Find module for third party libraries that do not support clients to use CMake
  • The library interface may change during installation. Use the BUILD_INTERFACE and INSTALL_INTERFACE generator expressions as filters.

add_library

  • Always add namespaced aliases for libraries.
  • When you export Foo in namespace Foo::, also create an alias Foo::Foo
  • Dont’t make libraries STATIC/SHARED unless they cannot be built otherwise.
  • Leave the control of BUILD_SHARED_LIBS to your clients!

target_link_libraries

  • Prefer to link against namespaced targets.
  • Specify the dependencies are private or public.
  • Avoid the link_libraries() command.
  • Avoid the link_directories() command.
  • No need to call add_dependencies().
  • Use target_link_libraries to express direct dependencies
  • Don't abuse requirements! E: -Wall is not a requirement

target_include_directories

  • Avoid the include_directories() command.

target_compile_definitions

  • Avoid the add_definitions() command.
  • Avoid adding definitions to CMAKE_<LANG>_FLAGS.

target_compile_options

  • Wrap compiler specific options in an appropriate condition.
  • Avoid the add_compile_options() command.
  • Avoid adding options to CMAKE_<LANG>_FLAGS.

Goal: no custom variables

  • Variables are so CMake 2.8.12: Modern CMake is about Targets and Properties!
  • Avoid custom variables in the arguments of project commands
  • Explicit is better than implicit

Goal: no custom functions

  • Contribute it to CMake!
  • If it is accepted, it is no longer a custom function.
  • Otherwise, the reason for rejection should give you a hint.
  • The maintainers are very helpful and experienced.

Package management

  • System packages: work out of the box
  • Prebuilt libraries: need to be put into CMAKE_PREFIX_PATH
  • Subprojects: need to turn find_package(Foo) into a no-op

More guidelines

  • The way you use CMake affects your users!
  • Cmake is code: Use the same principles for CMakeLists.txt and modules as for the rest of your codebase.
  • Create macros to wrap commands that have output parameters, otherwise, create a function.
  • Don't use file(GLOB) in projects.