使用CMakeLists.txt简化项目构建过程
在软件开发过程中,项目的构建是一个不可避免的环节。而随着项目规模的增大,手动管理编译过程变得越来越繁琐。为了简化构建流程并实现跨平台支持,CMake作为一种流行的构建系统被广泛采用。本文将介绍CMakeLists.txt文件的结构,以及如何使用CMake管理项目的编译过程。
一、CMakeLists.txt 文件结构
CMakeLists.txt 文件结构是指 CMakeLists.txt 文件中的基本部分和语法规则。CMakeLists.txt 文件是 CMake 的配置文件,用于描述整个项目的组成和构建规则。每个项目通常包含一个或多个 CMakeLists.txt 文件,位于项目的根目录或子目录中。CMake 通过递归地处理这些文件,构建项目的目标文件、库文件和可执行文件。
下面是 CMakeLists.txt 文件的基本结构和语法:
# 根据需要设置 CMake 最低版本号
cmake_minimum_required(VERSION 3.10)# 设置项目名称和支持的语言
project(MyProject LANGUAGES CXX)# 添加源文件和库文件
add_library(MyLibrary SHARED my_library.cpp)# 指定头文件目录和库文件目录
target_include_directories(MyLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_directories(MyLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/lib)# 添加依赖项
target_link_libraries(MyLibrary PRIVATE some_library)# 设置编译选项
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")# 定义安装规则
install(TARGETS MyLibrary DESTINATION /usr/lib)
install(DIRECTORY include/ DESTINATION /usr/include)
上述代码展示了 CMakeLists.txt 文件的基本结构和语法。它由多个命令和参数组成,下面对每个部分的作用进行解释:
-
cmake_minimum_required
: 该命令用于指定 CMake 的最低版本号要求,即项目所需的 CMake 版本号。在 CMakeLists.txt 文件的开头位置,需要使用该命令设置 CMake 的最低版本号。 -
project
: 该命令用于设置项目名称和支持的编程语言。支持的语言可以是 C、C++、Java 等,也可以是多种编程语言的组合。 -
add_library
: 该命令用于添加源文件和库文件。源文件可以是 .cpp 文件,库文件可以是动态库或静态库。 -
target_include_directories
和target_link_directories
: 这两个命令分别用于指定头文件目录和库文件目录的位置。target_include_directories
命令用于设置头文件目录的位置,target_link_directories
命令用于设置库文件目录的位置。 -
target_link_libraries
: 该命令用于添加依赖项,即项目所依赖的外部库文件。这些库文件可以是系统自带的标准库,也可以是第三方库。 -
set
: 该命令用于设置编译选项,如编译器的标准版本、编译器警告选项等。 -
install
: 该命令用于定义项目的安装规则,指定哪些文件需要被安装到特定的位置。通常情况下,可执行文件被安装到 /usr/bin 目录,库文件被安装到 /usr/lib 目录,头文件被安装到 /usr/include 目录。
二、示例项目介绍
以一个UVC项目为例:
list(APPEND CMAKE_MODULE_PATH "/home/lizh/workspaces/rv1126_facial_gate_release/external/rkmedia/cmake")cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 11)
add_definitions(-DDBUG)
add_definitions(-g)
PROJECT(uvc_app)
include(FindPkgConfig)
pkg_check_modules (JSON-C REQUIRED IMPORTED_TARGET json-c)include_directories(uvc)set(USE_RKAIQ ON)if(USE_RKAIQ)find_package(RkAiq REQUIRED)include_directories(${RKAIQ_INCLUDE_DIRS})add_definitions(-DRKAIQ)
endif()#head file path
set(BASE_PATH /home/lizh/workspaces/rv1126_facial_gate_release/external/camera_engine_rkaiq)
include_directories(
${BASE_PATH}/xcore
${BASE_PATH}/xcore/base
${BASE_PATH}/aiq_core
${BASE_PATH}/algos
${BASE_PATH}/common
${BASE_PATH}/common/linux
${BASE_PATH}/hwi
${BASE_PATH}/hwi/isp20
${BASE_PATH}/ipc
${BASE_PATH}/iq_parser
${BASE_PATH}/uAPI
${BASE_PATH}/ipc_server
#algos/awb
#../core/inc/luma
#../core/inc/stat_3a_ae
#../core/inc/stat_3a_af
#../core/inc/orb
#../core/inc/common
${BASE_PATH}/
${BASE_PATH}/include
${BASE_PATH}/include/common
${BASE_PATH}/include/common/mediactl
${BASE_PATH}/include/iq_parser
${BASE_PATH}/include/uAPI
${BASE_PATH}/include/xcore
${BASE_PATH}/include/xcore/base
${BASE_PATH}/include/algos
${BASE_PATH}/include/algos/a3dlut
${BASE_PATH}/include/algos/ablc
${BASE_PATH}/include/algos/accm
${BASE_PATH}/include/algos/acgc
${BASE_PATH}/include/algos/acp
${BASE_PATH}/include/algos/adebayer
${BASE_PATH}/include/algos/adehaze
${BASE_PATH}/include/algos/adpcc
${BASE_PATH}/include/algos/ae
${BASE_PATH}/include/algos/af
${BASE_PATH}/include/algos/afd
${BASE_PATH}/include/algos/afec
${BASE_PATH}/include/algos/agamma
${BASE_PATH}/include/algos/adegamma
${BASE_PATH}/include/algos/agic
${BASE_PATH}/include/algos/ahdr
${BASE_PATH}/include/algos/aie
${BASE_PATH}/include/algos/aldch
${BASE_PATH}/include/algos/alsc
${BASE_PATH}/include/algos/anr
${BASE_PATH}/include/algos/anr/tnr_md
${BASE_PATH}/include/algos/aorb
${BASE_PATH}/include/algos/ar2y
${BASE_PATH}/include/algos/asd
${BASE_PATH}/include/algos/asharp
${BASE_PATH}/include/algos/awb
${BASE_PATH}/include/algos/awdr
${BASE_PATH}/include/common/gen_mesh
${BASE_PATH}/include/ipc_server
)include_directories(/home/lizh/workspaces/rv1126_facial_gate_release/external/rkmedia/include/easymedia)
include_directories(/home/lizh/workspaces/rv1126_facial_gate_release/external/rkmedia/include/rkmedia)include_directories(/home/lizh/workspaces/rv1126_facial_gate_release/external/rkmedia)
include_directories(/home/lizh/workspaces/rv1126_facial_gate_release/external/camera_engine_rkaiq)set(LIB_SOURCEuvc/uvc-gadget.cuvc/uvc_video.cppuvc/yuv.cuvc/uvc_control.cuvc/uvc_encode.cppuvc/mpi_enc.cuvc/uevent.cuvc/drm.ccJSON/cJSON.cuvc/mpp_osd.c
)add_library(rkuvc SHARED ${LIB_SOURCE})
target_link_libraries(rkuvc pthread drm rockchip_mpp easymedia)set(SOURCEmain.c${LIB_SOURCE}
)set(UVC_APP_DEPENDENT_LIBSpthreaddrmrockchip_mpprtrgaeasymedia
)set(UVC_APP_INC${CMAKE_CURRENT_SOURCE_DIR}/uvc/
)option(ENABLE_USB3 "support usb3.0 config" OFF)
if (${ENABLE_USB3})add_definitions(-DUSE_USB3)
endif()option(ENABLE_AISERVER "rockchip aiserver" OFF)
if (${ENABLE_AISERVER})add_definitions(-DUSE_RK_AISERVER)set(SOURCE${SOURCE}uvc/uvc_ipc.cpp)find_package(Protobuf REQUIRED)if(PROTOBUF_FOUND)message(STATUS "protobuf library found")set(UVC_APP_DEPENDENT_LIBS ${UVC_APP_DEPENDENT_LIBS} protobuf-lite)include_directories(${PROTOBUF_INCLUDE_DIRS})include_directories(${CMAKE_CURRENT_BINARY_DIR})protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS${CMAKE_CURRENT_SOURCE_DIR}/uvc/uvc_data.proto)set(UVC_APP_INC ${UVC_APP_INC} ${PROTO_HDRS})set(SOURCE ${SOURCE} ${PROTO_SRCS} ${PROTO_HDRS})endif()
else()add_definitions(-fno-rtti)option(USE_ROCKIT "uvc camera use rockit" OFF)if(USE_ROCKIT)add_definitions(-DUSE_ROCKIT=1)SET(UVC_APP_DEPENDENT_LIBS${UVC_APP_DEPENDENT_LIBS}rockit)install(FILES conf/uvc.json DESTINATION ../etc/uvc_app/)else()
# add_definitions(-DUSE_RKMEDIA=1)
# add_definitions(-DEPTZ_ENABLE=1)
# include_directories(${ROCKX_HEADER_DIR})
# set(UVC_APP_DEPENDENT_LIBS
# ${UVC_APP_DEPENDENT_LIBS}
# easymedia
# rockx
# rga
# ${CMAKE_CURRENT_LIST_DIR}/libs/libuvcAlgorithm.so)
# set(SOURCE
# ${SOURCE}
# process/eptz_control.cpp
# process/zoom_control.cpp
# )
# set(Algorithm_LIBS ${CMAKE_CURRENT_LIST_DIR}/libs/libuvcAlgorithm.so)
# install(FILES ${Algorithm_LIBS} DESTINATION lib)endif()
endif()option(DBSERVER_SUPPORT "enbale dbserver" OFF)
if (${DBSERVER_SUPPORT})add_definitions(-DDBSERVER_SUPPORT)set(UVC_APP_DEPENDENT_LIBS ${UVC_APP_DEPENDENT_LIBS} IPCProtocol)
endif()if(CMAKE_SIZEOF_VOID_P EQUAL 8)add_definitions(-DUSE_ARM64)
else()target_link_libraries(rkuvc ${CMAKE_SOURCE_DIR}/libs/libmjpeg_fps_ctr.a)SET(UVC_APP_DEPENDENT_LIBS${UVC_APP_DEPENDENT_LIBS}${CMAKE_SOURCE_DIR}/libs/libmjpeg_fps_ctr.a)option(ENABLE_MINILOGGER "enbale minilogger" ON)if (${ENABLE_MINILOGGER})find_package(MiniLogger REQUIRED)add_definitions(-DENABLE_MINILOGGER)set(UVC_APP_DEPENDENT_LIBS ${UVC_APP_DEPENDENT_LIBS} MiniLogger::MiniLogger)target_link_libraries(rkuvc MiniLogger::MiniLogger)endif()
endif()option(COMPILES_CAMERA "compile:with rkmedia v4l2 flow " OFF)
option(EPTZ_SUPPORT "uvc support eptz" OFF)
if(COMPILES_CAMERA)include_directories(process)add_definitions(-DCAMERA_CONTROL)set(SOURCE${SOURCE}process/camera_control.cppprocess/camera_pu_control.cpp)
endif()ADD_EXECUTABLE(uvc_app ${SOURCE})
#target_link_libraries(uvc_app ${UVC_APP_DEPENDENT_LIBS} PkgConfig::JSON-C)
target_link_libraries(uvc_app ${UVC_APP_DEPENDENT_LIBS} PkgConfig::JSON-C rkuvc -lrkaiq)install(DIRECTORY ./uvc DESTINATION includeFILES_MATCHING PATTERN "*.h")install(TARGETS uvc_app DESTINATION bin)
install(DIRECTORY . DESTINATION binFILES_MATCHING PATTERN "*.sh"PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTEGROUP_READ GROUP_WRITE GROUP_EXECUTEWORLD_READ WORLD_WRITE WORLD_EXECUTE)if(EXISTS "mpp_enc_cfg.conf")set(ETC_DST "${PROJECT_SOURCE_DIR}/../../target/etc/")file(COPY mpp_enc_cfg.conf DESTINATION ${ETC_DST})
endif(EXISTS "mpp_enc_cfg.conf")if(DEFINED INSTALL_LIBRKUVC)
install(TARGETS rkuvc DESTINATION lib)
endif()
这是一个CMakeLists.txt文件,用于构建名为uvc_app的项目。以下是对该文件的解析:
首先,使用cmake_minimum_required
指定需要的最低CMake版本,并设置C++标准为11。
然后,通过PROJECT
命令设置项目名称为uvc_app。
接着,使用include
命令包含FindPkgConfig模块,并通过pkg_check_modules
命令查找名为JSON-C的依赖库。这里使用了IMPORTED_TARGET参数来导入json-c库。
然后,使用include_directories
命令添加一系列头文件路径。
继续,使用add_library
命令将LIB_SOURCE中的源文件编译为名为rkuvc的共享库,并链接pthread、drm、rockchip_mpp和easymedia等库。
然后,通过设置变量SOURCE指定项目的源文件。
紧接着,设置UVC_APP_DEPENDENT_LIBS变量,包含项目所依赖的库。
接下来,根据ENABLE_USB3和ENABLE_AISERVER选项的设置,进行相关的定义和处理。
然后,根据DBSERVER_SUPPORT选项的设置,进行相关定义和库的链接。
根据CMAKE_SIZEOF_VOID_P的大小来选择性地进行处理。
最后,使用ADD_EXECUTABLE命令将源文件编译为可执行文件uvc_app,并链接依赖的库。
最后,使用INSTALL命令将相关文件安装到指定目录。
三、CMakeLists.txt详解
CMakeLists.txt 是 CMake 构建系统使用的脚本文件,通过这个文件,CMake 能够为各种环境生成标准的构建文件。
CMakeLists.txt 配置文件的编写主要包含以下几个部分:
- cmake_minimum_required: 这个命令是用来设定运行这个 cmake 的最低版本要求的,对于不同版本的 cmake,其支持的命令、变量、属性等有所区别。
cmake_minimum_required(VERSION 3.5)
- project: 这个命令表明产生的工作空间的名称,一般与你的项目名称相同。
project(MyProject)
- set: 主要用来显式的定义变量。
set(SRC_LIST main.c)
- add_executable 和 add_library: 这两个命令分别是用来添加需要编译的可执行文件和库。如:
add_executable(main ${SRC_LIST})
这个命令会生成一个可执行文件 main,源文件是通过前面 set 命令定义的 SRC_LIST 变量。
add_library(my_lib STATIC ${SRC_LIST})
这个命令会生成一个静态库 my_lib,源文件是通过前面 set 命令定义的 SRC_LIST 变量。
- target_link_libraries: 这个命令用来为 target 添加需要链接的共享库。
target_link_libraries(main my_lib)
- include_directories 和 link_directories: 这两个命令分别用于指定头文件的搜索路径和库文件的搜索路径。
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
- find_package: 这个命令用来找系统中已存在的库。比如你的程序需要用到 Boost 库,你就需要使用此命令来找 Boost。
find_package(Boost REQUIRED)
if(Boost_FOUND)include_directories(${Boost_INCLUDE_DIRS})target_link_libraries(main ${Boost_LIBRARIES})
endif()
这些是 CMakeLists.txt 中常用的一些命令,实际上 CMake 还支持更加复杂的语法,能够适应不同的编译需求。你可以在官方的文档中找到更详细的信息。
四、配置和构建示例项目
- 创建一个名为"build"的目录,并进入该目录:
mkdir build
cd build
- 执行CMake命令生成构建文件:
cmake ..
- 使用生成的构建工具编译项目:
make
- 安装项目:
make install
五、常见问题和使用技巧
常见问题:
- CMake如何使用?
CMake是一个跨平台的自动化构建工具,常用于C++项目。可以通过编写CMakeLists.txt文件来描述项目和配置构建过程。在控制台进入目标文件夹,然后运行cmake .
即可开始构建。详细使用方法可以参考官方文档。
- 如何添加一个依赖库?
可以通过find_package
命令查找已安装的库,或者在CMakeLists.txt中添加依赖库的路径和链接方式。
- 如何设置编译选项?
可以使用add_definitions
命令添加编译器选项。例如,add_definitions(-DDEBUG)
可以定义一个DEBUG宏。
- 如何设置输出路径?
可以使用set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
命令指定可执行文件的输出路径。
- 如何使用外部头文件或源文件?
可以使用include_directories
命令添加头文件路径,或者通过add_library
将外部源文件编译为库再进行链接。
使用技巧:
-
使用target_link_libraries命令来链接库,这样可以避免手动设置链接路径和依赖关系。
-
在编写CMakeLists.txt文件时,应该将尽可能多的信息保存为变量,方便后续修改和维护。
-
可以使用
file(GLOB sources "*.cpp")
命令来自动搜索所有符合要求的源文件,方便管理。 -
如果需要编译多个可执行文件,可以使用
add_executable()
命令多次定义。同时,需要注意使用不同的变量名来保存源文件列表,避免相互覆盖。 -
在构建前应该清理CMake缓存。通常可以在构建目录中运行
rm CMakeCache.txt
命令来删除已有的缓存文件。
最佳实践:
-
建议将CMakeLists.txt文件拆分为多个小文件,并使用
include
命令进行引用。这样可以使文件结构更加清晰,方便维护。 -
建议使用CMake版本控制工具(如cmake-format)格式化代码和自动补全缺失的标准选项,以保证更好的代码风格和可读性。
-
建议使用CTest进行测试管理,该工具可以方便地为项目添加单元测试和集成测试。
-
建议在CMakeLists.txt中使用if语句来控制编译选项,例如根据平台或库是否安装来切换编译选项。
-
建议使用CMake的交叉编译功能,以支持在其他平台上构建项目。可以通过设置CMAKE_TOOLCHAIN_FILE路径来使用交叉编译。
结论:
CMakeLists.txt作为CMake构建系统的核心文件,为我们提供了一种简化项目构建过程的方式。通过了解CMakeLists.txt文件的结构和使用方法,我们可以更高效地管理项目的编译过程,提高开发效率。希望本文能够帮助读者更好地理解和使用CMake。
相关文章:
使用CMakeLists.txt简化项目构建过程
在软件开发过程中,项目的构建是一个不可避免的环节。而随着项目规模的增大,手动管理编译过程变得越来越繁琐。为了简化构建流程并实现跨平台支持,CMake作为一种流行的构建系统被广泛采用。本文将介绍CMakeLists.txt文件的结构,以及…...
构建并训练简单的CNN
1. 构建并训练深度神经网络模型 1.1 准备数据集 本次使用自己生成的一些数据,如下生成代码: # 准备数据集 # 此处自己生成一些原始的数据点 dataset_X=np.linspace(-10,10,100) dataset_y=2*np.square(dataset_X)+7...

