code:
Step 3: Adding Usage Requirements for a Library
===============================================

Exercise 1 - Adding Usage Requirements for a Library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:ref:`Usage requirements <Target Usage Requirements>` of a target parameters
allow for far better control over a library or executable's link and include
line while also giving more control over the transitive property of targets
inside CMake. The primary commands that
leverage usage requirements are:

* :command:`target_compile_definitions`
* :command:`target_compile_options`
* :command:`target_include_directories`
* :command:`target_link_directories`
* :command:`target_link_options`
* :command:`target_precompile_headers`
* :command:`target_sources`

Goal
----

Add usage requirements for a library.

Helpful Materials
-----------------

* :variable:`CMAKE_CURRENT_SOURCE_DIR`

Files to Edit
-------------

* ``MathFunctions/CMakeLists.txt``
* ``CMakeLists.txt``

Getting Started
---------------

In this exercise, we will refactor our code from
:guide:`tutorial/Adding a Library` to use the modern CMake approach. We will
let our library define its own usage requirements so they are passed
transitively to other targets as necessary. In this case, ``MathFunctions``
will specify any needed include directories itself. Then, the consuming target
``Tutorial`` simply needs to link to ``MathFunctions`` and not worry about
any additional include directories.

The starting source code is provided in the ``Step3`` directory. In this
exercise, complete ``TODO 1`` through ``TODO 3``.

First, add a call to :command:`target_include_directories` in
``MathFunctions/CMakeLists``. Remember that
:variable:`CMAKE_CURRENT_SOURCE_DIR` is the path to the source directory
currently being processed.

Then, update (and simplify!) the call to
:command:`target_include_directories` in the top-level ``CMakeLists.txt``.

Build and Run
-------------

Make a new directory called ``Step3_build``, run the :manual:`cmake
<cmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>` to
configure the project and then build it with your chosen build tool or by
using :option:`cmake --build . <cmake --build>` from the build directory.
Here's a refresher of what that looks like from the command line:

.. code-block:: console

  mkdir Step3_build
  cd Step3_build
  cmake ../Step3
  cmake --build .

Next, use the newly built ``Tutorial`` and verify that it is working as
expected.

Solution
--------

Let's update the code from the previous step to use the modern CMake
approach of usage requirements.

We want to state that anybody linking to ``MathFunctions`` needs to include
the current source directory, while ``MathFunctions`` itself doesn't. This
can be expressed with an ``INTERFACE`` usage requirement. Remember
``INTERFACE`` means things that consumers require but the producer doesn't.

At the end of ``MathFunctions/CMakeLists.txt``, use
:command:`target_include_directories` with the ``INTERFACE`` keyword, as
follows:

.. raw:: html

  TODO 1: Click to show/hide answer

.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
  :caption: TODO 1: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
  :language: cmake
  :start-after: # to find MathFunctions.h
  :end-before: # should we use our own

.. raw:: html

Now that we've specified usage requirements for ``MathFunctions`` we can
safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
``CMakeLists.txt``.

Remove this line:

.. raw:: html

  TODO 2: Click to show/hide answer

.. literalinclude:: Step3/CMakeLists.txt
  :caption: TODO 2: CMakeLists.txt
  :name: CMakeLists.txt-remove-EXTRA_INCLUDES
  :language: cmake
  :start-after: add_subdirectory(MathFunctions)
  :end-before: # add the executable

.. raw:: html

And remove ``EXTRA_INCLUDES`` from ``target_include_directories``:

.. raw:: html

  TODO 3: Click to show/hide answer

.. literalinclude:: Step4/CMakeLists.txt
  :caption: TODO 3: CMakeLists.txt
  :name: CMakeLists.txt-target_include_directories-remove-EXTRA_INCLUDES
  :language: cmake
  :start-after: # so that we will find TutorialConfig.h

.. raw:: html

Notice that with this technique, the only thing our executable target does to
use our library is call :command:`target_link_libraries` with the name
of the library target. In larger projects, the classic method of specifying
library dependencies manually becomes very complicated very quickly.

Exercise 2 - Setting the C++ Standard with Interface Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Now that we have switched our code to a more modern approach, let's demonstrate
a modern technique to set properties to multiple targets.

Let's refactor our existing code to use an ``INTERFACE`` library. We will
use that library in the next step to demonstrate a common use for
:manual:`generator expressions <cmake-generator-expressions(7)>`.

Goal
----

Add an ``INTERFACE`` library target to specify the required C++ standard.

Helpful Resources
-----------------

* :command:`add_library`
* :command:`target_compile_features`
* :command:`target_link_libraries`

Files to Edit
-------------

* ``CMakeLists.txt``
* ``MathFunctions/CMakeLists.txt``

Getting Started
---------------

In this exercise, we will refactor our code to use an ``INTERFACE`` library to
specify the C++ standard.

Start this exercise from what we left at the end of Step3 exercise 1. You will
have to complete ``TODO 4`` through ``TODO 7``.

Start by editing the top level ``CMakeLists.txt`` file. Construct an
``INTERFACE`` library target called ``tutorial_compiler_flags`` and
specify ``cxx_std_11`` as a target compiler feature.

Modify ``CMakeLists.txt`` and ``MathFunctions/CMakeLists.txt`` so that all
targets have a :command:`target_link_libraries` call to
``tutorial_compiler_flags``.

Build and Run
-------------

Since we have our build directory already configured from Exercise 1, simply
rebuild our code by calling the following:

.. code-block:: console

  cd Step3_build
  cmake --build .

Next, use the newly built ``Tutorial`` and verify that it is working as
expected.

Solution
--------

Let's update our code from the previous step to use interface libraries
to set our C++ requirements.

To start, we need to remove the two :command:`set` calls on the variables
:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
The specific lines to remove are as follows:

.. literalinclude:: Step3/CMakeLists.txt
  :caption: CMakeLists.txt
  :name: CMakeLists.txt-CXX_STANDARD-variable-remove
  :language: cmake
  :start-after: # specify the C++ standard
  :end-before: # configure a header file

Next, we need to create an interface library, ``tutorial_compiler_flags``. And
then use :command:`target_compile_features` to add the compiler feature
``cxx_std_11``.

.. raw:: html

  TODO 4: Click to show/hide answer

.. literalinclude:: Step4/CMakeLists.txt
  :caption: TODO 4: CMakeLists.txt
  :name: CMakeLists.txt-cxx_std-feature
  :language: cmake
  :start-after: # specify the C++ standard
  :end-before: # TODO 2: Create helper

.. raw:: html

Finally, with our interface library set up, we need to link our
executable ``Tutorial``, our ``SqrtLibrary`` library and our ``MathFunctions``
library to our new ``tutorial_compiler_flags`` library. Respectively, the code
will look like this:

.. raw:: html

  TODO 5: Click to show/hide answer

.. literalinclude:: Step4/CMakeLists.txt
  :caption: TODO 5: CMakeLists.txt
  :name: CMakeLists.txt-target_link_libraries-step4
  :language: cmake
  :start-after: add_executable(Tutorial tutorial.cxx)
  :end-before: # add the binary tree to the search path for include file

.. raw:: html

this:

.. raw:: html

  TODO 6: Click to show/hide answer

