cmake_policy¶
管理 CMake 策略設定。請參閱 cmake-policies(7)
手冊以了解已定義的策略。
隨著 CMake 的發展,有時需要變更現有的行為,以修正錯誤或改進現有功能的實作方式。CMake 策略機制旨在協助現有的專案在新的 CMake 版本引入行為變更時,仍能繼續建置。每個新策略(行為變更)都會被賦予一個 CMP<NNNN>
形式的識別碼,其中 <NNNN>
是一個整數索引。與每個策略相關的文件描述了 OLD
和 NEW
行為,以及引入該策略的原因。專案可以設定每個策略來選擇所需的行為。當 CMake 需要知道要使用哪種行為時,它會檢查專案指定的設定。如果沒有可用的設定,則會假定為 OLD
行為,並產生警告,要求設定策略。
依 CMake 版本設定策略¶
cmake_policy
命令用於將策略設定為 OLD
或 NEW
行為。雖然支援個別設定策略,但我們鼓勵專案根據 CMake 版本設定策略
- cmake_policy(VERSION <min>[...<max>])¶
在 3.12 版本中新增: 可選的 <max>
版本。
<min>
和可選的 <max>
都是 major.minor[.patch[.tweak]]
形式的 CMake 版本,而 ...
是字面上的。 <min>
版本必須至少為 2.4
,且至多為正在執行的 CMake 版本。如果指定了 <max>
版本,則必須至少為 <min>
版本,但可以超過正在執行的 CMake 版本。如果正在執行的 CMake 版本早於 3.12,則額外的 ...
點會被視為版本組件分隔符號,導致 ...<max>
部分被忽略,並保留基於 <min>
的 pre-3.12 行為。
這指定目前的 CMake 程式碼是為給定的 CMake 版本範圍 <min>[...<max>]
而撰寫的。它將「策略版本」設定為
範圍的
<max>
版本(如果已指定),或<min>
版本,或變數
CMAKE_POLICY_VERSION_MINIMUM
的值(如果它高於其他兩個版本)。
策略版本有效地請求自給定 CMake 版本起偏好的行為,並告知較新的 CMake 版本關於其新策略。正在執行的 CMake 版本已知的所有策略以及在該版本或更早版本中引入的所有策略都將設定為使用 NEW
行為。在較新版本中引入的所有策略都將取消設定(除非 CMAKE_POLICY_DEFAULT_CMP<NNNN>
變數設定了預設值)。這有效地請求自給定 CMake 版本起偏好的行為,並告知較新的 CMake 版本關於其新策略。
請注意,cmake_minimum_required(VERSION)
命令也隱含地呼叫了 cmake_policy(VERSION)
。
在 4.0 版本中變更: 已移除與 CMake 3.5 之前版本的相容性。在 CMake 4.0 及更高版本中,呼叫 cmake_minimum_required(VERSION)
或 cmake_policy(VERSION)
但未指定至少 3.5 作為其策略版本(可選地透過 ...<max>
)將會產生錯誤。
在 3.31 版本中變更: 與 CMake 3.10 之前版本的相容性已被棄用。在 CMake 3.31 及更高版本中,呼叫 cmake_minimum_required(VERSION)
或 cmake_policy(VERSION)
但未指定至少 3.10 作為其策略版本(可選地透過 ...<max>
)將會產生棄用警告。
在 3.27 版本中變更: 與 CMake 3.5 之前版本的相容性已被棄用。在 CMake 3.27 及更高版本中,呼叫 cmake_minimum_required(VERSION)
或 cmake_policy(VERSION)
但未指定至少 3.5 作為其策略版本(可選地透過 ...<max>
)將會產生棄用警告。
在 3.19 版本中變更: 與 CMake 2.8.12 之前版本的相容性已被棄用。在 CMake 3.19 及更高版本中,呼叫 cmake_minimum_required(VERSION)
或 cmake_policy(VERSION)
但未指定至少 2.8.12 作為其策略版本(可選地透過 ...<max>
)將會產生棄用警告。
明確地設定策略¶
- cmake_policy(SET CMP<NNNN> NEW|OLD)¶
告知 CMake 對於給定的策略使用 OLD
或 NEW
行為。依賴於給定策略舊行為的專案可以透過將策略狀態設定為 OLD
來消除策略警告。或者,可以修正專案以使用新行為,並將策略狀態設定為 NEW
。
注意
策略的 OLD
行為依定義已棄用
,並可能在未來的 CMake 版本中移除。
檢查策略設定¶
- cmake_policy(GET CMP<NNNN> <variable>)¶
檢查給定的策略是否設定為 OLD
或 NEW
行為。輸出 <variable>
值將為 OLD
或 NEW
(如果策略已設定),否則為空。
CMake 策略堆疊¶
CMake 將策略設定保存在堆疊中,因此 cmake_policy
命令所做的變更僅影響堆疊的頂端。每個子目錄都會自動管理策略堆疊上的新條目,以保護其父目錄和同級目錄。CMake 也為 include()
和 find_package()
命令載入的腳本管理新條目,除非使用 NO_POLICY_SCOPE
選項調用(另請參閱策略 CMP0011
)。cmake_policy
命令提供了一個介面來管理策略堆疊上的自訂條目
- cmake_policy(PUSH)¶
在策略堆疊上建立一個新條目。
- cmake_policy(POP)¶
移除使用
cmake_policy(PUSH)
建立的最後一個策略堆疊條目。
每個 PUSH
都必須有一個匹配的 POP
才能清除任何變更。這對於臨時變更策略設定很有用。呼叫 cmake_minimum_required(VERSION)
、cmake_policy(VERSION)
或 cmake_policy(SET)
命令只會影響目前策略堆疊的頂端。
在 3.25 版本中新增: block(SCOPE_FOR POLICIES)
命令提供了一種更靈活且更安全的策略堆疊管理方式。當離開區塊範圍時,pop 動作會自動完成,因此無需在每個 return()
之前呼叫 cmake_policy(POP)
。
# stack management with cmake_policy()
function(my_func)
cmake_policy(PUSH)
cmake_policy(SET ...)
if (<cond1>)
...
cmake_policy(POP)
return()
elseif(<cond2>)
...
cmake_policy(POP)
return()
endif()
...
cmake_policy(POP)
endfunction()
# stack management with block()/endblock()
function(my_func)
block(SCOPE_FOR POLICIES)
cmake_policy(SET ...)
if (<cond1>)
...
return()
elseif(<cond2>)
...
return()
endif()
...
endblock()
endfunction()
由 function()
和 macro()
命令建立的命令會在建立時記錄策略設定,並在調用時使用預先記錄的策略。如果函式或巨集實作設定了策略,則變更會自動向上傳播到呼叫者,直到它們到達最近的巢狀策略堆疊條目。