CMake中的list命令用于列表操作,其格式如下:
- Reading
- list(LENGTH
)
- list(GET
[ ...] )
- list(JOIN
)
- list(SUBLIST
)
-
- Search
- list(FIND
)
-
- Modification
- list(APPEND
[...])
- list(FILTER
{INCLUDE | EXCLUDE} REGEX )
- list(INSERT
[...])
- list(POP_BACK
[...])
- list(POP_FRONT
[...])
- list(PREPEND
[...])
- list(REMOVE_ITEM
...)
- list(REMOVE_AT
...)
- list(REMOVE_DUPLICATES
)
- list(TRANSFORM
[...])
-
- Ordering
- list(REVERSE
)
- list(SORT
[...])
list子命令APPEND, INSERT, FILTER, PREPEND, POP_BACK, POP_FRONT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, REVERSE和SORT可以在当前CMake变量范围内为list创建新值。与set命令类似,list命令在当前作用域中创建新的变量值,即使list本身实际上是在父作用域中定义的也是如此。要向上(upwards)传播这些操作的结果,需要使用带有PARENT_SCOPE的set命令、带有CACHE INTERNAL的set命令或其它一些值传播方式。
cmake中的list是;分割的字符串组。要创建list,可以使用set命令。注意:macro参数不是变量,因此不能在list命令中使用。
- set(var a b c d e) # create a list
- message("var: ${var}") # var: a;b;c;d;e
-
- set(var "a b c d e") # creates a string or a list with one item in it
- message("var: ${var}") # var: a b c d e
指定索引值(index value)时,如果
1.Reading:
LENGTH:返回list的长度
- set(values a b c d e)
- list(LENGTH values var)
- message("var: ${var}") # var: 5
GET:返回list中由索引指定的元素列表
- set(values a b c d e)
-
- list(GET values 1 3 var)
- message("var: ${var}") # var: b;d
-
- list(GET values -1 -3 -5 var)
- message("var: ${var}") # var: e;c;a
JOIN:返回使用粘合字符串(glue string)连接所有list元素的字符串。要连接多个不属于list的字符串,需要使用string命令的JOIN操作符
- set(values a b c d e)
- list(JOIN values "-" var)
- message("var: ${var}") # var: a-b-c-d-e
SUBLIST:返回给定list的子list.如果
- set(values a b c d e f g h i j)
-
- list(LENGTH values len)
- list(SUBLIST values 2 ${len} var)
- message("var: ${var}") # var: c;d;e;f;g;h;i;j
-
- list(SUBLIST values 2 2 var)
- message("var: ${var}") # var: c;d
-
- list(SUBLIST values 1 0 var)
- message("var: ${var}") # var:
-
- list(SUBLIST values 3 -1 var)
- message("var: ${var}") # var: d;e;f;g;h;i;j
-
- list(SUBLIST values 3 -2 var) # CMake Error at test_list.cmake:45 (list):
- # list length: -2 should be -1 or greater
2.Search:返回list中指定元素的的索引,如果未找到则返回-1
- set(values a b c d e f g h i j)
-
- list(FIND values c var)
- message("var: ${var}") # var: 2
-
- list(FIND values w var)
- message("var: ${var}") # var: -1
3.Modification:
APPEND:将元素附加到list中。如果当前范围内不存在名为的变量,则其值被视为空,并且元素将附加到该空list中
- set(values1 a b c d e)
- set(values2 1 2 3 4 5)
-
- list(APPEND var A B C)
- message("var: ${var}") # var: A;B;C
-
- list(APPEND var ${values1} ${values2})
- message("var: ${var}") # var: A;B;C;a;b;c;d;e;1;2;3;4;5
FILTER:从list中includes或removes与模式匹配的项(item)。在REGEX模式下,items将与给定的正则表达式匹配
- set(values a 1 b 2 c 3 d 4 e 5)
- list(FILTER values INCLUDE REGEX "[a-z]")
- message("values: ${values}") # values: a;b;c;d;e
-
- set(values a 1 b 2 c 3 d 4 e 5)
- list(FILTER values EXCLUDE REGEX "[a-z]")
- message("values: ${values}") # values: 1;2;3;4;5
INSERT:将元素插入到指定索引的list中。指定超出范围的索引会触发error。有效索引我0到N,其中N是list的长度,含N。空list的长度为0.如果当前范围内不存在名为的变量,则其值被视为空,并且元素将插入到该空list中
- set(values a b c d e)
-
- list(INSERT var 0 A B)
- message("var: ${var}") # var: A;B
-
- list(INSERT var 1 ${values})
- message("var: ${var}") # var: A;a;b;c;d;e;B
-
- list(INSERT var -2 C)
- message("var: ${var}") # var: A;a;b;c;d;C;e;B
-
- list(INCLUDE var 10 D) # CMake Error at test_list.cmake:84 (list):
- # list does not recognize sub-command INCLUDE
POP_BACK:如果没有给出变量名,则只删除最后一个元素。否则,在提供N个变量名的情况下,将最后N个元素的值分配给给定变量,然后从中删除最后N个值
- set(values a b c d e)
- list(POP_BACK values)
- message("values: ${values}") # values: a;b;c;d
-
- set(values a b c d e)
- list(POP_BACK values var1 var2 var3)
- message("values: ${values}; var1: ${var1}; var2: ${var2}; var3: ${var3}") # values: a;b; var1: e; var2: d; var3: c
POP_FRONT:如果没有给出变量名,则只删除最前一个元素。否则,在提供N个变量名的情况下,将最前N个元素的值分配给给定变量,然后从中删除最前N个值
- set(values a b c d e)
- list(POP_FRONT values)
- message("values: ${values}") # values: b;c;d;e
-
- set(values a b c d e)
- list(POP_FRONT values var1 var2 var3)
- message("values: ${values}; var1: ${var1}; var2: ${var2}; var3: ${var3}") # values: d;e; var1: a; var2: b; var3: c
PREPEND:将元素插入到list中的第0位。如果当前作用域中不存在名为的变量,则其值被视为空,并且元素将附加到该空list中
- list(PREPEND var a b c d)
- message("var: ${var}") # var: a;b;c;d
-
- set(values a b c d e)
- list(PREPEND values 1 2 3)
- message("values: ${values}") # values: 1;2;3;a;b;c;d;e
REMOVE_ITEM:从list中删除给定items的所有实例(removes all instances of the given items)
- set(values a 1 b 2 c 3 d 4 e 5)
- list(REMOVE_ITEM values 1 2 3 4 5)
- message("values: ${values}") # values: a;b;c;d;e
REMOVE_AT:从list中删除给定index的item
- set(values a 1 b 2 c 3 d 4 e 5)
- list(REMOVE_AT values 0 2 4 6 8)
- message("values: ${values}") # values: 1;2;3;4;5
REMOVE_DUPLICATES:删除list中的重复项。items的相对顺序被保留,但如果遇到重复项,则仅保留第一个实例
- set(values a 1 b 2 a 1 b 2 c 3)
- list(REMOVE_DUPLICATES values)
- message("values: ${values}") # values: a;1;b;2;c;3
TRANSFORM:通过将
- list(TRANSFORM
[] [OUTPUT_VARIABLE
- list(TRANSFORM
...) # 将指定的value追加或前置到list的每个元素
- list(TRANSFORM
...) # 将list的每个元素转换为大写或小写字符
- list(TRANSFORM
STRIP ...) # 移除list中的前后空格
- list(TRANSFORM
GENEX_STRIP ...) # 从list的每个元素中删除any generator expressions
- list(TRANSFORM
REPLACE ...) # 匹配正则表达式,替换list中每个元素的匹配项
- set(values a b c d e)
- list(TRANSFORM values APPEND 1)
- message("values: ${values}") # values: a1;b1;c1;d1;e1
- list(TRANSFORM values PREPEND 2)
- message("values: ${values}") # values: 2a1;2b1;2c1;2d1;2e1
-
- set(values a b c d e)
- list(TRANSFORM values APPEND 1 OUTPUT_VARIABLE var)
- message("values: ${values}; var: ${var}") # values: a;b;c;d;e; var: a1;b1;c1;d1;e1
-
- set(values a b c d e)
- list(TRANSFORM values TOUPPER)
- message("values: ${values}") # values: A;B;C;D;E
- list(TRANSFORM values TOLOWER)
- message("values: ${values}") # values: a;b;c;d;e
-
- set(values a b c d e)
- list(APPEND values " f j " " p q ")
- message("values: ${values}") # values: a;b;c;d;e; f j ; p q
- list(TRANSFORM values STRIP)
- message("values: ${values}") # values: a;b;c;d;e;f j;p q
-
- set(value one;$<1:two;three>;four;$
) - list(TRANSFORM value GENEX_STRIP)
- message("value: ${value}") # value: one;$<1:two;three>;four;
-
- set(values a 1 b 2 c 3 d 4 e 5)
- list(TRANSFORM values REPLACE "[a-z]" "T")
- message("values: ${values}") # values: T;1;T;2;T;3;T;4;T;5
-
- set(values a b c d e)
- list(TRANSFORM values APPEND 1 AT 0 3)
- message("values: ${values}") # values: a1;b;c;d1;e
-
- set(values a b c d e 1 2 3 4 5)
- list(TRANSFORM values APPEND "#" FOR 2 8 2)
- message("values: ${values}") # values: a;b;c#;d;e#;1;2#;3;4#;5
-
- set(values a b c d e 1 2 3 4 5)
- list(TRANSFORM values APPEND "#" REGEX [a-c])
- message("values: ${values}") # values: a#;b#;c#;d;e;1;2;3;4;5
- list(TRANSFORM
AT [ ...] ...) # 指定list索引
- list(TRANSFORM
FOR [] ...) # 指定一个范围,可选项,迭代增量
- list(TRANSFORM
REGEX ...) # 正则表达式,只有匹配正则表达式的元素才会被转换
4.Ordering:
REVERSE:就地(in-place)反转list的内容
- set(values a b c d e)
- list(REVERSE values)
- message("values: ${values}") # values: e;d;c;b;a
SORT:就地(in-place)按字母顺序对list进行排序
list(SORT [COMPARE ] [CASE <case>] [ORDER ])
使用COMPARE关键字选择排序的比较方法,
(1).STRING:按字母顺序对字符串list进行排序。如果没有给出COMPARE选项,这是默认行为
(2).FILE_BASENAME:按文件的basenames对文件的路径名list进行排序
(3).NATURAL:使用自然顺序(natural order)对字符串list进行排序
使用CASE关键字选择区分大小写或不区分大小写的排序模式。
(1).SENSITIVE:list items以区分大小写(case-sensitive)的方式排序。如果没有给出CASE选项,这是默认行为
(2).INSENSITIVE:list items不区分大小写
要控制排序顺序,可以给出ORDER关键字。
(1).ASCENDING:按升序对list进行排序。这是未给出ORDER选项时的默认行为
(2).DESCENDING:按降序对list进行排序
- set(values c 4 a I f 9 -1 B b)
- list(SORT values COMPARE STRING)
- message("values: ${values}") # values: -1;4;9;B;I;a;b;c;f
-
- set(values 10.0 1.1 2.1 8.0 2.0 3.1)
- list(SORT values)
- message("values: ${values}") # values: 1.1;10.0;2.0;2.1;3.1;8.0
-
- set(values 10.0 1.1 2.1 8.0 2.0 3.1)
- list(SORT values COMPARE NATURAL)
- message("values: ${values}") # values: 1.1;2.0;2.1;3.1;8.0;10.0
-
- set(values A c B e i H)
- list(SORT values CASE SENSITIVE)
- message("values: ${values}") # values: A;B;H;c;e;i
-
- set(values A c B e i H)
- list(SORT values CASE INSENSITIVE)
- message("values: ${values}") # values: A;B;c;e;H;i
-
- set(values A c B e i H)
- list(SORT values ORDER ASCENDING)
- message("values: ${values}") # values: A;B;H;c;e;i
-
- set(values A c B e i H)
- list(SORT values ORDER DESCENDING)
- message("values: ${values}") # values: i;e;c;H;B;A
执行上述测试代码需要3个文件:build.sh, CMakeLists.txt, test_list.cmake
build.sh内容如下:
- #! /bin/bash
-
- # supported input parameters(cmake commands)
- params=(function macro cmake_parse_arguments \
- find_library find_path find_file find_program find_package \
- cmake_policy cmake_minimum_required project include \
- string list set)
-
- usage()
- {
- echo "Error: $0 needs to have an input parameter"
-
- echo "supported input parameters:"
- for param in ${params[@]}; do
- echo " $0 ${param}"
- done
-
- exit -1
- }
-
- if [ $# != 1 ]; then
- usage
- fi
-
- flag=0
- for param in ${params[@]}; do
- if [ $1 == ${param} ]; then
- flag=1
- break
- fi
- done
-
- if [ ${flag} == 0 ]; then
- echo "Error: parameter \"$1\" is not supported"
- usage
- exit -1
- fi
-
- if [[ ! -d "build" ]]; then
- mkdir build
- cd build
- else
- cd build
- fi
-
- echo "==== test $1 ===="
- cmake -DTEST_CMAKE_FEATURE=$1 ..
CMakeLists.txt内容如下:
- cmake_minimum_required(VERSION 3.22)
- project(cmake_feature_usage)
-
- message("#### current cmake version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}")
- include(test_${TEST_CMAKE_FEATURE}.cmake)
- message("==== test finish ====")
test_list.cmake:为上面的所有示例代码
可能的执行结果如下图所示:
