CMake简单使用(一)

news/2024/12/15 21:24:24/

目录

  • 一、Linux下安装CMake
    • 1.1 源码安装
    • 1.2 初体验
  • 二、CMake Language
    • 2.1 message打印
    • 2.2 变量的操作 set list
      • 2.2.1 Set 方法
      • 2.2.2 List 方法
  • 三、CMake 流程控制
    • 3.1 if 条件
      • 3.1.1 基本语法
      • 3.1.2 常用的条件判断
      • 3.1.3 组合条件
    • 3.2 loop 循环
      • 3.2.1. foreach 循环
        • 基本语法
        • 基本语法
  • 四、CMake 语法函数
    • 4.1 基本语法
    • 4.2 函数特性
      • 4.2.1 作用域
      • 4.2.2 可变参数

一、Linux下安装CMake

1.1 源码安装

sudo apt-get install build-essential
sudo wget https://cmake.org/files/v3.28/cmake-3.28.0.tar.gz
tar -zxvf cmake-3.28.0.tar.gz
cd cmake-3.28.0
/configure
sudo make
sudo make install
cmake --version 检查是否安装成功

1.2 初体验

下面就可以写一段代码来简单使用一下CMake,
hello.cc:

#include <iostream>
int main() {std::cout << "hello cmake" << std::endl;return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.20.0) 
project(hello)
add_executable(hello hello.cc)

生成makefile文件:

cmake -B build

生成二进制可执行文件:

cmake --build build

运行可执行文件:

build/hello

二、CMake Language

如果不用上述的通过CMakeLists.txt运行cmake,还可以使用cmake -P filename.cmake来运行cmake文件,本写法较少在项目中用到,但适合学习cmake语法。

2.1 message打印

