Targets

Top level targets

A top-level target is created by the add_executable(), add_library(), or add_custom_target() commands.

For example, consider the following commands in a CMakeLists.txt file:


add_library (L F1 F2)
add_executable (E F3)
target_link_libraries (E PUBLIC L)

This gives rise to the following dependency graph where the nodes are either files or targets:

In this diagram there are three files (green) two top-level targets (blue) and the built-in target all (orange) which is the default target.

We say that:

GNU make targets

When CMake generates a GNU make file, the top-level targets are available as GNU make targets.

Declaring dependencies

add_dependencies is used to declare dependencies between top level targets.

For example, add_dependencies(Y X1 X2 X3) declares that X1,X2,X3 are dependencies of Y. In other words Y depends on X1, X2 and X3. This ensures that X1,X2,X3 are built before Y is built.

Y must have already been declared as a top-level target using add_executable(), add_library(), or add_custom_target(). Otherwise the cmake error "Cannot add target-level dependencies to non-existent target Y" is produced during the configure phase.

X1,X2,X3 need to be defined as top level targets somewhere; the definitions can come before or after the call to add_dependencies. Otherwise a cmake error such as "The dependency target X1 of target Y does not exist" is produced during the configure phase.

Byproducts of a command

Byproducts of a command mean files created by the command.

For example the protoc compiler takes .proto files as input and produces .cc and .h files as output.

Custom command

add_custom_command is used to add a custom build rule to the generated build system.

There are two main signatures for add_custom_command.

One is for adding a custom command to produce an output.

The second signature adds a custom command to a target such as a library or executable. This is useful for performing an operation before or after building the target. The command becomes part of the target and will only execute when the target itself is built. If the target is already built, the command will not execute.