CMake指令:list()

目录

1.简介

2.常用命令

2.1.APPEND:向列表末尾添加元素

2.2.PREPEND:向列表开头添加元素

2.3.INSERT:在指定索引处插入元素

2.4.REMOVE_ITEM:删除列表中指定值的元素

2.5.REMOVE_AT:删除指定索引处的元素

2.6.REMOVE_DUPLICATES:移除列表中的重复元素

2.7.LENGTH:获取列表长度(元素个数)

2.8.GET:获取列表中指定索引的元素

2.9.JOIN:将列表元素用指定分隔符连接成字符串

2.10.REVERSE:反转列表顺序

2.11.SORT:对列表进行排序(按字母顺序)

2.12.CLEAR:清空列表中的所有元素

[2.13.CONCAT:合并多个列表为一个列表(等价于多次 APPEND)](#2.13.CONCAT:合并多个列表为一个列表(等价于多次 APPEND))

3.注意事项

[4.set 命令和 list 命令异同](#4.set 命令和 list 命令异同)

5.总结


1.简介

在 CMake 中,list 命令用于操作列表(Lists) ,这是 CMake 中一种重要的数据结构(用于存储多个值,如源文件路径、编译选项、宏定义等)。list 命令支持多种子命令,用于实现列表的创建、修改、查询和处理等操作。

cpp 复制代码
list(COMMAND [arguments...])

其中,COMMAND 是子命令(如 APPENDREMOVE_ITEM 等),arguments 是对应子命令的参数。

2.常用命令

2.1.APPEND:向列表末尾添加元素

cpp 复制代码
list(APPEND my_list "item1" "item2")  # 添加多个元素
# 结果:my_list = ["item1", "item2"]

2.2.PREPEND:向列表开头添加元素

cpp 复制代码
list(PREPEND my_list "item0")
# 结果:my_list = ["item0", "item1", "item2"]

2.3.INSERT:在指定索引处插入元素

cpp 复制代码
list(INSERT my_list 1 "item0.5")  # 在索引 1 处插入元素
# 结果:my_list = ["item0", "item0.5", "item1", "item2"]

2.4.REMOVE_ITEM:删除列表中指定值的元素

cpp 复制代码
list(REMOVE_ITEM my_list "item0.5")  # 删除值为 "item0.5" 的元素
# 结果:my_list = ["item0", "item1", "item2"]

2.5.REMOVE_AT:删除指定索引处的元素

cpp 复制代码
list(REMOVE_AT my_list 0)  # 删除索引 0 处的元素
# 结果:my_list = ["item1", "item2"]

2.6.REMOVE_DUPLICATES:移除列表中的重复元素

cpp 复制代码
list(APPEND my_list "item1")  # 添加重复元素
# 此时 my_list = ["item1", "item2", "item1"]
list(REMOVE_DUPLICATES my_list)
# 结果:my_list = ["item1", "item2"]

2.7.LENGTH:获取列表长度(元素个数)

cpp 复制代码
list(LENGTH my_list list_length)
message(STATUS "列表长度:${list_length}")  # 输出:列表长度:2

2.8.GET:获取列表中指定索引的元素

cpp 复制代码
list(GET my_list 0 first_item)  # 获取索引 0 处的元素
message(STATUS "第一个元素:${first_item}")  # 输出:第一个元素:item1

2.9.JOIN:将列表元素用指定分隔符连接成字符串

cpp 复制代码
list(JOIN my_list ";" joined_string)
message(STATUS "连接后的字符串:${joined_string}")  # 输出:item1;item2

2.10.REVERSE:反转列表顺序

cpp 复制代码
list(REVERSE my_list)
# 结果:my_list = ["item2", "item1"]

2.11.SORT:对列表进行排序(按字母顺序)

cpp 复制代码
list(APPEND my_list "item3" "item0")
# 此时 my_list = ["item2", "item1", "item3", "item0"]
list(SORT my_list)
# 结果:my_list = ["item0", "item1", "item2", "item3"]

2.12.CLEAR:清空列表中的所有元素

cpp 复制代码
list(CLEAR temp_files)  # 清空临时文件列表

2.13.CONCAT:合并多个列表 为一个列表(等价于多次 APPEND

cpp 复制代码
list(CONCAT all_files src_files test_files)  # 合并源文件和测试文件列表

3.注意事项

  • CMake中的list是通过空格分隔的字符串表示的,因此要注意元素中是否包含空格或特殊字符。
  • 列表索引从 0 开始(类似 C/C++ 数组)。
  • list 命令修改的是当前作用域内的列表变量 ,若需在父作用域或全局作用域生效,需配合 PARENT_SCOPECACHE 使用。
  • 在使用list命令时,要确保指定的list变量已经存在,否则CMake会报错。
  • CMake的list命令是大小写敏感的,因此在指定元素或索引时要保持一致。
  • 列表常用于 add_executableadd_library 等命令中传递源文件列表,例如:
cpp 复制代码
list(APPEND SOURCES "file1.cpp" "file2.cpp")
add_executable(my_app ${SOURCES})

4.set 命令和 list 命令异同

在 CMake 中,set 命令和 list 命令的核心区别主要体现在 功能定位操作对象 上,具体可以从以下几个方面区分:

1.功能用途:通用赋值 vs 列表专项操作

set 命令的核心是 设置变量 ,可以为变量赋予任意类型的值(字符串、数字、列表、布尔值等),甚至能操作缓存变量(CACHE 选项)或环境变量(PARENT_SCOPE 等作用域)。

简单来说,只要是 "给某个变量赋值" 的场景,无论是普通数据还是复杂结构,都可以用 set,例如:

cpp 复制代码
set(APP_NAME "MyProject")          # 赋值字符串  
set(SOURCE_FILES main.cpp util.cpp) # 赋值列表(本质是用空格分隔的字符串)  
set(DEBUG ON CACHE BOOL "Debug mode") # 设置缓存变量  

list 命令的核心是 对列表进行专项操作 ,只能作用于 "列表类型" 的数据(CMake 中列表本质是用空格分隔的字符串,但 list 命令会将其按列表逻辑处理),支持对列表进行元素添加、删除、查找、排序、拆分、合并等操作,必须通过子命令指定具体操作(如 APPENDREMOVE_ITEMFIND 等)。

例如,对已有的列表变量进行修改:

cpp 复制代码
list(APPEND SOURCE_FILES module.cpp) # 向列表追加元素  
list(REMOVE_ITEM SOURCE_FILES util.cpp) # 从列表删除指定元素  
list(SORT SOURCE_FILES) # 对列表元素排序  

2.操作对象:变量赋值 vs 列表修改

set 可以 创建新变量或覆盖已有变量 ,赋值时直接给定值,无需关注值的类型是否为列表(即使是列表,也是作为一个整体赋值给变量)。

比如,用 set 定义列表时,本质是将多个元素用空格拼接成字符串,存储到变量中:

cpp 复制代码
set(MY_LIST item1 item2 item3) # 变量 MY_LIST 的值是 "item1 item2 item3"(列表形式的字符串)  

list 必须 基于已有的变量(且通常假设该变量存储的是列表) ,通过子命令对列表的结构进行修改(增、删、改、查元素),不会直接创建变量,而是操作已有变量中的列表数据。

例如,必须先通过 set 定义一个列表变量,再用 list 对其元素进行操作:

cpp 复制代码
set(MY_LIST item1 item2)       # 先用 set 定义列表变量  
list(INSERT MY_LIST 1 item0)  # 用 list 在索引 1 处插入元素,结果 MY_LIST 变为 "item1 item0 item2"  

3.常用场景:基础变量管理 vs 复杂列表处理

  • set 的使用场景更通用,包括:

    • 定义项目基本信息(如项目名称、版本);
    • 收集源文件、头文件路径(以列表形式赋值,但本质是变量赋值);
    • 设置编译选项(如 CMAKE_CXX_FLAGS)、缓存变量(用于用户配置)等。
  • list 的使用场景更聚焦于 列表的动态操作,例如:

    • 向已有源文件列表中追加特定平台的文件(list(APPEND ...));
    • 从列表中删除不需要的元素(如排除测试文件);
    • 对列表进行排序、去重、查找特定元素(list(SORT/REMOVE_DUPLICATES/FIND ...));
    • 拆分或合并列表(如 list(SPLIT ...) 按分隔符拆字符串为列表,list(JOIN ...) 用分隔符合并列表为字符串)。

总之,set命令和list命令可以简单理解为:

  • set 是 "万能赋值器",负责给变量 "存值",值可以是任何形式(单个值或列表),甚至能创建或修改变量的作用域(如缓存、父作用域);
  • list 是 "列表处理器",负责对 "已经存了列表值的变量" 进行 "元素级别的操作",必须依赖已有变量,且需要通过子命令指定具体的列表操作逻辑。

5.总结

子命令 功能描述 示例(列表名为 my_list
APPEND 向末尾添加元素 list(APPEND my_list "a" "b")
PREPEND 向开头添加元素 list(PREPEND my_list "x")
INSERT 在指定索引插入元素 list(INSERT my_list 1 "mid")
REMOVE_ITEM 删除指定值的元素 list(REMOVE_ITEM my_list "b")
REMOVE_AT 删除指定索引的元素 list(REMOVE_AT my_list 0)
REMOVE_DUPLICATES 去重 list(REMOVE_DUPLICATES my_list)
LENGTH 获取列表长度 list(LENGTH my_list len)
GET 获取指定索引的元素 list(GET my_list 2 val)
JOIN 连接元素为字符串 list(JOIN my_list ";" str)
REVERSE 反转列表顺序 list(REVERSE my_list)
SORT 按字母序排序 list(SORT my_list)
CLEAR 清除列表 list(CLEAR temp_files)
CONCAT 合并多个列表为一个列表 list(CONCAT all_files src_files test_files)

通过这些子命令,你可以灵活地操作 CMake 列表,实现源文件管理、编译选项配置、跨平台条件处理等复杂逻辑。

相关链接

相关推荐
蒙奇D索大1 小时前
【数据结构】图论核心算法解析:深度优先搜索(DFS)的纵深遍历与生成树实战指南
数据结构·算法·深度优先·图论·图搜索算法
让我们一起加油好吗1 小时前
【基础算法】高精度(加、减、乘、除)
c++·算法·高精度·洛谷
鑫鑫向栄1 小时前
[蓝桥杯]缩位求和
数据结构·c++·算法·职场和发展·蓝桥杯
Tony__Ferguson1 小时前
简述八大排序(Sort)
数据结构·算法·排序算法
stormsha1 小时前
MCP架构全解析:从核心原理到企业级实践
服务器·c++·架构
梁下轻语的秋缘1 小时前
每日c/c++题 备战蓝桥杯(P1204 [USACO1.2] 挤牛奶 Milking Cows)
c语言·c++·蓝桥杯
鑫鑫向栄2 小时前
[蓝桥杯]外卖店优先级
数据结构·c++·算法·职场和发展·蓝桥杯
<但凡.2 小时前
题海拾贝:P8598 [蓝桥杯 2013 省 AB] 错误票据
数据结构·算法·蓝桥杯
Zfox_2 小时前
【C++项目】:仿 muduo 库 One-Thread-One-Loop 式并发服务器
linux·服务器·c++·muduo库
wangyuxuan10292 小时前
AtCoder Beginner Contest 399题目翻译
开发语言·c++·算法