CMake使用外部动态库/静态库和头文件

news2024/12/26 0:31:15

CMake使用外部动态库/静态库和头文件

  • 一、准备工作
  • 二、新建一个新的CMake工程
  • 三、开始构建
  • 四、为target添加共享库
  • 五、链接静态库

一、准备工作

在博文《使用CMake构建静态库和动态库》中已经介绍了libhello动态库的构建和安装,现在我们看看如何使用这个外部动态库。

本文中的示例前提是已经安装了libhello.so共享库。

二、新建一个新的CMake工程

创建一个新的名为usehellolib的CMake工程,在main.cpp中使用libhello.so中提供的函数say_hello().

main.cpp

#include <iostream>
#include "hello.hpp"

int main(int, char**) {
    say_hello();
}

工程根目录下的CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.0.0)
project(usehellolib VERSION 0.1.0)

add_subdirectory(src)

# 以下内容非必须
include(CTest)
enable_testing()

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

src 目录下的 CMakeLists.txt内容如下:

add_executable(usehellolib main.cpp)

整个工程的目录结构看起来是这样的:

20230101212438

三、开始构建

按照惯例,到build目录下进行构建

cd build
cmake ..
make

此时会发现报错了,提示找不到hello.hpp

20230101212658

hello.hpp 位于/usr/include/hello 目录中,并没有位于系统标准的头文件路径, 为了让我们的工程能够找到hello.hpp,我们需要引入一个新的指令INCLUDE_DIRECTORIES:

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的后面,你可以通过两种方式来进行控制搜索路径添加的方式:

  • CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过 SET 这个 cmake 变量为 on,可以
    将添加的头文件搜索路径放在已有路径的前面。
  • 通过 AFTER 或者 BEFORE 参数,也可以控制是追加还是置前。

现在我们在 src/CMakeLists.txt 中添加一个头文件搜索路径,方式很简单,加入

INCLUDE_DIRECTORIES(/usr/include/hello)

20230101213311

进入build目录重新构建,发现找不到头文件的错误已经消失,但是出现了一个新错误:

20230101213236

这是因为我们并没有 link 到共享库 libhello 上。

四、为target添加共享库

我们现在需要完成的任务是将目标文件链接到 libhello,这里我们需要引入两个新的指令
LINK_DIRECTORIES 和 TARGET_LINK_LIBRARIES。

LINK_DIRECTORIES 的全部语法是:

LINK_DIRECTORIES(directory1 directory2 ...)

这个指令非常简单,添加非标准的共享库搜索路径,比如,在工程内部同时存在共享库和可执行二进制,在编译时就需要指定一下这些共享库的路径。这个例子中我们没有用到这个指令。

TARGET_LINK_LIBRARIES 的全部语法是:

TARGET_LINK_LIBRARIES(target library1
    <debug | optimized> library2
    ...)

这个指令可以用来为 target 添加需要链接的共享库,本例中target是一个可执行文件,但是同样可以用于为自己编写的共享库添加共享库链接。

为了解决上面遇到的函数未定义错误,我们向 src/CMakeLists.txt 中添加如下指令:

TARGET_LINK_LIBRARIES(main hello)
也可以写成
TARGET_LINK_LIBRARIES(main libhello.so)

20230101214207

重新构建,这时我们就得到了一个连接到libhello的可执行程序usehellolib,位于build/src目录:

20230101214520

执行看是否能运行成功, 发现仍然有报错:

./usehellolib: error while loading shared libraries: libhello.so.1: cannot open shared object file: No such file or directory

20230101215501

可是文件明明是存在的:
20230101215639

我们来看看ldconfig这个程序,位于/sbin下,它的作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新的搜索路径,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。

执行一下ldconfig

ldconfig

如果是普通用户的话,需要使用sudo

20230101221409

再次执行程序,此时已经可以正常运行:

20230101221539

检查一下程序的链接情况,可以看到确实链接了libhello共享库:

20230101221759

五、链接静态库

