1Ninja Multi-Config
2------------------
3
4.. versionadded:: 3.17
5
6Generates multiple ``build-<Config>.ninja`` files.
7
8This generator is very much like the :generator:`Ninja` generator, but with
9some key differences. Only these differences will be discussed in this
10document.
11
12Unlike the :generator:`Ninja` generator, ``Ninja Multi-Config`` generates
13multiple configurations at once with :variable:`CMAKE_CONFIGURATION_TYPES`
14instead of only one configuration with :variable:`CMAKE_BUILD_TYPE`. One
15``build-<Config>.ninja`` file will be generated for each of these
16configurations (with ``<Config>`` being the configuration name.) These files
17are intended to be run with ``ninja -f build-<Config>.ninja``. A
18``build.ninja`` file is also generated, using the configuration from either
19:variable:`CMAKE_DEFAULT_BUILD_TYPE` or the first item from
20:variable:`CMAKE_CONFIGURATION_TYPES`.
21
22``cmake --build . --config <Config>`` will always use ``build-<Config>.ninja``
23to build. If no ``--config`` argument is specified, ``cmake --build .`` will
24use ``build.ninja``.
25
26Each ``build-<Config>.ninja`` file contains ``<target>`` targets as well as
27``<target>:<Config>`` targets, where ``<Config>`` is the same as the
28configuration specified in ``build-<Config>.ninja`` Additionally, if
29cross-config mode is enabled, ``build-<Config>.ninja`` may contain
30``<target>:<OtherConfig>`` targets, where ``<OtherConfig>`` is a cross-config,
31as well as ``<target>:all``, which builds the target in all cross-configs. See
32below for how to enable cross-config mode.
33
34The ``Ninja Multi-Config`` generator recognizes the following variables:
35
36:variable:`CMAKE_CONFIGURATION_TYPES`
37  Specifies the total set of configurations to build. Unlike with other
38  multi-config generators, this variable has a value of
39  ``Debug;Release;RelWithDebInfo`` by default.
40
41:variable:`CMAKE_CROSS_CONFIGS`
42  Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
43  configurations available from all ``build-<Config>.ninja`` files.
44
45:variable:`CMAKE_DEFAULT_BUILD_TYPE`
46  Specifies the configuration to use by default in a ``build.ninja`` file.
47
48:variable:`CMAKE_DEFAULT_CONFIGS`
49  Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
50  configurations to build for a target in ``build.ninja``
51  if no ``:<Config>`` suffix is specified.
52
53Consider the following example:
54
55.. code-block:: cmake
56
57  cmake_minimum_required(VERSION 3.16)
58  project(MultiConfigNinja C)
59
60  add_executable(generator generator.c)
61  add_custom_command(OUTPUT generated.c COMMAND generator generated.c)
62  add_library(generated ${CMAKE_BINARY_DIR}/generated.c)
63
64Now assume you configure the project with ``Ninja Multi-Config`` and run one of
65the following commands:
66
67.. code-block:: shell
68
69  ninja -f build-Debug.ninja generated
70  # OR
71  cmake --build . --config Debug --target generated
72
73This would build the ``Debug`` configuration of ``generator``, which would be
74used to generate ``generated.c``, which would be used to build the ``Debug``
75configuration of ``generated``.
76
77But if :variable:`CMAKE_CROSS_CONFIGS` is set to ``all``, and you run the
78following instead:
79
80.. code-block:: shell
81
82  ninja -f build-Release.ninja generated:Debug
83  # OR
84  cmake --build . --config Release --target generated:Debug
85
86This would build the ``Release`` configuration of ``generator``, which would be
87used to generate ``generated.c``, which would be used to build the ``Debug``
88configuration of ``generated``. This is useful for running a release-optimized
89version of a generator utility while still building the debug version of the
90targets built with the generated code.
91
92Custom Commands
93^^^^^^^^^^^^^^^
94
95.. versionadded:: 3.20
96
97The ``Ninja Multi-Config`` generator adds extra capabilities to
98:command:`add_custom_command` and :command:`add_custom_target` through its
99cross-config mode. The ``COMMAND``, ``DEPENDS``, and ``WORKING_DIRECTORY``
100arguments can be evaluated in the context of either the "command config" (the
101"native" configuration of the ``build-<Config>.ninja`` file in use) or the
102"output config" (the configuration used to evaluate the ``OUTPUT`` and
103``BYPRODUCTS``).
104
105If either ``OUTPUT`` or ``BYPRODUCTS`` names a path that is common to
106more than one configuration (e.g. it does not use any generator expressions),
107all arguments are evaluated in the command config by default.
108If all ``OUTPUT`` and ``BYPRODUCTS`` paths are unique to each configuration
109(e.g. by using the ``$<CONFIG>`` generator expression), the first argument of
110``COMMAND`` is still evaluated in the command config by default, while all
111subsequent arguments, as well as the arguments to ``DEPENDS`` and
112``WORKING_DIRECTORY``, are evaluated in the output config. These defaults can
113be overridden with the ``$<OUTPUT_CONFIG:...>`` and ``$<COMMAND_CONFIG:...>``
114generator-expressions. Note that if a target is specified by its name in
115``DEPENDS``, or as the first argument of ``COMMAND``, it is always evaluated
116in the command config, even if it is wrapped in ``$<OUTPUT_CONFIG:...>``
117(because its plain name is not a generator expression).
118
119As an example, consider the following:
120
121.. code-block:: cmake
122
123  add_custom_command(
124    OUTPUT "$<CONFIG>.txt"
125    COMMAND generator "$<CONFIG>.txt" "$<OUTPUT_CONFIG:$<CONFIG>>" "$<COMMAND_CONFIG:$<CONFIG>>"
126    DEPENDS tgt1 "$<TARGET_FILE:tgt2>" "$<OUTPUT_CONFIG:$<TARGET_FILE:tgt3>>" "$<COMMAND_CONFIG:$<TARGET_FILE:tgt4>>"
127    )
128
129Assume that ``generator``, ``tgt1``, ``tgt2``, ``tgt3``, and ``tgt4`` are all
130executable targets, and assume that ``$<CONFIG>.txt`` is built in the ``Debug``
131output config using the ``Release`` command config. The ``Release`` build of
132the ``generator`` target is called with ``Debug.txt Debug Release`` as
133arguments. The command depends on the ``Release`` builds of ``tgt1`` and
134``tgt4``, and the ``Debug`` builds of ``tgt2`` and ``tgt3``.
135
136``PRE_BUILD``, ``PRE_LINK``, and ``POST_BUILD`` custom commands for targets
137only get run in their "native" configuration (the ``Release`` configuration in
138the ``build-Release.ninja`` file) unless they have no ``BYPRODUCTS`` or their
139``BYPRODUCTS`` are unique per config. Consider the following example:
140
141.. code-block:: cmake
142
143  add_executable(exe main.c)
144  add_custom_command(
145    TARGET exe
146    POST_BUILD
147    COMMAND ${CMAKE_COMMAND} -E echo "Running no-byproduct command"
148    )
149  add_custom_command(
150    TARGET exe
151    POST_BUILD
152    COMMAND ${CMAKE_COMMAND} -E echo "Running separate-byproduct command for $<CONFIG>"
153    BYPRODUCTS $<CONFIG>.txt
154    )
155  add_custom_command(
156    TARGET exe
157    POST_BUILD
158    COMMAND ${CMAKE_COMMAND} -E echo "Running common-byproduct command for $<CONFIG>"
159    BYPRODUCTS exe.txt
160    )
161
162In this example, if you build ``exe:Debug`` in ``build-Release.ninja``, the
163first and second custom commands get run, since their byproducts are unique
164per-config, but the last custom command does not. However, if you build
165``exe:Release`` in ``build-Release.ninja``, all three custom commands get run.
166