.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
  :caption: TODO 6: MathFunctions/CMakeLists.txt
  :name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
  :language: cmake
  :start-after: # link SqrtLibrary to tutorial_compiler_flags
  :end-before: target_link_libraries(MathFunctions

.. raw:: html

and this:

.. raw:: html

  TODO 7: Click to show/hide answer

.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
  :caption: TODO 7: MathFunctions/CMakeLists.txt
  :name: MathFunctions-SqrtLibrary-target_link_libraries-step4
  :language: cmake
  :start-after: # link MathFunctions to tutorial_compiler_flags

.. raw:: html

With this, all of our code still requires C++ 11 to build. Notice
though that with this method, it gives us the ability to be specific about
which targets get specific requirements. In addition, we create a single
source of truth in our interface library.

path: buildtools/windows/cmake/doc/cmake/html/_sources/guide/tutorial/Adding Usage Requirements for a Library.rst.txt


code:
Step 8: Adding a Custom Command and Generated File
==================================================

Suppose, for the purpose of this tutorial, we decide that we never want to use
the platform ``log`` and ``exp`` functions and instead would like to
generate a table of precomputed values to use in the ``mysqrt`` function.
In this section, we will create the table as part of the build process,
and then compile that table into our application.

First, let's remove the check for the ``log`` and ``exp`` functions in
``MathFunctions/CMakeLists.txt``. Then remove the check for ``HAVE_LOG`` and
``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove
:code:`#include <cmath>`.

In the ``MathFunctions`` subdirectory, a new source file named
``MakeTable.cxx`` has been provided to generate the table.

After reviewing the file, we can see that the table is produced as valid C++
code and that the output filename is passed in as an argument.

The next step is to create ``MathFunctions/MakeTable.cmake``. Then, add the
appropriate commands to the file to build the ``MakeTable`` executable and
then run it as part of the build process. A few commands are needed to
accomplish this.

First, we add an executable for ``MakeTable``.

.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
  :caption: MathFunctions/MakeTable.cmake
  :name: MathFunctions/MakeTable.cmake-add_executable-MakeTable
  :language: cmake
  :start-after: # first we add the executable that generates the table
  :end-before: target_link_libraries

After creating the executable, we add the ``tutorial_compiler_flags`` to our
executable using :command:`target_link_libraries`.

.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
  :caption: MathFunctions/MakeTable.cmake
  :name: MathFunctions/MakeTable.cmake-link-tutorial-compiler-flags
  :language: cmake
  :start-after: add_executable
  :end-before: # add the command to generate

Then we add a custom command that specifies how to produce ``Table.h``
by running MakeTable.

.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
  :caption: MathFunctions/MakeTable.cmake
  :name: MathFunctions/MakeTable.cmake-add_custom_command-Table.h
  :language: cmake
  :start-after: # add the command to generate the source code

Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
of sources for the library ``SqrtLibrary``.

.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
  :caption: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-add_library-Table.h
  :language: cmake
  :start-after:   # library that just does sqrt
  :end-before: # state that we depend on

We also have to add the current binary directory to the list of include
directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.

.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
  :caption: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
  :language: cmake
  :start-after: # state that we depend on our bin
  :end-before: target_link_libraries

As the last step, we need to include
``MakeTable.cmake`` at the top of the ``MathFunctions/CMakeLists.txt``.

.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
  :caption: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-include-MakeTable.cmake
  :language: cmake
  :start-after: # generate Table.h
  :end-before: # library that just does sqrt

Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:

.. literalinclude:: Step9/MathFunctions/mysqrt.cxx
  :caption: MathFunctions/mysqrt.cxx
  :name: MathFunctions/mysqrt.cxx
  :language: c++
  :start-after: // a hack square root calculation using simple operations

Run the :manual:`cmake  <cmake(1)>` executable or the
:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
with your chosen build tool.

When this project is built it will first build the ``MakeTable`` executable.
It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will
compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the
``MathFunctions`` library.

Run the Tutorial executable and verify that it is using the table.

repo_name: lazytadpole/codenamesilverfish

path: buildtools/windows/cmake/doc/cmake/html/_sources/guide/tutorial/Adding a Custom Command and Generated File.rst.txt

license: mit


code:
Step 2: Adding a Library
========================

At this point, we have seen how to create a basic project using CMake. In this
step, we will learn how to create and use a library in our project. We will
also see how to make the use of our library optional.

Exercise 1 - Creating a Library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To add a library in CMake, use the :command:`add_library` command and specify
which source files should make up the library.

Rather than placing all of the source files in one directory, we can organize
our project with one or more subdirectories. In this case, we will create a
subdirectory specifically for our library. Here, we can add a new
``CMakeLists.txt`` file and one or more source files. In the top level
``CMakeLists.txt`` file, we will use the :command:`add_subdirectory` command
to add the subdirectory to the build.

Once the library is created, it is connected to our executable target with
:command:`target_include_directories` and :command:`target_link_libraries`.

Goal
----

Add and use a library.

Helpful Resources
-----------------

* :command:`add_library`
* :command:`add_subdirectory`
* :command:`target_include_directories`
* :command:`target_link_libraries`
* :variable:`PROJECT_SOURCE_DIR`

Files to Edit
-------------

* ``CMakeLists.txt``
* ``tutorial.cxx``
* ``MathFunctions/CMakeLists.txt``

Getting Started
---------------

In this exercise, we will add a library to our project that contains our own
implementation for computing the square root of a number. The executable can
then use this library instead of the standard square root function provided by
the compiler.

For this tutorial we will put the library into a subdirectory called
``MathFunctions``. This directory already contains the header files
``MathFunctions.h`` and ``mysqrt.h``. Their respective source files
``MathFunctions.cxx`` and ``mysqrt.cxx`` are also provided. We will not need
to modify any of these files. ``mysqrt.cxx`` has one function called
``mysqrt`` that provides similar functionality to the compiler's ``sqrt``
function. ``MathFunctions.cxx`` contains one function ``sqrt`` which serves
to hide the implementation details of ``sqrt``.

From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and
complete through ``TODO 6``.

First, fill in the one line ``CMakeLists.txt`` in the ``MathFunctions``
subdirectory.

Next, edit the top level ``CMakeLists.txt``.

Finally, use the newly created ``MathFunctions`` library in ``tutorial.cxx``

Build and Run
-------------

Run the :manual:`cmake  <cmake(1)>` executable or the
:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
with your chosen build tool.

Below is a refresher of what that looks like from the command line:

.. code-block:: console

  mkdir Step2_build
  cd Step2_build
  cmake ../Step2
  cmake --build .

Try to use the newly built ``Tutorial`` and ensure that it is still
producing accurate square root values.

Solution
--------

In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
a library target called ``MathFunctions`` with :command:`add_library`. The
source files for the library are passed as an argument to
:command:`add_library`. This looks like the following line:

.. raw:: html

  TODO 1: Click to show/hide answer

.. code-block:: cmake
  :caption: TODO 1: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-add_library

  add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)

.. raw:: html

To make use of the new library we will add an :command:`add_subdirectory`
call in the top-level ``CMakeLists.txt`` file so that the library will get
built.

.. raw:: html

  TODO 2: Click to show/hide answer

.. code-block:: cmake
  :caption: TODO 2: CMakeLists.txt
  :name: CMakeLists.txt-add_subdirectory

  add_subdirectory(MathFunctions)

.. raw:: html

Next, the new library target is linked to the executable target using
:command:`target_link_libraries`.

.. raw:: html

  TODO 3: Click to show/hide answer

.. code-block:: cmake
  :caption: TODO 3: CMakeLists.txt
  :name: CMakeLists.txt-target_link_libraries

  target_link_libraries(Tutorial PUBLIC MathFunctions)

.. raw:: html

Finally we need to specify the library's header file location.
Modify the existing :command:`target_include_directories` call
to add the ``MathFunctions`` subdirectory as an include directory
so that the ``MathFunctions.h`` header file can be found.

.. raw:: html

  TODO 4: Click to show/hide answer

.. code-block:: cmake
  :caption: TODO 4: CMakeLists.txt
  :name: CMakeLists.txt-target_include_directories-step2

  target_include_directories(Tutorial PUBLIC
                            "${PROJECT_BINARY_DIR}"
                            "${PROJECT_SOURCE_DIR}/MathFunctions"
                            )

.. raw:: html

Now let's use our library. In ``tutorial.cxx``, include ``MathFunctions.h``:

.. raw:: html

  TODO 5: Click to show/hide answer

.. literalinclude:: Step3/tutorial.cxx
  :caption: TODO 5: tutorial.cxx
  :name: CMakeLists.txt-include-MathFunctions.h
  :language: cmake
  :start-after: #include <string>
  :end-before: #include "TutorialConfig.h"

.. raw:: html

Lastly, replace ``sqrt`` with the wrapper function ``mathfunctions::sqrt``.

.. raw:: html

  TODO 6: Click to show/hide answer

.. literalinclude:: Step3/tutorial.cxx
  :caption: TODO 6: tutorial.cxx
  :name: CMakeLists.txt-option
  :language: cmake
  :start-after:   const double inputValue = std::stod(argv[1]);
  :end-before: std::cout

.. raw:: html

Exercise 2 - Adding an Option
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Now let us add an option in the MathFunctions library to allow developers to
select either the custom square root implementation or the built in standard
implementation. While for the tutorial
there really isn't any need to do so, for larger projects this is a common
occurrence.

CMake can do this using the :command:`option` command. This gives users a
variable which they can change when configuring their cmake build. This
setting will be stored in the cache so that the user does not need to set
the value each time they run CMake on a build directory.

Goal
----

Add the option to build without ``MathFunctions``.

Helpful Resources
-----------------

* :command:`if`
* :command:`option`
* :command:`target_compile_definitions`

Files to Edit
-------------

* ``MathFunctions/CMakeLists.txt``
* ``MathFunctions/MathFunctions.cxx``

Getting Started
---------------

Start with the resulting files from Exercise 1. Complete ``TODO 7`` through
``TODO 14``.

First create a variable ``USE_MYMATH`` using the :command:`option` command
in ``MathFunctions/CMakeLists.txt``. In that same file, use that option
to pass a compile definition to the ``MathFunctions`` library.

Then, update ``MathFunctions.cxx`` to redirect compilation based on
``USE_MYMATH``.

Lastly, prevent ``mysqrt.cxx`` from being compiled when ``USE_MYMATH`` is on
by making it its own library inside of the ``USE_MYMATH`` block of
``MathFunctions/CMakeLists.txt``.

Build and Run
-------------

Since we have our build directory already configured from Exercise 1, we can
rebuild by simply calling the following:

.. code-block:: console

  cd ../Step2_build
  cmake --build .

Next, run the ``Tutorial`` executable on a few numbers to verify that it's
still correct.

Now let's update the value of ``USE_MYMATH`` to ``OFF``. The easiest way is to
use the :manual:`cmake-gui <cmake-gui(1)>` or  :manual:`ccmake <ccmake(1)>`
if you're in the terminal. Or, alternatively, if you want to change the
option from the command-line, try:

.. code-block:: console

  cmake ../Step2 -DUSE_MYMATH=OFF

Now, rebuild the code with the following:

.. code-block:: console

  cmake --build .

Then, run the executable again to ensure that it still works with
``USE_MYMATH`` set to ``OFF``. Which function gives better results, ``sqrt``
or ``mysqrt``?

Solution
--------

The first step is to add an option to ``MathFunctions/CMakeLists.txt``.
This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
:manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
changed by the user.

.. raw:: html

  TODO 7: Click to show/hide answer

.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
  :caption: TODO 7: MathFunctions/CMakeLists.txt
  :name: CMakeLists.txt-option-library-level
  :language: cmake
  :start-after: # should we use our own math functions
  :end-before: if (USE_MYMATH)

.. raw:: html

Next, make building and linking our library with ``mysqrt`` function
conditional using this new option.

Create an :command:`if` statement which checks the value of
``USE_MYMATH``. Inside the :command:`if` block, put the
:command:`target_compile_definitions` command with the compile
definition ``USE_MYMATH``.

.. raw:: html

  TODO 8: Click to show/hide answer

.. code-block:: cmake
  :caption: TODO 8: MathFunctions/CMakeLists.txt
  :name: CMakeLists.txt-USE_MYMATH

  if (USE_MYMATH)
    target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
  endif()

.. raw:: html

When ``USE_MYMATH`` is ``ON``, the compile definition ``USE_MYMATH`` will
be set. We can then use this compile definition to enable or disable
sections of our source code.

The corresponding changes to the source code are fairly straightforward.
In ``MathFunctions.cxx``, we make ``USE_MYMATH`` control which square root
function is used:

.. raw:: html

  TODO 9: Click to show/hide answer

.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
  :caption: TODO 9: MathFunctions/MathFunctions.cxx
  :name: MathFunctions-USE_MYMATH-if
  :language: c++
  :start-after: which square root function should we use?
  :end-before: }

.. raw:: html

Next, we need to include ``mysqrt.h`` if ``USE_MYMATH`` is defined.

.. raw:: html

  TODO 10: Click to show/hide answer

.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
  :caption: TODO 10: MathFunctions/MathFunctions.cxx
  :name: MathFunctions-USE_MYMATH-if-include
  :language: c++
  :start-after: include <cmath>
  :end-before: namespace mathfunctions