# 单行打印
message(hello cmake)
message("hello cmake")
# 多行打印
message("hello
cmake")
message([[hello
cmake]])

在这里插入图片描述
此外,还可以使用message获取关于cmake的信息,使用时需要加上${}表示获取变量,如获取版本号message(\${CMAKE_VERSION})

2.2 变量的操作 set list

cmake的变量分为两种:

  • cmake自带
  • 自定义
  • CMake变量的命名区分大小写
  • CMake中的变量在存储时都是字符串
  • CMake获取变量:${变量名}
  • 变量的基础操作是set()与unset(),但也可以用list或是string操作变量

2.2.1 Set 方法

  • set(<variable> <value>... [CACHE <type> <docstring> [FORCE]])
    • <variable>:要设置的变量名称。
    • <value>:变量的值,可以是单个值,也可以是多个值。
    • CACHE:如果需要将变量存储到 CMake 缓存中,可以使用此选项。
    • <type>:缓存变量的类型,例如 BOOL、STRING、FILEPATH 等。
    • <docstring>:缓存变量的描述信息,通常是对变量用途的说明。
    • FORCE:强制更新缓存变量,即使它已经存在。
  • set可以给一个变量设置多个值
    设置一个值:
set(MY_VAR "Hello World")
message(${MY_VAR})  # 输出 "Hello World"

设置多个值:

set(MY_LIST 1 2 3 4)
message("${MY_LIST}")  # 输出 "1;2;3;4"

2.2.2 List 方法

在 CMake 中,list 命令用于操作列表变量,包括添加、获取、插入、删除、查找和分割列表元素等。CMake 中的列表是用分号 (😉 分隔的一系列字符串。

  • list(<COMMAND> <LIST_NAME> [ARGS...])
    • <COMMAND>具体的列表操作命令。
    • <LIST_NAME>:操作的列表变量名称。
    • ARGS…:根据具体命令传递的参数。
  1. APPEND:向列表末尾添加元素
set(MY_LIST "A" "B")
list(APPEND MY_LIST "C" "D")
message("${MY_LIST}")  # 输出 "A;B;C;D"
  1. PREPEND:向列表开头添加元素
set(MY_LIST "A" "B")
list(PREPEND MY_LIST "C" "D")
message("${MY_LIST}")  # 输出 "C;D;A;B"
  1. INSERT:向指定位置插入元素
set(MY_LIST "A" "B" "C")
list(INSERT MY_LIST 1 "X" "Y")
message("${MY_LIST}")  # 输出 "A;X;Y;B;C"
  1. REMOVE_ITEM:移除指定的元素
set(MY_LIST "A" "B" "C" "B")
list(REMOVE_ITEM MY_LIST "B")
message("${MY_LIST}")  # 输出 "A;C"
  1. REMOVE_AT:移除指定位置的元素
set(MY_LIST "A" "B" "C" "D")
list(REMOVE_AT MY_LIST 1 3)
message("${MY_LIST}")  # 输出 "A;C"
  1. REMOVE_DUPLICATES:移除重复元素
set(MY_LIST "A" "B" "A" "C" "B")
list(REMOVE_DUPLICATES MY_LIST)
message("${MY_LIST}")  # 输出 "A;B;C"
  1. LENGTH:获取列表长度
set(MY_LIST "A" "B" "C")
list(LENGTH MY_LIST LEN)
message("Length: ${LEN}")  # 输出 "Length: 3"
  1. GET:获取指定位置的元素
set(MY_LIST "A" "B" "C")
list(GET MY_LIST 1 ITEM)
message("Item: ${ITEM}")  # 输出 "Item: B"
  1. FIND:查找元素的位置
set(MY_LIST "A" "B" "C")
list(FIND MY_LIST "B" INDEX)
message("Index: ${INDEX}")  # 输出 "Index: 1"
  1. SORT:对列表排序
set(MY_LIST "C" "A" "B")
list(SORT MY_LIST)
message("${MY_LIST}")  # 输出 "A;B;C"
  1. REVERSE:反转列表
set(MY_LIST "A" "B" "C")
list(REVERSE MY_LIST)
message("${MY_LIST}")  # 输出 "C;B;A"

三、CMake 流程控制

3.1 if 条件

3.1.1 基本语法

if (CONDITION)# 当 CONDITION 为真时执行的代码块
elseif (ANOTHER_CONDITION)# 当 ANOTHER_CONDITION 为真时执行的代码块
else()# 当上述条件均不满足时执行的代码块
endif()
  • if:开始条件判断。
  • elseif:可选的分支,用于添加额外的条件。
  • else:可选分支,处理所有未满足的情况。
  • endif:结束 if 块。

3.1.2 常用的条件判断

  1. 布尔值
set(VAR TRUE)
if (VAR)message("VAR is true")
else()message("VAR is false")
endif()

布尔值判断支持 TRUE、FALSE,以及空字符串(视为 FALSE)。
2. 数值比较

set(VAR 10)
if (VAR EQUAL 10)message("VAR is 10")
elseif (VAR GREATER 10)message("VAR is greater than 10")
else()message("VAR is less than 10")
endif()
  • EQUAL:等于
  • LESS:小于
  • GREATER:大于
  • LESS_EQUAL:小于等于
  • GREATER_EQUAL:大于等于
  • NOT:取反
  1. 字符串比较
set(VAR "hello")
if (VAR STREQUAL "hello")message("VAR equals hello")
endif()
  • STREQUAL:字符串相等
  • MATCHES:正则表达式匹配
  1. 文件和路径
if (EXISTS "CMakeLists.txt")message("CMakeLists.txt exists")
endif()
  • EXISTS:检查文件或目录是否存在
  • IS_DIRECTORY:检查是否为目录
  • IS_SYMLINK:检查是否为符号链接
  1. 变量自定义检查
if (DEFINED MY_VAR)message("MY_VAR is defined")
endif()

3.1.3 组合条件

条件可以用逻辑运算符组合:

  • AND:逻辑与
  • OR:逻辑或
  • NOT:逻辑非
if (VAR1 EQUAL 10 AND VAR2 STREQUAL "hello")message("Both conditions are true")
endif()

3.2 loop 循环

CMake 支持循环控制语句,用于多次重复执行一段代码,主要包括 foreachwhile 两种循环形式。

3.2.1. foreach 循环

基本语法
foreach(item RANGE)# 循环体,item 是当前值
endforeach()

foreach 用于遍历列表、范围或变量。其具体形式包括三种:
1. 遍历列表
❗️这可能是最常见的用法

set(LIST_VAR a b c d)
foreach(item IN LISTS LIST_VAR)message("Item: ${item}")
endforeach()#也可以直接指定值列表:
foreach(item a b c d)message("Item: ${item}")
endforeach()

这类似于C++11的增强for循环,item相当于auto+变量
2. 遍历范围
从0开始,左闭右闭:

foreach(i RANGE 5) # 从0开始message("Index: ${i}")
endforeach()

RANGE 5 表示 [0, 1, 2, 3, 4, 5]。

  • 除此之外,也可以指定起始与结束:
foreach(i RANGE 2 5)message("Index: ${i}")
endforeach()
  • 还可以指定步长
foreach(i RANGE 2 10 3) # 依次为 始点 终点 步长message("Index: ${i}")
endforeach()

3. 遍历zip拼接
方式1:

set(L1 key1 key2 key3)
set(L2 value1 value2 value3)
foreach(key value IN ZIP_LISTS L1 L2)message("Key: ${key}, Value: ${value}")
endforeach()

方式2:

set(L1 key1 key2 key3 key4)
set(L2 value1 value2 value3 value4)
set(L3 a b c)
foreach(num IN ZIP_LISTS L1 L2 L3)message("Key: ${num_0}, Value: ${num_1}, alphabet=${num_2}")
endforeach()

当某列表为空但另一列表非空时,不会报错,为空的列表也会被打印成空
在这里插入图片描述### 3.2.2 while 循环

基本语法
while(CONDITION)# 循环体
endwhile()

while 不经常使用,这里就不展开说了

四、CMake 语法函数

4.1 基本语法

使用function关键字定义函数:

function(<name> [arg1 [arg2 ...]])# 函数体# 使用 ${arg1}, ${arg2} 来访问参数
endfunction()
  • <name> 是函数名。
  • [arg1, arg2…] 是可选的参数。

4.2 函数特性

4.2.1 作用域

  • 函数内部定义的变量是局部变量,超出函数范围后会被销毁。
  • 如果需要修改全局变量,可以使用 PARENT_SCOPE。
function(set_global_var value)set(MY_VAR ${value} PARENT_SCOPE)
endfunction()set_global_var("Global Value")
message(${MY_VAR})  # 输出: Global Value

4.2.2 可变参数

  • 使用 ARGV 和 ARGN 访问所有参数或从固定参数后的可变参数。
  • ARGV:包含所有传递的参数。
    • 可以使用ARGV0、ARGV1指定传递的参数
  • ARGN:从定义的固定参数之后的所有额外参数。
function(print_all_args)message("All arguments: ${ARGV}")message("First arguments: ${ARGV0}")message("Second arguments: ${ARGV1}")
endfunction()print_all_args(1 2 3 4)  # 输出: All arguments: 1;2;3;4

在这里插入图片描述


http://www.ppmy.cn/news/1555413.html

相关文章

基于STM32的火灾烟雾报警器Proteus仿真设计(仿真+程序+设计报告+讲解视频)

基于STM32的火灾烟雾报警器Proteus仿真设计 1.主要功能2.仿真3. 程序4. 设计报告5. 资料清单 基于STM32的火灾烟雾报警器Proteus仿真设计(仿真程序设计报告讲解视频&#xff09; 仿真图proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 设计编号&#x…

Axure高保真数据可视化大屏图表组件库

推出了一款高保真数据可视化大屏图表组件库&#xff0c;旨在为用户提供丰富的图表类型&#xff0c;使数据呈现更加直观、生动。本文将详细介绍该组件库中的各类图表元件&#xff0c;包括面积图、折线图、柱状图、条形图、圆环图、雷达图、仪表图以及综合类图表&#xff0c;以满…

7-8 整型关键字的散列映射

给定一系列整型关键字和素数 p&#xff0c;用除留余数法定义的散列函数 H(key)key%p 将关键字映射到长度为 p 的散列表中。用线性探测法解决冲突。 输入格式: 输入第一行首先给出两个正整数 n&#xff08;≤1000&#xff09;和 p&#xff08;≥n 的最小素数&#xff09;&…

【ZYNQ开发】Vitis下保存与快速加载BSP配置的方法

在使用Xilinx的Vitis进行ZYNQ PS端开发时&#xff0c;常常涉及到对于BSP的设置&#xff0c;比较典型的像是使用lwip时&#xff0c;需要对DHCP、memory以及send_buffer等进行一些自定义的修改。在设计到硬件描述文件需要进行更换&#xff08;PL端更改程序&#xff09;重新加载工…

uniapp小程序的锚点定位(将页面滚动到目标位置)

小程序中&#xff0c;a页面跳转到b页面&#xff0c;跳转后滚动定位到b页面的特定位置。 1.uni.pageScrollTo传递一个scrollTop参数可以滚动到特定位置。2.可以通过 uni.createSelectorQuery()等获取定位元素的位置信息。3.uni.getSystemInfoSync()获取设备的导航栏和状态栏高度…

超高清监测护航风电叶片,铸就绿色能源新未来

中国是世界风电第一大国。 2023年&#xff0c;中国风电叶片市场规模约为442亿元。根据中商产业研究院分析师预测&#xff0c;2025年中国风电叶片市场规模将增长至562亿元。全球风电装机容量的不断扩容&#xff0c;无疑预示着风电叶片市场将持续保持旺盛态势。 风电叶片是风电…

Maven完整技术汇总

额外知识点 IDE IDE是集成开发环境的缩写&#xff0c;它是一种软件应用程序&#xff0c;提供了编码、调试和部署软件的一站式解决方案。这些功能集成在一起&#xff0c;使开发人员能够在一个环境中完成整个软件开发过程&#xff0c;从编写代码到调试和测试&#xff0c;直到最终…

最新全开源IM即时通讯系统源码(PC+WEB+IOS+Android)部署指南

全开源IM&#xff08;即时通讯&#xff09;系统源码部署是一个复杂但系统的过程&#xff0c;涉及多个组件和步骤。以下是一个详细的部署指南&#xff0c;旨在帮助开发者或系统管理员成功部署一个全开源的IM系统&#xff0c;如OpenIM。      IM即时通讯系统源码准备工作   …