CMake 引入第三方库
CMake 引入第三方库
在 CMake 中,如何引入第三方库是一个常见的问题。在本文中,我们将介绍 CMake 中引入第三方库的不同方法,以及它们的优缺点。
1. 使用 find_package 命令
在 CMake 中,使用 find_package 命令是最简单和最常用的方式来引入已安装的外部库。例如,我们可以使用以下命令来引入 OpenSSL 库:
find_package(OpenSSL REQUIRED)
在这个例子中,CMake 将查找已安装的 OpenSSL 库,并将其链接到我们的项目中。当然,我们也可以通过设置变量来指定 OpenSSL 的路径:
set(OPENSSL_ROOT_DIR /path/to/openssl)
find_package(OpenSSL REQUIRED)
使用 find_package 命令的主要优点是它能够自动查找和链接已经安装的库,这使得构建过程更加简单和直观。
2. 使用 add_subdirectory 命令
在某些情况下,我们可能需要修改外部库的源代码。此时,我们可以将外部库的源代码添加到我们的项目中,然后使用 add_subdirectory 命令来构建外部库。例如,我们可以使用以下命令来引入 JsonCpp 库:
add_subdirectory(/path/to/jsoncpp)
target_link_libraries(myapp PRIVATE jsoncpp_lib)
在这个例子中,我们将 JsonCpp 库的源代码添加到我们的项目中,并将 jsoncpp_lib 目标链接到我们的应用程序中。在构建我们的项目时,CMake 将自动构建 JsonCpp 库,并将其链接到我们的应用程序中。
使用 add_subdirectory 命令的主要优点是,它能够更方便地管理外部库的源代码。我们可以将外部库的源代码包含在我们的版本控制系统中,以便更好地管理和维护代码。但是,使用此方法需要手动管理外部库的源代码,因此更新可能会导致您的项目中出现构建问题。
3. 使用 ExternalProject_Add 命令
下面是一个使用 ExternalProject_Add 命令下载和构建 Google Test 库的例子。在这个例子中,我们将下载 Google Test 库的源代码,并将其作为独立项目构建。使用 ExternalProject_Add 命令的主要优点在于,它能够将外部项目的构建过程与主项目的构建过程隔离开来,从而更加灵活地控制外部项目的行为和依赖关系。
cmake_minimum_required(VERSION 3.11)include(ExternalProject)# 设置下载的 URL 和 SHA-256 哈希值
set(GTEST_VERSION "1.11.0")
set(GTEST_URL "https://github.com/google/googletest/archive/refs/tags/release-${GTEST_VERSION}.tar.gz")
set(GTEST_HASH "d722feaac7d6b2270c2f6896d364c3712cf18e9cd963c1e7f56c38e936e13fa1")# 下载和解压 Google Test 库的源代码
ExternalProject_Add(googletestPREFIX "${CMAKE_CURRENT_BINARY_DIR}/googletest"URL "${GTEST_URL}"URL_HASH SHA256=${GTEST_HASH}DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest/download"SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest/src"BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest/build"CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/googletest/install"
)# 将 Google Test 库的头文件和库文件链接到主项目中
set(GTEST_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest/install/include")
set(GTEST_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/googletest/install/lib/libgtest.a")
set(GTEST_MAIN_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/googletest/install/lib/libgtest_main.a")target_include_directories(myproject PRIVATE ${GTEST_INCLUDE_DIR})
target_link_libraries(myproject PRIVATE ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
在这个例子中,我们首先通过设置 GTEST_URL 和 GTEST_HASH 变量来指定要下载的 Google Test 库的版本和哈希值。然后,我们使用 ExternalProject_Add 命令来下载和解压源代码,并使用 CMake 构建 Google Test 库。这里通过设置 PREFIX、URL、URL_HASH、DOWNLOAD_DIR、SOURCE_DIR、BINARY_DIR 和 CMAKE_ARGS 等参数来指定 ExternalProject_Add 的行为。最后,我们将 Google Test 库的头文件和库文件链接到主项目中,以便在主项目中使用 Google Test 库。
4.使用FetchContent 命令
CMake 也可以通过 include(FetchContent) 命令引入第三方库。FetchContent 命令允许您从指定的 URL 或 Git 存储库中提取第三方库,并将其作为 CMake 项目的子目录构建。使用 FetchContent 命令时,您无需手动下载、解压缩或设置外部库的构建过程,CMake 会自动执行这些任务。
下面是使用 FetchContent 命令引入第三方库的示例:
include(FetchContent)FetchContent_Declare(my_libraryGIT_REPOSITORY https://example.com/my_library.gitGIT_TAG v1.0.0
)FetchContent_GetProperties(my_library)
if(NOT my_library_POPULATED)FetchContent_Populate(my_library)add_subdirectory(${my_library_SOURCE_DIR} ${my_library_BINARY_DIR})
endif()
在这个示例中,FetchContent_Declare 命令声明了一个名为 my_library 的第三方库,并指定了其 Git 存储库的 URL 和 Git tag。然后,FetchContent_GetProperties 命令获取指定的第三方库的属性,并检查它是否已经被 FetchContent_Populate 命令所提取。如果尚未提取,FetchContent_Populate 命令将提取指定的库,并将其作为 CMake 项目的子目录进行构建。最后,add_subdirectory 命令将提取的第三方库的源代码目录和二进制目录添加到 CMake 项目中。
使用 FetchContent 命令的优点是它使得引入第三方库更加方便,并且使得与外部库的集成更加简单。同时,使用 FetchContent 命令时,您可以很容易地在您的 CMake 项目中指定外部库的版本和源代码位置。
5.总结
当引入第三方库时,CMake 提供了多种不同的方式。每种方式都有自己的优缺点,具体取决于项目的需求和环境。下面是一些不同的引入第三方库的方法及其优缺点:
1、find_package 命令
find_package 命令是一种在 CMake 项目中查找已经安装的第三方库的方法。这种方法适用于大多数开源库,因为它们通常已经被打包为二进制发行版,可以通过包管理器或官方网站下载并安装。优点:使用已经安装的二进制发行版,构建速度快,不需要从源代码构建。缺点:无法使用最新版本的库,需要手动安装和更新库。2、add_subdirectory 命令
add_subdirectory 命令是一种在 CMake 项目中添加外部库源代码的方法。这种方法适用于已经包含在您的项目中的外部库,或者您需要从源代码构建外部库的情况。优点:直接在您的项目中构建外部库,方便修改外部库源代码。缺点:需要手动更新外部库,库的更新可能会导致项目中的构建问题。3、ExternalProject_Add 命令
ExternalProject_Add 命令是一种将外部库作为独立项目下载和构建的方法。这种方法适用于需要与外部库进行集成,但是不想将外部库的源代码包含在您的项目中。优点:不需要在您的项目中包含外部库的源代码,允许更好的代码分离和依赖管理。缺点:需要从头开始构建外部库,构建速度可能很慢。同时,需要手动更新外部库,库的更新可能会导致项目中的构建问题。4、FetchContent 命令
FetchContent 命令是一种从外部 URL 或 Git 存储库中提取源代码的方法。这种方法适用于不需要将外部库作为独立项目构建的情况,但是需要从源代码构建外部库。优点:与 ExternalProject_Add 相比,构建速度更快,而且不需要独立的构建目录。缺点:需要手动更新外部库,库的更新可能会导致项目中的构建问题。
总之,选择适当的方法取决于项目的需求和环境。对于大多数情况,find_package 命令是首选方法,因为它是最简单和最常用的方式。对于需要修改外部库源代码的情况,使用 add_subdirectory 命令可以更方便地管理代码。对于需要将外部库作为独立项目构建的情况,使用 ExternalProject_Add 命令是一种好的选择。这种方法的优点在于,它能够将外部库的构建过程与您的项目分离,使代码更易于管理和维护。不过,这种方法的缺点是需要手动更新外部库,更新可能会导致您的项目中出现构建问题。
如果您不需要将外部库作为独立项目构建,但是需要从源代码构建外部库,那么 FetchContent 命令是一种不错的选择。这种方法与 ExternalProject_Add 相比,构建速度更快,而且不需要独立的构建目录。但是,需要注意的是,需要手动更新外部库,更新可能会导致您的项目中出现构建问题。
综上所述,对于大多数情况,使用 find_package 命令是最简单和最常用的方式,因为它能够自动查找已经安装的外部库。对于需要修改外部库源代码的情况,使用 add_subdirectory 命令可以更方便地管理代码。对于需要将外部库作为独立项目构建的情况,使用 ExternalProject_Add 命令是一种好的选择。对于不需要将外部库作为独立项目构建,但是需要从源代码构建外部库的情况,使用 FetchContent 命令是一种不错的选择。
相关文章:
CMake 引入第三方库
CMake 引入第三方库 在 CMake 中,如何引入第三方库是一个常见的问题。在本文中,我们将介绍 CMake 中引入第三方库的不同方法,以及它们的优缺点。 1. 使用 find_package 命令 在 CMake 中,使用 find_package 命令是最简单和最常…...
软考中级-面向对象
面向对象基础(1)类类分为三种:实体类(世间万物)、接口类(又称边界类,提供用户与系统交互的方式)、控制类(前两类之间的媒介)。对象:由对象名数据&…...
Linux 系统构成:bootloader、kernel、rootfs
写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。 目录前言bootloaderk…...
SpringCloud - Eureka注册发现
目录 提供者与消费者 Eureka原理分析 搭建Eureka服务 服务注册 服务发现 提供者与消费者 服务提供者: 一次业务中,被其它微服务调用的服务(提供接口给其它微服务)服务消费者: 一次业务中,调用其它微服务的服务(调用其它微服务…...
WampServer安装教程
文章目录简介:官网地址安装步骤:我是阿波,学习PHP记录一下笔记,如果对你有帮助,欢迎一键三连,谢谢! 简介: WampServer是一个用于Windows操作系统的Web开发环境,其名称来…...
Go语言泛型基础
泛型 Go 并不是一种静止的、一成不变的编程语言。新的功能是在经过大量的讨论和实验后慢慢采用的。最初的 Go1.0发布以来,Go语言习惯的模式已经发生了重大变化1.7的context、1.11的modules、1.13 error嵌套等Go的 1.18 版本包括了类型参数的实现,也就是…...
基于android的中医养生app
需求信息: 中医健康养生APP分为四大模块,其中个人中心又分为4大块,游客用户个人中心是空白的。 上图为养生知识推广普及模块的功能结构图。 在养生知识推广普及模块界面,用户可以选择自己感兴趣的模块进行文章浏览,文章…...
2023美赛C代码思路结果【全部更新完毕】注释详尽
C题已完成全部代码,注释详尽,并增加扰动项,保证大家的结果不会撞 需要全部问题的可以点击:https://www.jdmm.cc/file/2708697/ 下面贴出核心代码: -- coding: utf-8 -- TODO: 入口函数 import numpy as np from…...
实现8086虚拟机(二)——模拟CPU和内存
文章目录CPU 架构EU(执行单元)BIU(总线接口单元)小结一下模拟内存模拟 BIU模拟 EU模拟 CPU总结要模拟 8086 CPU 运行,必须知道 CPU 的一些知识。下文的知识点都来自《Intel_8086_Family_Users_Manual 》。CPU 架构 微…...
Windows7下使用VMware11.1.1安装ubuntu-16.04.7
一、说明二、安装说明三、安装步骤详解1、先安装VMware软件2、创建虚拟机3、编辑虚拟机4、开启虚拟机,初始化Linux系统一、说明 虽然VMware和ubuntu最新版已经很高了,我这电脑由于是win7配值还低,所以采用低版本来安装 VMware版本࿱…...
基于SSM框架的CMS内容管理系统的设计与实现
基于SSM框架的CMS内容管理系统的设计与实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目…...
华为OD机试 - 运动会 | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 自动曝光(Python) | 机试题算法思路 【2023】 华为OD机试 - 双十一(Python) | 机试题算法思路 【2023】 华为OD机试 - 删除最少字符(Python) | 机试题算法思路 【2023-02】 华为OD机试 - Excel 单元格数值统计(Python) | 机试题算法思路 …...
(C语言篇)扫雷的实现
文章目录 一、开始时的基本思维:二、进入游戏的逻辑(test.c文件中实现)三、游戏的编写 1. 初始化棋盘 I. test.cII. game.hIII. game.c 2.打印棋盘 I. test.cII. game.hIII. game.c 3.布置雷 I. test.cII. game.hIII. game.c 4.排查雷 I. test.cII. game.hIII. gam…...
华为手表开发:WATCH 3 Pro(8)获取位置服务
华为手表开发:WATCH 3 Pro(8)获取位置服务初环境与设备文件夹:文件新增第二页面geolocation.hmlgeolocation.js修改首页 -> 新建按钮 “ 跳转 ”index.hmlindex.js 引用包:system.router首页效果点击结果按钮跳转后…...
AnLogicFPGA设计的时序约束及时序收敛
本篇博文讲了三个内容:时序约束基本概念、时序约束命令、时序收敛技巧 时序约束基本概念 时序设计的实质就是满足每一个触发器的建立(setup)时间和保持(hold)时间。 建立时间(Tsu) 触发器的时钟信号沿到来以前&…...
ubuntu22.10安装sogou输入法后不能输入中文字符(可以输入中文标点符号)
问题描述 想在ubuntu22.10系统上安装sogou中文输入法,按照sogou输入法网站给出的步骤安装后,发现无法输入中文字符,但是可以输入中文标点符号。 sogou网站:https://shurufa.sogou.com/linux/guide 寻找答案1 通过各种百度和必…...
基于微信小程序的生活日用品交易平台 的设计与实现
基于微信小程序的生活日用品交易平台 的设计与实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一…...
15:高级篇 - CTK 事件与监听
作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 生命周期层事件 在 Plugin 生命周期的不同状态相互转换时,CTK Plugin Framework 会发出各种不同的事件,以供事先注册好的事件监听器处理,这些事件被称为“生命周期层事件”。CTK Plugin Framework 支持的…...
SpringBoot Notes
文章目录1 SpringBootWeb快速入门1.1Spring官网1.2 Web分析2. HTTP协议2.1 HTTP介绍34 SpringBootWeb请求响应5 响应6 分层解耦6.1 三层架构6.1.1 三层架构介绍6.1.2 基于三层架构的程序执行流程:6.1.3 代码拆分6.2 分层解耦6.2.1 内聚、耦合6.2.2 解耦思路6.3 IOC&…...
CoreDNS
目录 文章目录目录本节实战前言1、环境变量2、DNS1.DNS 解析过程2.根域名服务器3.顶级域名服务器4.权威性域名服务器5.dig 域名3、CoreDNS1.CoreDNS 扩展配置(1)开开启日志服务(2)特定域名使用自定义 DNS 服务器(3&…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
