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.