CMake中list的使用

2023-10-27

      CMake中的list命令用于列表操作,其格式如下:

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子命令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)时,如果<element index>为0或更大,则从list的开头开始索引,0表示第一个list元素。如果<element index>为-1或更小,则从list末尾开始索引,-1表示最后一个list元素。使用负索引计数时要小心:它们不是从0开始的。-0相当于0,即第一个list元素。

      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.如果<length>为0,将返回一个空list.如果<length>为-1或list小于<begin>+<length>则将返回list中从<begin>开始的剩余元素

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>的变量,则其值被视为空,并且元素将附加到该空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>的变量,则其值被视为空,并且元素将插入到该空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个元素的值分配给给定变量,然后从<list>中删除最后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个元素的值分配给给定变量,然后从<list>中删除最前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中

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:通过将<ACTION>应用于所有或通过<SELECTOR>指定的元素来转换list,将结果存储在原list或指定的<output variable>中。TRANSFORM子命令不会更改list中元素的数量。如果指定了<SELECTOR>,则只会更改一些元素,其它元素将保持与转换前相同。<ACTION>指定应用于list元素的操作。这些操作与string命令的子命令具有完全相同的语义。<ACTION>必须是以下之一:

list(TRANSFORM <list> <ACTION> [<SELECTOR>] [OUTPUT_VARIABLE <output variable>])
list(TRANSFORM <list> <APPEND|PREPEND> <value> ...) # 将指定的value追加或前置到list的每个元素
list(TRANSFORM <list> <TOLOWER|TOUPPER> ...) # 将list的每个元素转换为大写或小写字符
list(TRANSFORM <list> STRIP ...) # 移除list中的前后空格
list(TRANSFORM <list> GENEX_STRIP ...) # 从list的每个元素中删除any generator expressions
list(TRANSFORM <list> REPLACE <regular_expression> <replace_expression> ...) # 匹配正则表达式,替换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;$<TARGET_OBJECTS:some_target>)
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

      <SELECTOR>确定转换list中的哪些元素。一次只能指定一种类型的selector,若给定,<SELECTOR>必须是以下之一:

