CMake Best Practices

In a Nutshell

  • Declare modules with ADD_LIBRARY or ADD_EXECUTABLE

  • Declare build flags with TARGET_xxx()

  • Declare dependencies with TARGET_LINK_LIBRARIES

  • Specify which is PUBLIC and which is PRIVATE

Boilderplate

Headers

cmake_minimum_required(VERSION 3.0)

# declare top-level flags
if (MSVC)
  add_compile_options(/W3 /WX)
else()
  add_compile_options(-W -Wall -Werror)
endif()

Add Libraries

Declare Flags

Declare Dependencies

Header-only libraries

INTERFACE basically indicates that we don't need to build anything

DO NOT

  1. Don't use macros that affect all targets:

    • INCLUDE_DIRECTORIES()

    • ADD_DEFINITIONS()

    • LINK_LIBRARIES

  2. Dont' use TARGET_INCLUDE_LIBRARIES() with path outside your own module

  3. Don't use TARGET_LINK_LIBRARIES() without specifying scope (PUBLIC, PRIVATE, or INTERFACE)

  4. Don't use TARGET_COMPILE_OPTIONS() to set flags that affect the ABI

Last updated