开个网站多少钱一年,湖南建筑信息网首页,wordpress 父页面,网站的后台文章目录 一. 组织1. 目录2. 脚本3. 模块 二. 语法1. 编码2. 源文件3. 命令调用4. 命令参数#xff08;1#xff09;括号参数#xff08;2#xff09;带引号的参数#xff08;3#xff09;未引用的参数 5. 转义序列6. 变量引用7. 注释#xff08;1#xff09;括号注释1括号参数2带引号的参数3未引用的参数 5. 转义序列6. 变量引用7. 注释1括号注释2行注释 三. 控制结构1. 条件块2. 循环3. 命令定义 四. 变量五. 环境变量六. 列表 一. 组织
CMake输入文件以CMake语言编写在名为CMakeLists.txt的源文件中或以.CMake文件扩展名结尾。 项目中的CMake语言源文件被组织为
目录Directories (CMakeLists.txt),脚本Scripts (script.cmake)模块Modules (module.cmake).
1. 目录
当CMake处理项目源树时入口点是顶级源目录中名为CMakeLists.txt的源文件。此文件可能包含整个生成规范或者使用add_subdirectory()命令将子目录添加到生成中。命令添加的每个子目录还必须包含一个CMakeLists.txt文件作为该目录的入口点。对于处理CMakeLists.txt文件的每个源目录CMake在构建树中生成一个相应的目录作为默认的工作和输出目录。
2. 脚本
通过使用带有-P选项的cmake命令行工具可以在脚本模式下处理单个script.cmake源文件。脚本模式只是在给定的CMake语言源文件中运行命令而不生成构建系统。它不允许CMake命令定义生成目标或操作。
3. 模块
目录或脚本中的CMake语言代码可以使用include()命令在include上下文的范围内加载module.CMake源文件。项目源树也可以提供它们自己的模块并CMAKE_MODULE_PATH变量中指定它们的位置。
二. 语法
1. 编码
CMake语言源文件可以用7位ASCII文本编写以便在所有支持的平台上实现最大的可移植性。换行符可以编码为\n或\r\n但在读取输入文件时会转换为\n。 请注意该实现是8位干净的因此在系统API支持这种编码的平台上源文件可以编码为UTF-8。此外CMake 3.2及以上版本支持在Windows上以UTF-8编码的源文件使用UTF-16调用系统API。此外CMake 3.0及更高版本允许在源文件中使用领先的UTF-8字节顺序标记。
2. 源文件
CMake语言源文件由零个或多个命令调用组成这些命令调用由换行符和可选的空格和注释分隔
file :: file_element*
file_element :: command_invocation line_ending |(bracket_comment|space)* line_ending
line_ending :: line_comment? newline
space :: match [ \t]
newline :: match \n请注意任何不在命令参数或括号注释内的源文件行都可以以行注释结束。
3. 命令调用
命令调用是一个名称后面跟着用空格分隔的带括号的参数
command_invocation :: space* identifier space* ( arguments )
identifier :: match [A-Za-z_][A-Za-z0-9_]*
arguments :: argument? separated_arguments*
separated_arguments :: separation argument? |separation* ( arguments )
separation :: space | line_ending例如
add_executable(hello world.c)命令名不区分大小写。参数中嵌套的无引号括号必须保持平衡。每个(或)都作为未引用的实参提供给命令调用。这可以用于调用if()命令来封闭条件。例如
if(FALSE AND (FALSE OR TRUE)) # evaluates to FALSE4. 命令参数
命令调用中有三种类型的参数
argument :: bracket_argument | quoted_argument | unquoted_argument1括号参数
受Lua长括号语法启发括号自变量将内容包含在相同长度的开头和结尾括号之间
bracket_argument :: bracket_open bracket_content bracket_close
bracket_open :: [ * [
bracket_content :: any text not containing a bracket_close withthe same number of as the bracket_open
bracket_close :: ] * ]左括号写为[后接零或更多后接[。相应的右括号写为]后接相同数量的后接]。支架不嵌套。可以始终为打开和关闭括号选择唯一的长度以包含其他长度的关闭括号。 括号参数内容由位于左括号和右括号之间的所有文本组成除了左括号后面的一行换行符如果有的话将被忽略。不执行对所附内容如转义序列或变量引用的评估。括号参数总是作为一个参数提供给命令调用。例如
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.
]])2带引号的参数
带引号的参数包含位于开头和结尾双引号字符之间的内容
quoted_argument :: quoted_element*
quoted_element :: any character except \ or |escape_sequence |quoted_continuation
quoted_continuation :: \ newline带引号的参数内容包括位于左引号和右引号之间的所有文本。转义序列和变量引用都会进行求值。引用的参数总是作为一个参数提供给命令调用。例如
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.\
)3未引用的参数
未引用的参数不包含在任何引用语法中。它不能包含任何空格、、#、“或\除非用反斜杠转义
unquoted_argument :: unquoted_element | unquoted_legacy
unquoted_element :: any character except whitespace or one of ()#\ |escape_sequence
unquoted_legacy :: see note in text未引用的参数内容由允许字符或转义字符的连续块中的所有文本组成。转义序列和变量引用都会进行求值。结果值的划分方式与列表划分为元素的方式相同。每个非空元素都作为参数提供给命令调用。因此一个未引用的参数可以作为零个或多个参数提供给命令调用。例如
foreach(argNoSpaceEscaped\ SpaceThis;Divides;Into;Five;ArgumentsEscaped\;Semicolon)message(${arg})
endforeach()5. 转义序列
转义序列是一个\后面跟一个字符
escape_sequence :: escape_identity | escape_encoded | escape_semicolon
escape_identity :: \ match [^A-Za-z0-9;]
escape_encoded :: \t | \r | \n
escape_semicolon :: \;后面跟着一个非字母数字字符的\只是对文字字符进行编码而不将其解释为语法。\t、\r或分别对制表符、回车符或换行符进行编码。A \:在任何变量引用之外对其自身进行编码但可以在未引用的参数中用于对而不除以其上的参数值。A\:内部变量引用对文本进行编码
6. 变量引用
变量引用的形式为${variable}在带引号的参数或未带引号的自变量中进行求值。变量引用由指定变量或缓存项的值替换或者如果两者都未设置则由空字符串替换。变量引用可以嵌套并由内而外进行评估例如${outer_${inner_variable}_variable}。
文字变量引用可以由字母数字字符、字符/_.±、和转义序列。嵌套引用可用于评估任何名称的变量。
Variables部分记录了变量名称的范围以及如何设置它们的值。环境变量引用的形式为$ENV{variable}。缓存变量引用的形式为$cache{variable}并由指定ca的值替换if()命令有一个特殊的条件语法允许使用缩写形式variable而不是${variable}的变量引用。但是环境变量总是需要被引用为$ENV{variable}。
7. 注释
注释以#字符开头该字符不在括号参数、带引号的参数内也不作为未带引号参数的一部分以\转义。有两种类型的注释
括号注释行注释
1括号注释
#后面紧跟着一个括号形成一个括号注释由整个括号外壳组成
bracket_comment :: # bracket_argument例如:
#[[This is a bracket comment. It runs until the close bracket.]]
message(First Argument\n #[[Bracket Comment]] Second Argument)2行注释
#后面没有紧跟括号形成一个行注释该注释一直持续到行的末尾
line_comment :: # any text not starting in a bracket_openand not containing a newline例如
# This is a line comment.
message(First Argument\n # This is a line comment :)Second Argument) # This is a line comment.三. 控制结构
1. 条件块
if()eleif()else()endif()命令定义要有条件执行的代码块。
2. 循环
foreach()endforeach()while()endwhile()命令分隔要在循环中执行的代码块。在这样的块中break()命令可以用于提前终止循环而continue()命令则可以用于立即开始下一次迭代。
3. 命令定义
macro()endmark()function()endfunction()命令定义了要记录的代码块以便以后作为命令调用。
四. 变量
变量是CMake语言中的基本存储单元。它们的值总是字符串类型的尽管有些命令可能会将字符串解释为其他类型的值。set()和unset()命令显式地设置或取消设置变量但其他命令也具有修改变量的语义。变量名称区分大小写几乎可以由任何文本组成但我们建议使用仅由字母数字字符加上_和-组成的名称。 变量具有动态范围。每个变量set或unset在当前作用域中创建一个绑定
块范围block()命令可以为变量绑定创建一个新的作用域。功能范围function()命令创建的命令定义创建的命令在被调用时处理新变量绑定范围中记录的命令。变量set或unset在此范围内绑定并且对于当前函数及其内的任何嵌套调用都可见但在函数返回后不可见。目录作用域源树中的每个目录都有自己的变量绑定。在处理目录的CMakeLists.txt文件之前CMake复制当前在父目录中定义的所有变量绑定如果有的话以初始化新的目录作用域。当使用CMake -P处理时CMake脚本将变量绑定到一个“目录”范围中。 不在函数调用内的变量set或unset绑定到当前目录作用域。永久缓存CMake存储一组单独的“缓存”变量或“缓存条目”其值在项目构建树中的多个运行中保持不变。缓存条目有一个单独的绑定作用域该绑定作用域仅通过显式请求进行修改例如通过set()和unset()命令的Cache选项进行修改。
在评估变量引用时CMake首先在函数调用堆栈如果有中搜索绑定然后返回到当前目录作用域中的绑定如果有的话。如果找到set绑定则使用其值。如果找到“未设置”的绑定或者没有找到绑定CMake将搜索缓存条目。如果找到缓存条目则使用其值。否则变量引用的计算结果为空字符串。$CACHE{}VAR}语法可用于直接查找缓存条目。
五. 环境变量
环境变量与普通变量一样有以下区别
范围环境变量在CMake过程中具有全局作用域。它们从不缓存。参考文献变量引用的形式为$ENV{Variable}使用ENV运算符。初始化CMake环境变量的初始值是调用进程的初始值。可以使用set()和unset()命令更改值。这些命令只影响正在运行的CMake进程而不会影响整个系统环境。更改后的值不会写回调用进程后续的构建或测试进程也看不到这些值。
六. 列表
尽管CMake中的所有值都存储为字符串但在某些上下文中例如在评估未引用的参数时字符串可能会被视为列表。在这样的上下文中字符串通过在上进行拆分而被划分为列表元素不在[和]字符数不相等且前面不紧跟\的字符。序列\:不划分值但替换为:在得到的元素中。 元素列表通过连接由:分隔的元素来表示为字符串例如set()命令将多个值作为列表存储到目标变量中
set(srcs a.c b.c c.c) # sets srcs to a.c;b.c;c.c列表用于简单的用例如源文件列表不应用于复杂的数据处理任务。大多数构造列表的命令都不会转义:列表元素中的字符从而使嵌套列表变平
set(x a b;c) # sets x to a;b;c, not a;b\;c通常列表不支持包含以下内容的元素:字符。为避免出现问题请考虑以下建议 许多CMake命令、变量和属性的接口都接受分号分隔的列表。避免将包含分号元素的列表传递给这些接口除非它们记录了直接支持或某种转义或编码分号的方式。 构造列表时用未使用的占位符替换:在元素中。然后替换:用于处理列表元素时的占位符。例如以下代码使用|代替:字符 set(mylist a b|c)
foreach(entry IN LISTS mylist)string(REPLACE | ; entry ${entry})# use ${entry} normally
endforeach()在生成器表达式列表中使用$SEMICON生成器表达式。 在命令调用中尽可能使用带引号的参数语法。被调用的命令将接收保留分号的参数内容。未引用的参数将以分号分隔。 在function()实现中避免使用ARGV和ARGN因为它们不区分值中的分号和分隔值的分号。相反更喜欢使用命名的位置参数以及ARGC和ARGV#变量。使用cmake_parse_arguments()解析参数时首选其parse_ARGV签名该签名使用ARGV#变量。