当前位置: 首页 > news >正文

CMake管理外部依赖的模块

在 CMake 中,FetchContentExternalProject 都是管理外部依赖的模块,但它们的 设计目标、使用场景和执行时机 有本质区别。以下通过对比表格、代码示例和场景分析详细说明它们的区别。


核心区别对比表

特性FetchContentExternalProject
执行阶段配置阶段cmake 命令运行时)构建阶段make/ninja 运行时)
集成方式直接作为项目子目录 (add_subdirectory)独立构建,作为外部进程
源码位置默认在 build/_deps 目录下默认在 build/ExternalProject 相关目录
构建控制自动集成到主项目构建流程需手动管理配置、编译、安装等步骤
典型场景头文件库、小型依赖项需编译的复杂库(如 Boost、OpenCV)
适用阶段CMake 配置阶段CMake 构建阶段
灵活性简单易用,但定制性弱复杂但高度可定制(支持分阶段操作)
版本要求CMake ≥3.11CMake ≥2.8.11(基础功能)

场景示例分析

场景1:集成一个仅头文件库(如 spdlog)

推荐使用 FetchContent
无需编译,直接包含头文件即可使用:

cmake_minimum_required(VERSION 3.14)
project(MyApp)include(FetchContent)# 声明依赖
FetchContent_Declare(spdlogGIT_REPOSITORY https://github.com/gabime/spdlog.gitGIT_TAG        v1.11.0  # 固定版本
)# 自动下载并添加子目录
FetchContent_MakeAvailable(spdlog)# 直接使用 spdlog
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE spdlog::spdlog_header_only)

场景2:编译一个需要构建的库(如 GoogleTest)

推荐使用 ExternalProject
需独立编译并安装到系统目录:

cmake_minimum_required(VERSION 3.10)
project(MyProject)include(ExternalProject)# 定义 GoogleTest 的构建流程
ExternalProject_Add(googletestGIT_REPOSITORY  https://github.com/google/googletest.gitGIT_TAG         release-1.12.1CMAKE_ARGS      -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}  # 安装到系统目录TEST_COMMAND    ""  # 跳过测试
)# 主项目链接已安装的库
add_executable(my_test test.cpp)
add_dependencies(my_test googletest)  # 确保先构建 googletest
target_link_libraries(my_test PRIVATE GTest::GTest GTest::Main)

关键区别详解

1. 执行时机
  • FetchContent
    在运行 cmake 配置项目时下载并解压源码,依赖项会成为主项目的一部分,直接参与配置和构建。

  • ExternalProject
    在运行 makeninja 构建项目时才下载和编译依赖项,作为独立进程运行。


2. 源码集成方式
  • FetchContent
    通过 add_subdirectory() 将依赖项源码直接嵌入主项目,共享同一个构建目录和变量作用域。

  • ExternalProject
    依赖项完全独立构建,需通过 find_package() 或手动指定头文件/库路径。


3. 典型使用场景
场景推荐模块原因
引入单头文件库(如 fmt)FetchContent无需编译,直接包含头文件
引入需编译的静态库ExternalProject独立构建,避免污染主项目配置
需要修改依赖项代码ExternalProject可通过 PATCH_COMMAND 修改源码
多阶段构建(如下载+编译)ExternalProject支持分阶段控制(下载、配置、编译、安装)

混合使用场景示例

若需在项目中同时使用两种模块(例如:主项目用 FetchContent,某个子依赖用 ExternalProject):

cmake_minimum_required(VERSION 3.14)
project(HybridExample)# 使用 FetchContent 引入头文件库
include(FetchContent)
FetchContent_Declare(fmtURL https://github.com/fmtlib/fmt/releases/download/9.1.0/fmt-9.1.0.zipURL_HASH SHA256=abcdef...
)
FetchContent_MakeAvailable(fmt)# 使用 ExternalProject 构建复杂库
include(ExternalProject)
ExternalProject_Add(my_heavy_libURL http://example.com/heavy-lib.tar.gzCONFIGURE_COMMAND <源码路径>/configure --prefix=${CMAKE_INSTALL_PREFIX}BUILD_COMMAND makeINSTALL_COMMAND make install
)# 主项目链接两者
add_executable(app main.cpp)
target_link_libraries(app PRIVATE fmt::fmt)
add_dependencies(app my_heavy_lib)  # 确保先构建 my_heavy_lib

如何选择?

  • 优先 FetchContent
    依赖项轻量、无需复杂构建流程、需要直接调用其 CMake 目标时。

  • 选择 ExternalProject
    依赖项需要独立构建、需自定义步骤(如打补丁)、或构建流程复杂(如 Autotools 项目)。


总结

  • FetchContent 是“轻量级依赖管理”,适合简单集成。
  • ExternalProject 是“重型构建工具”,适合完全控制外部项目流程。
  • 根据依赖项的性质(是否需要编译、是否需修改代码)和项目需求(是否需要隔离构建环境)选择合适工具。


为什么 FetchContent_Declare 中可以使用 PATCH_COMMAND

尽管 PATCH_COMMAND 在官方文档中属于 ExternalProject 模块,但在实际使用中,某些 CMake 版本(尤其是较新版本)允许在 FetchContent_Declare 中使用 PATCH_COMMAND。这是因为 FetchContent 底层借用了 ExternalProject 的机制来实现依赖管理,从而间接支持了一些 ExternalProject 的参数。以下是详细解释和注意事项:


1. 底层实现机制

FetchContent 模块在内部调用了 ExternalProject 的功能来管理依赖项的下载和配置。因此,FetchContent_Declare 的某些参数(如 PATCH_COMMAND)实际上是通过 ExternalProject_Add 传递的。尽管官方文档未明确列出这些参数,但在实践中它们可能被隐式支持。

示例代码分析
FetchContent_Declare(san_cmakeGIT_REPOSITORY https://github.com/arsenm/sanitizers-cmakeGIT_TAG        masterSOURCE_DIR     external/sanitizers-cmakePATCH_COMMAND  sed -i 's/old_text/new_text/' ${san_cmake_SOURCE_DIR}/CMakeLists.txt
)
  • 实际行为
    当调用 FetchContent_MakeAvailable(san_cmake) 时,CMake 会通过 ExternalProject 的流程处理依赖项,期间执行 PATCH_COMMAND

2. 版本兼容性

  • CMake ≥3.14
    部分版本开始支持在 FetchContent 中直接使用 ExternalProject 的参数(如 PATCH_COMMAND),但需谨慎使用,因为这是非官方行为。
  • CMake ❤️.14
    此类版本可能直接报错,因为参数未被识别。

3. 使用 PATCH_COMMAND 的风险

尽管功能上有效,但需要注意以下问题:

  1. 非官方支持
    CMake 官方文档未明确说明 FetchContent 支持 PATCH_COMMAND,未来版本可能移除此特性。
  2. 跨平台兼容性
    补丁命令(如 sed)在不同操作系统(Windows/macOS/Linux)中的行为可能不同,需额外处理。
  3. 路径依赖
    必须确保 ${san_cmake_SOURCE_DIR}PATCH_COMMAND 执行时已正确赋值(需在 FetchContent_Populate 之后)。

4. 正确用法示例

若需在 FetchContent 中安全使用 PATCH_COMMAND,应结合 FetchContent_Populate 显式控制流程:

代码示例
cmake_minimum_required(VERSION 3.14)
project(MyProject)include(FetchContent)# 声明依赖项
FetchContent_Declare(san_cmakeGIT_REPOSITORY https://github.com/arsenm/sanitizers-cmakeGIT_TAG        masterSOURCE_DIR     ${CMAKE_SOURCE_DIR}/external/sanitizers-cmakePATCH_COMMAND  sed -i.bak 's/cmake_minimum_required(VERSION 2.8.12)/cmake_minimum_required(VERSION 2.8.12...3.27)/' ${san_cmake_SOURCE_DIR}/CMakeLists.txt
)# 手动触发下载和补丁
FetchContent_GetProperties(san_cmake)
if(NOT san_cmake_POPULATED)FetchContent_Populate(san_cmake)  # 此步骤会执行 PATCH_COMMANDadd_subdirectory(${san_cmake_SOURCE_DIR} ${san_cmake_BINARY_DIR})
endif()# 使用依赖项
include(${san_cmake_SOURCE_DIR}/cmake/sanitize-helpers.cmake)

5. 替代方案推荐

若需更稳定的修补机制,建议以下方法:

方法1:通过 ExternalProject 显式控制
include(ExternalProject)ExternalProject_Add(san_cmakeGIT_REPOSITORY https://github.com/arsenm/sanitizers-cmakeGIT_TAG        masterSOURCE_DIR     ${CMAKE_SOURCE_DIR}/external/sanitizers-cmakePATCH_COMMAND  sed -i 's/.../' <SOURCE_DIR>/CMakeLists.txtCONFIGURE_COMMAND ""BUILD_COMMAND    ""INSTALL_COMMAND  ""
)# 主项目中引用
add_subdirectory(${CMAKE_SOURCE_DIR}/external/sanitizers-cmake)
方法2:下载后手动修补
FetchContent_Declare(san_cmake ...)
FetchContent_MakeAvailable(san_cmake)# 在下载完成后执行修补
add_custom_command(TARGET san_cmakePOST_BUILDCOMMAND sed -i 's/.../' ${san_cmake_SOURCE_DIR}/CMakeLists.txt
)

6. 总结

  • 可用性
    在较新 CMake 版本中,FetchContent_Declare 确实可以借用 ExternalProjectPATCH_COMMAND,但属于非官方行为。
  • 风险
    跨平台兼容性差,未来版本可能不再支持。
  • 推荐做法
    若需修补依赖项,优先使用 ExternalProject 或在 FetchContent 下载后通过 add_custom_command 执行修补。

相关文章:

CMake管理外部依赖的模块

在 CMake 中&#xff0c;FetchContent 和 ExternalProject 都是管理外部依赖的模块&#xff0c;但它们的 设计目标、使用场景和执行时机 有本质区别。以下通过对比表格、代码示例和场景分析详细说明它们的区别。 核心区别对比表 特性FetchContentExternalProject执行阶段配置阶…...