list(TRANSFORM <list> <ACTION> AT <index> [<index> ...] ...) # 指定list索引
list(TRANSFORM <list> <ACTION> FOR <start> <stop> [<step>] ...) # 指定一个范围,<step>可选项,迭代增量
list(TRANSFORM <list> <ACTION> REGEX <regular_expression> ...) # 正则表达式,只有匹配正则表达式的元素才会被转换

      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 <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])

      使用COMPARE关键字选择排序的比较方法,<compare>选项应该是其中之一:
      (1).STRING:按字母顺序对字符串list进行排序。如果没有给出COMPARE选项,这是默认行为
      (2).FILE_BASENAME:按文件的basenames对文件的路径名list进行排序
      (3).NATURAL:使用自然顺序(natural order)对字符串list进行排序
      使用CASE关键字选择区分大小写或不区分大小写的排序模式。<case>选项应该是其中之一:
      (1).SENSITIVE:list items以区分大小写(case-sensitive)的方式排序。如果没有给出CASE选项,这是默认行为
      (2).INSENSITIVE:list items不区分大小写
      要控制排序顺序,可以给出ORDER关键字。<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:为上面的所有示例代码

      可能的执行结果如下图所示:

      GitHub: https://github.com/fengbingchun/Linux_Code_Test

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake中list的使用 的相关文章

  • CMake中configure_file的使用

    CMake中的configure file命令用于将一个文件拷贝到另一个位置并修改其内容 其格式如下 configure file
  • CMake中define_property的使用

    CMake中的define property命令用于定义和记录自定义属性 其格式如下 define property
  • CMake中list的使用

    CMake中的list命令用于列表操作 其格式如下 Reading list LENGTH
  • Vcpkg介绍及使用

    Vcpkg用于在Windows Linux Mac上管理C和C 库 极大简化了第三方库的安装 它由微软开源 源码地址 https github com Microsoft vcpkg 最新发布版本为2023 04 15 Release 它的
  • CMake中add_definitions/add_compile_definitions的使用

    CMake中的add definitions命令用于在源文件的编译中添加 D定义标志 其格式如下 add definitions DFOO DBAR 将当前目录中的target的定义添加到编译器命令行 compiler command li
  • 图像处理库(fbc_cv):源自OpenCV代码提取

    在实际项目中会经常用到一些基本的图像处理操作 而且经常拿OpenCV进行结果对比 因此这里从OpenCV中提取了一些代码组织成fbc cv库 项目fbc cv所有的代码已放到GitHub中 地址为 https github com feng
  • Ubuntu下通过CMake文件编译CUDA+OpenCV代码操作步骤

    在 CUDA Test 工程中 CUDA测试代码之前仅支持在Windows10 VS2013编译 今天在Ubuntu 14 04下写了一个CMakeLists txt文件 支持在Linux下也可以通过CMake编译CUDA Test工程 C
  • CMake中aux_source_directory的使用

    CMake中的aux source directory命令用于查找目录中的所有源文件 其格式如下 aux source directory
  • 在Ubuntu14.04 64位上编译CMake源码操作步骤

    在Ubuntu上通过apt get install安装CMake并不是最新版的 这里记录下在Ubuntu上通过源码安装CMake的操作步骤 1 卸载旧版CMake 执行以下命令 apt get autoremove cmake 如果卸载不掉
  • CMake中option和cmake_dependent_option的使用

    CMake中的option命令为用户提供可以选择的布尔选项 boolean option 其格式如下 option
  • Linux下遍历指定目录的C++实现

    之前在 https blog csdn net fengbingchun article details 51474728 给出了在Windows遍历指定文件夹的C 实现 这里给出在Linux下遍历目录的实现 Windows和Linux下的
  • CMake中set_target_properties/get_target_property的使用

    CMake中的set target properties命令用于为targets设置属性 targets can have properties that affect how they are built 其格式如下 set target
  • GCC编译选项参数介绍

    gcc和g 分别是gnu的c和c 编译器 下面是整理的常用编译选项参数 1 x 设定文件所使用的语言 使文件后缀名无效 如下 执行完后生成test o gcc c x c test jpg 2 c 只编译生成目标文件即 o 只编译不链接生成
  • C++中插件使用举例

    插件并不是在构建时链接的 而是在运行时发现并加载的 因此 用户可以利用你定义好的插件API来编写自己的插件 这样他们就能以指定方式扩展API的功能 插件库是一个动态库 它可以独立于核心API编译 在运行时根据需要显示加载 不过插件也可以使用
  • CMake中if的使用

    CMake中的if命令用于有条件地执行一组命令 其格式如下 if
  • CMake中while/continue/break的使用

    CMake中的while命令用于在条件为true时评估 evaluate 一组命令 其格式如下 while
  • CMake中cmake_minimum_required的使用

    CMake中的命令cmake minimum required用于设定需要的最低版本的CMake 其格式如下 cmake minimum required VERSION
  • Ubuntu14.04下配置OpenGL及测试代码

    ubuntu14 04 64位下 默认是没有安装OpenGL相关依赖库的 若安装 则依次执行如下几条命令即可 sudo apt get update sudo apt get install build essential sudo apt
  • CMake中target_compile_definitions的使用

    CMake中的target compile definitions命令用于向target添加编译定义 其格式如下 target compile definitions
  • CMake中include的使用

    CMake中的include命令用于从文件或模块 file or module 加载并运行CMake code 其格式如下 include

