【小沐学C++】C++ 基于CMake构建工程项目(Windows、Linux)

文章目录

  • 1、简介
  • 2、下载cmake
  • 3、安装cmake
  • 4、测试cmake
    • 4.1 单个源文件
    • 4.2 同一目录下多个源文件
    • 4.3 不同目录下多个源文件
    • 4.4 标准组织结构
    • 4.5 动态库和静态库的编译
    • 4.6 对库进行链接
    • 4.7 添加编译选项
    • 4.8 添加控制选项
  • 5、构建最小项目
    • 5.1 新建代码文件
    • 5.2 新建CMakeLists.txt
    • 5.3 构建项目
    • 5.4 编译项目
    • 5.5 运行项目
    • 5.6 修改相关文件
  • 结语

1、简介

官网地址:
https://cmake.org

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。
在这里插入图片描述

2、下载cmake

(1)官网下载地址一
https://cmake.org/download/
在这里插入图片描述

(2)官网下载地址二
https://cmake.org/files/
在这里插入图片描述
(3)GitHub下载地址:
https://github.com/Kitware/CMake/releases
在这里插入图片描述

ubuntu系统下只需要如下一句命令即可:

# ubuntu
sudo apt install cmake

CMake 提供了多种版本,包括但不限于 “RC 版本”(Release Candidate)和“稳定版本”(Latest Release)。切换到系统存放源代码的目录,再用 curl 命令通过该链接将 CMake 的二进制分发压缩包下载下来:

cd /usr/local/src

curl -LO https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz

# or
yum install -y wget
wget -c https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz
# wget -c https://cmake.org/files/v3.26/cmake-3.26.0-rc1-linux-x86_64.tar.gz

在这里插入图片描述

3、安装cmake

CMake 二进制分发压缩包下载完毕后,运行以下两条命令将压缩包解压缩,并将得到的文件夹移动到系统的本地程序目录,同时将文件夹重命名为 cmake(即 /usr/local/cmake):

tar -xvf cmake-3.26.0-rc1-linux-x86_64.tar.gz
# tar zxvf cmake-3.22.2-linux-x86_64.tar.gz
mv cmake-3.26.0-rc1-linux-x86_64 /usr/local/cmake

在这里插入图片描述
在这里插入图片描述
查看安装后的路径:

ls /usr/local/cmake

在这里插入图片描述

如果你是第一次按照本文步骤安装 CMake,为方便之后运行 CMake 的相关命令,请运行以下两条命令将 CMake 的可执行文件目录添加到系统环境变量 PATH 中:

echo 'export PATH="/usr/local/cmake/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

在这里插入图片描述
查看~/.bashrc:

vi ~/.bashrc
#在最后添加export PATH=/usr/local/cmake/bin:$PATH

在这里插入图片描述

查看cmake的版本:

cmake --verison

在这里插入图片描述

4、测试cmake

4.1 单个源文件

main.c:

#include <stdio.h>

int main(void)
{
	printf("Hello World\n");
	return 0;
}

然后在main.c相同目录下编写CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (demo)
add_executable(main main.c)

执行命令:

cmake .

在这里插入图片描述
在这里插入图片描述
再来看看目录下的文件,成功生成了Makefile,还有一些cmake运行时自动生成的文件:
在这里插入图片描述
查看Makefile:

vi Makefile

在这里插入图片描述
输入make命令进行编译:

make
ls
./main
#make clean

在这里插入图片描述

4.2 同一目录下多个源文件

安装tree命令,方便查看文件夹的层级关系:

ubuntu:sudo apt-get install tree
centos:yum -y install tree

在这里插入图片描述

tree ./

在这里插入图片描述

修改CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)

project (demo)
add_executable(main main.c anotherTest.c)

执行命令:

cmake .
ls
make
./main

在这里插入图片描述
如果在同一目录下有多个源文件。cmake提供了一个命令可以把指定目录下所有的源文件存储在一个变量中,这个命令就是 aux_source_directory(dir var)。第一个参数dir是指定目录,第二个参数var是用于存放源文件列表的变量。

修改CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)

project (demo)
aux_source_directory(. SRC_LIST)
add_executable(main ${SRC_LIST})

使用aux_source_directory把当前目录下的源文件存列表存放到变量SRC_LIST里,然后在add_executable里调用SRC_LIST(注意调用变量时的写法)。
aux_source_directory()也存在弊端,它会把指定目录下的所有源文件都加进来,可能会加入一些我们不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件,如下:

