Targets, Properties, And More#

Target Types#

  • Two basic types: add_executable() and add_library()

  • add_executable() is simple

    • No other node depends on it

    • Rather, executables only depend on other nodes

    • ⟶ Entry points into dependency graph

    • As such, executables rarely have properties attached to them

  • add_library()

    Type

    Description

    Normal library

    STATIC (default), SHARED, MODULE. Has sources to be built.

    Object libraries

    Technically much like normal libraries, but not an archive or shared object (only virtual, implemented by CMake)

    Interface libraries

    No sources; only there to propagate properties to dependers, and to have further dependencies on their own.

Properties#

(For a complete list see add_library())

Target function

Property name

Description

Documentation

target_compile_definitions()

COMPILE_DEFINITIONS

Macros set on the compiler command line (-Dname=value)

target_compile_definitions()

target_compile_options()

COMPILE_OPTIONS

Non-macro compiler flags/options

TARGET_COMPILE_OPTIONS()

target_include_directories()

INCLUDE_DIRECTORIES

Include directories

target_include_directories()

target_link_libraries()

(Much more complicated, see documentation)

Dependencies, in the widest sense

target_link_libraries()

set_target_properties()

Any property, including custom properties

See documentation

set_target_properties()

Properties: PRIVATE, PUBLIC, INTERFACE?#

  • PUBLIC: propagated to containing target itself, and to all dependers, transitively

    • Dependency through #include <other.h> in a header file ⟶ all includers need to know

    • PUBLIC properties only possible when target has compiled code

  • PRIVATE: propagated to containing target itself, invisible to dependers

    • For example, one might structure a target’s source code into src/, private-inc/, and public-inc/private-inc/ would be target_include_directories(... PRIVATE ...)

    • For example, target_compile_definitions() for target-local compilation only

  • INTERFACE: propagated only to dependers, invisible to containing target

    • Just like PUBLIC - except that PUBLIC is not possible on INTERFACE targets (e.g. header-only libraries)

    • Asymmetric (a smell that is encountered in many dark corners of CMake)

    • Documentation has no clear explanation. Exceptions, and paragraph-long explanations.

Demo Time#

Move on to Screenplay: Public And Private Include Directories

Final Note: include_directories()#

Why Noy Use include_directories() For That