CMake意为cross-platform make,可用于管理c/c++工程。
CMake解析配置文件CMakeLists.txt生成Makefile,相比直接用Makefile管理工程,CMake更灵活和简单。
结构
Cmake的输入是源码目录下的 ‘CMakeLists.txt’ 文件,或者后缀为’.cmake’。
这个文件可以用 ‘include’ 或者 ‘add_subdirectory’ 命令增加入其它的输入文件。组织结构有以下几部分组成:
- Directories (CMakeLists.txt)
- Scripts (<script>.cmake)
- Modules (<module>.cmake)
Directories
顶层目录下的 ‘CMakeLists.txt’ 文件可以使用命令 ‘add_subdirectory’ 来添加子目录,
此子目录下必须存在 ‘CMakeLists.txt’ 文件
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
Scripts
脚本模式可以使用以下命令运行给定的CMake源文件中的命令,但是不会构建系统。
cmake [<options>] (<path-to-source> | <path-to-existing-build>)
cmake [(-D<var>=<value>)...] -P <cmake-script-file>
cmake --build <dir> [<options>] [-- <build-tool-options>...]
cmake -E <command> [<options>]
cmake --find-package <options>...
Modeles
使用命令 ‘include’ 来导入 ‘
include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>] [NO_POLICY_SCOPE])
语法
编码
使用7-bit ASCII进行编码,新行可使用 ‘\n’ 或 ‘\r\n’,将被转换为 ‘\n’ 做为输入文件读取
源文件
CMakeList.txt文件是由注释、命令和空白字符组成。
命令调用
命令是由:命令名、(、空格分隔的参数、)组成。
‘CMakeLists.txt’ 文件中命令调用大小写不敏感的。 例如:
command (args….)
上面的command可以是一个命令名;或者是一个宏;也可以是一个函数名。
命令参数
args是以空格分隔的参数例表(如果参数中包含空格,则要加双引号)
除了用于分隔参数的空白字符(空格、换行号、tabs)都是被忽略不计的。任何包含在双引号中的字符都做为一个参数。
三种参数类型:括号、引号和普通
Bracket Argument:
message([=[
This is the first line in a bracket argument with bracket length 1.
No \-escape sequences or ${variable} references are evaluated.
This is always one argument even though it contains a ; character.
The text does not end on a closing bracket of length 0 like ]].
It does end in a closing bracket of length 1.
]=])
Quoted Argument:
message("This is a quoted argument containing multiple lines.
This is always one argument even though it contains a ; character.
Both \\-escape sequences and ${variable} references are evaluated.
The text does not end on an escaped double-quote like \".
It does end in an unescaped double quote.
")
可以在行尾添加 ‘' 进行行连接,例如:
message("\
This is the first line of a quoted argument. \
In fact it is the only line but since it is long \
the source code uses line continuation.\
")
Unquoted Argument:
foreach(arg
NoSpace
Escaped\ Space
This;Divides;Into;Five;Arguments
Escaped\;Semicolon
)
message("${arg}")
endforeach()
前两种都是提供一个参数,而且不会进行转义,最后一个需要注意转义!
转义
‘'后跟的部分字符进行转义:
escape_sequence ::= escape_identity | escape_encoded | escape_semicolon
escape_identity ::= '\(' | '\)' | '\#' | '\"' | '\ ' |
'\\' | '\$' | '\@' | '\^'
escape_encoded ::= '\t' | '\r' | '\n'
escape_semicolon ::= '\;'
‘(‘,’)’,’#’,’”‘,’ ‘,’',’$’,‘@’,’^’ 进行简单转义;’\t’ : tab ‘\r’ : return ‘\n’ : newline;’;‘ 用于参数中不表示隔离参数
变量引用
变量引用的形式为 ‘${variable_name}’,替换为变量的值,或空字符串(变量未赋值)。
变量引用可以嵌套,从内到外展开,例如 ‘${outer_${inner_variable}_variable}’
环境变量引用形式为 ‘$ENV{VAR}’
注释
注释由一个不是 (括号中的参数、引用参数或’'转义)一部分的’#’字符开始,有行注释和括号注释:
括号注释:
#[[This is a bracket comment.
It runs until the close bracket.]]
message("First Argument\n" #[[Bracket Comment]] "Second Argument")
行注释:
# This is a line comment.
message("First Argument\n" # This is a line comment :)
"Second Argument") # This is a line comment.
控制结构
Conditional Blocks
# some_command will be called if the variable's value is not:
# empty, 0, N, NO, OFF, FALSE, NOTFOUND, or -NOTFOUND.
if(var)
some_command(...)
elseif()
some_command(...)
else()
some_command(...)
endif()
Loops
set(VAR a b c)
# loop over a, b,c with the variable f
foreach(f ${VAR})
message(${f})
endforeach(f)
while(condition)
command(args ...)
command(args ...)
endwhile(condition)
Command Definitions
macro()/endmacro() 和 function()/endfunction() 进行宏和函数的定义:
# define a macro hello
macro(hello MESSAGE)
message(${MESSAGE})
endmacro(hello)
# call the macro with the string "hello world"
hello("hello world")
# define a function hello
function(hello MESSAGE)
message(${MESSAGE})
endfunction(hello)
Variables
变量命名大小写敏感,set()/unset()对变量进行赋值操作:
set (VAR " hello world ") #赋值
unset (VAR) #取消赋值
CMake支持简单的变量:字符串或字符串列表。用${VAR} 语法得到变量的引用。
可以用一个set命令把一个字符串列表设置为一个变量,然后把这个变量传递给需要传递多参数的函数。例如:
set(Foo a b c)
command(${Foo})
上面两行等效
command(a b c)
如果你想传把一个字符串列表做为一个单独的参数传递给函数,用双引号包含它。例如:
Command(“${Foo}”)
#等效于
command(“a b c”)
环境变量:
用$ENV{VAR}得到环境变量的引用
设置环境变量:
Set(ENV{VAR} /home)
Lists
字符串(string)和字符串列表(lists)
CMake的基本数据类型是字符串(string)。
CMake也支持由字符串组成的字符串列表。字符串列表可以由;或空格分隔的组成。例如:下面设置变量var是等效的。
set(var a;b;c)
set(var a b c)
字符串列表可以用 foreach命令叠代(iterated)或list命令操作。
正则表达式
一些CMake命令(如if和 string),能使用正则表达式或使用正则表达式作为参数。
一个简单的形式,一个正则表达式用于在一个序列的字符串中精确查找一个字符。
然而在大多时候,一个精确查找是不知道的或者只是匹配最前或者最后字符。
所以这里用正则表达式进行不同的转换。
Cmake标准是可被描述的。这个描述是基于开源的正则表达式类(Texas Instruments)。
- ^ 匹配一行或一字符串开头
- $匹配一行或一字符串结尾
- .匹配单一字符或一个新行
- [ ]匹配括号中的任一字符
- [^ ] 匹配不在括号内的任一字符
- [-] 匹配指定范围内的字符
- * 匹配0次或多次
- + 匹配一次或多次
- ? 匹配0次或一次
- ()保存匹配的表达式并用随后的替换它