Axi_Lite接口的IP核与地址与缓冲与AxiGP0
AXI Interconnect互连内核将一个或多个 AXI 内存映射主设备连接到一个或多个内存映射从设备。 AXI_GP 接口 AXI_GP 接口是直接连接主机互联和从机互联的端口的。 AXI_HP 接口具有一个 1kB 的数据 FIFO 来做缓冲 [4],但是 AXI_GP 接口与它不同,没…...
maven以及配置
oss oss配置 <!--oss--> <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.6.0</version></dependency> lombok <!--lombok--><dependency><gro…...

系统可靠性分析与设计
系统可靠性分析与设计 内容提要 可靠性相关概念 骚戴理解:计算机系统的可靠性和可用性不是完全相同的概念,尽管它们在某些方面有重叠之处。 可靠性指的是计算机系统在特定时间段内正常运行的能力,即系统在面对各种故障或意外情况时能够继续…...

热点不热!如何修复笔记本电脑未连接到移动热点的问题
当你远离常规Wi-Fi时,移动热点是让你的笔记本电脑上网的关键,但当它没有按计划运行时,你会怎么办?以下是Windows笔记本电脑无法连接到移动热点时的几种修复方法。 为什么我的笔记本电脑没有连接到我的热点 由于你的笔记本电脑正试图连接到另一个有限制和可能存在问题的设…...
2024年申报国自然项目基金撰写及技巧
随着社会经济发展和科技进步,基金项目对创新性的要求越来越高。申请人需要提出独特且有前瞻性的研究问题,具备突破性的科学思路和方法。因此,基金项目申请往往需要进行跨学科的技术融合。申请人需要与不同领域结合,形成多学科交叉…...
springMvc的简介
1.说说你对 SpringMVC 的理解 SpringMVC 是基于对java EE servlet的封装,它是轻量级MVC 框架,它是Spring下的一个模块,我们通过编写一个方法实现对应的handler,一个servlet 请求 2.什么是MVC模式? MVC全名是Model V…...