cmake_minimum_required (VERSION 2.8)

project (demo)
set( SRC_LIST
	 ./main.c
	 ./anotherTest.c)
	 
add_executable(main ${SRC_LIST})

4.3 不同目录下多个源文件

在这里插入图片描述
修改CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (demo)

include_directories (test1 test2)

aux_source_directory (test1 SRC_LIST)
aux_source_directory (test2 SRC_LIST1)

add_executable (main main.c ${SRC_LIST} ${SRC_LIST1})

在这里插入图片描述

4.4 标准组织结构

一般会把源文件放到src目录下,把头文件放入到include文件下,生成的对象文件放入到build目录下,最终输出的elf文件会放到bin目录下,这样整个结构更加清晰。
在这里插入图片描述
修改CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (demo)

add_subdirectory (src)

这里指定src目录下存放了源文件,当执行cmake时,就会进入src目录下去找src目录下的CMakeLists.txt,所以在src目录下也建立一个CMakeLists.txt:
添加CMakeLists.txt:

aux_source_directory (. SRC_LIST)
include_directories (../include)
add_executable (main ${SRC_LIST})
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

这里又出现一个新的命令set,是用于定义变量的,EXECUTABLE_OUT_PATH和PROJECT_SOURCE_DIR是CMake自带的预定义变量,其意义如下,

EXECUTABLE_OUTPUT_PATH :目标二进制可执行文件的存放位置
PROJECT_SOURCE_DIR:工程的根目录

在这里插入图片描述
新建build文件夹,然后进入:

mkdir build
cd build
cmake ..
make
ls
../bin/main

在这里插入图片描述
也可以只使用一个CMakeLists.txt,把最外层的CMakeLists.txt内容改成如下:

cmake_minimum_required (VERSION 2.8)
project (demo)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory (src SRC_LIST)
include_directories (include)
add_executable (main ${SRC_LIST})

4.5 动态库和静态库的编译

有时需要编译出动态库和静态库,然后等着让其它程序去使用。测试工程文件夹如下:

  • Windows示例如下:
    在这里插入图片描述
    CMakeLists.txt内容如下:
cmake_minimum_required (VERSION 2.8)

project (myrand)

# find *.cpp *.c
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/getRandomAPI.cpp)

# find *.h
include_directories (${PROJECT_SOURCE_DIR}/include)

########################################
# create lib and dll
add_library (myrand_shared SHARED ${SRC_LIST})
add_library (myrand_static STATIC ${SRC_LIST})

set_target_properties (myrand_shared PROPERTIES OUTPUT_NAME "myrand")
set_target_properties (myrand_static PROPERTIES OUTPUT_NAME "myrand_s")

set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

########################################
# create exe
add_compile_options(-std=c++11 -Wall)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_executable (myrand_test ${SRC_LIST})
命令解释如下:
(1)add_library: 生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态还是静态,如果没有就默认静态;第3个参数指定生成库的源文件)
(2)set_target_properties: 设置最终生成的库的名称,还有其它功能,如设置库的版本号等等
(3)LIBRARY_OUTPUT_PATH: 库文件的默认输出路径,这里设置为工程目录下的lib目录

在build目录下运行cmake,并把生成的库文件(.dll、.lib)存放到lib文件夹下,exe放到bin文件夹里。执行命令如下:

cd C:\Users\tomcat\Desktop\test_cmake
mkdir build
cd build
cmake ..

在这里插入图片描述
打开build文件夹如下:
在这里插入图片描述
通过命令行编译myrand.sln,如下。

# release x64(默认)
cd C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE
.\devenv.com C:\Users\tomcat\Desktop\test_cmake\build\myrand.sln /Build

# or debug x64
.\devenv.com F:\00Projects\test.sln /Build "Debug|64"

# or debug win32
.\devenv.com F:\00Projects\test.sln /Build "Debug|Win32"

运行结果如下:
在这里插入图片描述
运行结果文件夹如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.6 对库进行链接

在src目录下添加一个main.cpp,调用上面一节生成的库文件。

cmake_minimum_required (VERSION 2.8)
project (myrand_test)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.cpp)

# find *.h
include_directories (${PROJECT_SOURCE_DIR}/include)

find_library(TEST_LIB NAMES myrand HINTS ${PROJECT_SOURCE_DIR}/lib/debug)

add_executable (test ${SRC_LIST})
target_link_libraries (test ${TEST_LIB})

执行命令:

cmake ..

在这里插入图片描述
在这里插入图片描述

4.7 添加编译选项

添加一些编译选项,如-Wall,-std=c++11等,就可以使用add_compile_options来进行操作。

cmake_minimum_required (VERSION 2.8)
project (test)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_compile_options(-std=c++11 -Wall) 
add_executable(test main.cpp)

4.8 添加控制选项

有时只编译一些指定的源码,可以使用cmake的option命令:

1、本来要生成多个bin或库文件,现在只想生成部分指定的bin或库文件
2、对于同一个bin文件,只想编译其中部分代码(使用宏来控制)

CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.0)
project(test)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.cpp)
set (SRC_LIST2 ${PROJECT_SOURCE_DIR}/src/main2.cpp)

option(USE_TEST_1 "use test 1" OFF)
option(USE_TEST_2 "use test 2" OFF)
option(USE_TEST_3 "use test 3" OFF)

if (USE_TEST_1)
    add_definitions(-DTEST_1)
endif()

if (USE_TEST_2)
    add_definitions(-DTEST_2)
endif()

if (USE_TEST_3)
    add_definitions(-DTEST_3)
endif()

add_executable(main ${SRC_LIST})

if (USE_PROJECT2)
    add_executable(main2 ${SRC_LIST2})
else()
    message(STATUS "No project main2")    
endif()

main.cpp:

#include <windows.h>
#include <iostream>

int main()
{
#ifdef TEST_1
	printf("getRandom_1\n");
#endif

#ifdef TEST_2
	printf("getRandom_2\n");
#endif

#ifdef TEST_3
	printf("getRandom_3\n");
#endif

	system("pause");
	return 0;
}
cmake .. -DTEST_3=ON -DTEST_2=OFF -DUSE_PROJECT2=OFF
cmake .. -DTEST_3=ON && make

5、构建最小项目

5.1 新建代码文件

编辑代码文件:tutorial.cpp

  • tutorial.cpp
// tutorial.cpp

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
    if (argc < 2) {
        std::cout << "Usage: " << argv[0] << " number" << std::endl;
        return 1;
    }

    // convert input to double
    const double inputValue = atof(argv[1]);

    // calculate square root
    const double outputValue = sqrt(inputValue);
    std::cout << "(爱看书的小沐)The square root of " << inputValue
              << " is " << outputValue
              << std::endl;
    return 0;
}

5.2 新建CMakeLists.txt

在同一个文件夹内新建文件:CMakeLists.txt。

  • CMakeLists.txt
cmake_minimum_required(VERSION 3.15)

# set the project name
project(Tutorial)

# add the executable
add_executable(Tutorial tutorial.cpp)

cmake_minimum_required:指定使用 CMake 的最低版本号,
project:指定项目名称,
add_executable:用来生成可执行文件,需要指定生成可执行文件的名称和相关源文件。

现在开始构建、编译和运行上面代码示例。
在这里插入图片描述

5.3 构建项目

在当前项目工作文件夹,创建一个构建目录 build,接下来,进入 build 目录并运行 CMake 来配置项目,并生成构建系统。

mkdir build
cd build
cmake ..
  • 命令执行情况:
    在这里插入图片描述
  • 生成文件和文件夹如下:
    在这里插入图片描述

5.4 编译项目

然后调用该构建系统来实际编译/链接项目:

cmake --build .

在这里插入图片描述

  • 生成文件和文件夹如下:
    在这里插入图片描述

5.5 运行项目

.\debug\Tutorial.exe 3.14

运行结果如下:
在这里插入图片描述

5.6 修改相关文件

编辑代码文件:CMakeLists.txt

  • CMakeLists.txt
cmake_minimum_required(VERSION 3.15)

## set the project name
# project(Tutorial)
project(Tutorial VERSION 1.2.3)

string(TIMESTAMP COMPILE_TIME %Y%m%d-%H%M%S)
configure_file(TutorialConfig.h.in TutorialConfig.h)

# set(SRC_LIST a.cpp b.cpp c.cpp)
SET(SRC_LIST tutorial.cpp)
		   
## add the executable
# add_executable(Tutorial tutorial.cpp)
# add_executable(${PROJECT_NAME} tutorial.cpp)
# add_executable(${PROJECT_NAME} a.cpp b.cpp c.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})

target_include_directories(${PROJECT_NAME} PUBLIC
                           ${PROJECT_BINARY_DIR} )

新建文件:TutorialConfig.h.in

  • TutorialConfig.h.in
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define Tutorial_VERSION_PATCH @PROJECT_VERSION_PATCH@

#define TIMESTAMP @COMPILE_TIME@

编辑代码文件:tutorial.cpp

  • tutorial.cpp
// tutorial.cpp

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include "TutorialConfig.h"

int main(int argc, char* argv[])
{
    if (argc < 2) {
    	std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
                << Tutorial_VERSION_MINOR << std::endl;
        std::cout << "Usage: " << argv[0] << " number" << std::endl;
        return 1;
    }

    // convert input to double
    const double inputValue = atof(argv[1]);

    // calculate square root
    const double outputValue = sqrt(inputValue);
    std::cout << "(爱看书的小沐)The square root of " << inputValue
              << " is " << outputValue
              << std::endl;
    return 0;
}

执行如下命令:

cmake --build .
.\debug\Tutorial.exe

在这里插入图片描述
生成文件:TutorialConfig.h
TutorialConfig.h:

在这里插入图片描述

在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/62680.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一、1.汇编指令、寄存器和寻址方式

立即数&#xff1a;可以立即在一条机器指令后找到具体数值的数&#xff0c;如内存中00位写着加指令&#xff0c;01位写着1100_1111&#xff0c;意思就是将1100_1111&#xff08;十进制207&#xff09;加到某处&#xff0c;反之可以表示数据的地址。 低端字节序&#xff1a;16位…

Java实现数字加密

Java实现数字加密 需求分析代码实现小结Time 需求分析 1.首先&#xff0c;考虑方法是否需要接收数据处理&#xff1f; 需要一个4位数&#xff0c;至于是哪一个数&#xff0c;让方法的调用者传递。 所以&#xff0c;方法的参数&#xff0c;就是这个需要加密的四位数 2.接着&…

nsqd的架构及源码分析

文章目录 一 nsq的整体代码结构 二 回顾nsq的整体架构图 三 nsqd进程的作用 四 nsqd启动流程的源码分析 五 本篇博客总结 在博客 nsq整体架构及各个部件作用详解_YZF_Kevin的博客-CSDN博客 中我们讲了nsq的整体框架&#xff0c;各个部件的大致作用。如果没看过的&…

【websocket - Tornado】简易聊天应用

1、背景 项目测试的过程中需要自己搭建一个webscoket站点,确保此类服务接入后台系统后访问不受影响。python的服务框架常用的有Flask、Django、Tornado,每个框架的侧重点不同,导致使用的场景就会有所差异。 Flask轻量级,采用常规的同步编程方式,需要安装其他模块辅助,主…

Pytest测试框架2

目录&#xff1a; pytest参数化用例pytest标记测试用例pytest设置跳过、预期失败用例pytest运行用例pytest测试用例调度与运行pytest命令行常用参数python执行pytestpytest异常处理 1.pytest参数化用例 参数化 通过参数的方式传递数据&#xff0c;从而实现数据和脚本分离。…

并网逆变器学习笔记6---三电平SVPWM下的连续和不连续调制

之前在学习中总结过一次DPWM策略选择&#xff1a;并网逆变器学习笔记5---三电平DPWM 但是对于三电平逆变器而言&#xff0c;如何从连续调制切换到不连续调制&#xff0c;存在一些疑惑点&#xff0c;下午闲来无事&#xff0c;把SVPWM下的连续调制和不连续调制的开关状态选择&am…

MyCat核心概念、需求案例讲解、环境准备及分片配置

1.MyCat概念介绍 2.MyCat入门需求 2.1 需求分析 2.2 环境准备 输入以下命令检查服务器防火墙状态 dead代表关闭状态&#xff0c;如果不关闭也可以需要开放特定的端口号&#xff01;&#xff01; systemctl status firewalld接着需要在三台服务器上的MySQL上创建三个数据库db0…

(树) 剑指 Offer 36. 二叉搜索树与双向链表 ——【Leetcode每日一题】