[计算机科学#7]:CPU的三阶段,取指令、解码、执行

【核知坊】&#xff1a;释放青春想象&#xff0c;码动全新视野。 我们希望使用精简的信息传达知识的骨架&#xff0c;启发创造者开启创造之路&#xff01;&#xff01;&#xff01; 内容摘要&#xff1a;本文详细介绍了CPU的工作原理&#xff0c;包括其结构…...

向量数据库和关系型数据库的区别,优点,缺点和典型应用场景

向量数据库与关系型数据库的全面对比 向量数据库和关系型数据库是两种截然不同的数据管理系统&#xff0c;各自针对特定的数据模型和查询模式进行了优化。随着人工智能和大数据技术的发展&#xff0c;向量数据库作为新兴的数据库类型&#xff0c;在处理非结构化数据方面展现出…...

《跨越边界:探索跨端框架中通用状态管理方案设计》

一款应用往往需要在多个终端&#xff0c;如Web、移动端、桌面端等同时运行&#xff0c;以满足用户多元化的使用场景。在这复杂的跨端开发领域中&#xff0c;状态管理堪称关键枢纽&#xff0c;直接关乎应用的性能、稳定性以及开发与维护的效率。如何设计一套通用的状态管理方案&…...

PHP之CURL通过header传参数及接收

一、传参数之冒号 注意一点&#xff0c;这里的header数据不是KV结构&#xff0c;而是一个一维数组。 看清楚&#xff0c;注意一点&#xff0c;是这样的结构&#xff1a; $ch curl_init(); $headers [X-Custom-Header: value123,Authorization: Bearer your_token_here // …...

【C++】brpc安装

brpc安装教程 环境&#xff1a;Ubuntu24.04 1 简单安装 即安装到系统环境下&#xff0c;依赖也是依赖apt安装。 官方参考教程 依赖准备 安装依赖&#xff1a; sudo apt-get install -y git g make libssl-dev libgflags-dev libprotobuf-dev libprotoc-dev protobuf-com…...

从0开始的c++知识讲解之字符串(1)

作者作为新手&#xff0c;对于知识的讲解也是边输出内容也是边学习&#xff0c;如有缺陷&#xff0c;请多海涵&#xff0c;但同样&#xff0c;我会帮助你从新手视角看到新手的疑惑&#xff0c;并帮助你解决此疑惑 一&#xff0c;开宗明义&#xff0c;立意先行 string在C里有可…...

Linux 第六讲 --- 工具篇(一)yum/apt与vim

前言&#xff1a; 经过前五讲对Linux基础指令与权限系统的系统学习&#xff0c;相信你已经能在命令行中自如地穿梭于文件丛林&#xff0c;精准调配权限密钥。但真正的Linux玩家&#xff0c;绝不会止步于基础操作的重复劳作。 从今天起&#xff0c;我们将打开Linux的"瑞士…...

xml 和 yaml 的区别

XML 和 YAML/YML 是两种常用的数据序列化格式&#xff0c;用于存储和读取结构化数据。以下是它们的核心区别和使用方法&#xff1a; 1. 格式特性对比 特性XMLYAML/YML语法复杂度标签嵌套&#xff0c;结构严格缩进分层&#xff0c;更简洁可读性较低&#xff08;冗余标签&#…...

1.67g 雨晨 22635.5305 Windows 11 企业版 23H2 极速增强版

五一特别制作 &#xff08;主要更新简述&#xff09; 全程由最新YCDISM2025装载制作 1、可选功能&#xff1a; 添加&#xff1a; Microsoft-Windows-LanguageFeatures-Basic-en-us-Package Microsoft-Windows-LanguageFeatures-OCR-en-us-Package 2、功能增强&a…...

【C++】类和对象(中)——默认成员函数详解(万字)

文章目录 上文链接类的默认成员函数1. 构造函数(1) 什么是构造函数(2) 构造函数的使用 2. 析构函数(1) 什么是析构函数(2) 析构函数的使用(3) 小练习 3. 拷贝构造函数(1) 什么是拷贝构造函数(2) 拷贝构造函数的使用 4. 赋值运算符重载(1) 运算符重载(2) 运算符重载的简单应用(3…...

Ubuntu18 登录界面死循环 Ubuntu进不了桌面

今天碰到这个问题&#xff0c;真是把我恶心到了 网上很多方法都不靠谱&#xff0c;最后我还是自己摸索出一个方法 先进入终端 开机后在登陆界面按下shift ctrl F1&#xff08;或者F2&#xff0c;一直按&#xff09;进入tty命令行终端登陆后输入(本人的用户名为hp&#xff…...

caffe适配cudnn9.6.0(ai修改代码踩坑)

caffe适配cudnn&#xff1a;https://github.com/dyc2424748461/caffe &#xff08;测试一下&#xff0c;成没成&#xff0c;反正我看到它用gpu了&#x1f636;&#xff09; 因为突发奇想&#xff0c;想要玩easymocap&#xff0c;先是简单使用media跑通了一下&#xff0c;然后过…...

【MySQL数据库】视图

1&#xff0c;视图的基本介绍 视图是一个虚拟表&#xff0c;其内容由查询定义。与真实表一样的是&#xff0c;视图包含带有名称的列和行数据&#xff1b;与真实表不一样的是&#xff0c;视图本身并不在数据库中存储数据。视图的数据变化会影响到基表&#xff0c;基表的数据变化…...

Linux日常使用与运维的AI工具全景调研:效率革命的终极指南

Linux日常使用与运维的AI工具全景调研:效率革命的终极指南 引言:当Linux遇上AI,运维世界正在发生什么? 作为一名Linux系统管理员,你是否还在为以下问题困扰: 深夜被报警短信惊醒,却要手动排查复杂的系统故障?面对海量日志文件,像大海捞针一样寻找关键错误信息?重复…...

Linux——线程(3)线程同步

一、线程同步的引入 通过上面的抢票系统我们发现&#xff0c;有的线程&#xff0c;进行工作&#xff08;挂锁&#xff09;&#xff0c;当其马上结束工作&#xff08;解锁&#xff09;&#xff0c;发现外面有很多线程在排队等着加锁执行任务&#xff0c;这个线程解锁后就立马给…...

Redis实现分布式锁

分布式锁是分布式系统中解决资源竞争问题的重要机制。Redis凭借其高性能和原子性操作&#xff0c;成为实现分布式锁的热门选择。本文将详细介绍如何使用Java和Redis实现分布式锁&#xff0c;并重点讲解如何通过Lua脚本保证锁操作的原子性。 一、分布式锁的基本要求 一个可靠的…...

JavaScript如何实现类型判断?

判断一个数据的类型&#xff0c;常用的方法有以下几种&#xff1a; typeofinstanceofObject.prototype.toString.call(xxx) 下面来分别分析一下这三种方法各自的优缺点 typeof typeof的本意是用来判断一个数据的数据类型&#xff0c;所以返回的也是一个数据类型。但是会遇到下…...

Spring MVC 与 FreeMarker 整合

以下是 Spring MVC 与 FreeMarker 整合的详细步骤&#xff0c;包含配置和代码示例&#xff1a; 1. 添加依赖 在 pom.xml 中引入 Spring MVC 和 FreeMarker 的依赖&#xff08;以 Maven 为例&#xff09;&#xff1a; <!-- Spring Web MVC --> <dependency><gr…...

设计模式简述(十五)观察者模式

观察者模式 描述基本组件使用 描述 观察者模式&#xff0c;顾名思义就是一个对象观察着其他对象&#xff0c;一旦被观察的对象发生变化时&#xff0c;观察者对象也要做出相应动作。 其中&#xff0c;被观察者持有观察者的引用。由观察者主动注入被观察者内&#xff08;有点像…...

用手机相册教我数组概念——照片分类术[特殊字符][特殊字符]

目录 前言一、现实场景1.1 手机相册的照片管理1.2 照片分类的需求 二、技术映射2.1 数组与照片分类的对应关系2.2 数组索引与照片标签的类比 三、知识点呈现3.1 数组的基本概念3.2 数组在编程中的重要性3.3 数组的定义与初始化3.4 数组的常见操作&#xff08;增删改查&#xff…...

字符串格式漏洞-[第五空间2019 决赛]PWN5

之前其实也写了一篇&#xff0c;现在再来看。又有新的收获了&#xff0c;于是记录一下 前置知识 格式化字符串漏洞详解-CSDN博客 讲得很清楚&#xff0c;我就不照猫画虎了 实践 main函数 首先先办法泄露我们输入的地址 from pwn import * elfpathlevel0 # ioprocess(elfp…...

数据结构学习之顺序表

在C语言学习到一定阶段之后&#xff0c;接下来我们就进入到了数据结构的部分内容。 目录 数据结构与线性表 顺序表 顺序表分类&#xff1a; 接下来我们要写一段代码实现动态顺序表。 首先我们需要准备三个文件&#xff1a; 1.接下来我们要定义一个数据表 2.当创建号我们的…...

AWS CloudFront全球加速利器:解析出海业务的核心优势与最佳实践

对于寻求全球化发展的企业而言&#xff0c;AWS CloudFront凭借其强大的全球基础设施和边缘计算能力&#xff0c;成为加速出海业务的关键工具。本文将深入剖析CloudFront的核心优势&#xff0c;并探讨其如何助力企业突破跨境业务瓶颈&#xff0c;同时符合SEO优化策略&#xff0c…...

Flowable7.x学习笔记(十六)分页查询我的待办

前言 我的待办具体区分为3种情况&#xff0c;第一个就是办理人指定就是我&#xff0c;我可以直接审批&#xff1b;第二种就是我是候选人&#xff0c;我需要先拾取任务然后再办理&#xff1b;第三种是我是候选组&#xff0c;我需要切换到指定的角色去拾取任务再办理。如果任务已…...

Annotate better with CVAT

WIN10 配置标注环境 WSL + Docker Desktop 安装手册 https://docs.cvat.ai/docs/administration/basics/installation/ hebing@hello:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE cvat/ui …...

QML Image 组件详解

目录 引言相关阅读QML Image元素基础知识 项目结构示例解析1. 本地资源图像加载2. 网络图像加载3. 图像填充模式 应用主结构 总结下载链接 引言 本文将介绍QML中Image元素的基本用法和关键特性&#xff0c;包括加载本地资源图像、处理网络图像、以及调整图像的填充模式。通过一…...

BOFZ 緩衝區溢出shell脚本檢測工具

地址:https://github.com/MartinxMax/bofz BOFZ BOFZ 是一款簡單的緩衝區溢出掃描器&#xff0c;旨在檢測指定可執行文件中的緩衝區溢出漏洞。 此工具可用於快速測試應用程序或二進制文件中是否存在常見的安全缺陷&#xff0c;特別是那些由於對用戶輸入處理時邊界檢查不當而引…...

【Dify系列教程重置精品版】第五章:Dify配置Ollama

上一章我们在Dify上尝试配置了“月之暗面”。这一章我们在Dify上配置另一个模型“Ollama”。 什么是ollama呢?简单来说:它允许用户在个人计算机或服务器上快速部署和管理多种开源大语言模型,如 Llama3、Phi3、Gemma2 等,而无需依赖昂贵的云服务或专业的技术背景。 反正就是…...

RISC-V AIA SPEC学习(四)

第五章 Interrupts for Machine andSupervisor Levels 核心内容​​ 1.主要中断类型与默认优先级:​​ 定义了机器级别(M-level)和监管者级别(S-level)的标准中断类型(如MEI、SEI、MTI等)。默认优先级规则:本地中断(如软件/定时器)优先级高于外部中断,RAS事件(如低/高…...

Leetcode刷题报告2——双指针法

文章目录 前言[15. 三数之和](https://leetcode.cn/problems/3sum/)题干题解知识点总结 [42. 接雨水](https://leetcode.cn/problems/trapping-rain-water/)题干题解 前言 这部分总共是4道题&#xff0c;我就挑两道比较典型的题写一下博客吧。 双指针法的核心思路是通过合理的…...

线段树原理和代码详解

目录 线段树维护的信息类型 线段树的结构 线段树的初始化 线段树的功能&#xff1a; 单点修改&#xff0c;区间查询 区间修改&#xff0c;区间查询 以下内容均为个人见解&#xff0c;如有不足还请指出&#xff0c;作者会及时修改&#xff01; 期待大家的点赞、收藏、评论&…...

xray-poc编写示例

禁止未授权扫描和测试行为&#xff01;&#xff01;&#xff01; 1. SQL 时间盲注检测 (Time-Based Blind SQLi) name: generic/time-based-sqli rules:- method: GETpath: "/product?id1 AND (SELECT 1 FROM (SELECT SLEEP(5))a)--"expression: |response.status…...

[2-01-01].前端开发工具

前端学习大纲 一、VsCode: 1.1、下载地址 https://code.visualstudio.com/ 1.2.插件安装 为方便后续开发&#xff0c;建议安装如下插件 1.3.创建项目 先创建一个空的文件夹&#xff0c;如project_xxxx。然后打开vscode&#xff0c;再在vscode里面选择 File -> Open Fol…...

自动化实现web端Google SignUp——selenium

案例&#xff1a;自动化获取Google注册页面——selenium 前言 提示&#xff1a;通过案例掌握selenium语法 涉及技术&#xff1a;Python Selenium 在本文中&#xff0c;我们将通过一个实际案例来学习如何使用Selenium自动化工具模拟Google账号注册流程。这个案例涵盖了Selen…...

如何阅读GitHub上的深度学习项目

一、前期准备&#xff1a;构建知识基础 1. 必备工具与环境 开发工具&#xff1a; IDE&#xff1a;VS Code&#xff08;推荐&#xff0c;轻量化插件丰富&#xff0c;如 Python、PyTorch 插件&#xff09;、PyCharm&#xff08;适合大型项目&#xff09;。版本控制&#xff1a;…...

【LeetCode 热题 100】3.无重复字符的最长子串:详解滑动窗口解法

&#x1f4cc; 原题链接&#xff1a;Longest Substring Without Repeating Characters &#x1f4d6; 一、题目描述 给定一个字符串 s&#xff0c;请你找出其中不含有重复字符的最长子串的长度。 示例&#xff1a; 输入: s "abcabcbb" 输出: 3 解释: 最长不重复子…...

Android12 Rom定制设置默认语言为中文

Android12 Rom定制设置默认语言为中文 1.前言&#xff1a; 最近在做客制化定制时需要默认语言为中文&#xff0c;而且可以切换输入法&#xff0c;之前讲解过在ROM中如何设置默认输入法&#xff0c;这里就不展开了&#xff0c;其实这个需求很简单&#xff0c;就是调试的时候发现…...

【设计模式】GoF设计模式之备忘录模式(Memento Pattern)

设计模式之备忘录模式 Memento Pattern V1.0核心概念角色代码示例程序运行结果代码讲解 适用场景 V1.0 核心概念 备忘录模式的核心是定义一个备忘录类&#xff08;Memento&#xff09;&#xff0c;这个类的实例能够表示发起人类&#xff08;Originator&#xff09;的一种状态…...

springboot分层打包,减少重复构建和传输的开销

在 Spring Boot 中&#xff0c;分层打包&#xff08;Layered Packaging&#xff09; 是一种优化策略&#xff0c;特别针对 容器化部署&#xff08;如 Docker&#xff09; 的场景设计。它的核心思想是将应用的不同部分&#xff08;依赖、资源、代码等&#xff09;划分为独立的层…...

Linux——虚拟地址空间

1.虚拟地址空间 进程地址空间又叫虚拟地址空间 我们大家知道程序在运行时使用的空间被划分为多个不同的区域&#xff0c;每个区域都有不同的作用 正文代码&#xff1a;存放程序的可执行代码 通常都是只读的初始化数据&#xff1a;未初始化数据堆区&#xff1a;用于动态分配内存…...

GPU虚拟化实现(七)

GPU虚拟化实现(七) 章节回顾进程管理资源限制和环境变量利用率监控线程信号处理退出处理代码具体运作流程怎么限制SM的总结章节回顾 在上一章,分析了项目的主要代码模块功能:共享内存和初始化、GPU 内存管理、GPU 利用率管理以及锁机制,在这一章将继续分析其他的代码模块…...

【QNX+Android虚拟化方案】137 - msm-5.4 Kernel U盘 插入中断、枚举、匹配完整流程详解

【QNX+Android虚拟化方案】137 - msm-5.4 Kernel U盘 插入中断、枚举、匹配完整流程详解 1. HUB提交中断URB给HCD控制器,URB完成回调函数为 hub_irq()2. U盘插入后,触发运行 hub_irq() 中断回调函数2.1 高通 DWC3 Host HCD 初始化流程2.2 urb->complete(urb) 中断回调流程…...

分布式锁的几种实现

前几天看一个面试视频&#xff0c;提到了分布式锁一直想写写&#xff0c;但奈何考试太多&#xff0c;直到今天才有时间。好啦&#xff0c;开始今天的文章吧。 一.定义 分布式锁&#xff1a;当多个进程不在同一个系统中(比如分布式系统中控制共享资源访问)&#xff0c;用分布式…...

Android 解绑服务问题:java.lang.IllegalArgumentException: Service not registered

问题与处理策略 问题描述 在 Android 项目中&#xff0c;解绑&#xff08;unbindService()&#xff09;一个服务&#xff08;Service&#xff09;时&#xff0c;报如下错误 java.lang.IllegalArgumentException: Service not registered问题原因 错误表明在解绑服务时&…...

注册登录页面项目

关系型数据库地址&#xff1a;C:\Users\ASUS\AppData\Local\Temp\HuaweiDevEcoStudioDatabases\rdb #注册页面register.ets import dataRdb from ohos.data.rdbconst STORE_CONFIG {name: weather4.db } const TABLE_NAME weather_info const SQL_CREATE_TABLE CREATE TAB…...

从 Python 基础到 Django 实战 —— 数据类型驱动的 Web 开发之旅

主题简介&#xff1a; 本主题以 Python 基础数据类型为核心&#xff0c;结合 Django 框架的开发流程&#xff0c;系统讲解如何通过掌握数字、字符串、列表、元组、字典等基础类型&#xff0c;快速构建功能完善的 Web 应用。通过理论与实践结合&#xff0c;帮助学员从零基础 Py…...

数字智慧方案5971丨智慧农业大数据平台解决方案(59页PPT)(文末有下载方式)

详细资料请看本解读文章的最后内容。 资料解读&#xff1a;智慧农业大数据平台解决方案 在现代农业发展进程中&#xff0c;智慧农业大数据平台解决方案正成为推动农业变革的关键力量。这一方案从项目简介到大数据展示&#xff0c;各个环节紧密相连&#xff0c;致力于为农业发展…...

MOOS-ivp使用(一)——水下机器人系统的入门与使用

MOOS-ivp使用&#xff08;一&#xff09;——水下机器人系统的入门与使用 MOOS-ivp&#xff08;Marine Operational Oceanographic System for Intelligent Vehicle Planning&#xff09;是专为水下机器人&#xff08;如AUV&#xff09;设计的开源框架。类似于ROS&#xff0c;…...

【网络服务器】——回声服务器(echo)

作用 实现回声服务器的客户端/服务器程序&#xff0c;客户端通过网络连接到服务器&#xff0c;并发送任意一串英文信息&#xff0c;服务器端接收信息后&#xff0c;执行数据处理函数&#xff1a;将每个字符转换为大写并回送给客户端显示。 客户端&#xff1a;发送字符信息 服…...