Unity Profiler 详细解析(一)
Overview: . Profiler简介 . Profiler各模块介绍 . 各平台下Profiler的使用 . 基于Profiler的优化定位 . Profiler的主要参数详解 . Profiler案例 Profiler简介 Profiler 是Unity中分析性能开销的工具 • 各种开销一览无遗 • 可跨平台使用(Web、PC、iOS、Android、…...
BMS电池管理系统理论基础
目录 1 、锂离子电池特性分析 1.1、 锂离子电池工作原理 1.2 锂离子电池特性 (1)容量特性...
BLUE引擎变量数据分析
今天跟大家说一下BLUE引擎的变量运用,以及使用中的小细节。大家在使用变量的时候,自定义变量不要以P、G、M、I、D、N、A开头。 变量与变量之间的常用格式: SMALL M88 <$STR(G88)> ;检测私人变量M88,是否小于全局变量G88 LARGE M88 &l…...

第三章 C++的循环结构
系列文章目录 第一章 C的输入第二章 C的输出 文章目录 系列文章目录前言一、个人名片二、while三、do-while四、for总结 前言 今天来学循环结构! 一、个人名片 个人主页:睡觉觉觉得 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评…...

基于卷积优化优化的BP神经网络(分类应用) - 附代码
基于卷积优化优化的BP神经网络(分类应用) - 附代码 文章目录 基于卷积优化优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.卷积优化优化BP神经网络3.1 BP神经网络参数设置3.2 卷积优化算法应用 4.测试结果…...

【MATLAB源码-第50期】基于simulink的BPSK调制解调仿真,输出误码率。
操作环境: MATLAB 2022a 1、算法描述 1. Bernoulli Binary: 这个模块生成伯努利二进制随机数,即0或1。这些数字表示要传输的原始数字信息。 2. Unipolar to Bipolar Converter: 此模块将伯努利二进制数据从0和1转换为-1和1,这是BPSK调制的标…...

【Acwing166】数独(dfs+剪枝+位运算)超级详细题解!
本题思路来源于acwing算法提高课 题目描述 看本文需要准备的知识 1.dfs算法基本思想 2.位运算基础 3.对剪枝这个名词的大概了解 剪枝优化位运算优化 常见四种剪枝策略 首先考虑这道题的搜索顺序,很明显,可以随意选择一个空格子,分支为这…...

Docker Swarm 集群搭建
Docker Swarm Mode Docker Swarm 集群搭建 Docker Swarm 节点维护 Docker Service 创建 1.准备主机 搭建一个 docker swarm 集群,包含 5 个 swarm 节点。这 5 个 swarm 节点的 IP 与暂 时的角色分配如下(注意,搭建完成后会切换角色ÿ…...

Mac 开机提示Google LLC 注册 无法登录进入系统
Google LLC 会在电脑启动时提示如下弹窗,并要求登录谷歌账户进行验证 此时很明显没有用来进行验证的账号,所以需要关掉这个验证程序 从日志里面可以看到LLC启动了一个Tiny.app的程序 只需要想办法把这个程序删掉即可 关机 按住 Command R 开机 进入R…...

excel单元格各种组合求和
单元格如果连续选择的话使用冒号,不是连续选择使用逗号;sum(A1:A4)表示对A1到A4求和;sum(A1,A4)表示求A1A4的和; 如下图,求斜线上四个单元格的和,结果见下图; 求A列和C列全部单元格的和&#x…...

SysTick—系统定时器
SysTick 简介 SysTick—系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit 的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK 等于72M。当重装载数值寄存器的值递减到0的时候&#…...

ATPCS:ARM-Thumb程序调用的基本规则
为了使单独编译的c文件和汇编文件之间能够互相调用,需要制定一系列的规则,AAPCS就是ARM程序和Thumb程序中子程序调用的基本规则。 1、ATPCS概述 ATPCS规定了子程序调用过程中寄存器的使用规程、数据站的使用规则、参数的传递规则。为了适应一些特殊的需…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...