.. raw:: html

Finally, we need to include ``cmath`` now that we are using ``std::sqrt``.

.. raw:: html

  TODO 11: Click to show/hide answer

.. code-block:: c++
  :caption: TODO 11 : MathFunctions/MathFunctions.cxx
  :name: tutorial.cxx-include_cmath

  #include <cmath>

.. raw:: html

At this point, if ``USE_MYMATH`` is ``OFF``, ``mysqrt.cxx`` would not be used
but it will still be compiled because the ``MathFunctions`` target has
``mysqrt.cxx`` listed under sources.

There are a few ways to fix this. The first option is to use
:command:`target_sources` to add ``mysqrt.cxx`` from within the ``USE_MYMATH``
block. Another option is to create an additional library within the
``USE_MYMATH`` block which is responsible for compiling ``mysqrt.cxx``. For
the sake of this tutorial, we are going to create an additional library.

First, from within ``USE_MYMATH`` create a library called ``SqrtLibrary``
that has sources ``mysqrt.cxx``.

.. raw:: html

  TODO 12: Click to show/hide answer

.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
  :caption: TODO 12 : MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-add_library-SqrtLibrary
  :language: cmake
  :start-after: # library that just does sqrt
  :end-before: # TODO 7: Link

.. raw:: html

Next, we link ``SqrtLibrary`` onto ``MathFunctions`` when ``USE_MYMATH`` is
enabled.

.. raw:: html

  TODO 13: Click to show/hide answer

.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
  :caption: TODO 13 : MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-target_link_libraries-SqrtLibrary
  :language: cmake
  :start-after: to tutorial_compiler_flags
  :end-before: endif()

.. raw:: html

Finally, we can remove ``mysqrt.cxx`` from our ``MathFunctions`` library
source list because it will be pulled in when ``SqrtLibrary`` is included.

.. raw:: html

  TODO 14: Click to show/hide answer

.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
  :caption: TODO 14 : MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-remove-mysqrt.cxx-MathFunctions
  :language: cmake
  :end-before: # TODO 1:

.. raw:: html

With these changes, the ``mysqrt`` function is now completely optional to
whoever is building and using the ``MathFunctions`` library. Users can toggle
``USE_MYMATH`` to manipulate what library is used in the build.


code:
Step 5: Installing and Testing
==============================

Exercise 1 - Install Rules
^^^^^^^^^^^^^^^^^^^^^^^^^^

Often, it is not enough to only build an executable, it should also be
installable. With CMake, we can specify install rules using the
:command:`install` command. Supporting local installations for your builds in
CMake is often as simple as specifying an install location and the targets and
files to be installed.

Goal
----

Install the ``Tutorial`` executable and the ``MathFunctions`` library.

Helpful Materials
-----------------

* :command:`install`

Files to Edit
-------------

* ``MathFunctions/CMakeLists.txt``
* ``CMakeLists.txt``

Getting Started
---------------

The starting code is provided in the ``Step5`` directory. In this
exercise, complete ``TODO 1`` through ``TODO 4``.

First, update ``MathFunctions/CMakeLists.txt`` to install the
``MathFunctions`` and ``tutorial_compiler_flags`` libraries to the ``lib``
directory. In that same file, specify the install rules needed to install
``MathFunctions.h`` to the ``include`` directory.

Then, update the top level ``CMakeLists.txt`` to install
the ``Tutorial`` executable to the ``bin`` directory. Lastly, any header files
should be installed to the ``include`` directory. Remember that
``TutorialConfig.h`` is in the :variable:`PROJECT_BINARY_DIR`.

Build and Run
-------------

Make a new directory called ``Step5_build``. Run the
:manual:`cmake <cmake(1)>` executable or the
:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
with your chosen build tool.

Then, run the install step by using the :option:`--install <cmake --install>`
option of the :manual:`cmake  <cmake(1)>` command (introduced in 3.15, older
versions of CMake must use ``make install``) from the command line. This step
will install the appropriate header files, libraries, and executables.
For example:

.. code-block:: console

  cmake --install .

For multi-configuration tools, don't forget to use the
:option:`--config <cmake--build --config>` argument to specify the configuration.

.. code-block:: console

  cmake --install . --config Release

If using an IDE, simply build the ``INSTALL`` target. You can build the same
install target from the command line like the following:

.. code-block:: console

  cmake --build . --target install --config Debug

The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
root of where the files will be installed. If using the :option:`cmake --install`
command, the installation prefix can be overridden via the
:option:`--prefix <cmake--install --prefix>` argument. For example:

.. code-block:: console

  cmake --install . --prefix "/home/myuser/installdir"

Navigate to the install directory and verify that the installed ``Tutorial``
runs.

Solution
--------

The install rules for our project are fairly simple:

* For ``MathFunctions``, we want to install the libraries and header file to
  the ``lib`` and ``include`` directories respectively.

* For the ``Tutorial`` executable, we want to install the executable and
  configured header file to the ``bin`` and ``include`` directories
  respectively.

So to the end of ``MathFunctions/CMakeLists.txt`` we add:

.. raw:: html

  TODO 1: Click to show/hide answer

.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  :caption: TODO 1: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-install-TARGETS
  :language: cmake
  :start-after: # install libs
  :end-before: # install include headers

.. raw:: html

and

.. raw:: html

  TODO 2: Click to show/hide answer

.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  :caption: TODO 2: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-install-headers
  :language: cmake
  :start-after: # install include headers

.. raw:: html

The install rules for the ``Tutorial`` executable and configured header file
are similar. To the end of the top-level ``CMakeLists.txt`` we add:

.. raw:: html

  TODO 3,4: Click to show/hide answer

.. literalinclude:: Step6/CMakeLists.txt
  :caption: CMakeLists.txt
  :name: TODO 3,4: CMakeLists.txt-install-TARGETS
  :language: cmake
  :start-after: # add the install targets
  :end-before: # TODO 1: Replace enable_testing() with include(CTest)

.. raw:: html

That is all that is needed to create a basic local
install of the tutorial.

.. _`Tutorial Testing Support`:

Exercise 2 - Testing Support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

CTest offers a way to easily manage tests for your project. Tests can be
added through the :command:`add_test` command. Although it is not
explicitly covered in this tutorial, there is a lot of compatibility
between CTest and other testing frameworks such as :module:`GoogleTest`.

Goal
----

Create unit tests for our executable using CTest.

Helpful Materials
-----------------

* :command:`enable_testing`
* :command:`add_test`
* :command:`function`
* :command:`set_tests_properties`
* :manual:`ctest <ctest(1)>`

Files to Edit
-------------

* ``CMakeLists.txt``

Getting Started
---------------

The starting source code is provided in the ``Step5`` directory. In this
exercise, complete ``TODO 5`` through ``TODO 9``.

First, we need to enable testing. Next, begin adding tests to our project
using :command:`add_test`. We will work through adding 3 simple tests and
then you can add additional testing as you see fit.

Build and Run
-------------

Navigate to the build directory and rebuild the application. Then, run the
:program:`ctest` executable: :option:`ctest -N` and :option:`ctest -VV`. For
multi-config generators (e.g. Visual Studio), the configuration type must be
specified with the :option:`-C \<mode\> <ctest -C>` flag.  For example, to run tests in Debug
mode use ``ctest -C Debug -VV`` from the build directory
(not the Debug subdirectory!). Release mode would be executed from the same
location but with a ``-C Release``. Alternatively, build the ``RUN_TESTS``
target from the IDE.

Solution
--------

Let's test our application. At the end of the top-level ``CMakeLists.txt``
file we first need to enable testing with the
:command:`enable_testing` command.

.. raw:: html

  TODO 5: Click to show/hide answer

.. literalinclude:: Step6/CMakeLists.txt
  :caption: TODO 5: CMakeLists.txt
  :name: CMakeLists.txt-enable_testing
  :language: cmake
  :start-after: # enable testing
  :end-before: # does the application run

.. raw:: html

With testing enabled, we will add a number of basic tests to verify
that the application is working correctly. First, we create a test using
:command:`add_test` which runs the ``Tutorial`` executable with the
parameter 25 passed in. For this test, we are not going to check the
executable's computed answer. This test will verify that
application runs, does not segfault or otherwise crash, and has a zero
return value. This is the basic form of a CTest test.

.. raw:: html

  TODO 6: Click to show/hide answer

.. literalinclude:: Step6/CMakeLists.txt
  :caption: TODO 6: CMakeLists.txt
  :name: CMakeLists.txt-test-runs
  :language: cmake
  :start-after: # does the application run
  :end-before: # does the usage message work

.. raw:: html

Next, let's use the :prop_test:`PASS_REGULAR_EXPRESSION` test property to
verify that the output of the test contains certain strings. In this case,
verifying that the usage message is printed when an incorrect number of
arguments are provided.

.. raw:: html

  TODO 7: Click to show/hide answer

.. literalinclude:: Step6/CMakeLists.txt
  :caption: TODO 7: CMakeLists.txt
  :name: CMakeLists.txt-test-usage
  :language: cmake
  :start-after: # does the usage message work?
  :end-before: # define a function to simplify adding tests

.. raw:: html

The next test we will add verifies the computed value is truly the
square root.

.. raw:: html

  TODO 8: Click to show/hide answer

.. code-block:: cmake
  :caption: TODO 8: CMakeLists.txt
  :name: CMakeLists.txt-test-standard

  add_test(NAME StandardUse COMMAND Tutorial 4)
  set_tests_properties(StandardUse
    PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
    )

.. raw:: html

This one test is not enough to give us confidence that it will
work for all values passed in. We should add more tests to verify this.
To easily add more tests, we make a function called ``do_test`` that runs the
application and verifies that the computed square root is correct for
given input. For each invocation of ``do_test``, another test is added to
the project with a name, input, and expected results based on the passed
arguments.

.. raw:: html

  TODO 9: Click to show/hide answer

.. literalinclude:: Step6/CMakeLists.txt
  :caption: TODO 9: CMakeLists.txt
  :name: CMakeLists.txt-generalized-tests
  :language: cmake
  :start-after: # define a function to simplify adding tests

.. raw:: html


