<> 翻譯 2.1 變量和緩存

<<Modern CMake>> 翻譯 2.1 變量和緩存

局部變量

咱們首先來看變量。局部變量一般這樣設置:html

set(MY_VARIABLE "value") 

變量的名稱一般使用全大寫字母,後面緊跟變量的值。您可使用 ${} 來獲取變量的值,例如,${MY_VARIABLE}1 CMake 具備做用範圍的概念:在設置變量後,只要在同一範圍內,你均可以存取該變量的值。 離開函數或子目錄中的一個文件,變量也隨之消失。 您能夠在 PARENT_SCOPE 的尾部設置變量用於子做用域。緩存

你能夠設置多個值造成一個列表:函數

set(MY_LIST "one" "two") 

這至關於多個值之間用 ; 隔開。因此如下聲明和上面的效果相同:測試

set(MY_LIST "one;two") 

list( 命令有一些實用方法來處理列表,separate_arguments 可以將一個空格分隔的字符串轉爲一個列表(直接修改變量值)。 請注意,CMake 中若是沒有空格,值也能夠不用引號引發來。 這容許您大多數時候均可以不把值用引號引發來。spa

使用 ${} 語法擴展變量時,對於空格的相關規則是同樣的。對於文件和目錄路徑處理要特別當心。 由於路徑能夠隨時包含空格,所以當它們是變量時應該始終用引號引發來(即永遠不要寫${MY_PATH},老是應該寫爲"${MY_PATH}")。命令行

緩存變量

若是你想從命令行設置變量,CMake 會提供變量緩存。 有些變量已經內置了,好比CMAKE_BUILD_TYPE。 這種若是變量還沒有(從命令行)設置,則設置變量值的語法以下:翻譯

set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "Description") 

這將不會取代已經設置的變量值,所以您能夠在命令行上設置它們,而不會在執行 CMake 文件時被覆蓋。 若是要將這些變量做爲全局變量,你能夠這樣書寫:code

set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "" FORCE) mark_as_advanced(MY_CACHE_VARIABLE) 

第一行將致使不管如何都對變量進行設置。 第二行使你運行 cmake -L ..或使用 GUI時,變量將不會顯示在列表中。 這很常見的,所以你也可使用 INTERNAL 類型來達到一樣的效果(雖然從技術上來講它強制爲 STRING 類型,但不會影響任何依賴於變量的 CMake 代碼):htm

set(MY_CACHE_VARIABLE "VALUE" CACHE INTERNAL "") 

因爲 BOOL 類型很是常見,您也可使用 option 指令簡潔地設置它:ip

option(MY_OPTION "This is settable from the command line" OFF) 

對於 BOOL 數據類型值 ON 和 OFF,有幾種不一樣語境。

有關 CMake 中內置變量列表,請參閱 cmake-variables

環境變量

你也能夠用 set(ENV{variable_name} value) 設置,用 $ENV{variable_name} 獲取環境變量值, 但一般最好避免環境變量。

緩存

緩存實際上就是一個文本文件,CMakeCache.txt。CMake 運行時會在構建目錄中建立這個文件。 這就是 CMake 記住你設置的任何內容的方式,所以每次從新運行 CMake 時你沒必要從新(在命令行上)列上這些選項。

屬性

CMake 存儲信息的另外一種方式是使用屬性。 這相似於變量,但它只能附加到其餘條目上,例如目錄或目標。 全局屬性能夠做爲無緩存全局變量。 許多目標屬性經過從 CMAKE_ 打頭的相匹配的變量初始化而來。 例如,設置 CMAKE_CXX_STANDARD 意味着全部的新目標建立時都將把 CXX_STANDARD 設置爲 CMAKE_CXX_STANDARD 變量的值。 設置屬性有兩種方法:

set_property(TARGET TargetName PROPERTY CXX_STANDARD 11) set_target_properties(TargetName PROPERTIES CXX_STANDARD 11) 

第一種形式更通用,能夠一次設置多個目標/文件/測試,並提供有用的選項。 第二個是在一個目標上設置多個屬性的快捷方式。 你能夠這樣獲取目標屬性:

get_property(ResultVariable TARGET TargetName PROPERTY CXX_STANDARD) 

有關全部內置屬性的列表,請參閱 cmake-properties。 在某些狀況下,您也能夠定義你本身的屬性。2

1.  if 語句有點奇怪,由於它可使用也能夠不使用包圍語法來獲取變量; 這是歷史緣由形成的: if出如今  ${} 語法出現以前。  ↩
2. 例如, Interface 目標對容許的自定義屬性有一些限制。  ↩
相關文章
相關標籤/搜索