Ninja Multi-Config¶
版本 3.17 新增。
產生多個 build-<Config>.ninja
檔案。
此產生器非常類似 Ninja
產生器,但有一些關鍵差異。本文檔將僅討論這些差異。
與 Ninja
產生器不同,Ninja Multi-Config
使用 CMAKE_CONFIGURATION_TYPES
一次產生多個組態,而不是像 CMAKE_BUILD_TYPE
一次只產生一個組態。將為每個組態產生一個 build-<Config>.ninja
檔案(其中 <Config>
是組態名稱)。這些檔案旨在與 ninja -f build-<Config>.ninja
一起執行。build.ninja
檔案也會被產生,它使用來自 CMAKE_DEFAULT_BUILD_TYPE
或 CMAKE_CONFIGURATION_TYPES
的第一個項目的組態。
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
指定一個 以分號分隔的清單,其中包含在
build.ninja
中目標要建置的組態,如果未指定:<Config>
後綴。
考慮以下範例
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
這將建置 generator
的 Debug
組態,它將用於產生 generated.c
,而 generated.c
將用於建置 generated
的 Debug
組態。
但是,如果 CMAKE_CROSS_CONFIGS
設定為 all
,並且您改為執行以下命令
ninja -f build-Release.ninja generated:Debug
# OR
cmake --build . --config Release --target generated:Debug
這將建置 generator
的 Release
組態,它將用於產生 generated.c
,而 generated.c
將用於建置 generated
的 Debug
組態。這對於在仍然建置使用產生程式碼建置的目標的偵錯版本時,執行發行最佳化版本的產生器實用程式非常有用。
自訂命令¶
版本 3.20 新增。
Ninja Multi-Config
產生器透過其跨組態模式為 add_custom_command()
和 add_custom_target()
新增了額外的功能。COMMAND
、DEPENDS
和 WORKING_DIRECTORY
參數可以在「命令組態」(正在使用的 build-<Config>.ninja
檔案的「原生」組態)或「輸出組態」(用於評估 OUTPUT
和 BYPRODUCTS
的組態)的上下文中評估。
如果 OUTPUT
或 BYPRODUCTS
命名的路徑對於多個組態通用(例如,它不使用任何產生器表達式),則預設情況下,所有參數都在命令組態中評估。如果所有 OUTPUT
和 BYPRODUCTS
路徑對於每個組態都是唯一的(例如,透過使用 $<CONFIG>
產生器表達式),則 COMMAND
的第一個參數仍然預設在命令組態中評估,而所有後續參數,以及 DEPENDS
和 WORKING_DIRECTORY
的參數,都在輸出組態中評估。這些預設值可以透過 $<OUTPUT_CONFIG:...>
和 $<COMMAND_CONFIG:...>
產生器表達式覆蓋。請注意,如果在 DEPENDS
中或作為 COMMAND
的第一個參數中按名稱指定目標,則它始終在命令組態中評估,即使它被包裹在 $<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>>"
)
假設 generator
、tgt1
、tgt2
、tgt3
和 tgt4
都是可執行目標,並假設 $<CONFIG>.txt
是在 Debug
輸出組態中使用 Release
命令組態建置的。generator
目標的 Release
建置會使用 Debug.txt Debug Release
作為參數呼叫。該命令依賴於 tgt1
和 tgt4
的 Release
建置,以及 tgt2
和 tgt3
的 Debug
建置。
目標的 PRE_BUILD
、PRE_LINK
和 POST_BUILD
自訂命令僅在其「原生」組態(build-Release.ninja
檔案中的 Release
組態)中執行,除非它們沒有 BYPRODUCTS
或它們的 BYPRODUCTS
在每個組態中都是唯一的。考慮以下範例
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
,則所有三個自訂命令都會執行。