忍者多配置

在 3.17 版本加入.

生成多个 build-<Config>.ninja 文件。

此生成器与 Ninja 生成器非常相似,但有一些关键差异。本文档将仅讨论这些差异。

Ninja 生成器不同,Ninja Multi-Config 使用 CMAKE_CONFIGURATION_TYPES 一次生成多个配置,而不是使用 CMAKE_BUILD_TYPE 仅生成一个配置。将为每个配置生成一个 build-<Config>.ninja 文件(<Config> 是配置名称。)这些文件旨在使用 ninja -f build 运行-<配置>.ninja。使用 CMAKE_DEFAULT_BUILD_TYPE 中的配置或 CMAKE_CONFIGURATION_TYPES 中的第一项配置,也会生成一个 build.ninja 文件。

cmake --build --config <Config> 将始终使用 build-<Config>.ninja 进行构建。如果未指定 --config 参数,则 cmake --build 将使用 build.ninja

每个 build-<Config>.ninja 文件包含 <target> 目标以及 <target>:<Config> 目标,其中 <Config> 与``build-<Config>.ninja`` 中指定的配置此外,如果启用交叉配置模式,build-<Config>.ninja 可能包含``<target>:<OtherConfig>`` 目标,其中 <OtherConfig> 是一个交叉配置,以及 <target>:all,它在所有交叉配置中构建目标。请参阅下文了解如何启用交叉配置模式。

Ninja Multi-Config 生成器识别以下变量:

CMAKE_CONFIGURATION_TYPES

指定要构建的总配置集。与其他多配置生成器不同,此变量默认值为“Debug;Release;RelWithDebInfo”。

CMAKE_CROSS_CONFIGS

指定一个 分号分隔的列表 所有``build-<Config>.ninja`` 文件中可用的配置。

CMAKE_DEFAULT_BUILD_TYPE

指定在 build.ninja 文件中默认使用的配置。

CMAKE_DEFAULT_CONFIGS

如果未指定 :<Config> 后缀,则指定要在 build.ninja 中为目标构建的配置的 分号分隔列表

考虑以下示例:

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)

现在假设您使用“Ninja Multi-Config”配置项目并运行以下命令之一:

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

这将构建 generatorDebug 配置,它将用于生成 generated.c,后者将用于构建 generatedDebug 配置.

但是,如果 CMAKE_CROSS_CONFIGS 设置为 all,则改为运行以下命令:

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

这将构建 generatorRelease 配置,它将用于生成 generated.c,后者将用于构建 generatedDebug 配置.这对于运行生成器实用程序的发布优化版本,同时仍然构建使用生成的代码构建的目标的调试版本非常有用。

自定义命令

在 3.20 版本加入.

Ninja Multi-Config 生成器通过其交叉配置模式向 add_custom_command()add_custom_target() 添加了额外的功能。 COMMANDDEPENDSWORKING_DIRECTORY 参数可以在“命令配置”(build-<Config>.ninja 的“本机”配置)的上下文中进行评估 正在使用的文件)或“输出配置”(用于评估 OUTPUTBYPRODUCTS 的配置)。

如果 OUTPUTBYPRODUCTS 命名的路径对多个配置是通用的(例如,它不使用任何生成器表达式),则所有参数默认情况下都在命令配置中进行评估。如果所有 OUTPUTBYPRODUCTS 路径对于每个配置都是唯一的(例如,通过使用 $<CONFIG> 生成器表达式),COMMAND 的第一个参数仍然在评估默认情况下是命令配置,而所有后续参数以及“DEPENDS”和“WORKING_DIRECTORY”的参数都在输出配置中进行评估。这些默认值可以被 $<OUTPUT_CONFIG:...>$<COMMAND_CONFIG:...> 生成器表达式覆盖。请注意,如果目标在“DEPENDS”中由其名称指定,或者作为“COMMAND”的第一个参数,则它始终在命令配置中进行评估,即使它包含在 :genex:`$< OUTPUT_CONFIG:...>`(因为它的普通名称不是生成器表达式)。

例如,请考虑以下内容:

add_custom_command(
  OUTPUT "$<CONFIG>.txt"
  COMMAND
    generator "$<CONFIG>.txt"
              "$<OUTPUT_CONFIG:$<CONFIG>>"
              "$<COMMAND_CONFIG:$<CONFIG>>"
  DEPENDS
    tgt1
    "$<TARGET_FILE:tgt2>"
    "$<OUTPUT_CONFIG:$<TARGET_FILE:tgt3>>"
    "$<COMMAND_CONFIG:$<TARGET_FILE:tgt4>>"
  )

假设 generatortgt1tgt2tgt3tgt4 都是可执行目标,并假设 $<CONFIG>.txt``使用“发布”命令配置在“调试”输出配置中构建。 ``generator 目标的``Release`` 构建以``Debug.txt Debug Release`` 作为参数调用。该命令取决于``tgt1`` 和``tgt4`` 的``Release`` 构建,以及``tgt2`` 和``tgt3`` 的``Debug`` 构建。

PRE_BUILDPRE_LINKPOST_BUILD 目标的自定义命令仅在其“本机”配置中运行(build-Release.ninja 中的 Release 配置文件)除非它们没有“副产品”或者它们的“副产品”在每个配置中都是唯一的。考虑以下示例:

add_executable(exe main.c)
add_custom_command(
  TARGET exe
  POST_BUILD
  COMMAND
    ${CMAKE_COMMAND} -E echo "Running no-byproduct command"
  )
add_custom_command(
  TARGET exe
  POST_BUILD
  COMMAND
    ${CMAKE_COMMAND} -E echo
    "Running separate-byproduct command for $<CONFIG>"
  BYPRODUCTS $<CONFIG>.txt
  )
add_custom_command(
  TARGET exe
  POST_BUILD
  COMMAND
    ${CMAKE_COMMAND} -E echo
    "Running common-byproduct command for $<CONFIG>"
  BYPRODUCTS exe.txt
  )

在这个例子中,如果你在 build-Release.ninja 中构建 exe:Debug,第一个和第二个自定义命令会运行,因为它们的副产品在每个配置中都是唯一的,但最后一个自定义命令不会.但是,如果您在 build-Release.ninja 中构建 exe:Release,所有三个自定义命令都会运行。