那么如何链接到静态库呢? 很简单,只需要将
TARGET_LINK_LIBRRARIES 指令修改为:
TARGET_LINK_LIBRARIES(usehellolib libhello.a)

重新构建并查看链接情况:

20230101223755

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS 15.0+ 中 SwiftUI 顶部或底部悬浮功能小面板的极简实现

功能需求 我们有时需要在 App 主视图的顶部或底部固定悬浮放置一个功能视图: 如上图所示,我们将一个列表项目输入小面板按需放在主视图的顶部或底部: 当放置在顶部时,解决了其对导航栏(NavigationView)中 toolbar 内容的遮挡问题;当放置在底部时,考虑到了其对列表最后…

spring boot 实现搜索引擎的设计思想

目录 实现思路 索引模块 预处理 对文档进行分词 搜索模块 实现思路 索引构建模块 搜索模块 数据库模块 索引模块 对于搜索一个东西&#xff0c;我们很自然的能想到遍历去查找。比如我要查找一本书叫 《红楼梦》&#xff0c;那么我直接在所有结果中进行遍历查找&#xff…

druid解析-过滤器详解

druid支持过滤器&#xff0c;可以在获取连接或者调用连接对象的方法时&#xff0c;先调用过滤器&#xff0c;之后再执行底层方法&#xff0c;比如DruidDataSource的getConnection()方法&#xff1a; public DruidPooledConnection getConnection(long maxWaitMillis) throws SQ…

网络安全一哥的奇安信发布了全球高级可持续威胁年度报告 值得学习

声明 本文是学习全球高级持续性威胁 APT 2021年度报告. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 中国境内高级持续性威胁综述 基于中国境内海量DNS域名解析和奇安信威胁情报中心失陷检测&#xff08;IOC&#xff09;库的碰撞分析&…

9_1、Java基本语法之常用类String、StringBuffer、StringBuilder的使用

一、String的使用及常用方法 1、概述 String:表示字符串&#xff0c;使用""引起来。 1.1、String类是声明为final的&#xff0c;不可被继承。 1.2、String类实现了Serializable接口&#xff0c;表示字符串支持序列化。 …

【王道操作系统】2.1.3 原语实现对进程的控制

原语实现对进程的控制 文章目录原语实现对进程的控制1.什么是进程控制2.原语实现对进程的控制3.回忆进程的组织4.进程控制大致图解5.进程控制原语的相同点6.进程控制的五种原语1.什么是进程控制 2.原语实现对进程的控制 3.回忆进程的组织 4.进程控制大致图解 这里说明一下调度和…

MySQL【AUTO_INCREMENT 】自增列

使用案例场景再现&#xff1a; 创建一个为test的数据库&#xff0c;为数据库test创建一个数据表student &#xff0c;其中包含的字段有 id name sex&#xff0c;admission_time,其中要求student表中的人员id必须连续排列。 create database test use test cr…

SCI论文解读复现【NO.1】基于Transformer-YOLOv5的侧扫声纳图像水下海洋目标实时检测

此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c;帮助…

三旗舰焕新发布引领品牌向上 长城汽车登陆2022广州车展

近日&#xff0c;长城汽车携哈弗、魏牌、欧拉、坦克、长城炮以及沙龙六大品牌&#xff0c;登陆第二十届广州国际汽车展览会&#xff08;以下简称“2022广州车展”&#xff09;。魏牌全新旗舰蓝山DHT-PHEV、坦克500 PHEV长续航版、大型高性能豪华皮卡山海炮等车型联袂而至&#…

创建静态库存文件 ansible(3)

目录 创建一个名为/home/student/ansible/inventory的静态库存文件如下所示&#xff1a; &#xff08;1&#xff09;node1是dev主机组的成员 &#xff08;2&#xff09;node2是test主机组的成员 &#xff08;3&#xff09;node1和node2是prod主机组的成员 &#xff08;4&am…

【Qt】控件——QPlainTextEdit使用简单介绍:常用方法及信号、逐行读取编辑框的内容、使用自带的快捷菜单、作为日志显示窗口