code:
Step 12: Packaging Debug and Release
====================================

**Note:** This example is valid for single-configuration generators and will
not work for multi-configuration generators (e.g. Visual Studio).

By default, CMake's model is that a build directory only contains a single
configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is
possible, however, to setup CPack to bundle multiple build directories and
construct a package that contains multiple configurations of the same project.

First, we want to ensure that the debug and release builds use different names
for the libraries that will be installed. Let's use `d` as the
postfix for the debug libraries.

Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level
``CMakeLists.txt`` file:

.. literalinclude:: Complete/CMakeLists.txt
  :caption: CMakeLists.txt
  :name: CMakeLists.txt-CMAKE_DEBUG_POSTFIX-variable
  :language: cmake
  :start-after: project(Tutorial VERSION 1.0)
  :end-before: target_compile_features(tutorial_compiler_flags

And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable:

.. literalinclude:: Complete/CMakeLists.txt
  :caption: CMakeLists.txt
  :name: CMakeLists.txt-DEBUG_POSTFIX-property
  :language: cmake
  :start-after: # add the executable
  :end-before: # add the binary tree to the search path for include files

Let's also add version numbering to the ``MathFunctions`` library. In
``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and
:prop_tgt:`SOVERSION` properties:

.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
  :caption: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-VERSION-properties
  :language: cmake
  :start-after: # setup the version numbering
  :end-before: # install libs

From the ``Step12`` directory, create ``debug`` and ``release``
subdirectories. The layout will look like:

.. code-block:: none

  - Step12
     - debug
     - release

Now we need to setup debug and release builds. We can use
:variable:`CMAKE_BUILD_TYPE` to set the configuration type:

.. code-block:: console

  cd debug
  cmake -DCMAKE_BUILD_TYPE=Debug ..
  cmake --build .
  cd ../release
  cmake -DCMAKE_BUILD_TYPE=Release ..
  cmake --build .

Now that both the debug and release builds are complete, we can use a custom
configuration file to package both builds into a single release. In the
``Step12`` directory, create a file called ``MultiCPackConfig.cmake``. In this
file, first include the default configuration file that was created by the
:manual:`cmake  <cmake(1)>` executable.

Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which
projects to install. In this case, we want to install both debug and release.

.. literalinclude:: Complete/MultiCPackConfig.cmake
  :caption: MultiCPackConfig.cmake
  :name: MultiCPackConfig.cmake
  :language: cmake

From the ``Step12`` directory, run :manual:`cpack <cpack(1)>` specifying our
custom configuration file with the ``config`` option:

.. code-block:: console

  cpack --config MultiCPackConfig.cmake

path: buildtools/windows/cmake/doc/cmake/html/_sources/guide/tutorial/Packaging Debug and Release.rst.txt


code:
Step 9: Packaging an Installer
==============================

Next suppose that we want to distribute our project to other people so that
they can use it. We want to provide both binary and source distributions on a
variety of platforms. This is a little different from the install we did
previously in :guide:`tutorial/Installing and Testing`, where we were
installing the binaries that we had built from the source code. In this
example we will be building installation packages that support binary
installations and package management features. To accomplish this we will use
CPack to create platform specific installers. Specifically we need to add a
few lines to the bottom of our top-level ``CMakeLists.txt`` file.

.. literalinclude:: Step10/CMakeLists.txt
  :caption: CMakeLists.txt
  :name: CMakeLists.txt-include-CPack
  :language: cmake
  :start-after: # setup installer

That is all there is to it. We start by including
:module:`InstallRequiredSystemLibraries`. This module will include any runtime
libraries that are needed by the project for the current platform. Next we set
some CPack variables to where we have stored the license and version
information for this project. The version information was set earlier in this
tutorial and the ``License.txt`` has been included in the top-level source
directory for this step.  The :variable:`CPACK_SOURCE_GENERATOR` variable
selects a file format for the source package.

Finally we include the :module:`CPack module <CPack>` which will use these
variables and some other properties of the current system to setup an
installer.

The next step is to build the project in the usual manner and then run the
:manual:`cpack <cpack(1)>` executable. To build a binary distribution, from the
binary directory run:

.. code-block:: console

  cpack

To specify the generator, use the :option:`-G <cpack -G>` option. For multi-config builds,
use :option:`-C <cpack -C>` to specify the configuration. For example:

.. code-block:: console

  cpack -G ZIP -C Debug

For a list of available generators, see :manual:`cpack-generators(7)` or call
:option:`cpack --help`. An :cpack_gen:`archive generator <CPack Archive Generator>`
like ZIP creates a compressed archive of all *installed* files.

To create an archive of the *full* source tree you would type:

.. code-block:: console

  cpack --config CPackSourceConfig.cmake

Alternatively, run ``make package`` or right click the ``Package`` target and
``Build Project`` from an IDE.

Run the installer found in the binary directory. Then run the installed
executable and verify that it works.


code:
Step 10: Selecting Static or Shared Libraries
=============================================

In this section we will show how the :variable:`BUILD_SHARED_LIBS` variable can
be used to control the default behavior of :command:`add_library`,
and allow control over how libraries without an explicit type (``STATIC``,
``SHARED``, ``MODULE`` or ``OBJECT``) are built.

To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
users to optionally select if the value should be ``ON`` or ``OFF``.

.. literalinclude:: Step11/CMakeLists.txt
  :caption: CMakeLists.txt
  :name: CMakeLists.txt-option-BUILD_SHARED_LIBS
  :language: cmake
  :start-after: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
  :end-before: # configure a header file to pass the version number only

Next, we need to specify output directories for our static and shared
libraries.

.. literalinclude:: Step11/CMakeLists.txt
  :caption: CMakeLists.txt
  :name: CMakeLists.txt-cmake-output-directories
  :language: cmake
  :start-after: # we don't need to tinker with the path to run the executable
  :end-before: # configure a header file to pass the version number only

Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:

.. literalinclude:: Step11/MathFunctions/MathFunctions.h
  :caption: MathFunctions/MathFunctions.h
  :name: MathFunctions/MathFunctions.h
  :language: c++

At this point, if you build everything, you may notice that linking fails
as we are combining a static library without position independent code with a
library that has position independent code. The solution to this is to
explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
SqrtLibrary to be ``True`` when building shared libraries.

.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
  :caption: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-POSITION_INDEPENDENT_CODE
  :language: cmake
  :start-at: # state that SqrtLibrary need PIC when the default is shared libraries
  :end-at:  )

Define ``EXPORTING_MYMATH`` stating we are using ``declspec(dllexport)`` when
building on Windows.

.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
  :caption: MathFunctions/CMakeLists.txt
  :name: MathFunctions/CMakeLists.txt-dll-export
  :language: cmake
  :start-at: # define the symbol stating we are using the declspec(dllexport) when
  :end-at: target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")

**Exercise**: We modified ``MathFunctions.h`` to use dll export defines.
Using CMake documentation can you find a helper module to simplify this?

path: buildtools/windows/cmake/doc/cmake/html/_sources/guide/tutorial/Selecting Static or Shared Libraries.rst.txt


code:
CMake Tutorial
**************

Introduction
============

The CMake tutorial provides a step-by-step guide that covers common build
system issues that CMake helps address. Seeing how various topics all
work together in an example project can be very helpful.

Steps
=====

.. include:: source.txt

|tutorial_source|
Each step has its own subdirectory containing code that may be used as a
starting point. The tutorial examples are progressive so that each step
provides the complete solution for the previous step.

.. toctree::
  :maxdepth: 2

  A Basic Starting Point
  Adding a Library
  Adding Usage Requirements for a Library
  Adding Generator Expressions
  Installing and Testing
  Adding Support for a Testing Dashboard
  Adding System Introspection
  Adding a Custom Command and Generated File
  Packaging an Installer
  Selecting Static or Shared Libraries
  Adding Export Configuration
  Packaging Debug and Release

..
  Whenever a step above is renamed or removed, leave forwarding text in
  its original document file, and list it below to preserve old links
  to cmake.org/cmake/help/latest/ URLs.

.. toctree::
  :maxdepth: 1
  :hidden:


code:
User Interaction Guide
**********************

.. only:: html

   .. contents::

Introduction
============

Where a software package supplies a CMake-based buildsystem
with the source of their software, the consumer of the
software is required to run a CMake user interaction tool
in order to build it.

Well-behaved CMake-based buildsystems do not create any
output in the source directory, so typically, the user
performs an out-of-source build and performs the build
there.  First, CMake must be instructed to generate a
suitable buildsystem, then the user invokes a build tool
to process that generated buildsystem.  The generated
buildsystem is specific to the machine used to generate
it and is not redistributable.  Each consumer of a provided
source software package is required to use CMake to
generate a buildsystem specific to their system.

Generated buildsystems should generally be treated as
read-only. The CMake files as a primary artifact should
completely specify the buildsystem and there should be no
reason to populate properties manually in an IDE for
example after generating the buildsystem.  CMake will
periodically rewrite the generated buildsystem, so
modifications by users will be overwritten.

The features and user interfaces described in this manual
are available for all CMake-based build systems by virtue
of providing CMake files.

The CMake tooling may report errors to the user when
processing provided CMake files, such as reporting that
the compiler is not supported, or the compiler does not
support a required compile option, or a dependency can
not be found.  These errors must be resolved by the user
by choosing a different compiler,
:guide:`installing dependencies <Using Dependencies Guide>`,
or instructing CMake where to find them, etc.

Command Line cmake tool
-----------------------

A simple but typical use of :manual:`cmake(1)` with a fresh
copy of software source code is to create a build directory
and invoke cmake there:

.. code-block:: console

  $ cd some_software-1.4.2
  $ mkdir build
  $ cd build
  $ cmake .. -DCMAKE_INSTALL_PREFIX=/opt/the/prefix
  $ cmake --build .
  $ cmake --build . --target install

It is recommended to build in a separate directory to the
source because that keeps the source directory pristine,
allows for building a single source with multiple
toolchains, and allows easy clearing of build artifacts by
simply deleting the build directory.

The CMake tooling may report warnings which are intended
for the provider of the software, not intended for the
consumer of the software.  Such warnings end with "This
warning is for project developers".  Users may disable
such warnings by passing the :option:`-Wno-dev <cmake -Wno-dev>`
flag to :manual:`cmake(1)`.

