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

CMake管理依赖实战:多仓库的无缝集成

随着软件复杂度的增加,单个项目可能需要依赖多个外部库或模块。这些依赖项可能是来自不同的代码仓库,如ATestBTest。为了实现高效的依赖管理,CMake提供了多种方式来处理这种多仓库的情况。下面我们将详细介绍几种常见的方法,并通过实例展示它们的应用场景。

方法一:使用 add_subdirectory(代码强绑定)

示例

假设我们有两个项目ATestBTest,其中BTestATest的一个子模块。

A的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(ATest)add_subdirectory(BTest)add_executable(ATest main.cpp)target_link_libraries(ATest PRIVATE BTest)

B的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(BTest)add_library(BTest STATIC btest.cpp btest.h)
优点与缺点
  • 优点: 简单直接,适合小型项目。
  • 缺点: 需要将BTest作为子目录包含在ATest中,不够灵活。
应用场景

适用于BTest作为ATest的一部分,且两者紧密耦合的情况。

方法二:使用 find_package(系统级安装)

示例

BTest是一个独立的库时,可以使用find_package来查找并链接它。

B的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(BTest)add_library(BTest STATIC btest.cpp btest.h)install(TARGETS BTest DESTINATION lib)
install(FILES btest.h DESTINATION include)include(CMakePackageConfigHelpers)
write_basic_package_version_file("${PROJECT_BINARY_DIR}/BTestConfigVersion.cmake"VERSION ${PROJECT_VERSION}COMPATIBILITY AnyNewerVersion
)
configure_package_config_file("BTestConfig.cmake.in""${PROJECT_BINARY_DIR}/BTestConfig.cmake"INSTALL_DESTINATION lib/cmake/BTest
)
install(FILES "${PROJECT_BINARY_DIR}/BTestConfig.cmake" "${PROJECT_BINARY_DIR}/BTestConfigVersion.cmake"DESTINATION lib/cmake/BTest)

A的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(ATest)find_package(BTest REQUIRED)add_executable(ATest main.cpp)target_link_lraries(ATest PRIVATE BTest::BTest)
优点与缺点
  • 优点: 灵活,适合复用,适合大型项目。
  • 缺点: 需要额外的配置步骤。
应用场景

适用于BTest是一个独立库,并且需要被多个项目复用的情况。

方法三:使用 FetchContent(现代源码集成)

示例

如果希望在构建时动态下载BTest,可以使用FetchContent

A的 CMakeLists.txt

cmake_minimum_required(VERSION 3.14)
project(ATest)include(FetchContent)
FetchContent_Declare(BTestGIT_REPOSITORY https://github.com/example/BTest.gitGIT_TAG v1.0
)
FetchContent_MakeAvailable(BTest)add_executable(ATest main.cpp)target_link_libraries(ATest PRIVATE BTest::BTest)

B的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(BTest)add_library(BTest STATIC btest.cpp btest.h)add_library(BTest::BTest ALIAS BTest)
优点与缺点
  • 优点: 自动化程度高,无需手动克隆。
  • 缺点: 构建时需要网络连接,依赖仓库可用性影响构建。
应用场景

适用于BTest是一个外部依赖,但不希望将其作为子模块或本地库的情况。

方法四:使用 ExternalProject(完全控制构建)

示例

对于复杂的构建过程,可以使用ExternalProject

A的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(ATest)include(ExternalProject)
ExternalProject_Add(BTestGIT_REPOSITORY https://github.com/example/BTest.gitGIT_TAG v1.0PREFIX ${CMAKE_BINARY_DIR}/BTestINSTALL_DIR ${CMAKE_BINARY_DIR}/BTest/install
)set(BTEST_INCLUDE_DIR ${CMAKE_BINARY_DIR}/BTest/install/include)
set(BTEST_LIBRARY ${CMAKE_BINARY_DIR}/BTest/install/lib/libBTest.a)add_executable(ATest main.cpp)target_include_directories(ATest PRIVATE ${BTEST_INCLUDE_DIR})
target_link_libraries(ATest PRIVATE ${BTEST_LIBRARY})add_dependencies(ATest BTest)

B的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(BTest)add_library(BTest STATIC btest.cpp btest.h)install(TARGETS BTest DESTINATION lib)
install(FILES btest.h DESTINATION include)
优点与缺点
  • 优点: 自动化程度高,可控制依赖的构建过程。
  • 缺点: 配置复杂,构建时间长。
应用场景

适用于BTest的构建过程复杂且需要自动化的情况。

方法五:使用 CPM.cmake(动态Git集成)

适用场景
  • 需要灵活控制依赖版本。
  • 避免本地存储依赖代码。

