Key Concepts
************

This chapter provides an introduction to CMake's key concepts. As you
start working with CMake, you will run into a variety of concepts such
as targets, generators, and commands. Understanding these concepts will
provide you with the working knowledge you need to create effective
CMakeLists files. Many CMake objects such as targets, directories
and source files have properties associated with them. A property is a
key-value pair attached to a specific object. The most generic way to access
properties is through the :command:`set_property` and :command:`get_property`
commands. These commands allow you to set or get a property from any object
in CMake that has properties. See the
:manual:`cmake-properties <cmake-properties(7)>` manual for a list of
supported properties. From the command line a full list of properties
supported in  CMake can be obtained by running :manual:`cmake <cmake(1)>`
with the ``--help-property-list`` option.

.. index::
   single: targets

Targets
=======

Probably the most important item is targets. Targets represent executables,
libraries, and utilities built by CMake. Every :command:`add_library`,
:command:`add_executable`, and :command:`add_custom_target` command creates a
target. For example, the following command will create a target named "foo"
that is a static library, with ``foo1.c`` and ``foo2.c`` as source files.

.. code-block:: cmake

 add_library(foo STATIC foo1.c foo2.c)

.. index::
   single: libraries ; module
   single: libraries ; shared
   single: libraries ; static

The name "foo" is now available for use as a library name everywhere
else in the project, and CMake will know how to expand the name into
the library when needed. Libraries can be declared as a particular
type such as ``STATIC``, ``SHARED``, ``MODULE``, or left
undeclared. ``STATIC`` indicates that the library must be built as a
static library. Likewise, ``SHARED`` indicates it must be built as a
shared library. ``MODULE`` indicates that the library must be created
so that it can be dynamically-loaded into an executable. Module
libraries are implemented as shared libraries on many platforms, but
not all.  Therefore, CMake does not allow other targets to link to
modules. If none of these options are specified, it indicates that the
library could be built as either shared or static. In that case, CMake
uses the setting of the variable :variable:`BUILD_SHARED_LIBS` to determine if
the library should be ``SHARED`` or ``STATIC``. If it is not set, then
CMake defaults to building static libraries.

.. index::
   single: Windows ; executable
   single: WinMain

Likewise, executables have some options. By default, an executable
will be a traditional console application that has a main entry
point. One may specify a ``WIN32`` option to request a WinMain entry
point on Windows systems, while retaining main on non-Windows systems.

.. index::
   single: targets ; properties

In addition to storing their type, targets also keep track of general
properties. These properties can be set and retrieved using the
:command:`set_target_properties` and :command:`get_target_property` commands,
or the more general :command:`set_property` and :command:`get_property`
commands. One useful property is :prop_tgt:`LINK_FLAGS`, which is used to
specify additional link flags for a specific target. Targets store a list of
libraries that they link against, which are set using the
:command:`target_link_libraries` command. Names passed into this command can
be libraries, full paths to libraries, or the name of a library from
an :command:`add_library` command. Targets also store the link directories to
use when linking, and custom commands to execute after building.

Usage Requirements
==================

CMake will also propagate "usage requirements" from linked library
targets. Usage requirements affect compilation of sources in the
<target>. They are specified by properties defined on linked
targets.

For example, to specify include directories that are required when
linking to a library you would can do the following:

.. code-block:: cmake

 add_library(foo foo.cxx)
 target_include_directories(foo PUBLIC
                            "${CMAKE_CURRENT_BINARY_DIR}"
                            "${CMAKE_CURRENT_SOURCE_DIR}"
                            )

Now anything that links to the target foo will automatically have
foo's binary and source as include directories. The order of the
include directories brought in through "usage requirements" will match
the order of the targets in the :command:`target_link_libraries` call.

For each library or executable CMake creates, it tracks of all the
libraries on which that target depends using the
:command:`target_link_libraries` command. For example:

.. code-block:: cmake

 add_library(foo foo.cxx)
 target_link_libraries(foo bar)

 add_executable(foobar foobar.cxx)
 target_link_libraries(foobar foo)

will link the libraries "foo" and "bar" into the executable "foobar"
even though only "foo" was explicitly specified for it.

Specifying Optimized or Debug Libraries with a Target
=====================================================

On Windows platforms, users are often required to link debug libraries
with debug libraries, and optimized libraries with optimized
libraries. CMake helps satisfy this requirement with the
:command:`target_link_libraries` command, which accepts an optional flag
labeled as ``debug`` or ``optimized``. If a library is preceded with either
``debug`` or ``optimized``, then that library will only be linked in with the
appropriate configuration type. For example

.. index::
   single: command ; add_executable

.. code-block:: cmake

 add_executable(foo foo.c)
 target_link_libraries(foo debug libdebug optimized libopt)

In this case, foo will be linked against libdebug if a debug build was
selected, or against libopt if an optimized build was selected.

Object Libraries
================

Large projects often organize their source files into
groups, perhaps in separate subdirectories, that each need different
include directories and preprocessor definitions. For this use case
CMake has developed the concept of Object Libraries.

An Object Library is a collection of source files compiled into an object file
which is not linked into a library file or made into an archive. Instead other
targets created by :command:`add_library` or :command:`add_executable` may
reference the objects using an expression of the form
``$<TARGET_OBJECTS:name>`` as a source, where "name" is the target
created by the :command:`add_library` call. For example:

.. code-block:: cmake

  add_library(A OBJECT a.cpp)
  add_library(B OBJECT b.cpp)
  add_library(Combined $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)

will include A and B object files in a library called Combined. Object
libraries may contain only sources (and headers) that compile to
object files.


.. index::
   single: source files

Source Files
============

The source file structure is in many ways similar to a target. It
stores the filename, extension, and a number of general properties
related to a source file. Like targets, you can set and get properties
using :command:`set_source_files_properties` and
:command:`get_source_file_property`, or the more generic versions.

Directories, Tests, and Properties
==============================================

In addition to targets and source files, you may find yourself
occasionally working with other objects such as directories and tests.
Normally such interactions take the shape of setting or getting properties
(e.g. :command:`set_directory_properties` or :command:`set_tests_properties`)
from these objects.
