CMP0058

於 3.3 版本新增。

Ninja 要求客製化命令的副產品必須明確指定。

當建置過程中產生的中間檔案被耗時的操作或龐大的依賴樹所使用時,可以透過僅在內容變更時更新檔案時間戳記,來減少增量建置所需的工作。使用這種方法,產生規則必須有一個單獨的輸出檔案,該檔案始終以比規則的任何依賴項更新的時間戳記來更新,以便建置工具僅在輸入變更時重新執行規則。我們將單獨的輸出檔案稱為規則的見證,將產生的檔案稱為規則的副產品

副產品可能不會被列為輸出,因為它們的時間戳記可能比輸入舊。在 CMake 設計時,沒有任何建置工具(如 make)能夠表達副產品。因此,3.2 之前的 CMake 版本無法指定它們。專案通常在產生它們的規則中未宣告副產品。例如

add_custom_command(
  OUTPUT witness.txt
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
          ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
          byproduct.txt # timestamp may not change
  COMMAND ${CMAKE_COMMAND} -E touch witness.txt
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
  )
add_custom_target(Provider DEPENDS witness.txt)
add_custom_command(
  OUTPUT generated.c
  COMMAND expensive-task -i byproduct.txt -o generated.c
  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt
  )
add_library(Consumer generated.c)
add_dependencies(Consumer Provider)

這對於所有產生器都適用,除了 Ninja。Ninja 建置工具會看到一個規則將 byproduct.txt 列為依賴項,而沒有規則將其列為輸出。Ninja 然後會抱怨沒有辦法滿足依賴項,並停止建置,即使有僅限順序的依賴項確保 byproduct.txt 在其消費者需要它之前就會存在。有關 Ninja 為何這樣運作的更多詳細資訊,請參閱 Ninja Issue 760 中對這個問題的討論。

Ninja 不會將副產品在產生它們的規則中保持未宣告狀態,而是期望將副產品與其他輸出一起列出。此類規則可以使用 restat 選項進行標記,該選項會告知 Ninja 在規則執行後檢查輸出的時間戳記。這可以防止時間戳記沒有變更的副產品不必要地導致其依賴項重新建置。

由於上述方法沒有告知 CMake 哪個客製化命令產生 byproduct.txt,Ninja 產生器沒有足夠的資訊將副產品新增為任何規則的輸出。CMake 2.8.12 及更高版本解決了這個問題,並允許使用上述方法的專案透過產生 phony 建置規則來建置,以告知 Ninja 容忍此類遺失的檔案。然而,此解決方法會阻止 Ninja 診斷出真正遺失的依賴項。它在來源內建置中也效果不佳,在來源內建置中,每個客製化命令依賴項(即使是來源檔案),都需要以這種方式處理,因為 CMake 沒有足夠的資訊來了解哪些檔案是作為客製化命令的副產品產生的。

引入副產品

CMake 3.2 在 add_custom_command()add_custom_target() 命令中引入了 BYPRODUCTS 選項。此選項允許明確指定副產品

add_custom_command(
  OUTPUT witness.txt
  BYPRODUCTS byproduct.txt # explicit byproduct specification
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
          ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
          byproduct.txt # timestamp may not change
...

Ninja 產生器使用 BYPRODUCTS 選項在產生它們的客製化命令的輸出中列出副產品,其他產生器則忽略它。

CMake 3.3 及更高版本傾向於要求專案明確指定客製化命令的副產品,以便它可以完全避免使用 phony 規則解決方法。引入了政策 CMP0058,以提供與仍然需要此解決方法的現有專案的相容性。

此政策對 Ninja 以外的產生器沒有影響。此政策的 OLD 行為是為建置樹中未知的依賴項產生 Ninja phony 規則。此政策的 NEW 行為是不產生這些規則,而是要求專案明確指定客製化命令的 BYPRODUCTS

此政策是在 CMake 3.3 版本中引入的。它可以使用 cmake_policy()cmake_minimum_required() 進行設定。如果未設定,CMake 會在看到來源外建置樹中未知的依賴項時發出警告,並使用 OLD 行為。

政策設定必須在專案頂層 CMakeLists.txt 檔案的末尾範圍內,並具有全域影響。

注意

政策的 OLD 行為 依定義已棄用,並可能在未來版本的 CMake 中移除。