语法格式如下:
#注释内容
备注:注释从 #开始到行尾结束
例子:
- # 这是单行注释
- message("First Argument\n" # 这是单行注释 :)
- "Second Argument") # 这是单行注释.
Cmake 使用括号参数 (Bracket Argument )来实现多行注释
语法格式如下:
- # [ = *[注释内容] = *]
备注:其中 * 号表示 0 个或者多个 =,当然左边 = 号的数量要等于右边 = 的数量
最简单格式是:
#[[注释内容]]
例子:
- #[[这是多行注释!
- 这是多行注释!
- 这是多行注释!]]
- message("First Argument\n" #[[这是多行注释]] "Second Argument")
在 cmake 语言中,所有的变量都是 string 类型。可以使用 cmake 内置的 set() 和 unset() 命令来明确的设置或者移除一个变量。
语法格式如下:
- set(变量名变量值)
备注:变量名是大小写敏感的,变量名可以包含任何文本,官方建议只使用字母数字 - 和_
例子:
set(var 123)
语法格式如下:
- ${变量名}
- $ENV{VAR}
备注: $ENV{VAR} 是对环境变量 VAR 的引用,cmake 支持变量嵌套引用,解引用的顺序从内到外
例子:
- set(var 123)
- message(" var = ${var}")
- message("PATH = $ENV{PATH}")
- set(inner_var foo)
- set(outer_foo_var 999)
- message("nest variable value is :${outer_${inner_var}_var}")
列表也是字符串,可以把列表看做特殊的变量,这个变量有多个值,每个值用分号 ";" 进行分隔。
语法格式如下:
- set(列表名 值1 值2 ... 值N)
- 或者
- set(列表名 "值1;值2; ...;值N")
例子:
- set(list_var 1 2 3 4) # list_var = 1;2;3;4
- set(list_foo "5;6;7;8") # list_foo = 5;6;7;8
语法格式如下:
${列表名}
例子:
- set(list_var 1 2 3 4) # list_var = 1;2;3;4
- set(list_foo "5;6;7;8") # list_foo = 5;6;7;8
- message(${list_var})#输出: 1234
- message(${list_foo})#输出:5678
- message("${list_var}")#输出:1;2;3;4
- message("${list_foo}")#输出:5;6;7;8
备注:不加引号的引用 cmake 将自动在分号处进行切分成多个列表元素,并把它们作为多个独立的参数传给命令。加了引号的引用 cmake 不会进行切分并保持分号不动,把整个引号内的内容当作一个参数传给命令。
在 cmake 语言中,不管是条件语句,循环语句,函数或者宏,都是命令。
用于条件 / 循环的表达式的操作符,这些操作符是大小写敏感的。操作符的处理优先级:
带 () 的表达式> 一元 > 二元 > 逻辑
操作符类型 | 操作符名称 |
---|---|
一元 | EXISTS, COMMAND, DEFINED. |
二元 | EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, STREQUAL,STRLESS, STRLESS_EQUAL, STRGREATER, STRGREATER_EQUAL,VERSION_EQUAL, VERSION_LESS, VERSION_LESS_EQUAL, VERSION_GREATER, VERSION_GREATER_EQUAL,MATCHES |
逻辑 | NOT, AND, OR |
Cmake 中的布尔常量值也是大小写敏感的。
类型 | 值 |
---|---|
true | 1, ON, YES, TRUE, Y, 非 0 的值 |
false | 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, 空字符串 "", 以 - NOTFOUND 结尾的字符串 |
语法格式如下:
- if(表达式)
- # 要执行的命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- elseif(表达式2)
- # 要执行的命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- else(表达式)
- # 要执行的命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- endif(表达式)
备注:elseif 和 else 部分是可选的,也可以有多条 elseif ,这些是根据你的实际的业务需求来选择的。缩进和空格对语句解析没有影响。
例子:
- set(if_tap OFF)
- set(elseif_tap ON)
- if(${if_tap})
- message("这是 if 表达式")
- elseif(${elseif_tap})
- message("这是 elseif 表达式")
- else(${if_tap})
- message("这是 else 表达式")
- endif(${if_tap})
语法格式如下:
- while(表达式)
- # 要执行的命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- endwhile(表达式)
备注:循环可以用 break() 命令退出,continue() 命令可以跳过下面的语句块,立即进入下一次的循环迭代。
例子:
- set(a "")
- while(NOT a STREQUAL "xxxxx")
- set(a "${a}x")
- message(" a = ${a}")
- endwhile()
语法格式一如下:
- foreach(循环变量 参数1 参数2 ...)
- # 要执行的命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- endforeach(循环变量)
备注:每次迭代设置 ${循环变量} = 参数 N
例子:
- foreach(item "A" "B" "C")
- message(" ${item}")
- endforeach(item)
语法格式二如下:
- foreach(循环变量 RANGE total)
- # 要执行的命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- endforeach(循环变量)
备注:循环的范围从 0~total
- foreach(循环变量 RANGE start stop [step])
- # 要执行的命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- endforeach(循环变量)
备注:循环的范围从 start ~stop ,循环增量为 step
例子:
- foreach(x RANGE 10)
- message(" ${x}")
- endforeach(x)
- foreach(x RANGE 10 14 2)
- message(" ${x}")
- endforeach(x)
语法格式三如下:
- foreach(loop_var IN [LISTS [list1 [...]]]
- [ITEMS [item1 [...]]])
备注:foreach 支持对列表的遍历
例子:
- set(list_var "1;2;3;4")
- foreach(x IN LISTS list_var)
- message(" ${x}")
- endforeach(x)
备注:同样 foreach 也支持 break(),continue() 命令操作
Cmake 支持很多内置的命令,像我们之前使用的 set,message,if,while,foreach 等待都是内置的命令。也可以自定义命令。命令可以带字符串参数,但是没有还回值。命令名是大小写不敏感的,所以 SET 和 set 表示同一个命令,但是命令带的参数名是大小写敏感的 ARG 和 arg 是两个不同的参数。
自定义函数命令格式如下:
- function(<name> [arg1 [arg2 [arg3 ...]]])
- # 自定义命令块
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- endfunction(<name>)
备注:定义了一个函数名为 name,参数为 arg1, arg2, arg3, ... 的函数命令。参数之间用空格进行分隔,如果某一参数里面包含空格最好用双引号把该参数包起来(引号内的所有字符串只当作一个参数),比如 "arg1"。如果不指定参数列表,则函数可以接受任意的参数,ARGC 内置变量表明传人参数的个数,ARGV0, ARGV1, ARGV2, ... 内置变量可以获得对应传入的参数,ARGV 内置变量可以获得整个参数列表
命令的调用格式如下:
name(实参列表)
例子:
- function(foo x y z)
- message("Calling function 'foo':")
- message(" x = ${x}")
- message(" y = ${y}")
- message(" z = ${z}")
- message("ARGC = ${ARGC} arg1 = ${ARGV0} arg2 = ${ARGV1} arg3 = ${ARGV2} all args = ${ARGV}")
- endfunction(foo)
- foo("1" "2" "3")
自定义宏命令格式如下:
- macro(<name> [arg1 [arg2 [arg3 ...]]])
- COMMAND1(ARGS ...)
- COMMAND2(ARGS ...)
- endmacro(<name>)
备注:宏和函数的基本上是一样的,只是说函数命令有自己的作用域,宏命令的作用域和调用者的作用域一样。
Cmake 里面有三种作用域,全局层的,目录层的,函数层的。
其中全局层的 < 目录层的 < 函数层的
备注:如果修改时通过 set 命令明确指定 PARENT_SCOPE 参数,修改的变量作用域就是在上一层作用域,而不是当前作用域。
[1] https://cmake.org/cmake/help/v3.10/manual/cmake-language.7.html#id9
[2] http://preshing.com/20170522/learn-cmakes-scripting-language-in-15-minutes/
[3] https://cgold.readthedocs.io/en/latest/overview.html
来源: http://www.jianshu.com/p/1ec2b5602b03