-
命令格式
set(<variable> <value>... [PARENT_SCOPE])#設(shè)置普通變量
set(<variable> <value>...CACHE<type> <docstring> [FORCE])#設(shè)置緩存條目
set(ENV{<variable>} [<value>])#設(shè)置環(huán)境變量??
set命令可以設(shè)置普通變量、緩存條目、環(huán)境變量三種變量的值,分別對應(yīng)上述三種命令格式。set的值<value>...表示可以給變量設(shè)置0個或者多個值,當(dāng)設(shè)置多個值時(大于2個),多個值會通過分號連接符連接成一個真實的值賦值給變量,當(dāng)設(shè)置0個值時,實際上是把變量變?yōu)槲丛O(shè)置狀態(tài),相當(dāng)于調(diào)用unset命令。 -
命令解析
下面分別對三種變量的設(shè)置進(jìn)行說明。
1. 設(shè)置普通變量
??命令格式:
set(<variable> <value>... [PARENT_SCOPE])
??命令含義:將變量variable設(shè)置為值<value>...,變量variable的作用域為調(diào)用set命令的函數(shù)或者當(dāng)前目錄,如果使用了PARENT_SCOPE選項,意味著該變量的作用域會傳遞到上一層(也就是上一層目錄或者當(dāng)前函數(shù)的調(diào)用者,如果是函數(shù)則傳遞到函數(shù)的調(diào)用者,如果是目錄則傳遞到上一層目錄),并且在當(dāng)前作用域該變量不受帶PARENT_SCOPE選項的set命令的影響(如果變量之前沒有定義,那么在當(dāng)前作用域仍然是無定義的;如果之前有定義值,那么值和之前定義的值保持一致)。
??關(guān)于變量的作用域:每一個新的目錄或者函數(shù)都會創(chuàng)建一個新的作用域,普通變量的作用域,如果不使用PARENT_SCOPE選項,只能從外層往內(nèi)層傳遞。- 1)先來看最常用的用法,設(shè)置變量為一個給定的值
cmake_minimum_required (VERSION 3.10.2) project (set_test) set (normal_var a) message (">>> value = ${normal_var}")??輸出為:
>>> value = a- 2)設(shè)置變量為多個給定的值
cmake_minimum_required (VERSION 3.10.2) project (set_test) set (normal_var a b c) message (">>> value = ${normal_var}")??輸出為:
>>> value = a;b;c??可以看到多個值被
;號連接最終的值之后賦給變量。- 3)設(shè)置變量為空
cmake_minimum_required (VERSION 3.10.2) project (set_test) set (normal_var a b c) message (">>> value = ${normal_var}") set (normal_var) # 設(shè)置變量為空 message (">>> value = ${normal_var}")??輸出為:
>>> value = a;b;c >>> value =- 4)在函數(shù)內(nèi)使用選項
PARENT_SCOPE,對應(yīng)的作用域只能傳遞到調(diào)用它的函數(shù)。
場景1:在函數(shù)內(nèi)使用選項PARENT_SCOPE定義變量,在函數(shù)定義的文件中(非另一個函數(shù)中)使用該變量。
結(jié)果:變量無定義。
結(jié)論:函數(shù)內(nèi)定義的變量,在函數(shù)定義的文件中調(diào)用,找不到變量的定義。# CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_test) function (test_fn arg1) set (normal_var_in_fn ${arg1} PARENT_SCOPE) endfunction (test_fn) message (">>> in directory, value = ${normal_var_fn}")
場景2:在函數(shù)內(nèi)使用選項# 輸出 >>> in directory, value = >>> in function, value =PARENT_SCOPE定義變量,在函數(shù)內(nèi)使用該變量。
結(jié)果:變量無定義。
結(jié)論:函數(shù)內(nèi)使用選項PARENT_SCOPE定義的變量,在函數(shù)內(nèi)也是無定義的。# CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_test) function (test_fn arg1) set (normal_var_in_fn ${arg1} PARENT_SCOPE) message (">>> in function, value = ${normal_var_fn}") endfunction (test_fn) test_fn (hello)
場景3:在函數(shù)內(nèi)使用選項# 輸出 >>> in function, value =PARENT_SCOPE定義變量,在函數(shù)內(nèi)使用該變量,并且使用set命令不帶PARENT_SCOPE選項定義過該變量。
結(jié)果:函數(shù)內(nèi)的變量值為不帶PARENT_SCOPE選項的set命令所定義的。
結(jié)論:選項PARENT_SCOPE定義的變量作用域在上一層函數(shù),當(dāng)前函數(shù)的變量必須使用不帶選項PARENT_SCOPE定義。# CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_test) function (test_fn arg1) set (normal_var_in_fn nohello) set (normal_var_in_fn ${arg1} PARENT_SCOPE) message (">>> in function, value = ${normal_var_in_fn}") endfunction (test_fn) test_fn (hello)
場景4:在函數(shù)(示例中為# 輸出 >>> in function, value = nohellotest_fn)內(nèi)使用選項PARENT_SCOPE定義變量,在另一個函數(shù)(調(diào)用者,示例中為test_fn_parent)內(nèi)調(diào)用該函數(shù)。
結(jié)果:調(diào)用者函數(shù)內(nèi)有該變量的定義。
結(jié)論:選項PARENT_SCOPE將變量傳遞到上一層調(diào)用函數(shù)。# CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_test) function (test_fn arg1) set (normal_var_in_fn nohello) set (normal_var_in_fn ${arg1} PARENT_SCOPE) message (">>> in function, value = ${normal_var_in_fn}") endfunction (test_fn) function (test_fn_parent arg1) test_fn (${arg1}) message (">>> in parent function, value = ${normal_var_in_fn}") endfunction (test_fn_parent) test_fn_parent (hello)# 輸出 >>> in function, value = nohello >>> in parent function, value = hello - 5)在目錄內(nèi)使用選項
PARENT_SCOPE,對應(yīng)的作用域只能傳遞到上層目錄,變量的傳遞過程與4)中函數(shù)的場景類似,不再贅述。注意一點:本例在test和test/sub下分別創(chuàng)建一個CMakeLists.txt文件。
示例如下:# test/sub/CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_sub_test) set (normal_var_in_sub_dir sub_hello) set (normal_var_in_sub_dir hello PARENT_SCOPE) message (">>>>>> in sub directory, value = ${normal_var_in_sub_dir}")# test/CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_test) add_subdirectory (sub) message (">>> in top level, value = ${normal_var_in_sub_dir}")# 輸出 >>>>>> in sub directory, value = sub_hello >>> in top level, value = hello
2. 設(shè)置緩存條目
??命令格式:
set(<variable> <value>...CACHE<type> <docstring> [FORCE])
??命令含義:將緩存條目variable設(shè)置為值<value>...,除非用戶進(jìn)行設(shè)置或使用了選項FORCE,默認(rèn)情況下緩存條目的值不會被覆蓋。緩存條目可以通過CMAKE的GUI界面的add entry按鈕來增加。緩存條目的實質(zhì)為可以跨層級進(jìn)行傳遞的變量,類似于全局變量。
??緩存條目的<type>主要有以下幾類:-
BOOL:布爾值ON/OFF,CMAKE的GUI界面對此類緩存條目會提供一個復(fù)選框。 -
FILEPATH:文件路徑,CMAKE的GUI界面對此類緩存條目會提供一個文件選擇框。 -
PATH:目錄路徑,CMAKE的GUI界面對此類緩存條目會提供一個目錄選擇框。 -
STRING / STRINGS:文本行,CMAKE的GUI界面對此類緩存條目會提供一個文本框(對應(yīng)STRING)或下拉選擇框(對應(yīng)STRINGS)。 -
INTERNAL:文本行,但是只用于內(nèi)部,不對外呈現(xiàn)。主要用于運(yùn)行過程中存儲變量,因此使用該type意味著使用FORCE。
??緩存條目的幾個注意事項:
1)如果變量先前未定義或者使用了FORCE選項,則緩存條目會直接被賦值。
2)可以在使用cmake構(gòu)建的使用通過-D選項來給緩存條目賦值,這樣CMakeLists.txt內(nèi)的set命令只會為緩存條目添加類型。
3)如果變量類型是目錄或者文件路徑,通過-D選項傳入的若只是相對路徑,那么set會給這個相對路徑前添加當(dāng)前的工作目錄以變成絕對路徑(如果已經(jīng)是絕對路徑則不會處理)。# CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_test) set (cache_entry_val ON OFF CACHE BOOL "choose ON to enable") message (">>> value = ${cache_entry_val}") set (cache_entry_val2 ON CACHE BOOL "choose ON to enable" FORCE) message (">>> value2 = ${cache_entry_val2}") set (cache_entry_val3 ON) set (cache_entry_val3 OFF CACHE BOOL "choose ON to enable") message (">>> value3 = ${cache_entry_val3}") set (cache_entry_input OFF CACHE BOOL "choose ON to enable") message (">>> value4 = ${cache_entry_input}") set (mypath "test" CACHE FILEPATH "choose a file path") message (">>> value5 = ${mypath}")# 輸入cmake構(gòu)建,使用-D選項 cmake . -Dcache_entry_input=ON -Dmypath=sub # 輸出 >>> value = ON;OFF >>> value2 = ON >>> value3 = ON >>> value4 = ON >>> value5 = /XXX/XXX/XXX/sub
3. 設(shè)置環(huán)境變量
??命令格式:
set(ENV{<variable>} [<value>])
??命令含義:將環(huán)境變量設(shè)置為值<value>(注意沒有...),接著使用$ENV{<variable>}會得到新的值。cmake中的環(huán)境變量可以參考:環(huán)境變量。
??環(huán)境變量設(shè)置的幾個注意事項:
1)該命令設(shè)置的環(huán)境變量只在當(dāng)前的cmake進(jìn)程生效,既不會影響調(diào)用者的環(huán)境變量,也不會影響系統(tǒng)環(huán)境變量。
2)如果<value>值為空或者ENV{<variable>}后沒有參數(shù),則該命令會清除掉當(dāng)前環(huán)境變量的值。
3)<value>后的參數(shù)會被忽略。# CMakeLists.txt cmake_minimum_required (VERSION 3.10.2) project (set_test) message (">>> value = $ENV{CMAKE_PREFIX_PATH}") set (ENV{CMAKE_PREFIX_PATH} "/test/sub") message (">>> value = $ENV{CMAKE_PREFIX_PATH}") set (ENV{CMAKE_PREFIX_PATH}) message (">>> value = $ENV{CMAKE_PREFIX_PATH}") set (ENV{CMAKE_PREFIX_PATH} "/test/top/") message (">>> value = $ENV{CMAKE_PREFIX_PATH}") set (ENV{CMAKE_PREFIX_PATH} "") message (">>> value = $ENV{CMAKE_PREFIX_PATH}")# 輸出 >>> value = >>> value = /test/sub >>> value = >>> value = /test/top >>> value =
?