列表在CMake中大量使用。初始化列表语法如下:
set(myList a b c) # Creates the list "a;b;c"
归根结底,列表只是一个由分号分隔列表项的单个字符串,这使得操作单个列表项变得不太方便。CMake提供了list()
命令来简化这类任务,他的基本语法如下:
list(<command> <list> [<other_args>])
其中,
是处理列表的命令,每个命令有各自的
,具体如下:
Reading
list(LENGTH <list> <out-var>)
list(GET <list> <element index> [<index> ...] <out-var>)
list(JOIN <list> <glue> <out-var>)
list(SUBLIST <list> <begin> <length> <out-var>)
Search
list(FIND <list> <value> <out-var>)
Modification
list(APPEND <list> [<element>...])
list(FILTER <list> {INCLUDE | EXCLUDE} REGEX <regex>)
list(INSERT <list> <index> [<element>...])
list(POP_BACK <list> [<out-var>...])
list(POP_FRONT <list> [<out-var>...])
list(PREPEND <list> [<element>...])
list(REMOVE_ITEM <list> <value>...)
list(REMOVE_AT <list> <index>...)
list(REMOVE_DUPLICATES <list>)
list(TRANSFORM <list> <ACTION> [...])
Ordering
list(REVERSE <list>)
list(SORT <list> [...])
列表长度
list(LENGTH <list> <out-var>)
通过 out-var
返回列表的长度。
set(myList a b c) # Creates the list "a;b;c"
list(LENGTH myList len)
message("length = ${len}") # length = 3
通过index访问元素
list(GET <list> <element index> [<index> ...] <out-var>)
其中,index
是列表的索引,可以指定过多个,out-var
是通过 index
找到的元素。
指定索引值时,如果 0
或更大,则从列表开头开始索引,0
表示第一个列表元素。如果为 -1
或更小,则从列表末尾开始索引,-1
表示最后一个列表元素。使用负索引计数时要小心:不是从 0
开始,而是从 -1
开始。-0
相当于 0
,即第一个列表元素。这和 Python
中 list
的索引是一致的。
set(myList a b c) # Creates the list "a;b;c"
list(GET myList 2 1 letters)
message("letters = ${letters}") # letters = c;b
拼接元素 (CMake 3.12 引入)
list(JOIN <list> <glue> <out-var>)
使用
作为连接符将列表中的元素拼接起来,并通过 out-var
返回拼接结果。
set(myList a b c) # Creates the list "a;b;c"
list(JOIN myList - join)
message("join = ${join}") # join = a-b-c
子列表(CMake 3.12 引入)
list(SUBLIST <list> <begin> <length> <out-var>)
返回给定列表的子列表。如果
为 0
,将返回一个空列表。如果
是 -1
或列表长度小于
则返回列表从
到结尾的所有元素。
set(myList a b c d e) # Creates the list "a;b;c;d;e"
list(SUBLIST myList 1 3 sublist)
message("sublist[1:3] = ${sublist}") # sublist[1:3] = b;c;d
list(SUBLIST myList 1 0 sublist)
message("sublist[1:0] = ${sublist}") # sublist[1:0] =
list(SUBLIST myList 1 -1 sublist)
message("sublist[1:-1] = ${sublist}") # sublist[1:-1] = b;c;d;e
list(SUBLIST myList 2 7 sublist)
message("sublist[2:7] = ${sublist}") # sublist[2:7] = c;d;e
list(FIND <list> <value> <out-var>)
返回列表中指定元素的索引,如果未找到该元素则返回 -1
。
set(myList a b c d e) # Creates the list "a;b;c;d;e"
list(FIND myList d find)
message("find(d) = ${find}") # find(d) = 3
list(FIND myList g find)
message("find(g) = ${find}") # find(g) = -1
以下操作会修改原有列表。
在队尾追加元素
list(APPEND <list> [<element>...])
将元素追加到列表最后。如果
不存在,则其值将被视为空,并且
将附加到该空列表中。
set(myList a b c d e) # Creates the list "a;b;c;d;e"
list(APPEND myList 1 2 3)
message("append(1 2 3) = ${myList}") # append(1 2 3) = a;b;c;d;e;1;2;3
list(APPEND newList 1 2 3)
message("append(1 2 3) = ${newList}") # append(1 2 3) = 1;2;3
在队头插入元素 (CMake 3.15 引入)
list(PREPEND <list> [<element>...])
将元素插入到列表中的第 0 个位置。如果
不存在,则其值将被视为空,并且
将附加到该空列表中。
set(myList a b c d e) # Creates the list "a;b;c;d;e"
list(PREPEND myList 1 2 3)
message("prepend(1 2 3) = ${myList}") # prepend(1 2 3) = 1;2;3;a;b;c;d;e
list(PREPEND newList 1 2 3)
message("prepend(1 2 3) = ${newList}") # prepend(1 2 3) = 1;2;3
过滤元素 (CMake 3.6 引入)
list(FILTER <list> {INCLUDE | EXCLUDE} REGEX <regex>)
从列表中包含或排除与
匹配的元素。REGEX
表示支持正则表达式。
set(newList hello hi world)
list(FILTER newList INCLUDE REGEX h)
message("newList = ${newList}") # newList = hello;hi
set(newList hello hi world)
list(FILTER newList EXCLUDE REGEX h)
message("newList = ${newList}") # newList = world
插入元素
list(INSERT <list> <index> [<element>...])
将元素插入到列表的指定索引处。指定超出范围的索引是错误的。
有效索引为 0
到 N
,其中 N
是列表的长度。空列表的长度为 0
。
如果
不存在,则其值将被视为空,并且
将附加到该空列表中。
set(newList world)
list(INSERT newList 0 hello)
message("newList = ${newList}") # newList = hello;world
list(INSERT newList 3 null) # Error
从队尾删除元素 (CMake 3.15 引入)
list(POP_BACK <list> [<out-var>...])
如果未给出
,则仅删除最后一个元素。否则,在提供N个
的情况下,将最后N个元素的值分配给给定变量,并从
中删除最后N个元素。
set(myList a b c d e) # Creates the list "a;b;c;d;e;1;2;3"
list(POP_BACK myList)
message("myList = ${myList}") # myList = a;b;c;d;e;1;2
list(POP_BACK myList a b)
message("myList = ${myList}, a = ${a}, b = ${b}") # myList = a;b;c;d;e, a = 2, b = 1
从队头删除元素 (CMake 3.15 引入)
list(POP_FRONT <list> [<out-var>...])
如果未给出
,则仅删除第一个元素。否则,在提供N个
的情况下,将前N个元素的值分配给给定变量,并从
中删除前N个元素。
set(myList a b c d e 1 2 3) # Creates the list "a;b;c;d;e;1;2;3"
list(POP_FRONT myList)
message("myList = ${myList}") # myList = b;c;d;e;1;2;3
list(POP_FRONT myList a b)
message("myList = ${myList}, a = ${a}, b = ${b}") # myList = d;e;1;2;3, a = b, b = c
按值删除元素
list(REMOVE_ITEM ...)
从列表中删除给定值的所有元素。
set(myList a b 3 d e 1 2 3) # Creates the list "a;b;3;d;e;1;2;3"
list(REMOVE_ITEM myList 1 2 3)
message("myList = ${myList}") # myList = a;b;d;e
按索引删除元素
list(REMOVE_AT <list> <index>...)
从列表中删除给定索引处的元素。
set(myList a b 3 d e 1 2 3) # Creates the list "a;b;3;d;e;1;2;3"
list(REMOVE_AT myList 1 2 3)
message("myList = ${myList}") # myList = a;e;1;2;3
元素去重
list(REMOVE_DUPLICATES <list>)
删除列表中的重复项目。保留项目的相对顺序,但如果遇到重复项,则仅保留第一个重复的元素。
set(myList a b 3 d 3 1 2 3) # Creates the list "a;b;3;d;e;1;2;3"
list(REMOVE_DUPLICATES myList)
message("myList = ${myList}") # myList = a;b;3;d;1;2
对元素进行批量变换
list(TRANSFORM <list> <ACTION> [<SELECTOR>] [OUTPUT_VARIABLE <output variable>])
将变换方法
应用于每个元素,或应用于
选定的元素,对于输出结果,可以直接对原列表进行修改,也可以输出到 OUTPUT_VARIABLE
指定的变量。
变换方法
如下:
APPEND、PREPEND
list(TRANSFORM <list> (APPEND|PREPEND) <value> ...)
将指定值
附加到列表的每个元素的前面或后面。
TOUPPER、TOLOWER
list(TRANSFORM <list> (TOLOWER|TOUPPER) ...)
将列表的每个元素转换为大写或小写字符。
STRIP
list(TRANSFORM <list> STRIP ...)
删除列表中每个元素前后的空格。
GENEX_STRIP
list(TRANSFORM <list> GENEX_STRIP ...)
删除列表中每个元素的生成器表达式。
REPLACE
list(TRANSFORM <list> REPLACE <regular_expression> <replace_expression> ...)
将与正则表达式
匹配的部分替换成
。
TRANSFORM
还允许使用选择器
选定要执行变换的操作的元素,可用的选择器如下:
AT
list(TRANSFORM <list> <ACTION> AT <index> [<index> ...] ...)
通过索引选择。
FOR
list(TRANSFORM <list> <ACTION> FOR <start> <stop> [<step>] ...)
通过
和
指定一个遍历索引的范围,可以选择使用
定义遍历步长(默认为1)。
REGEX
list(TRANSFORM <list> <ACTION> REGEX <regular_expression> ...)
指定正则表达式。只有与正则表达式匹配的元素才会被转换。
反转列表
list(REVERSE <list>)
该操作为就地操作,会修改原有列表。
set(myList a b c d e 1 2 3) # Creates the list "a;b;c;d;e;1;2;3"
list(REVERSE myList)
message("myList = ${myList}") # myList = 3;2;1;e;d;c;b;a
排序
list(SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])
默认按 ASCII
码顺序升序排序,区分大小写。
使用 COMPARE
可以指定排序的方式。(CMake 3.13 引入)
STRING
按 ASCII
码顺序排序,默认为该项。
FILE_BASENAME
按文件的 basename
对文件 pathname
列表进行排序。
NATURAL(CMake 3.18 引入)
使用自然顺序对字符串列表进行排序。示例如下:
对于列表 10.0 1.1 2.1 8.0 2.0 3.1
,
STRING
模式排序为 1.1 10.0 2.0 2.1 3.1 8.0
;
NATURAL
模式排序为 1.1 2.0 2.1 3.1 8.0 10.0
。
使用 CASE
可以指定是否区分大小写。(CMake 3.13 引入)
SENSITIVE
区分大小写,默认为该项。
INSENSITIVE
不区分大小写。
使用 ORDER
可以指定升序或降序。(CMake 3.13 引入)
ASCENDING
按升序对列表进行排序,默认为该项。
DESCENDING
按降序对列表进行排序。