cmake-gui tool
--------------

Users more accustomed to GUI interfaces may use the
:manual:`cmake-gui(1)` tool to invoke CMake and generate
a buildsystem.

The source and binary directories must first be
populated.  It is always advised to use different
directories for the source and the build.

.. image:: GUI-Source-Binary.png
   :alt: Choosing source and binary directories

Generating a Buildsystem
========================

There are several user interface tools which may be used
to generate a buildsystem from CMake files.  The
:manual:`ccmake(1)` and :manual:`cmake-gui(1)` tools guide
the user through setting the various necessary options.
The :manual:`cmake(1)` tool can be invoked to specify
options on the command line.  This manual describes options
which may be set using any of the user interface tools,
though the mode of setting an option is different for each
tool.

Command line environment
------------------------

When invoking :manual:`cmake(1)` with a command line
buildsystem such as ``Makefiles`` or ``Ninja``, it is
necessary to use the correct build environment to
ensure that build tools are available. CMake must be
able to find the appropriate
:variable:`build tool <CMAKE_MAKE_PROGRAM>`,
compiler, linker and other tools as needed.

On Linux systems, the appropriate tools are often
provided in system-wide locations and may be readily
installed through the system package manager. Other
toolchains provided by the user or installed in
non-default locations can also be used.

When cross-compiling, some platforms may require
environment variables to be set or may provide
scripts to set the environment.

Visual Studio ships multiple command prompts and
``vcvarsall.bat`` scripts for setting up the
correct environments for command line buildsystems. While
not strictly necessary to use a corresponding
command line environment when using a Visual Studio
generator, doing so has no disadvantages.

When using Xcode, there can be more than one Xcode
version installed.  Which one to use can be selected
in a number of different ways, but the most common
methods are:

* Setting the default version in the preferences
  of the Xcode IDE.
* Setting the default version via the ``xcode-select``
  command line tool.
* Overriding the default version by setting the
  ``DEVELOPER_DIR`` environment variable when running
  CMake and the build tool.

For convenience, :manual:`cmake-gui(1)` provides an
environment variable editor.

Command line ``-G`` option
--------------------------

CMake chooses a generator by default based on the
platform.  Usually, the default generator is sufficient
to allow the user to proceed to build the software.

The user may override the default generator with
the :option:`-G <cmake -G>` option:

.. code-block:: console

  $ cmake .. -G Ninja

The output of :option:`cmake --help` includes a list of
:manual:`generators <cmake-generators(7)>` available
for the user to choose from.  Note that generator
names are case sensitive.

On Unix-like systems (including Mac OS X), the
:generator:`Unix Makefiles` generator is used by
default.  A variant of that generator can also be used
on Windows in various environments, such as the
:generator:`NMake Makefiles` and
:generator:`MinGW Makefiles` generator.  These generators
generate a ``Makefile`` variant which can be executed
with ``make``, ``gmake``, ``nmake`` or similar tools.
See the individual generator documentation for more
information on targeted environments and tools.

The :generator:`Ninja` generator is available on all
major platforms. ``ninja`` is a build tool similar
in use-cases to ``make``, but with a focus on
performance and efficiency.

On Windows, :manual:`cmake(1)` can be used to generate
solutions for the Visual Studio IDE.  Visual Studio
versions may be specified by the product name of the
IDE, which includes a four-digit year.  Aliases are
provided for other means by which Visual Studio
versions are sometimes referred to, such as two
digits which correspond to the product version of the
VisualC++ compiler, or a combination of the two:

.. code-block:: console

  $ cmake .. -G "Visual Studio 2019"
  $ cmake .. -G "Visual Studio 16"
  $ cmake .. -G "Visual Studio 16 2019"

Visual Studio generators can target different architectures.
One can specify the target architecture using the
:option:`-A <cmake -A>` option:

.. code-block:: console

  cmake .. -G "Visual Studio 2019" -A x64
  cmake .. -G "Visual Studio 16" -A ARM
  cmake .. -G "Visual Studio 16 2019" -A ARM64

On Apple, the :generator:`Xcode` generator may be used to
generate project files for the Xcode IDE.

Some IDEs such as KDevelop4, QtCreator and CLion have
native support for CMake-based buildsystems.  Those IDEs
provide user interface for selecting an underlying
generator to use, typically a choice between a ``Makefile``
or a ``Ninja`` based generator.

Note that it is not possible to change the generator
with :option:`-G <cmake -G>` after the first invocation of CMake.
To change the generator, the build directory must be
deleted and the build must be started from scratch.

When generating Visual Studio project and solutions
files several other options are available to use when
initially running :manual:`cmake(1)`.

The Visual Studio toolset can be specified with the
:option:`cmake -T` option:

.. code-block:: console

    $ # Build with the clang-cl toolset
    $ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T ClangCL
    $ # Build targeting Windows XP
    $ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T v120_xp

Whereas the :option:`-A <cmake -A>` option specifies the _target_
architecture, the :option:`-T <cmake -T>` option can be used to specify
details of the toolchain used.  For example, ``-Thost=x64``
can be given to select the 64-bit version of the host
tools.  The following demonstrates how to use 64-bit
tools and also build for a 64-bit target architecture:

.. code-block:: console

    $ cmake .. -G "Visual Studio 16 2019" -A x64 -Thost=x64

Choosing a generator in cmake-gui
---------------------------------

The "Configure" button triggers a new dialog to
select the CMake generator to use.

.. image:: GUI-Configure-Dialog.png
   :alt: Configuring a generator

All generators available on the command line are also
available in :manual:`cmake-gui(1)`.

.. image:: GUI-Choose-Generator.png
   :alt: Choosing a generator

When choosing a Visual Studio generator, further options
are available to set an architecture to generate for.

.. image:: VS-Choose-Arch.png
   :alt: Choosing an architecture for Visual Studio generators

.. _`Setting Build Variables`:

Setting Build Variables
=======================

Software projects often require variables to be
set on the command line when invoking CMake.  Some of
the most commonly used CMake variables are listed in
the table below:

========================================== ============================================================
 Variable                                   Meaning
========================================== ============================================================
 :variable:`CMAKE_PREFIX_PATH`              Path to search for
                                            :guide:`dependent packages <Using Dependencies Guide>`
 :variable:`CMAKE_MODULE_PATH`              Path to search for additional CMake modules
 :variable:`CMAKE_BUILD_TYPE`               Build configuration, such as
                                            ``Debug`` or ``Release``, determining
                                            debug/optimization flags.  This is only
                                            relevant for single-configuration buildsystems such
                                            as ``Makefile`` and ``Ninja``.  Multi-configuration
                                            buildsystems such as those for Visual Studio and Xcode
                                            ignore this setting.
 :variable:`CMAKE_INSTALL_PREFIX`           Location to install the
                                            software to with the
                                            ``install`` build target
 :variable:`CMAKE_TOOLCHAIN_FILE`           File containing cross-compiling
                                            data such as
                                            :manual:`toolchains and sysroots <cmake-toolchains(7)>`.
 :variable:`BUILD_SHARED_LIBS`              Whether to build shared
                                            instead of static libraries
                                            for :command:`add_library`
                                            commands used without a type
 :variable:`CMAKE_EXPORT_COMPILE_COMMANDS`  Generate a ``compile_commands.json``
                                            file for use with clang-based tools
========================================== ============================================================

Other project-specific variables may be available
to control builds, such as enabling or disabling
components of the project.

There is no convention provided by CMake for how
such variables are named between different
provided buildsystems, except that variables with
the prefix ``CMAKE_`` usually refer to options
provided by CMake itself and should not be used
in third-party options, which should use
their own prefix instead.  The
:manual:`cmake-gui(1)` tool can display options
in groups defined by their prefix, so it makes
sense for third parties to ensure that they use a
self-consistent prefix.

Setting variables on the command line
-------------------------------------

CMake variables can be set on the command line either
when creating the initial build:

.. code-block:: console

    $ mkdir build
    $ cd build
    $ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug

or later on a subsequent invocation of
:manual:`cmake(1)`:

.. code-block:: console

    $ cd build
    $ cmake . -DCMAKE_BUILD_TYPE=Debug

The :option:`-U <cmake -U>` flag may be used to unset variables
on the :manual:`cmake(1)` command line:

.. code-block:: console

    $ cd build
    $ cmake . -UMyPackage_DIR

A CMake buildsystem which was initially created
on the command line can be modified using the
:manual:`cmake-gui(1)` and vice-versa.

The :manual:`cmake(1)` tool allows specifying a
file to use to populate the initial cache using
the :option:`-C <cmake -C>` option.  This can be useful to simplify
commands and scripts which repeatedly require the
same cache entries.

Setting variables with cmake-gui
--------------------------------

Variables may be set in the cmake-gui using the "Add Entry"
button.  This triggers a new dialog to set the value of
the variable.

.. image:: GUI-Add-Entry.png
   :alt: Editing a cache entry

The main view of the :manual:`cmake-gui(1)` user interface
can be used to edit existing variables.

The CMake Cache
---------------

When CMake is executed, it needs to find the locations of
compilers, tools and dependencies.  It also needs to be
able to consistently re-generate a buildsystem to use the
same compile/link flags and paths to dependencies.  Such
parameters are also required to be configurable by the
user because they are paths and options specific to the
users system.

When it is first executed, CMake generates a
``CMakeCache.txt`` file in the build directory containing
key-value pairs for such artifacts.  The cache file can be
viewed or edited by the user by running the
:manual:`cmake-gui(1)` or :manual:`ccmake(1)` tool.  The
tools provide an interactive interface for re-configuring
the provided software and re-generating the buildsystem,
as is needed after editing cached values.  Each cache
entry may have an associated short help text which is
displayed in the user interface tools.

The cache entries may also have a type to signify how it
should be presented in the user interface.  For example,
a cache entry of type ``BOOL`` can be edited by a
checkbox in a user interface, a ``STRING`` can be edited
in a text field, and a ``FILEPATH`` while similar to a
``STRING`` should also provide a way to locate filesystem
paths using a file dialog.  An entry of type ``STRING``
may provide a restricted list of allowed values which are
then provided in a drop-down menu in the
:manual:`cmake-gui(1)` user interface (see the
:prop_cache:`STRINGS` cache property).