随机推荐

  • pytorch/torch安装简明教程

    LINUX上安装 0 进入官网https pytorch org 按照你的系统以及配置 获取安装命令 1 安装gpu版本的torch cuda包 用于torch调用gpu加速库 pip install torch 1 5 0 cu101 t
  • redis运维之数据迁移

    1 导出redis的aof和rdb文件 在Redis中 可以使用BGSAVE命令导出AOF日志 而使用SAVE命令导出RDB文件 2 AOF和RDB日志的导出位置 打开redis conf文件 找到如下配置 dir path to your
  • promise中的回调函数、async和await的执行顺序

    一 几个关键问题 1 宏队列 用来保存待执行的宏任务 回调 比如 定时器回调 DOM事件回调 ajax回调 2 微队列 用来保存待执行的微任务 回调 比如 promise的回调 MutationObserver的回调 3 JS执行时 必须先
  • USB物理层

    USB总线接口具有向外提供电源的能力 并且是5V的电压 非常的适合TTL信号系统 使用这个电源可以再一定程度上为设备供电 减少了USB电源设计 简化了USB系统结构 USB 电缆有四根导线 电源线 红色Vbus 地线 黑色GND D 绿色
  • tkFileDialog.py

    def askopenfilename options Ask for a filename to open return Open options show def asksaveasfilename options Ask for a
  • Cause: com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully.....

    最近将之前的项目部署到了服务器之后 发现在长时间不访问网站后 再次打开页面会出现白屏现象 除非重新刷新页面 否则无法正常加载数据 使用F12查看请求返回的JSON数据发现提示内部错误 由此可知问题在服务端 服务器相关信息 OS CentOS
  • Spring cloud Alibaba 之 分布式链路追踪 sleuth

    什么是链路追踪 微服务之间相互调用 每一个请求过来可能调用多个服务 比如 一个请求调用A 服务 A 又依赖B 服务 B又依赖C 服务 这样形成一个调用链 当我们查询日志的时候都需要知道一个请求的完整路径 这个时候链路追踪就产生作用 A 调用
  • 学python心得体会800字-浅谈我对python的学习感受

    python是一门非常有潜力的高级语言 历经多年的发展 其在编程上发挥着越来越大的作用 在这学期中 通过选修python课上的基础知识学习 我对python也有了一定的认识 而且 在字符串上的处理 python相对于c语言也是给程序员极大的
  • k8s 部署 jenkins

    一 前提条件 1 安装helm 二 安装harbor 1 添加harbor helm仓库 helm repo add jenkins https charts jenkins io 2 更新仓库 helm repo update
  • 什么是UE像素流送,像素流推流是什么原理?

    游戏开发者通常在运行游戏逻辑时会将游戏渲染到屏幕的同一台设备上来运行虚幻引擎应用 多人联网游戏可能会在应用程序的多个实例之间分发部分游戏逻辑 但每个单独的实例仍然会为自己的玩家在本地渲染游戏 即使是使用 HTML5 部署选项创建可以在 We
  • 【C/C++】读取字符串的多种方式(带空格)

    获取字符 字符串对象 字符串行的多种方式 Created By Liu Xianmeng On 2022 12 10 include
  • Linux逻辑卷管理(LVM)

    一 逻辑卷 LV 卷组 VG 物理卷 PV 关系 逻辑卷 LV 是卷组 VG 的一部分 可以在卷组大小内动态增加 每个卷组可分为多个逻辑卷 卷组由多个物理卷 PV 组成 每个物理卷是一个块设备 磁盘分区等 二 LVM存储 1 准备物理设备
  • VSCode自动格式化Vue代码

    VSCode自动格式化Vue代码 Prettier Code formatter 配置代码格式化文件 配置setting json VsCode关于Vue的格式化插件非常多 网上的资料也五花八门 可以使用的非常少 经过多次探索 终于找到一个
  • 剑指offer第45题:扑克牌顺子

    剑指offer第45题 扑克牌顺子 题目描述 扑克牌顺子 源码 题目描述 扑克牌顺子 LL今天心情特别好 因为他去买了一副扑克牌 发现里面居然有2个大王 2个小王 一副牌原本是54张 他随机从中抽出了5张牌 想测测自己的手气 看看能不能抽到
  • python,tensorflow,keras,pandas,numpy版本不匹配的问题(已解决)

    事情的起因 因为自己手残 更新了我搭建的tensorflow虚拟环境中numpy的版本 更高 导致import pandas 时出现版本不匹配的问题 于是将pandas一起更新 这时 pandas和numpy可以使用 但是由于tensorf
  • Linux 学习笔记2 常用命令

    Linux 学习笔记1 安装linux详细教程 O丶ne丨柒夜的博客 CSDN博客 查看使用7007端口的进程 ps aux grep 7007 Linux 目录结构 基本介绍 1 liux的文件系统是采用级层式的树状目录结构 在此结构中的
  • 五种边缘检测算法(附代码)

    一 Roberts 边缘检测算子 Roberts边缘检测算子根据任意一对互相垂直方向上的差分可用来计算梯度的原理 采用对角线方向相邻两像素之差 即 然后根据式 1 9 2 计算出Roberts的梯度幅度值 它们的卷积算子为 Roberts检
  • mysql tmp下#sql_xxx_0.MYD 类文件占满空间的经历

    作为一名全职运维 随时会碰到各种问题 今天晚上收到紧报警 一台数据库服务器磁盘空间使用快速从80 使用率到90 我们的数据库都是 gt 2T的磁盘 意识到这肯定是比较严重问题马上上线处理 状况如下 root mysql node1 tmp
  • 实用高效的寻路算法——A*寻路算法的实现及优化思路

    前言 寻路是游戏比较重要的一个组成部分 因为不仅AI还有很多地方 例如RTS游戏里操控人物点到地图某个点 然后人物自动寻路走过去 都需要用到自动寻路的功能 本文将介绍一个经常被使用且效率理想的寻路方法 A 寻路算法 并且提供额外的优化思路
  • CMake中list的使用

    CMake中的list命令用于列表操作 其格式如下 Reading list LENGTH