CMake 快取¶
CMake 快取可以被視為一個設定檔。當第一次在專案上執行 CMake 時,它會在建置樹的頂層目錄中產生一個 CMakeCache.txt
檔案。CMake 使用此檔案來儲存一組全域快取變數,這些變數的值在專案建置樹中的多次執行中會持續存在。
這個快取有幾個用途。第一個用途是儲存使用者的選擇和設定,這樣如果他們再次執行 CMake,就不需要重新輸入這些資訊。例如,option
命令會建立一個布林變數並將其儲存在快取中。
option(USE_JPEG "Do you want to use the jpeg library")
上面的程式碼會建立一個名為 USE_JPEG
的變數並將其放入快取中。這樣使用者就可以從使用者介面設定該變數,並且它的值在使用者將來再次執行 CMake 時會保持不變。要在快取中建立變數,請使用諸如 option
、find_file
或標準的 set
命令搭配 CACHE
選項的命令。
set(USE_JPEG ON CACHE BOOL "include jpeg support?")
當您使用 CACHE
選項時,您還可以提供變數的類型和文件字串。變數的類型由 cmake-gui
用於控制該變數的設定和顯示方式,但該值始終以字串形式儲存在快取檔案中。
快取的另一個目的是讓 CMake 本身可以在多次 CMake 執行之間持久儲存值。這些條目可能對使用者不可見或不可調整。通常,這些值是與系統相關的變數,需要 CMake 編譯並執行程式來確定其值。一旦確定了這些值,它們就會儲存在快取中,以避免每次執行 CMake 時都必須重新計算。CMake 通常會限制這些變數為永遠不應該更改的屬性(例如您所在機器的位元組順序)。如果您大幅更改電腦,例如變更作業系統或切換到不同的編譯器,您將需要刪除快取檔案(可能還有您所有二元樹的目標檔案、函式庫和可執行檔)。
有些專案非常複雜,在快取中設定一個值可能會導致下次建置快取時出現新的選項。例如,VTK 支援使用 MPI 來執行分散式運算。這需要建置過程確定 MPI 函式庫和標頭檔案的位置,並讓使用者調整它們的值。但是,只有在 VTK 中首先開啟另一個選項 VTK_USE_PARALLEL
時,MPI 才可用。因此,為了避免不了解 MPI 的人感到困惑,這些選項會被隱藏起來,直到 VTK_USE_PARALLEL
開啟為止。因此,CMake 會在快取區域中顯示 VTK_USE_PARALLEL
選項,如果使用者開啟該選項並使用 CMake 重新設定,則會出現新的 MPI 選項,然後他們可以設定這些選項。規則是持續建置快取,直到它不再變更為止。對於大多數專案來說,這只會發生一次。對於一些複雜的專案,可能需要兩次或更多次。
您可能會想直接編輯快取檔案,或透過提供一個預先填入的 CMakeCache.txt
檔案來「初始化」一個專案。這可能無法運作,並且可能會在未來導致其他問題。首先,CMake 快取的語法可能會變更。其次,快取檔案包含完整路徑,這使得它們不適合在二元樹之間移動。
一旦變數進入快取,其「快取」值通常無法從 CMakeLists 檔案中修改。這背後的理由是,一旦 CMake 將變數及其初始值放入快取中,使用者就可以從 GUI 修改該值。如果下次呼叫 CMake 時,將其變更覆寫回 set
值,則使用者將永遠無法進行 CMake 不會覆寫的變更。set(FOO ON CACHE BOOL "doc")
命令通常只會在快取中沒有該變數時才執行某些操作。一旦變數進入快取,該命令將不會有任何作用。
在極少數情況下,您真的想更改快取變數的值,請將 FORCE
選項與 set
命令的 CACHE
選項結合使用。FORCE
選項會導致 set
命令覆寫並變更變數的快取值。
關於變數及其與快取的互動,應該提出幾個最後的重點。如果變數在快取中,仍可以使用 set
命令在 CMakeLists 檔案中覆寫它,而無需使用 CACHE
選項。當參考的變數未在目前範圍中定義時,會檢查快取值。set
命令將為目前範圍定義一個變數,而不會變更快取中的值。
# assume that FOO is set to ON in the cache
set(FOO OFF)
# sets foo to OFF for processing this CMakeLists file
# and subdirectories; the value in the cache stays ON
快取中的變數也具有一個屬性,指示它們是否為進階變數。預設情況下,當執行 ccmake
或 cmake-gui
時,不會顯示進階快取條目。這是為了讓使用者可以專注於他們應該考慮變更的快取條目。進階快取條目是使用者可以修改的其他選項,但通常不會修改。一個大型軟體專案擁有 50 個或更多選項並不罕見,而且進階屬性可讓軟體專案將它們分為大多數使用者的主要選項和進階使用者的進階選項。根據專案的不同,可能沒有任何非進階快取條目。要使快取條目成為進階條目,請使用 mark_as_advanced
命令以及變數名稱(又稱快取條目)。
在某些情況下,您可能希望將快取條目限制為一組預定義的選項。您可以透過在快取條目上設定 STRINGS
屬性來做到這一點。以下 CMakeLists 程式碼說明了這一點,它像往常一樣建立了一個名為 CRYPTOBACKEND
的屬性,然後將其 STRINGS
屬性設定為一組三個選項。
set(CRYPTOBACKEND "OpenSSL" CACHE STRING
"Select a cryptography backend")
set_property(CACHE CRYPTOBACKEND PROPERTY STRINGS
"OpenSSL" "LibTomCrypt" "LibDES")
當執行 cmake-gui
且使用者選取 CRYPTOBACKEND
快取條目時,他們將看到一個下拉式選單,讓他們選取他們想要的選項。
設定 CMake 的初始值¶
有時您可能需要在不執行 GUI 的情況下設定快取條目。當設定夜間儀表板,或如果您將使用相同的快取值建立許多建置樹時,這種情況很常見。在這些情況下,可以使用兩種不同的方式初始化 CMake 快取。第一種方法是使用 -DCACHE_VAR:TYPE=VALUE
引數在 CMake 命令列上傳遞快取值。例如,請考慮以下用於 UNIX 機器的夜間儀表板指令碼
#!/bin/tcsh
cd ${HOME}
# wipe out the old binary tree and then create it again
rm -rf Foo-Linux
mkdir Foo-Linux
cd Foo-Linux
# run cmake to setup the cache
cmake -DBUILD_TESTING:BOOL=ON <etc...> ../Foo
# generate the dashboard
ctest -D Nightly
相同的概念可以用於 Windows 上的批次檔案。
第二種方法是建立一個使用 cmake
的 -C
選項載入的檔案。在這種情況下,不是使用 -D
選項設定快取,而是透過 CMake 剖析的檔案來設定。此檔案的語法是標準的 CMakeLists 語法,它通常是一系列的 set
命令,例如
# Build the vtkHybrid kit.
set(VTK_USE_HYBRID ON CACHE BOOL "doc string")
在某些情況下,可能存在一個現有的快取,而您想要強制將快取值設定為某種方式。例如,假設您想要開啟 Hybrid,即使使用者之前執行過 CMake 並關閉了它。然後您可以執行
# Build the vtkHybrid kit always.
set(VTK_USE_HYBRID ON CACHE BOOL "doc" FORCE)
另一個選項是您想要設定選項,然後隱藏這些選項,讓使用者不會想要在之後調整它們。這可以使用類型 INTERNAL
來完成。INTERNAL
快取變數意味著 FORCE
,並且永遠不會在快取編輯器中顯示。
# Build the vtkHybrid kit always and don't distract
# the user by showing the option.
set(VTK_USE_HYBRID ON CACHE INTERNAL "doc")