The CMake files shipped with a software package may also
define boolean toggle options using the :command:`option`
command.  The command creates a cache entry which has a
help text and a default value.  Such cache entries are
typically specific to the provided software and affect
the configuration of the build, such as whether tests
and examples are built, whether to build with exceptions
enabled etc.

Presets
=======

CMake understands a file, ``CMakePresets.json``, and its
user-specific counterpart, ``CMakeUserPresets.json``, for
saving presets for commonly-used configure settings. These
presets can set the build directory, generator, cache
variables, environment variables, and other command-line
options. All of these options can be overridden by the
user. The full details of the ``CMakePresets.json`` format
are listed in the :manual:`cmake-presets(7)` manual.

Using presets on the command-line
---------------------------------

When using the :manual:`cmake(1)` command line tool, a
preset can be invoked by using the :option:`--preset <cmake --preset>`
option. If :option:`--preset <cmake --preset>` is specified,
the generator and build directory are not required, but can be
specified to override them. For example, if you have the following
``CMakePresets.json`` file:

.. code-block:: json

  {
    "version": 1,
    "configurePresets": [
      {
        "name": "ninja-release",
        "binaryDir": "${sourceDir}/build/${presetName}",
        "generator": "Ninja",
        "cacheVariables": {
          "CMAKE_BUILD_TYPE": "Release"
        }
      }
    ]
  }

and you run the following:

.. code-block:: console

  cmake -S /path/to/source --preset=ninja-release

This will generate a build directory in
``/path/to/source/build/ninja-release`` with the
:generator:`Ninja` generator, and with
:variable:`CMAKE_BUILD_TYPE` set to ``Release``.

If you want to see the list of available presets, you can
run:

.. code-block:: console

  cmake -S /path/to/source --list-presets

This will list the presets available in
``/path/to/source/CMakePresets.json`` and
``/path/to/source/CMakeUsersPresets.json`` without
generating a build tree.

Using presets in cmake-gui
--------------------------

If a project has presets available, either through
``CMakePresets.json`` or ``CMakeUserPresets.json``, the
list of presets will appear in a drop-down menu in
:manual:`cmake-gui(1)` between the source directory and
the binary directory. Choosing a preset sets the binary
directory, generator, environment variables, and cache
variables, but all of these options can be overridden after
a preset is selected.

Invoking the Buildsystem
========================

After generating the buildsystem, the software can be
built by invoking the particular build tool.  In the
case of the IDE generators, this can involve loading
the generated project file into the IDE to invoke the
build.

CMake is aware of the specific build tool needed to invoke
a build so in general, to build a buildsystem or project
from the command line after generating, the following
command may be invoked in the build directory:

.. code-block:: console

  $ cmake --build .

The :option:`--build <cmake --build>` flag enables a
particular mode of operation for the :manual:`cmake(1)`
tool.  It invokes the  :variable:`CMAKE_MAKE_PROGRAM`
command associated with the
:manual:`generator <cmake-generators(7)>`, or
the build tool configured by the user.

The :option:`--build <cmake --build>` mode also accepts
the parameter :option:`--target <cmake--build --target>` to
specify a particular target to build, for example a
particular library, executable or custom target, or a
particular special target like ``install``:

.. code-block:: console

  $ cmake --build . --target myexe

The :option:`--build <cmake --build>` mode also accepts a
:option:`--config <cmake--build --config>` parameter
in the case of multi-config generators to specify which
particular configuration to build:

.. code-block:: console

  $ cmake --build . --target myexe --config Release

The :option:`--config <cmake--build --config>` option has no
effect if the generator generates a buildsystem specific
to a configuration which is chosen when invoking cmake
with the :variable:`CMAKE_BUILD_TYPE` variable.

Some buildsystems omit details of command lines invoked
during the build.  The :option:`--verbose <cmake--build --verbose>`
flag can be used to cause those command lines to be shown:

.. code-block:: console

  $ cmake --build . --target myexe --verbose

The :option:`--build <cmake --build>` mode can also pass
particular command line options to the underlying build
tool by listing them after ``--``.  This can be useful
to specify options to the build tool, such as to continue the
build after a failed job, where CMake does not
provide a high-level user interface.

For all generators, it is possible to run the underlying
build tool after invoking CMake.  For example, ``make``
may be executed after generating with the
:generator:`Unix Makefiles` generator to invoke the build,
or ``ninja`` after generating with the :generator:`Ninja`
generator etc.  The IDE buildsystems usually provide
command line tooling for building a project which can
also be invoked.

Selecting a Target
------------------

Each executable and library described in the CMake files
is a build target, and the buildsystem may describe
custom targets, either for internal use, or for user
consumption, for example to create documentation.

CMake provides some built-in targets for all buildsystems
providing CMake files.

``all``
  The default target used by ``Makefile`` and ``Ninja``
  generators.  Builds all targets in the buildsystem,
  except those which are excluded by their
  :prop_tgt:`EXCLUDE_FROM_ALL` target property or
  :prop_dir:`EXCLUDE_FROM_ALL` directory property.  The
  name ``ALL_BUILD`` is used for this purpose for the
  Xcode and Visual Studio generators.
``help``
  Lists the targets available for build.  This target is
  available when using the :generator:`Unix Makefiles` or
  :generator:`Ninja` generator, and the exact output is
  tool-specific.
``clean``
  Delete built object files and other output files.  The
  ``Makefile`` based generators create a ``clean`` target
  per directory, so that an individual directory can be
  cleaned.  The ``Ninja`` tool provides its own granular
  ``-t clean`` system.
``test``
  Runs tests.  This target is only automatically available
  if the CMake files provide CTest-based tests.  See also
  `Running Tests`_.
``install``
  Installs the software.  This target is only automatically
  available if the software defines install rules with the
  :command:`install` command.  See also
  `Software Installation`_.
``package``
  Creates a binary package.  This target is only
  automatically available if the CMake files provide
  CPack-based packages.
``package_source``
  Creates a source package.  This target is only
  automatically available if the CMake files provide
  CPack-based packages.

For ``Makefile`` based systems, ``/fast`` variants of binary
build targets are provided. The ``/fast`` variants are used
to build the specified target without regard for its
dependencies.  The dependencies are not checked and
are not rebuilt if out of date.  The :generator:`Ninja`
generator is sufficiently fast at dependency checking that
such targets are not provided for that generator.

``Makefile`` based systems also provide build-targets to
preprocess, assemble and compile individual files in a
particular directory.

.. code-block:: console

  $ make foo.cpp.i
  $ make foo.cpp.s
  $ make foo.cpp.o

The file extension is built into the name of the target
because another file with the same name but a different
extension may exist.  However, build-targets without the
file extension are also provided.

.. code-block:: console

  $ make foo.i
  $ make foo.s
  $ make foo.o

In buildsystems which contain ``foo.c`` and ``foo.cpp``,
building the ``foo.i`` target will preprocess both files.

Specifying a Build Program
--------------------------

The program invoked by the :option:`--build <cmake --build>`
mode is determined by the :variable:`CMAKE_MAKE_PROGRAM` variable.
For most generators, the particular program does not need to be
configured.

===================== =========================== ===========================
      Generator           Default make program           Alternatives
===================== =========================== ===========================
 XCode                 ``xcodebuild``
 Unix Makefiles        ``make``
 NMake Makefiles       ``nmake``                   ``jom``
 NMake Makefiles JOM   ``jom``                     ``nmake``
 MinGW Makefiles       ``mingw32-make``
 MSYS Makefiles        ``make``
 Ninja                 ``ninja``
 Visual Studio         ``msbuild``
 Watcom WMake          ``wmake``
===================== =========================== ===========================

The ``jom`` tool is capable of reading makefiles of the
``NMake`` flavor and building in parallel, while the
``nmake`` tool always builds serially.  After generating
with the :generator:`NMake Makefiles` generator a user
can run ``jom`` instead of ``nmake``.  The
:option:`--build <cmake --build>`
mode would also use ``jom`` if the
:variable:`CMAKE_MAKE_PROGRAM` was set to ``jom`` while
using the :generator:`NMake Makefiles` generator, and
as a convenience, the :generator:`NMake Makefiles JOM`
generator is provided to find ``jom`` in the normal way
and use it as the :variable:`CMAKE_MAKE_PROGRAM`. For
completeness, ``nmake`` is an alternative tool which
can process the output of the
:generator:`NMake Makefiles JOM` generator, but doing
so would be a pessimization.

Software Installation
=====================

The :variable:`CMAKE_INSTALL_PREFIX` variable can be
set in the CMake cache to specify where to install the
provided software.  If the provided software has install
rules, specified using the :command:`install` command,
they will install artifacts into that prefix.  On Windows,
the default installation location corresponds to the
``ProgramFiles`` system directory which may be
architecture specific.  On Unix hosts, ``/usr/local`` is
the default installation location.

The :variable:`CMAKE_INSTALL_PREFIX` variable always
refers to the installation prefix on the target
filesystem.

In cross-compiling or packaging scenarios where the
sysroot is read-only or where the sysroot should otherwise
remain pristine, the :variable:`CMAKE_STAGING_PREFIX`
variable can be set to a location to actually install
the files.

The commands:

.. code-block:: console

  $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
    -DCMAKE_SYSROOT=$HOME/root \
    -DCMAKE_STAGING_PREFIX=/tmp/package
  $ cmake --build .
  $ cmake --build . --target install

result in files being installed to paths such
as ``/tmp/package/lib/libfoo.so`` on the host machine.
The ``/usr/local`` location on the host machine is
not affected.

Some provided software may specify ``uninstall`` rules,
but CMake does not generate such rules by default itself.

Running Tests
=============

The :manual:`ctest(1)` tool is shipped with the CMake
distribution to execute provided tests and report
results.  The ``test`` build-target is provided to run
all available tests, but the :manual:`ctest(1)` tool
allows granular control over which tests to run, how to
run them, and how to report results.  Executing
:manual:`ctest(1)` in the build directory is equivalent
to running the ``test`` target:

.. code-block:: console

  $ ctest

A regular expression can be passed to run only tests
which match the expression.  To run only tests with
``Qt`` in their name:

.. code-block:: console

  $ ctest -R Qt

