if()
elseif() # optional block, can be repeated
else() # optional block
endif()
else和endif中可不带参数,如果要带则需要与if中的条件参数一样。
if()
1, ON, YES, TRUE, Y, 或者非0数字(包括浮点数)表示TRUE。
0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, 空字符串,以-NOTFOUND结尾的常量表示FALSE。
常量大小写不敏感。
#constant 大小写不敏感
##constant true
if(1 AND ON AND YES AND TRUE AND Y AND 0.1 )#AND ""
message("constant true")
endif()
##constant false
if(NOT(0 OR OFF OR NO OR fALSE OR N OR IGNORE OR "" OR NOTFOUND))
#以及以-NOTFOUND结尾的常量
message("constant false")
endif()
if()
如果变量的值不是表示false的常量都为TRUE,否则都是false,包括未定义。
注意:宏参数不是变量。
注意:环境变量不能通过此检测,即都是false。
#variable
set(VAR "1")
#变量在条件中是直接使用var的,而使用${VAR}实际上走的是constant逻辑
#两者在这里没有什么明显区别,但是在macro中使用就有区别了,macro中,使用参数为false,而使用$则根据参数值确定
#其值只要不是const fasle,且定义了,都是true
if(VAR)
message("variable ")
endif()
if(${VAR})
message("variable value" )
endif()
#注意宏参数不是变量
macro(test mvar)
if(${mvar})
message("macro argument" ${mvar})
endif()
endmacro(test mvar)
test(${VAR})
#env varaiable不能被检测。
set(ENV{CXXFLAGS} "test")
message("-------->" $ENV{CXXFLAGS})
if(ENV{CXXFLAGS})
message("variable env " )
endif()
#print:
#variable
#variable value
#macro argument1
#-------->test
if()
带引号的字符串除了以下的场景外都是false:
#string
#除非等于constant true或者cmp0054为new,并且字符串值为变量名,否则都是false
set(VAR "111")
if(NOT "test")
message("string" )
endif()
cmake_policy(SET CMP0054 OLD)
if("VAR")
message("string var" )
endif()
#print:
#string
#string var
NOT、AND、OR
if(COMMAND )
存在名字为command-name的命令、函数、宏则为true,
if(POLICY )
如果存在policy-id则为true,形式如CMP0054
if(TARGET )
已经存在通过add_executable(), add_library(), or add_custom_target()创建的目标名则为true
if(TEST )
已经存在通过add_test()创建的测试名则返回true。
if(DEFINED |CACHE{}|ENV{})
如果定义了变量、缓存变量、环境变量name,则返回true。注意name和CACHE{name}是不一样的。
if( IN_LIST )
判断变量或字符串是否在variable中。
if(EXISTS )
文件或目录是否存在。注意需要传入全路径,如~/开始的目录则不回被扩展为家目录并作为相对目录(即找不到)。
如果路径为符号链接,那么结果由实际目标确定,即如果目标不存在则返回false,否则返回true
字符串为空则为false
if( IS_NEWER_THAN )
判断file1是否比file2新
if(IS_DIRECTORY )
判断是否是目录,要求全路径。
if(IS_SYMLINK )
判断是否是软链接,要求全路径。
if(IS_ABSOLUTE )
判断是否是绝对路径。注意一些特殊场景:
if( MATCHES )
如果变量或字符串符合正则regex规则,则为true
if( Comparisons )
Comparisons包括LESS、GREATER、EQUAL、LESS_EQUAL、GREATER_EQUAL。
只有当指定变量或字符串的值为合法数字,并且前者小于、大于、等于、小于等于、大于等于时为true。
if( strComparisons )¶
Comparisons包括STRLESS、STRGREATER、STREQUAL、STRLESS_EQUAL、STRGREATER_EQUAL。
只有左侧变量或者字符串值的字母顺序小于、、大于、等于、小于等于、大于等于右侧时为true。
if( version_Comparisons )¶
Comparisons包括VERSION_LESS、VERSION_GREATER、VERSION_EQUAL、VERSION_LESS_EQUAL、VERSION_GREATER_EQUAL。
只有左侧变量或者字符串的版本小于、大于、等于、小于等于、大于等于右侧时为true。
if( PATH_EQUAL )
只有左侧路径等于右侧时为true。
比较时,是按路径的逐个部分进行比较,多个分隔符会被合并,斜杠和反斜杠两种分隔符也不会区分。
# comparison is TRUE
if ("/a//b/c" PATH_EQUAL "/a/b/c")
...
endif()
# comparison is TRUE
if ("/a//b/c" PATH_EQUAL "/a\\b/c")
message("path equal" )
endif()
# comparison is FALSE
if ("/a//b/c" STREQUAL "/a/b/c")
...
endif()
if命令在CMake的历史中很早就被编写出来了,早于${}变量求值语法,为了方便,它求值由其参数命名的变量,如上面的签名所示。注意,在if命令接收参数之前,使用${}进行正常的变量求值。因此下面的代码
set(var1 OFF)
set(var2 "var1")
if(${var2})
等同于
if(var1)
并且会以if的变量形式处理,即判断var1变量的值,为OFF,因此为false。
而如果我们移除${}
if(var2)
则条件为true,因为var2的变量值不是为false的常量值。
遍历列表中的所有值,并执行一系列命令
foreach( )
endforeach()
items是以分号或者空格分隔的列表。
#items:;或者空格分隔的列表,不要加引号,否则认为是一个
foreach(it a;b;c;d) #"a;b;c;d" print:string list:abcd
message("string list:" ${it})
endforeach(it "a;b;c;d")
#print
#string list:a
#string list:b
#string list:c
#string list:d
foreach( RANGE )
从0开始到stop的数字(包含stop),stop是非负整数
foreach( RANGE [])
指定遍历的起始数字、结束数字以及步长。
foreach(it RANGE 5)
message("range 5:"${it})
endforeach(it RANGE 5)
foreach(it RANGE 5 12 2)
message("5-12,step 2:"${it})
endforeach()
print:
range 5:0
range 5:1
range 5:2
range 5:3
range 5:4
range 5:5
5-12,step 2:5
5-12,step 2:7
5-12,step 2:9
5-12,step 2:11
foreach( IN [LISTS []] [ITEMS []])
可以通过LISTS或ITEMS将多个列表合并遍历。
set(A 0;1)
set(B 2 3)
set(C "4 5")
set(D 6;7 8)
set(E "")
foreach(X IN LISTS A B C D E)
message(STATUS "X=${X}")
endforeach()
print:
-- X=0
-- X=1
-- X=2
-- X=3
-- X=4 5
-- X=6
-- X=7
-- X=8
foreach(... IN ZIP_LISTS )
将多个list压缩,类似于多个map。
list(APPEND English one two three four)
list(APPEND Bahasa satu dua tiga)
foreach(num IN ZIP_LISTS English Bahasa)
message(STATUS "num_0=${num_0}, num_1=${num_1}")
endforeach()
foreach(en ba IN ZIP_LISTS English Bahasa)
message(STATUS "en=${en}, ba=${ba}")
endforeach()
print:
-- num_0=one, num_1=satu
-- num_0=two, num_1=dua
-- num_0=three, num_1=tiga
-- num_0=four, num_1=
-- en=one, ba=satu
-- en=two, ba=dua
-- en=three, ba=tiga
-- en=four, ba=
遍历次数为最长的那个列表长度。
while()
endwhile()
condition与if相同,为true时重复执行command,可以使用break和continue命令。