CPM.cmake 是一个轻量级的CMake脚本,它利用了CMake内建的FetchContent模块,但提供了更多功能,如版本控制、缓存机制等关键特性。通过简单的命令,即可将CPM引入现有项目,立即享有强大的依赖管理功能。

实现步骤
BTest/CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(BTest LANGUAGES CXX VERSION 1.0.0)add_library(BTest STATIC src/b.cpp)
target_include_directories(BTest PUBLIC include)
ATest/CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(ATest LANGUAGES CXX)include(cmake/CPM.cmake)  # 下载CPM脚本CPMAddPackage(NAME BTestGIT_REPOSITORY "https://github.com/your/BTest.git"GIT_TAG v1.0.0
)add_executable(ATest src/main.cpp)
target_link_libraries(ATest PRIVATE BTest)
优点与缺点
  • 优点:

    • 版本灵活控制:可以精确指定依赖库的版本号或Git标签,确保项目的稳定性和可追溯性。
    • 轻量化和即插即用:无需安装额外工具,仅需下载一个CPM.cmake脚本文件即可使用。
    • 跨平台支持:适用于任何操作系统,无论是Windows、Linux还是macOS都能无缝工作。
  • 缺点:

    • 需要网络访问:所有依赖库最初都要从网上下载构建,如果离线使用则需设置环境变量CPM_SOURCE_CACHE来缓存依赖。
应用场景

适用于需要对依赖库进行精确版本控制,并且希望避免在本地存储依赖代码的场景。例如,在持续集成环境中,每次构建时都需要确保获取到确切版本的依赖,保证构建的可复现性。

比较与选择

方法优点缺点场景
add_subdirectory简单直接,易于实现需要将BTest放在ATest的目录下,不够灵活BTestATest的子模块或子目录的情况
find_package灵活,适合复用需要额外的配置步骤BTest是独立库,需要被多个项目复用的情况
FetchContent自动下载依赖,无需手动操作构建时需要网络连接,依赖仓库可用性影响构建BTest是外部依赖,但不希望将其作为子模块或本地库的情况
ExternalProject自动化程度高,可控制依赖的构建过程配置复杂,构建时间长BTest的构建过程复杂且需要自动化的情况
CPM.cmake版本灵活控制,轻量化,跨平台支持需要网络访问,初次构建可能较慢需要灵活控制依赖版本,避免本地存储依赖代码的场景

结论

选择合适的方法取决于具体的需求和项目规模。

  • 对于简单的项目,add_subdirectory可能是最简单的选择;
  • 而对于更复杂的项目,特别是当依赖项是独立的库时,find_packageFetchContent则更为适用。
  • 如果依赖项的构建过程特别复杂,则 CPMExternalProject可能是一个更好的选择。

相关文章:

CMake管理依赖实战:多仓库的无缝集成

随着软件复杂度的增加,单个项目可能需要依赖多个外部库或模块。这些依赖项可能是来自不同的代码仓库,如ATest和BTest。为了实现高效的依赖管理,CMake提供了多种方式来处理这种多仓库的情况。下面我们将详细介绍几种常见的方法,并通…...

Touchgfx 编写下载算法文件(.stldr)

一)下载算法文件主要参考官方的STM32 ST-LINK Utility模板:(文件所在位置如下:) C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ExternalLoader\M25P64_STM3210E-EVAL\Project\MD…...

回不去的乌托邦

回不去的乌托邦 坐在电脑面前愣神间已至深夜,依然睡意不起。 相比于带着疲惫入睡,伏案发呆更令人惬意。想起最近在自媒体上看到的一句话“最顶级的享受变成了回不去的乌托邦”。 “这是兄弟们最后一次逛校园了,我拍个照”。我的记忆力总是用在…...

如何在 SpringBoot 项目使用 Redis 的 Pipeline 功能

本文是博主在批量存储聊天中用户状态和登陆信息到 Redis 缓存中时,使用到了 Pipeline 功能,并对此做出了整理。 一、Redis Pipeline 是什么 Redis 的 Pipeline 功能可以显著提升 Redis 操作的性能,性能提升的原因在于可以批量执行命令。当我…...

Linux----线程

一、基础概念对比 特性进程 (Process)线程 (Thread)资源分配资源分配的基本单位(独立地址空间)共享进程资源调度单位操作系统调度单位CPU调度的最小单位创建开销高(需复制父进程资源)低(共享进程资源)通信…...

实现rolabelimg对于dota格式文件的直接加载和保存