Tests can be excluded by regular expression too.  To
run only tests without ``Qt`` in their name:

.. code-block:: console

  $ ctest -E Qt

Tests can be run in parallel by passing :option:`-j <ctest -j>`
arguments to :manual:`ctest(1)`:

.. code-block:: console

  $ ctest -R Qt -j8

The environment variable :envvar:`CTEST_PARALLEL_LEVEL`
can alternatively be set to avoid the need to pass
:option:`-j <ctest -j>`.

By default :manual:`ctest(1)` does not print the output
from the tests. The command line argument :option:`-V <ctest -V>`
(or ``--verbose``) enables verbose mode to print the
output from all tests.
The :option:`--output-on-failure <ctest --output-on-failure>`
option prints the test output for failing tests only.
The environment variable :envvar:`CTEST_OUTPUT_ON_FAILURE`
can be set to ``1`` as an alternative to passing the
:option:`--output-on-failure <ctest --output-on-failure>`
option to :manual:`ctest(1)`.


code:
Using Dependencies Guide
************************

.. only:: html

   .. contents::

Introduction
============

Projects will frequently depend on other projects, assets, and artifacts.
CMake provides a number of ways to incorporate such things into the build.
Projects and users have the flexibility to choose between methods that
best suit their needs.

The primary methods of bringing dependencies into the build are the
:command:`find_package` command and the :module:`FetchContent` module.
The :module:`FindPkgConfig` module is also sometimes used, although it
lacks some of the integration of the other two and is not discussed any
further in this guide.

Dependencies can also be made available by a custom
:ref:`dependency provider <dependency_providers>`.
This might be a third party package manager, or it might be custom code
implemented by the developer.  Dependency providers co-operate with the
primary methods mentioned above to extend their flexibility.

.. _prebuilt_find_package:

Using Pre-built Packages With ``find_package()``
================================================

A package needed by the project may already be built and available at some
location on the user's system.  That package might have also been built by
CMake, or it could have used a different build system entirely.  It might
even just be a collection of files that didn't need to be built at all.
CMake provides the :command:`find_package` command for these scenarios.
It searches well-known locations, along with additional hints and paths
provided by the project or user.  It also supports package components and
packages being optional.  Result variables are provided to allow the project
to customize its own behavior according to whether the package or specific
components were found.

In most cases, projects should generally use the :ref:`basic signature`.
Most of the time, this will involve just the package name, maybe a version
constraint, and the ``REQUIRED`` keyword if the dependency is not optional.
A set of package components may also be specified.

.. code-block:: cmake
  :caption: Examples of ``find_package()`` basic signature

  find_package(Catch2)
  find_package(GTest REQUIRED)
  find_package(Boost 1.79 COMPONENTS date_time)

The :command:`find_package` command supports two main methods for carrying
out the search:

**Config mode**
  With this method, the command looks for files that are typically provided
  by the package itself.  This is the more reliable method of the two, since
  the package details should always be in sync with the package.

**Module mode**
  Not all packages are CMake-aware. Many don't provide the files needed to
  support config mode.  For such cases, a Find module file can be provided
  separately, either by the project or by CMake.  A Find module is typically
  a heuristic implementation which knows what the package normally provides
  and how to present that package to the project.  Since Find modules are
  usually distributed separately from the package, they are not as reliable.
  They are typically maintained separately, and they are likely to follow
  different release schedules, so they can easily become out-of-date.

Depending on the arguments used, :command:`find_package` may use one or both
of the above methods.  By restricting the options to just the basic signature,
both config mode and module mode can be used to satisfy the dependency.
The presence of other options may restrict the call to using only one of the
two methods, potentially reducing the command's ability to find the dependency.
See the :command:`find_package` documentation for full details about this
complex topic.

For both search methods, the user can also set cache variables on the
:manual:`cmake(1)` command line or in the :manual:`ccmake(1)` or
:manual:`cmake-gui(1)` UI tools to influence and override where to find
packages. See the :ref:`User Interaction Guide <Setting Build Variables>`
for more on how to set cache variables.

.. _Libraries providing Config-file packages:

Config-file packages
--------------------

The preferred way for a third party to provide executables, libraries,
headers, and other files for use with CMake is to provide
:ref:`config files <Config File Packages>`.  These are text files shipped
with the package, which define CMake targets, variables, commands, and so on.
The config file is an ordinary CMake script, which is read in by the
:command:`find_package` command.

The config files can usually be found in a directory whose name matches the
pattern ``lib/cmake/<PackageName>``, although they may be in other locations
instead (see :ref:`search procedure`).  The ``<PackageName>`` is usually the
first argument to the :command:`find_package` command, and it may even be the
only argument.  Alternative names can also be specified with the ``NAMES``
option:

.. code-block:: cmake
  :caption: Providing alternative names when finding a package

  find_package(SomeThing
    NAMES
      SameThingOtherName   # Another name for the package
      SomeThing            # Also still look for its canonical name
  )

The config file must be named either ``<PackageName>Config.cmake`` or
``<LowercasePackageName>-config.cmake`` (the former is used for the remainder
of this guide, but both are supported).  This file is the entry point
to the package for CMake.  A separate optional file named
``<PackageName>ConfigVersion.cmake`` or
``<LowercasePackageName>-config-version.cmake`` may also exist in the same
directory.  This file is used by CMake to determine whether the version of
the package satisfies any version constraint included in the call to
:command:`find_package`.  It is optional to specify a version when calling
:command:`find_package`, even if a ``<PackageName>ConfigVersion.cmake``
file is present.

If the ``<PackageName>Config.cmake`` file is found and any version constraint
is satisfied, the :command:`find_package` command considers the package to be
found, and the entire package is assumed to be complete as designed.

There may be additional files providing CMake commands or
:ref:`imported targets` for you to use.  CMake does not enforce any naming
convention for these files.  They are related to the primary
``<PackageName>Config.cmake`` file by use of the CMake :command:`include`
command.  The ``<PackageName>Config.cmake`` file would typically include
these for you, so they won't usually require any additional step other than
the call to :command:`find_package`.

If the location of the package is in a
:ref:`directory known to CMake <search procedure>`, the
:command:`find_package` call should succeed.  The directories known to CMake
are platform-specific.  For example, packages installed on Linux with a
standard system package manager will be found in the ``/usr`` prefix
automatically.  Packages installed in ``Program Files`` on Windows will
similarly be found automatically.

Packages will not be found automatically without help if they are in
locations not known to CMake, such as ``/opt/mylib`` or ``$HOME/dev/prefix``.
This is a normal situation, and CMake provides several ways for users to
specify where to find such libraries.

The :variable:`CMAKE_PREFIX_PATH` variable may be
:ref:`set when invoking CMake <Setting Build Variables>`.
It is treated as a list of base paths in which to search for
:ref:`config files <Config File Packages>`.  A package installed in
``/opt/somepackage`` will typically install config files such as
``/opt/somepackage/lib/cmake/somePackage/SomePackageConfig.cmake``.
In that case, ``/opt/somepackage`` should be added to
:variable:`CMAKE_PREFIX_PATH`.

The environment variable ``CMAKE_PREFIX_PATH`` may also be populated with
prefixes to search for packages.  Like the ``PATH`` environment variable,
this is a list, but it needs to use the platform-specific environment variable
list item separator (``:`` on Unix and ``;`` on Windows).

The :variable:`CMAKE_PREFIX_PATH` variable provides convenience in cases
where multiple prefixes need to be specified, or when multiple packages
are available under the same prefix.  Paths to packages may also be
specified by setting variables matching ``<PackageName>_DIR``, such as
``SomePackage_DIR``.  Note that this is not a prefix, but should be a full
path to a directory containing a config-style package file, such as
``/opt/somepackage/lib/cmake/SomePackage`` in the above example.
See the :command:`find_package` documentation for other CMake variables and
environment variables that can affect the search.

.. _Libraries not Providing Config-file Packages:

Find Module Files
-----------------

Packages which do not provide config files can still be found with the
:command:`find_package` command, if a ``FindSomePackage.cmake`` file is
available.  These Find module files are different to config files in that:

#. Find module files should not be provided by the package itself.
#. The availability of a ``Find<PackageName>.cmake`` file does not indicate
   the availability of the package, or any particular part of the package.
#. CMake does not search the locations specified in the
   :variable:`CMAKE_PREFIX_PATH` variable for ``Find<PackageName>.cmake``
   files.  Instead, CMake searches for such files in the locations given
   by the :variable:`CMAKE_MODULE_PATH` variable.  It is common for users to
   set the :variable:`CMAKE_MODULE_PATH` when running CMake, and it is common
   for CMake projects to append to :variable:`CMAKE_MODULE_PATH` to allow use
   of local Find module files.
#. CMake ships ``Find<PackageName>.cmake`` files for some
   :manual:`third party packages <cmake-modules(7)>`.  These files are a
   maintenance burden for CMake, and it is not unusual for these to fall
   behind the latest releases of the packages they are associated with.
   In general, new Find modules are not added to CMake any more.  Projects
   should encourage the upstream packages to provide a config file where
   possible.  If that is unsuccessful, the project should provide its own
   Find module for the package.

See :ref:`Find Modules` for a detailed discussion of how to write a
Find module file.

.. _Imported Targets from Packages:

Imported Targets
----------------

Both config files and Find module files can define :ref:`Imported targets`.
These will typically have names of the form ``SomePrefix::ThingName``.
Where these are available, the project should prefer to use them instead of
any CMake variables that may also be provided.  Such targets typically carry
usage requirements and apply things like header search paths, compiler
definitions, etc. automatically to other targets that link to them (e.g. using
:command:`target_link_libraries`).  This is both more robust and more
convenient than trying to apply the same things manually using variables.
Check the documentation for the package or Find module to see what imported
targets it defines, if any.

Imported targets should also encapsulate any configuration-specific paths.
This includes the location of binaries (libraries, executables), compiler
flags, and any other configuration-dependent quantities.  Find modules may
be less reliable in providing these details than config files.

A complete example which finds a third party package and uses a library
from it might look like the following:

