# Ninja Multi-Config

Generates multiple `build-<Config>.ninja` files.

This generator is very much like the `Ninja` generator, but with some key differences. Only these differences will be discussed in this document.

Unlike the `Ninja` generator, `Ninja Multi-Config` generates multiple configurations at once with `CMAKE_CONFIGURATION_TYPES` instead of only one configuration with `CMAKE_BUILD_TYPE`. One `build-<Config>.ninja` file will be generated for each of these configurations (with `<Config>` being the configuration name.) These files are intended to be run with `ninja -f build-<Config>.ninja`. A `build.ninja` file is also generated, using the configuration from either `CMAKE_DEFAULT_BUILD_TYPE` or the first item from `CMAKE_CONFIGURATION_TYPES`.

`cmake --build . --config <Config>` will always use `build-<Config>.ninja` to build. If no `--config` argument is specified, `cmake --build .` will default to `build-Debug.ninja`, unless a `build.ninja` is generated (see below), in which case that will be used instead.

Each `build-<Config>.ninja` file contains `<target>` targets as well as `<target>:<Config>` targets, where `<Config>` is the same as the configuration specified in `build-<Config>.ninja` Additionally, if cross-config mode is enabled, `build-<Config>.ninja` may contain `<target>:<OtherConfig>` targets, where `<OtherConfig>` is a cross-config, as well as `<target>:all`, which builds the target in all cross-configs. See below for how to enable cross-config mode.

The `Ninja Multi-Config` generator recognizes the following variables:

`CMAKE_CONFIGURATION_TYPES`

  Specifies the total set of configurations to build. See the variable’s documentation for more information.

`CMAKE_CROSS_CONFIGS`

  Specifies a semicolon-separated list of configurations available from all `build-<Config>.ninja` files. This variable activates cross-config mode. Targets from each config specified in this variable can be built from any `build-<Config>.ninja` file. Custom commands will use the configuration native to `build-<Config>.ninja`. If it is set to `all`, all configurations from `CMAKE_CONFIGURATION_TYPES` are cross-configs. If it is not specified, or empty, each `build-<Config>.ninja` file will only contain build rules for its own configuration.

  The value of this variable must be a subset of `CMAKE_CONFIGURATION_TYPES`.

`CMAKE_DEFAULT_BUILD_TYPE`

  Specifies the configuration to use by default in a `build.ninja` file. If this variable is specified, `build.ninja` uses build rules from `build-<Config>.ninja` by default. All custom commands are executed with this configuration. If the variable is not specified, the first item from `CMAKE_CONFIGURATION_TYPES` is used instead.

  The value of this variable must be one of the items from `CMAKE_CONFIGURATION_TYPES`.

`CMAKE_DEFAULT_CONFIGS`

  Specifies a semicolon-separated list of configurations to build for a target in `build.ninja` if no `:<Config>` suffix is specified. If it is set to `all`, all configurations from `CMAKE_CROSS_CONFIGS` are used. If it is not specified, it defaults to `CMAKE_DEFAULT_BUILD_TYPE`.

  For example, if you set `CMAKE_DEFAULT_BUILD_TYPE` to `Release`, but set `CMAKE_DEFAULT_CONFIGS` to `Debug` or `all`, all `<target>` aliases in `build.ninja` will resolve to `<target>:Debug` or `<target>:all`, but custom commands will still use the `Release` configuration.

  The value of this variable must be a subset of `CMAKE_CROSS_CONFIGS` or be the same as `CMAKE_DEFAULT_BUILD_TYPE`. It must not be specified if `CMAKE_DEFAULT_BUILD_TYPE` or `CMAKE_CROSS_CONFIGS` is not used.

Consider the following example:

    cmake_minimum_required(VERSION 3.16)
    project(MultiConfigNinja C)

    add_executable(generator generator.c)
    add_custom_command(OUTPUT generated.c COMMAND generator generated.c)
    add_library(generated ${CMAKE_BINARY_DIR}/generated.c)

Now assume you configure the project with `Ninja Multi-Config` and run one of the following commands:

    ninja -f build-Debug.ninja generated
    # OR
    cmake --build . --config Debug --target generated

This would build the `Debug` configuration of `generator`, which would be used to generate `generated.c`, which would be used to build the `Debug` configuration of `generated`.

But if `CMAKE_CROSS_CONFIGS` is set to `all`, and you run the following instead:

    ninja -f build-Release.ninja generated:Debug
    # OR
    cmake --build . --config Release --target generated:Debug

This would build the `Release` configuration of `generator`, which would be used to generate `generated.c`, which would be used to build the `Debug` configuration of `generated`. This is useful for running a release-optimized version of a generator utility while still building the debug version of the targets built with the generated code.