❓ 剑指 Offer 36. 二叉搜索树与双向链表 难度&#xff1a;中等 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个 排序的循环双向链表。要求不能创建任何新的节点&#xff0c;只能调整树中节点指针的指向。 为了让您更好地理解问题&#xff0c;以下面的二叉搜索树为…

相机传感器格式与镜头光圈参数

相机靶面大小 CCD/CMOS图像传感器尺寸&#xff08;sensor format&#xff09;1/2’‘、1/3’‘、1/4’实际是多大 1英寸——靶面尺寸为宽12.7mm*高9.6mm&#xff0c;对角线16mm。 2/3英寸——靶面尺寸为宽8.8mm*高6.6mm&#xff0c;对角线11mm。 1/2英寸——靶面尺寸为宽6.…

SSE技术和WebSocket技术实现即时通讯

文章目录 一、SSE1.1 什么是SSE1.2 工作原理1.3 特点和适用场景1.4 API用法1.5 代码实现 二、WebSocket2.1 什么是WebSocket2.2 工作原理2.3 特点和适用场景2.4 API用法2.5 代码实现 三、SSE与WebSocket的比较 当涉及到实现实时通信的Web应用程序时&#xff0c;两种常见的技术选…

网络安全【黑客技术】自学

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成…

每天五分钟机器学习:梯度下降算法和正规方程的比较

本文重点 梯度下降算法和正规方程是两种常用的机器学习算法,用于求解线性回归问题。它们各自有一些优点和缺点,下面将分别对它们进行详细的讨论。 区别 1. 梯度下降算法是一种迭代的优化算法,通过不断迭代调整参数来逼近最优解。它的基本思想是根据目标函数的梯度方向,沿…

openGauss学习笔记-32 openGauss 高级数据管理-批处理模式

文章目录 openGauss学习笔记-32 openGauss 高级数据管理-批处理模式32.1 语法格式32.2 参数说明32.3 示例 openGauss学习笔记-32 openGauss 高级数据管理-批处理模式 openGauss支持从文本文件执行SQL语句。openGauss提供了gsql工具实现SQL语句的批量处理。 以下场景建议使用批…

测试人员简单使用Jenkins

一、测试人员使用jenkins干什么&#xff1f; 部署测试环境 二、相关配置说明 一般由开发人员进行具体配置 1.Repository URL&#xff1a;填写git地址 2.填写开发分支&#xff0c;测试人员可通过相应分支进行测试环境的构建部署 当多个版本并行时&#xff0c;开发人员可以通过…

【各个突破】Echart的象柱形图数值为0时,图像发生严重偏移,一招即可解决

【各个突破】Echart的象柱形图数值为0时&#xff0c;图像发生严重偏移&#xff0c;一招即可解决 1&#xff0c;问题描述2&#xff0c;解决方法3&#xff0c;最终结果 1&#xff0c;问题描述 当数值是0亩时&#xff0c;圆形图标发生位置偏移&#xff0c;据悉&#xff0c;该bug是…

掌握 JVM 调优命令

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ JVM 日常调优总结起来就是&#xff1a;首先通过 jps 命令查看当前进程&#xff0c;然后根据 pid 通过 jinfo 命令查看和修改 jvm 参数&#xff0c;通过 jstat 命令查看 cla…

漫画 | TCP/IP之大明邮差

后记&#xff1a; 1973年&#xff0c;卡恩与瑟夫开发出了网络中最核心的两个协议&#xff1a;TCP协议和IP协议&#xff0c;随后为了验证两个协议的可用性&#xff0c;他们做了一个实验&#xff0c;在多个异构网络中进行数据传输&#xff0c;数据包在经过近10万公里的旅程后到达…

git删除已经提交的大文件

当你不小心把一个巨大的二进制文件提交到git仓库的时候&#xff0c;此时删除再提交也没有用了&#xff0c;大文件已经在仓库中留底了。另外比如需要删除某个需要保密的文件&#xff0c;都是相同的解决办法。 我本来想着把dll放在三方库里面提交到仓库里&#xff0c;省得在不同…

STM32 低功耗-待机模式

STM32 待机模式 文章目录 STM32 待机模式第1章 低功耗模式简介第2章 待机模式简介2.1 进入待机模式2.1 退出待机模式 第3章 待机模式代码部分总结 第1章 低功耗模式简介 在 STM32 的正常工作中&#xff0c;具有四种工作模式&#xff1a;运行、睡眠、停止和待机模式。 在系统或…