.. code-block:: cmake

  cmake_minimum_required(VERSION 3.10)
  project(MyExeProject VERSION 1.0.0)

  # Make project-provided Find modules available
  list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

  find_package(SomePackage REQUIRED)
  add_executable(MyExe main.cpp)
  target_link_libraries(MyExe PRIVATE SomePrefix::LibName)

Note that the above call to :command:`find_package` could be resolved by
a config file or a Find module.  It uses only the basic arguments supported
by the :ref:`basic signature`.  A ``FindSomePackage.cmake`` file in the
``${CMAKE_CURRENT_SOURCE_DIR}/cmake`` directory would allow the
:command:`find_package` command to succeed using module mode, for example.
If no such module file is present, the system would be searched for a config
file.

Downloading And Building From Source With ``FetchContent``
==========================================================

Dependencies do not necessarily have to be pre-built in order to use them
with CMake.  They can be built from sources as part of the main project.
The :module:`FetchContent` module provides functionality to download
content (typically sources, but can be anything) and add it to the main
project if the dependency also uses CMake.  The dependency's sources will
be built along with the rest of the project, just as though the sources were
part of the project's own sources.

The general pattern is that the project should first declare all the
dependencies it wants to use, then ask for them to be made available.
The following demonstrates the principle (see :ref:`fetch-content-examples`
for more):

.. code-block:: cmake

  include(FetchContent)
  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
  )
  FetchContent_Declare(
    Catch2
    GIT_REPOSITORY https://github.com/catchorg/Catch2.git
    GIT_TAG        605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1
  )
  FetchContent_MakeAvailable(googletest Catch2)

Various download methods are supported, including downloading and extracting
archives from a URL (a range of archive formats are supported), and a number
of repository formats including Git, Subversion, and Mercurial.
Custom download, update, and patch commands can also be used to support
arbitrary use cases.

When a dependency is added to the project with :module:`FetchContent`, the
project links to the dependency's targets just like any other target from the
project.  If the dependency provides namespaced targets of the form
``SomePrefix::ThingName``, the project should link to those rather than to
any non-namespaced targets.  See the next section for why this is recommended.

Not all dependencies can be brought into the project this way.  Some
dependencies define targets whose names clash with other targets from the
project or other dependencies.  Concrete executable and library targets
created by :command:`add_executable` and :command:`add_library` are global,
so each one must be unique across the whole build.  If a dependency would
add a clashing target name, it cannot be brought directly into the build
with this method.

``FetchContent`` And ``find_package()`` Integration
===================================================

.. versionadded:: 3.24

Some dependencies support being added by either :command:`find_package` or
:module:`FetchContent`.  Such dependencies must ensure they define the same
namespaced targets in both installed and built-from-source scenarios.
A consuming project then links to those namespaced targets and can handle
both scenarios transparently, as long as the project does not use anything
else that isn't provided by both methods.

The project can indicate it is happy to accept a dependency by either method
using the ``FIND_PACKAGE_ARGS`` option to :command:`FetchContent_Declare`.
This allows :command:`FetchContent_MakeAvailable` to try satisfying the
dependency with a call to :command:`find_package` first, using the arguments
after the ``FIND_PACKAGE_ARGS`` keyword, if any.  If that doesn't find the
dependency, it is built from source as described previously instead.

.. code-block:: cmake

  include(FetchContent)
  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
    FIND_PACKAGE_ARGS NAMES GTest
  )
  FetchContent_MakeAvailable(googletest)

  add_executable(ThingUnitTest thing_ut.cpp)
  target_link_libraries(ThingUnitTest GTest::gtest_main)

The above example calls
:command:`find_package(googletest NAMES GTest) <find_package>` first.
CMake provides a :module:`FindGTest` module, so if that finds a GTest package
installed somewhere, it will make it available, and the dependency will not be
built from source.  If no GTest package is found, it *will* be built from
source.  In either case, the ``GTest::gtest_main`` target is expected to be
defined, so we link our unit test executable to that target.

High-level control is also available through the
:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` variable.  This can be set to
``NEVER`` to disable all redirection to :command:`find_package`.  It can be
set to ``ALWAYS`` to try :command:`find_package` even if ``FIND_PACKAGE_ARGS``
was not specified (this should be used with caution).

The project might also decide that a particular dependency must be built from
source.  This might be needed if a patched or unreleased version of the
dependency is required, or to satisfy some policy that requires all
dependencies to be built from source.  The project can enforce this by adding
the ``OVERRIDE_FIND_PACKAGE`` keyword to :command:`FetchContent_Declare`.
A call to :command:`find_package` for that dependency will then be redirected
to :command:`FetchContent_MakeAvailable` instead.

.. code-block:: cmake

  include(FetchContent)
  FetchContent_Declare(
    Catch2
    URL https://intranet.mycomp.com/vendored/Catch2_2.13.4_patched.tgz
    URL_HASH MD5=abc123...
    OVERRIDE_FIND_PACKAGE
  )

  # The following is automatically redirected to FetchContent_MakeAvailable(Catch2)
  find_package(Catch2)

For more advanced use cases, see the
:variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` variable.

.. _dependency_providers_overview:

Dependency Providers
====================

.. versionadded:: 3.24

The preceding section discussed techniques that projects can use to specify
their dependencies.  Ideally, the project shouldn't really care where a
dependency comes from, as long as it provides the things it expects (often
just some imported targets).  The project says what it needs and may also
specify where to get it from, in the absence of any other details, so that it
can still be built out-of-the-box.

The developer, on the other hand, may be much more interested in controlling
*how* a dependency is provided to the project.  You might want to use a
particular version of a package that you built yourself.  You might want
to use a third party package manager.  You might want to redirect some
requests to a different URL on a system you control for security or
performance reasons.  CMake supports these sort of scenarios through
:ref:`dependency_providers`.

A dependency provider can be set to intercept :command:`find_package` and
:command:`FetchContent_MakeAvailable` calls.  The provider is given an
opportunity to satisfy such requests before falling back to the built-in
implementation if the provider doesn't fulfill it.

Only one dependency provider can be set, and it can only be set at a very
specific point early in the CMake run.
The :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable lists CMake files
that will be read while processing the first :command:`project()` call (and
only that call).  This is the only time a dependency provider may be set.
At most, one single provider is expected to be used throughout the whole
project.

For some scenarios, the user wouldn't need to know the details of how the
dependency provider is set.  A third party may provide a file that can be
added to :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES`, which will set up
the dependency provider on the user's behalf.  This is the recommended
approach for package managers.  The developer can use such a file like so::

  cmake -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=/path/to/package_manager/setup.cmake ...

For details on how to implement your own custom dependency provider, see the
:command:`cmake_language(SET_DEPENDENCY_PROVIDER)` command.


code:
.. title:: CMake Reference Documentation

Introduction
############

CMake is a tool to manage building of source code.  Originally, CMake was
designed as a generator for various dialects of ``Makefile``, today
CMake generates modern buildsystems such as ``Ninja`` as well as project
files for IDEs such as Visual Studio and Xcode.

CMake is widely used for the C and C++ languages, but it may be used to
build source code of other languages too.

People encountering CMake for the first time may have different initial
goals.  To learn how to build a source code package downloaded from the
internet, start with the :guide:`User Interaction Guide`.
This will detail the steps needed to run the :manual:`cmake(1)` or
:manual:`cmake-gui(1)` executable and how to choose a generator, and
how to complete the build.

The :guide:`Using Dependencies Guide` is aimed at developers
wishing to get started using a third-party library.

For developers starting a project using CMake, the :guide:`CMake Tutorial`
is a suitable starting point.  The :manual:`cmake-buildsystem(7)`
manual is aimed at developers expanding their knowledge of maintaining
a buildsystem and becoming familiar with the build targets that
can be represented in CMake.  The :manual:`cmake-packages(7)` manual
explains how to create packages which can easily be consumed by
third-party CMake-based buildsystems.

Command-Line Tools
##################

.. toctree::
   :maxdepth: 1

   /manual/cmake.1
   /manual/ctest.1
   /manual/cpack.1

Interactive Dialogs
###################

.. toctree::
   :maxdepth: 1

   /manual/cmake-gui.1
   /manual/ccmake.1

Reference Manuals
#################

.. toctree::
   :maxdepth: 1

   /manual/cmake-buildsystem.7
   /manual/cmake-commands.7
   /manual/cmake-compile-features.7
   /manual/cmake-configure-log.7
   /manual/cmake-cxxmodules.7
   /manual/cmake-developer.7
   /manual/cmake-env-variables.7
   /manual/cmake-file-api.7
   /manual/cmake-generator-expressions.7
   /manual/cmake-generators.7
   /manual/cmake-language.7
   /manual/cmake-modules.7
   /manual/cmake-packages.7
   /manual/cmake-policies.7
   /manual/cmake-presets.7
   /manual/cmake-properties.7
   /manual/cmake-qt.7
   /manual/cmake-server.7
   /manual/cmake-toolchains.7
   /manual/cmake-variables.7
   /manual/cpack-generators.7

.. only:: not man

 Guides
 ######

 .. toctree::
    :maxdepth: 1

    /guide/tutorial/index
    /guide/user-interaction/index
    /guide/using-dependencies/index
    /guide/importing-exporting/index
    /guide/ide-integration/index

.. only:: html or text

 Release Notes
 #############

 .. toctree::
    :maxdepth: 1

    /release/index

.. only:: html

 Index and Search
 ################

 * :ref:`genindex`
 * :ref:`search`


code:
.. cmake-manual-description: CMake Curses Dialog Command-Line Reference

ccmake(1)
*********

Synopsis
========

.. parsed-literal::

 ccmake [<options>] -B <path-to-build> [-S <path-to-source>]
 ccmake [<options>] <path-to-source | path-to-existing-build>

Description
===========

The :program:`ccmake` executable is the CMake curses interface.  Project
configuration settings may be specified interactively through this
GUI.  Brief instructions are provided at the bottom of the terminal
when the program is running.

CMake is a cross-platform build system generator.  Projects specify
their build process with platform-independent CMake listfiles included
in each directory of a source tree with the name ``CMakeLists.txt``.
Users build a project by using CMake to generate a build system for a
native tool on their platform.

Options
=======

.. program:: ccmake

.. include:: OPTIONS_BUILD.txt

.. include:: OPTIONS_HELP.txt

See Also
========

.. include:: LINKS.txt