目錄
- 1.條件判斷
- 1.基本表達式
- 2.邏輯判斷
- 3.比較
- 4.文件操作
- 5.其他
- 2.循環
- 1.foreach
- 2.while
1.條件判斷
- 在進行條件判斷的時候,如果有多個條件,那么可以寫多個
elseif
,最后一個條件可以使用else
,但是開始和結束是必須要成對出現的,分別為:if
和endif
- 語法:
if(<condition>)<commands> elseif(<condition>) # 可選快, 可以重復<commands> else() # 可選快<commands> endif()
1.基本表達式
- 語法:
if(<expression>)
- 如果是基本表達式,
expression
有以下三種情況:常量、變量、字符串- 如果是
1
,ON
,YES
,TRUE
,Y
,非零值
,非空字符串
時,條件判斷返回True
- 如果是
0
,OFF
,NO
,FALSE
,N
,IGNORE
,NOTFOUND
,空字符串
時,條件判斷返回False
- 如果是
2.邏輯判斷
- NOT:邏輯取反
if(NOT <condition>)
- AND:邏輯與
if(<cond1> AND <cond2>)
- OR:邏輯或
if(<cond1> OR <cond2>)
3.比較
- 基于數值的比較
if(<variable|string> LESS <variable|string>) if(<variable|string> GREATER <variable|string>) if(<variable|string> EQUAL <variable|string>) if(<variable|string> LESS_EQUAL <variable|string>) if(<variable|string> GREATER_EQUAL <variable|string>)
- 基于字符串的比較
if(<variable|string> STRLESS <variable|string>) if(<variable|string> STRGREATER <variable|string>) if(<variable|string> STREQUAL <variable|string>) if(<variable|string> STRLESS_EQUAL <variable|string>) if(<variable|string> STRGREATER_EQUAL <variable|string>)
4.文件操作
- 判斷文件或者目錄是否存在
if(EXISTS path-to-file-or-directory)
- 判斷是不是目錄:此處
path
必須是絕對路徑if(IS_DIRECTORY path)
- 判斷是不是軟鏈接:此處的
file-name
必須是絕對路徑if(IS_SYMLINK file-name)
- 判斷是不是絕對路徑
if(IS_ABSOLUTE path)
5.其他
- 判斷某個元素是否在列表中:CMake版本要求 > 3.3
if(<variable|string> IN_LIST <variable>)
- 比較兩個路徑是否相等:CMake版本要求 > 3.24
if(<variable|string> PATH_EQUAL <variable|string>)
- 關于路徑的比較其實就是兩個字符串的比較,如果路徑格式書寫沒有問題也可以通過下面這種方式進行比較
if(<variable|string> STREQUAL <variable|string>)
- 在書寫某個路徑的時候,可能由于誤操作會多寫幾個分隔符,比如把
/a/b/c
寫成/a//b///c
,此時通過STREQUAL
對這兩個字符串進行比較肯定是不相等的,但是通過PATH_EQUAL
去比較兩個路徑,得到的結果確實相等的,可以看下面的例子:cmake_minimum_required(VERSION 3.26) project(test)if("/home//robin///Linux" PATH_EQUAL "/home/robin/Linux")message("路徑相等") # √ else()message("路徑不相等") endif()message(STATUS "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")if("/home//robin///Linux" STREQUAL "/home/robin/Linux")message("路徑相等") else()message("路徑不相等") # √ endif()
- 結論:在進行路徑比較的時候
- 如果使用
PATH_EQUAL
可以自動剔除路徑中多余的分割線然后再進行路徑的對比 - 使用
STREQUAL
則只能進行字符串比較
- 如果使用
- 關于路徑的比較其實就是兩個字符串的比較,如果路徑格式書寫沒有問題也可以通過下面這種方式進行比較
2.循環
1.foreach
- 通過
foreach
就可以對items
中的數據進行遍歷,然后通過loop_var
將遍歷到的當前的值取出 - 語法:
foreach(<loop_var> <items>)<commands> endforeach()
loop_var
在取值的時候有以下幾種用法:foreach(<loop_var> RANGE <stop>)
- 參數:
RANGE
:關鍵字,表示要遍歷范圍stop
:這是一個正整數,表示范圍的結束值,[0, stop]
loop_var
:存儲每次循環取出的值
- 示例:
cmake_minimum_required(VERSION 3.2) project(test)foreach(item RANGE 10)message(STATUS "當前遍歷的值為: ${item}" ) endforeach()
- 參數:
foreach(<loop_var> RANGE <start> <stop> [<step>])
- 在遍歷一個整數區間的時候,除了可以指定起始范圍,還可以指定步長
- 參數:
RANGE
:關鍵字,表示要遍歷范圍start
:這是一個正整數,表示范圍的起始值,也就是說最小值為start
stop
:這是一個正整數,表示范圍的結束值,也就是說最大值為stop
step
:控制每次遍歷的時候以怎樣的步長增長,默認為1,可以不設置loop_var
:存儲每次循環取出的值
- 示例:
cmake_minimum_required(VERSION 3.2) project(test)foreach(item RANGE 10 30 2)message(STATUS "當前遍歷的值為: ${item}" ) endforeach()
foreach(<loop_var> IN [LISTS [<lists>]] [ITEMS [<items>]])
- 這是
foreach
的另一個變體,通過這種方式可以對更加復雜的數據進行遍歷,前兩種方式只適用于對某個正整數范圍內的遍歷 - 參數:
IN
:關鍵字,表示在xxx
里面LISTS
:關鍵字,對應的是列表list
,通過set、list
可以獲得ITEMS
:關鍵字,對應的也是列表loop_var
:存儲每次循環取出的值
- 示例1:
cmake_minimum_required(VERSION 3.2) project(test)# 創建 list set(WORD a b c d) set(NAME I am DieSnowK)# 遍歷 list foreach(item IN LISTS WORD NAME)message(STATUS "當前遍歷的值為: ${item}" ) endforeach()
- 結果1
-- 當前遍歷的值為: a -- 當前遍歷的值為: b -- 當前遍歷的值為: c -- 當前遍歷的值為: d -- 當前遍歷的值為: I -- 當前遍歷的值為: am -- 當前遍歷的值為: DieSnowK
- 示例2
cmake_minimum_required(VERSION 3.2) project(test)set(WORD a b c "d e f") set(NAME I am DieSnowK)foreach(item IN ITEMS ${WORD} ${NAME})message(STATUS "當前遍歷的值為: ${item}" ) endforeach()
- 結果2
-- 當前遍歷的值為: a -- 當前遍歷的值為: b -- 當前遍歷的值為: c -- 當前遍歷的值為: d e f -- 當前遍歷的值為: I -- 當前遍歷的值為: am -- 當前遍歷的值為: DieSnowK
- 兩種示例的區別:
- 遍歷過程中將關鍵字
LISTS
改成了ITEMS
,后邊跟的還是一個或者多個列表 - 只不過此時需要通過
${}
將列表中的值取出
- 遍歷過程中將關鍵字
- 這是
foreach(<loop_var>... IN ZIP_LISTS <lists>)
- 注意:CMake版本要求 > 3.17
- 通過這種方式,遍歷的還是一個或多個列表,可以理解為是方式3的加強版
- 因為通過上面的方式遍歷多個列表,但是又想把指定列表中的元素取出來使用是做不到的,在這個加強版中就可以輕松實現
- 參數:
IN
:關鍵字,表示在xxx
里面ZIP_LISTS
:關鍵字,對應的是列表list
,通過set、list
可以獲得loop_var
:存儲每次循環取出的值,可以根據要遍歷的列表的數量指定多個變量,用于存儲對應的列表當前取出的那個值- 如果指定了多個變量名,它們的數量應該和列表的數量相等
- 如果只給出了一個
loop_var
,那么它將一系列的loop_var_N
變量來存儲對應列表中的當前項loop_var_0
對應第一個列表loop_var_1
對應第二個列表- 以此類推…
- 示例:
cmake_minimum_required(VERSION 3.17) project(test)# 通過list給列表添加數據 list(APPEND WORD Die SnowK "Die SnowK") list(APPEND NAME I am Die SnowK haha)# 遍歷列表 foreach(item1 item2 IN ZIP_LISTS WORD NAME)message(STATUS "當前遍歷的值為: item1 = ${item1}, item2=${item2}" ) endforeach()message("=============================") # 遍歷列表 foreach(item IN ZIP_LISTS WORD NAME)message(STATUS "當前遍歷的值為: item1 = ${item_0}, item2=${item_1}" ) endforeach()
- 結果
-- 當前遍歷的值為: item1 = Die, item2=I -- 當前遍歷的值為: item1 = SnowK, item2=am -- 當前遍歷的值為: item1 = Die SnowK, item2=Die -- 當前遍歷的值為: item1 = , item2=SnowK -- 當前遍歷的值為: item1 = , item2=haha ============================= -- 當前遍歷的值為: item1 = Die, item2=I -- 當前遍歷的值為: item1 = SnowK, item2=am -- 當前遍歷的值為: item1 = Die SnowK, item2=Die -- 當前遍歷的值為: item1 = , item2=SnowK -- 當前遍歷的值為: item1 = , item2=haha
2.while
- 語法:循環結束對應的條件判斷的書寫格式和
if/elseif
是一樣的while(<condition>)<commands> endwhile()
- 示例:
cmake_minimum_required(VERSION 3.5) project(test)# 創建一個列表 NAME set(NAME I am Die SnowK haha) # 得到列表長度 list(LENGTH NAME LEN)# 循環 while(${LEN} GREATER 0)message(STATUS "names = ${NAME}")# 彈出列表頭部元素list(POP_FRONT NAME)# 更新列表長度list(LENGTH NAME LEN) endwhile()
- 結果
-- names = I;am;Die;SnowK;haha -- names = am;Die;SnowK;haha -- names = Die;SnowK;haha -- names = SnowK;haha -- names = haha