【CMake】(10) 变量操作

302 阅读1分钟

追加

追加操作允许你将新元素添加到现有的变量或列表中。

使用 set 进行变量追加

set 命令不仅可以用于定义变量,还可以用于修改变量的值,包括追加新值。下面是 set 命令用于追加操作的示例:

cmake_minimum_required(VERSION 3.0)
project(TEST)

set(VAR "Hello")
set(MORE_STRINGS "World" "CMake" "Example")

# 追加字符串到变量
set(VAR ${VAR} ${MORE_STRINGS})

message(STATUS "VAR: ${VAR}")

上述示例中,VAR 的原始值是 "Hello"。通过 set 命令,我们追加了 MORE_STRINGS 中的字符串,最终 VAR 包含了 "Hello World CMake Example"

使用 list 进行追加

list 命令在处理 CMake 列表时更为强大,可以用于追加、移除和操作列表。以下是使用 list 命令进行追加操作的示例:

cmake_minimum_required(VERSION 3.0)
project(TEST)

set(LIST_VAR "One" "Two")
set(MORE_ITEMS "Three" "Four" "Five")

# 使用 list 命令追加元素
list(APPEND LIST_VAR ${MORE_ITEMS})

message(STATUS "LIST_VAR: ${LIST_VAR}")

在这个例子中,LIST_VAR 的原始值是列表 "One;Two"。使用 list(APPEND ...) 命令后,MORE_ITEMS 中的元素被追加到 LIST_VAR 中,得到 "One;Two;Three;Four;Five"

列表

1. 创建和修改列表

使用 set 命令创建列表:

set(MY_LIST "item1" "item2" "item3")

这会创建一个名为 MY_LIST 的列表,包含三个条目 "item1"、"item2" 和 "item3"。

追加元素到列表:

list(APPEND MY_LIST item4 item5)

这会将 "item4" 和 "item5" 追加到 MY_LIST

移除元素:

list(REMOVE_ITEM MY_LIST item2)

这会从 MY_LIST 移除 "item2"。

插入元素:

list(INSERT MY_LIST 1 item1_5)

这会在 MY_LIST 的索引1的位置(即 "item1" 之后)插入 "item1_5"。

移除重复元素:

list(REMOVE_DUPLICATES MY_LIST)

这将移除 MY_LIST 中的重复条目。

2. 查询列表

获取列表长度:

list(LENGTH MY_LIST MY_LIST_LENGTH)

这将获取 MY_LIST 的长度并存储在变量 MY_LIST_LENGTH 中。

获取列表中特定索引的元素:

list(GET MY_LIST 0 FIRST_ITEM)

这将获取 MY_LIST 中索引为0的元素并存储在变量 FIRST_ITEM 中。

查找列表中的元素:

list(FIND MY_LIST "item3" ITEM_INDEX)

如果 "item3" 在 MY_LIST 中,ITEM_INDEX 将是其索引,否则 ITEM_INDEX 将为 -1。

3. 列表转换

将列表元素组合为一个字符串:

list(JOIN MY_LIST "," MY_LIST_STRING)

这将用逗号将 MY_LIST 中的所有元素连接成一个字符串,存储在 MY_LIST_STRING

排序列表:

list(SORT MY_LIST)

这将会按照字母顺序对名为listName的列表中的元素进行升序排序。

基本语法如下:

list (SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])

高级选项

对于更复杂的排序需求,list(SORT ...)命令提供了几个可选参数:

  • COMPARE:选择排序方法。可选的方法有STRING(默认,按字母顺序)、FILE_BASENAME(按文件基本名排序)和NATURAL(自然排序)。
  • CASE:确定排序是否大小写敏感。可选的值有SENSITIVE(默认,大小写敏感)和INSENSITIVE(大小写不敏感)。
  • ORDER:排序顺序,可选择ASCENDING(默认,升序)或DESCENDING(降序)。

注意

  • 当使用FILE_BASENAME进行排序时,排序仅考虑文件的基本名,不包括路径或扩展名。
  • 使用NATURAL排序时,数字会按照其数值大小而不是字典顺序进行排序。例如,file10.txt会排在file2.txt之后。
  • list(SORT ...)命令修改的是列表本身,而不是创建一个新的排序后的列表。

示例

假设你有一个包含文件路径的列表,并且你想要按照文件的基本名进行不区分大小写的降序排序。下面是如何实现:

cmake_minimum_required(VERSION 3.10)
project(SortExample)

# 创建一个包含文件路径的列表
set(FILE_LIST "src/main.cpp" "include/Header.h" "tests/Test.cpp")

# 按文件基本名进行不区分大小写的降序排序
list(SORT FILE_LIST COMPARE FILE_BASENAME CASE INSENSITIVE ORDER DESCENDING)

# 打印排序后的列表
foreach(FILE IN LISTS FILE_LIST)
    message(STATUS "Sorted file: ${FILE}")
endforeach()

list(SORT ...)命令将FILE_LIST中的文件路径按照它们的基本名(忽略大小写)进行降序排序。排序后的列表会通过foreach循环打印出来。

4. 列表和文件路径

当处理文件路径时,列表操作尤为有用。例如,使用 file(GLOB ...) 命令搜索某个目录下的所有文件,并将它们添加到列表中,然后使用 list 命令进行进一步操作。

示例:移除特定文件

如果你的项目目录下有多个源文件,但你想在构建库时排除一个测试文件 main.cpp,可以这样操作:

cmake_minimum_required(VERSION 3.0)
project(MyLibrary)

file(GLOB_RECURSE LIB_SOURCES "src/*.cpp")
list(REMOVE_ITEM LIB_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp")

add_library(mylib ${LIB_SOURCES})

上述示例中,file(GLOB_RECURSE ...) 会递归搜索 src 目录下的所有 .cpp 文件,并将它们添加到 LIB_SOURCES 列表中。然后 list(REMOVE_ITEM ...) 会从列表中移除 main.cpp 文件。