1)注释的语法:在CMake中注释使用#字符开始到此行结束。
2)CMake命令:命令不区分大小写(参数会区分大小写),命令由命令、参数列表组成,参数之间使用空格进行分隔。使用一对双引号包括的字符串认为是一个参数。命令可以是一个内置命令(例如:project,add_executable等),也可以是一个用户定义的宏(macro)或者函数(function)。
3)数据类型:CMake的基本数据类型是字符串,一组字符串在一起称为列表(list),例如:
# 通过 set 命令构建一个 listVAR
set(VAR a b c)
使用语法 ${VariableName} 来访问名字为 VariableName 的变量的值(变量名区分大小写)。需要注意的是,即使在字符串中也可以使用 ${VariableName} 来访问变量的值:
set(VAR a b c)
# 输出 VAR = a;b;c
message("VAR = ${VAR}")
使用语法 $ENV{VariableName} 来访问环境变量的值(ENV{VariableName} 则表示环境变量本身)
# 输出环境变量 PATH 的值
message($ENV{PATH})
4)条件控制和循环结构
条件控制命令为 if 命令
if(expression)
#...
elseif(expression2)
#...
else()
#...
endif()
对于 if(string) 来说:
如果 string 为(不区分大小写)1、ON、YES、TRUE、Y、非 0 的数则表示真
如果 string 为(不区分大小写)0、OFF、NO、FALSE、N、IGNORE、空字符串、以 -NOTFOUND 结尾的字符串则表示假
如果 string 不符合上面两种情况,则 string 被认为是一个变量的名字。变量的值为第二条所述的各值则表示假,否则表示真。
# 此策略(Policy)在 CMake2.8.0 才被引入
# 因此这里需要指定最低 CMake 版本为 2.8
cmake_minimum_required(VERSION 2.8)
set(YES 0)
# 输出 True
if(YES)
message(True)
else()
message(False)
endif()
# 输出 False
if(${YES})
message(True)
else()
message(False)
endif()
表达式中可以包含操作符,操作符包括:
一元操作符,例如:EXISTS、COMMAND、DEFINED 等
二元操作符,例如:EQUAL、LESS、GREATER、STRLESS、STRGREATER 等
NOT(非操作符)
AND(与操作符)、OR(或操作符)
操作符优先级:一元操作符 > 二元操作符 > NOT > AND、OR
常用操作符介绍:
if(NOT expression)
为真的前提是 expression 为假
if(expr1 AND expr2)
为真的前提是 expr1 和 expr2 都为真
if(expr1 OR expr2)
为真的前提是 expr1 或者 expr2 为真
if(COMMAND command-name)
为真的前提是存在 command-name 命令、宏或函数且能够被调用
if(EXISTS name)
为真的前提是存在 name 的文件或者目录(应该使用绝对路径)
if(file1 IS_NEWER_THAN file2)
为真的前提是 file1 比 file2 新或者 file1、file2 中有一个文件不存在(应该使用绝对路径)
if(IS_DIRECTORY directory-name)
为真的前提是 directory-name 表示的是一个目录(应该使用绝对路径)
if(variable|string MATCHES regex)
为真的前提是变量值或者字符串匹配 regex 正则表达式
if(variable|string LESS variable|string)
if(variable|string GREATER variable|string)
if(variable|string EQUAL variable|string)
为真的前提是变量值或者字符串为有效的数字且满足小于(大于、等于)的条件
if(variable|string STRLESS variable|string)
if(variable|string STRGREATERvariable|string)
if(variable|string STREQUALvariable|string)
为真的前提是变量值或者字符串以字典序满足小于(大于、等于)的条件
if(DEFINED variable)
为真的前提是 variable 表示的变量被定义了。
foreach 循环范例:
set(VAR a b c)
foreach(f ${VAR})
message(${f})
endforeach()
while 循环范例:
set(VAR 5)
while(${VAR} GREATER 0)
message(${VAR})
math(EXPR VAR "${VAR} - 1")
endwhile()
5)函数和宏定义
函数会为变量创建一个局部作用域,而宏则使用全局作用域。范例:
# 定义一个宏 hello
macro(hello MESSAGE)
message(${MESSAGE})
endmacro()
# 调用宏 hello
hello("hello world")
# 定义一个函数 hello
function(hello MESSAGE)
message(${MESSAGE})
endfunction()
函数和宏可以通过命令 return() 返回,但是函数和宏的返回值必须通过参数传递出去。例如:
cmake_minimum_required(VERSION 2.8)
function(get_func RESULT)
#RESULT 的值为实参的值,因此需要使用 ${RESULT}
#这里使用 PARENT_SCOPE 是因为函数会构建一个局部作用域
set(${RESULT} "Hello Function" PARENT_SCOPE)
endfunction()
macro(get_macro RESULT)
set(${RESULT} "Hello Macro")
endmacro()
get_func(V1)
# 输出 Hello Function
message(${V1})
get_macro(V2)
# 输出 Hello Macro
message(${V2})
7)字符串的一些问题
字符串可跨行且支持转移字符,例如:
set(VAR "hello
world")
# 输出结果为:
# ${VAR} = hello
# world
message("\${VAR} = ${VAR}")