在本篇博客中,我们将讲解如何修改roLabelImg.py文件,使其能够直接加载和保存Dota格式的标注文件(txt)以替换掉复杂的xml文件。通过对源代码的修改,我们将实现支持加载并保存Dota格式标注数据,以便与roLabel…...

bboss v7.3.5来袭!新增异地灾备机制和Kerberos认证机制,助力企业数据安全

ETL & 流批一体化框架 bboss v7.3.5 发布,多源输出插件增加为特定输出插件设置记录过滤功能;Elasticsearch 客户端新增异地双中心灾备机制,提升框架高可用性;Elasticsearch client 和 http 微服务框架增加对 Kerberos 认证支持…...

华为昇腾服务器固件Firmware、驱动Drive、CANN各自的作用与联系?

文章目录 **1. 固件(Firmware)****2. 驱动(Driver)****3. CANN(Compute Architecture for Neural Networks)****三者关系****典型问题定位** 华为昇腾服务器的固件、驱动和CANN是支撑其AI计算能力的核心组件…...

MySQL 视图入门

一、什么是 MySQL 视图 1.1 视图的基本概念 在 MySQL 中,视图是一种虚拟表,它本身并不存储实际的数据,而是基于一个或多个真实表(基表)的查询结果集。可以把视图想象成是一个预定义好的查询语句的快捷方式。当你查询…...

算法很美笔记(Java)——动态规划

解重叠子问题(当前解用到了以前求过的解) 形式:记忆型递归或递推(dp) 动态规划本质是递推,核心是找到状态转移的方式,也就是填excel表时的逻辑(填的方式),而…...

C++ ——继承

体现的是代码复用的思想 1、子类继承父类,子类就拥有了父类的特性(成员方法和成员属性) 2、已存在的类被称为“基类”或者“父类”或者“超类”;新创建的类被称为“派生类”或者“子类” 注意: (1&#…...

LeetCode 热题 100 283. 移动零

LeetCode 热题 100 | 283. 移动零 大家好,今天我们来解决一道经典的算法题——移动零。这道题在LeetCode上被标记为简单难度,要求我们将数组中的所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。下面我将详细讲解解题思路,…...

游戏引擎学习第116天

回顾昨天的工作 本次工作内容主要集中在游戏开发的低级编程优化,尤其是手动优化软件渲染。工作目的之一是鼓励开发者避免依赖外部库,而是深入理解代码并进行优化。当前阶段正进行SIMD(单指令多数据)优化,使用Intel推荐…...

react(9)-redux

使用CRA快速创建react项目 npx create-react-app react-redux 安装配套工具 npm i reduxjs/toolkit react-redux 启动项目 在创建项目时候会出现一个问题 You are running create-react-app 5.0.0, which is behind the latest release (5.0.1). We no longer support…...

Linux内核实时机制7 - 实时改造机理 - 软中断优化下

Linux内核实时机制7 - 实时改造机理 - 软中断优化下 https://blog.csdn.net/u010971180/article/details/145722641以下分别以Linux4.19、Linux5.4、Linux5.10、Linux5.15 展开分析,深入社区实时改造机理的软中断优化过程。https://blog.csdn.net/weixin_41028621/article/det…...

企业知识管理平台重构数字时代知识体系与智能服务网络

内容概要 现代企业知识管理平台的演进呈现出全生命周期管理与智能服务网络构建的双重特征。通过四库体系(知识采集库、加工库、应用库、评估库)的协同运作,该系统实现了从知识沉淀、结构化处理到价值释放的完整闭环。其中,知识图…...

大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(3)

Paimon的下载及安装,并且了解了主键表的引擎以及changelog-producer的含义参考: 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1) 利用Paimon表做lookup join,集成mysql cdc等参考: 大数据组件(四)快速入门实时数据…...

SVN把英文换中文

原文链接:SVN设置成中文版本 都是英文,换中文 Tortoise SVN 安装汉化教程(乌龟SVN) https://pan.quark.cn/s/cb6f2eee3f90 下载中文包...

Ubuntu 的RabbitMQ安装

目录 1.安装Erlang 查看erlang版本 退出命令 2. 安装 RabbitMQ 3.确认安装结果 4.安装RabbitMQ管理界面 5.启动服务并访问 1.启动服务 2.查看服务状态 3.通过IP:port 访问界面 4.添加管理员用户 a)添加用户名:admin,密码&#xff1…...

基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案

随着物联网和嵌入式技术的快速发展,嵌入式设备对实时音视频通信的需求日益增长。然而,传统的音视频解决方案往往存在体积庞大、实时性差、互动体验不佳等问题,难以满足嵌入式设备的资源限制和应用场景需求。 针对以上痛点,本文将介…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...