Qt控件-QPlainTextEdit使用 参考链接&#xff1a; https://blog.csdn.net/seniorwizard/article/details/109726147; https://blog.csdn.net/seniorwizard/article/details/109726147 文章目录Qt控件-QPlainTextEdit使用QPlainTextEdit控件简单介绍1. 逐行读取文本编辑框的内容…

【PCB专题】什么是金属化孔(PTH)和非金属化孔(NPTH)

计出来的,并不是放在那里好看的,每个不同的孔洞都有其目的。一般来说孔洞越多,PCB的成本也越高。 PCB中的孔类型大体上可以被区分为PTH(Plating Through Hole)电镀导通孔,和NPTH(None Plating Through Hole)非电镀导通孔两大类。这里说的通孔是指从PCB的一面直接贯穿到…

Spark数据倾斜性能调优

目录 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 某个task执行特别慢的情况 某个task莫名其妙内存溢出的情况 查看导致数据倾斜的key的数据分布情况 知识拓展 coalesce 和 repartition 的区别 数据倾斜的解决方案 解决方案一&am…

【哈工大大一年度项目经验与感想】立项篇 中(2021.9.17~2021.11.17)

第四步&#xff1a;立项报告书写 立项报告的目的在于向答辩老师或者投资方阐述你的项目是什么&#xff1f;做什么的&#xff1f;解决什么问题&#xff1f;打算怎么解决这些问题&#xff1f;有什么创新点、特色&#xff1f;目标&#xff1f;所以一篇立项报告正文需要包括以下内容…

21级数据结构考前模拟题

说明&#xff1a; 此试卷为21级数据结构考前模拟题&#xff0c;老师并未给出标准答案&#xff0c;故以下所有答案均为博主给出&#xff0c;并只供参考&#xff0c;不保证其正确性&#xff01;&#xff01;&#xff01; 只更新了部分&#xff0c;还在写题中&#xff01;&#xf…

同步+异步日志系统(C++实现)

对于一个服务器而言&#xff0c;不论是在调试中还是在运行中&#xff0c;都需要通过打日志的方式来记录程序的运行情况。本文设计的日志系统实现了同步与异步两种功能&#xff0c;原理见下图&#xff1a; 同步日志&#xff1a;日志写入函数与工作线程串行执行&#xff0c;由于涉…

人脸识别与美颜算法实战-基于机器学习的人脸识别

机器学习根据输出的类型一般分为两类,分类和回归。分类的输出一般是离散值,回归输出的值一般是连续的。比如,人脸识别这种就属于分类问题,房价预测一般是一个回归问题。 鸢尾花分类 # -*- coding: UTF-8 -*- # 导入数据集 from sklearn.datasets import load_iris iris =…

InnoDB事务原理理解(redo log,undo log,锁,MVCC的理解)

目录事务事务的四大特性ACID事务相关SQL语句事务原理事务如何解决隔离性隔离性总结事务如何解决原子性、一致性、持久性redo log 重做日志CheckPoint 检查点机制Double Writer 双写磁盘undo log 回滚日志锁表级锁表读锁、表写锁元数据锁MDL意向锁行级锁行读锁&#xff0c;行写锁…

coremail邮件安全网关产品详细学习笔记(上)

声明 本文是学习中国企业邮箱安全性研究报告. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 钓鱼邮件 钓鱼邮件的规模 在本章内容中&#xff0c;钓鱼邮件是指含有恶意欺诈信息的邮件&#xff0c;包括OA钓鱼邮件、鱼叉邮件、钓鲸邮件、CEO仿…

PHP代码审计

1. "" 与 “” 在进行比较的时候&#xff0c;会先将字符串类型转化成相同&#xff0c;如果整型跟字符型比较字符或从左往右提取整型直到遇到字符结束&#xff0c;再比较。 在进行比较的时候&#xff0c;会先判断两种字符串的类型是否相等&#xff0c;当等号两边类…