kmpkg_list
kmpkg_list 是 CMake 原生 list() 函数的替代方案,重点优化了对包含内部分号的元素(例如嵌套列表)的处理逻辑。
用法
kmpkg_list(SET <输出变量> [<元素>...])
kmpkg_list(<子命令> <列表变量> [<其他参数>...])
说明
当需要正确处理“列表的列表(嵌套列表)”时,应优先使用 kmpkg_list() 而非原生 list()。
kmpkg_list() 支持原生 list() 函数的所有子命令,但存在以下限制:
GET、REMOVE_ITEM、REMOVE_AT仅支持单个索引/值(不支持批量操作);POP_BACK和POP_FRONT不支持将弹出的值存入另一个输出变量。需采用 C++ 风格:先GET获取值,再执行POP_(BACK|FRONT);- 不支持
FILTER和TRANSFORM子命令。
kmpkg_list 额外新增了 kmpkg_list(SET) 子命令,该子命令可正确创建嵌套列表(列表的列表)。
更多基础用法可参考 CMake 官方 list() 文档。
关于零元素列表的特殊说明
kmpkg_list 最核心的特殊行为源于空字符串 "" 的双重语义:CMake 中 "" 既表示“零元素列表”,也表示“包含一个空元素的列表”。kmpkg_list 始终将 "" 解读为零元素列表,这可能导致以下特殊行为:
示例 1:向空列表追加两个空元素
set(lst "")
kmpkg_list(APPEND lst "" "")
# 最终 lst = ";"(表示包含两个空元素的列表)
示例 2:向空列表追加一个空元素(最特殊的场景)
set(lst "")
kmpkg_list(APPEND lst "")
# 最终 lst = ""
# 原因:空列表追加一个空元素后,理论上是“包含一个空元素的列表”,但受 "" 语义影响仍表现为 ""
非空列表无此特殊行为:
set(lst "a")
kmpkg_list(APPEND lst "")
# 最终 lst = "a;"(表示包含 "a" 和一个空元素的列表)
示例
1. 创建列表(支持嵌套)
kmpkg_list(SET foo_param) # 初始化空列表
if(DEFINED arg_FOO)
kmpkg_list(SET foo_param FOO "${arg_FOO}") # 构建嵌套列表
endif()
2. 向列表追加含内部分号的元素
set(OPTIONS -DFOO=BAR)
if(KMPKG_TARGET_IS_WINDOWS)
# 原生 list() 会将 "-DOS=WINDOWS;FOO" 拆分为两个元素,kmpkg_list 可保留为单个元素
kmpkg_list(APPEND OPTIONS "-DOS=WINDOWS;FOO")
endif()
3. 弹出列表末尾元素
if(NOT list STREQUAL "") # 先判断列表非空
kmpkg_list(GET list end -1) # 先获取末尾元素到变量 end
kmpkg_list(POP_BACK list) # 再弹出末尾元素
endif()