编译工具:CMake(五) | 静态库与动态库构建

news2024/11/22 15:15:03

编译工具:CMake(五) | 静态库与动态库构建

  • 建立共享库
  • 编译共享库
    • 指令 ADD_LIBRARY
  • 添加静态库
  • 动态库版本号
  • 安装共享库和头文件

在这里插入图片描述

建立共享库

Compilation_tool/cmake路径下建立test3目录

在 t3 目录下建立 CMakeLists.txt,内容如下:

PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(lib)

在 lib 目录下建立两个源文件 hello.c 与 hello.h

hello.c 内容如下:

#include “hello.h”
void HelloFunc()
{
printf(“Hello World\n”);
}

hello.h 内容如下:

#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
void HelloFunc();
#endif

在 lib 目录下建立 CMakeLists.txt,内容如下:

SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

编译共享库

仍然采用 out-of-source 编译的方式,建立一个 build 目录
在 build目录中

cmake ..
make

这时,你就可以在 lib 目录得到一个 libhello.so,这就是共享库。
在这里插入图片描述

如果你要指定 libhello.so 生成的位置,可以通过在主工程文件 CMakeLists.txt 中修改 ADD_SUBDIRECTORY(lib)指令来指定一个编译输出位置或者在 lib/CMakeLists.txt 中添加SET(LIBRARY_OUTPUT_PATH <路径>)来指定一个新的位置。

指令 ADD_LIBRARY

ADD_LIBRARY(libname
[SHARED|STATIC|MODULE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)

你不需要写全 libhello.so,只需要填写 hello 即可,cmake 系统会自动为你生成libhello.X

类型有三种:

  • SHARED,动态库
  • STATIC,静态库
  • MODULE,在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。

EXCLUDE_FROM_ALL 参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手工构建。

添加静态库

同样使用上面的指令,我们在支持动态库的基础上再为工程添加一个静态库,按照一般的习惯,静态库名字跟动态库名字应该是一致的,只不过后缀是.a 罢了。

下面我们用这个指令再来添加静态库:

ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})

然后再在 build 目录进行外部编译,我们会发现,静态库根本没有被构建,仍然只生成了一个动态库。因为 hello 作为一个 target 是不能重名的,所以,静态库构建指令无效。

如果我们把上面的 hello 修改为 hello_static:

ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})

就可以构建一个 libhello_static.a 的静态库了。
在这里插入图片描述
这种结果显示不是我们想要的,我们需要的是名字相同的静态库和动态库,因为 target 名称是唯一的,所以,我们肯定不能通过 ADD_LIBRARY 指令来实现了。这时候我们需要用到另外一个指令: SET_TARGET_PROPERTIES

SET_TARGET_PROPERTIES(target1 target2 ...
						PROPERTIES prop1 value1
						prop2 value2 ...)

这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本。

在本例中,我们需要作的是向 lib/CMakeLists.txt 中添加一条:

SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

这样,我们就可以同时得到 libhello.so/libhello.a 两个库了。

在这里插入图片描述

让我们来检查一下最终的构建结果,我们发现,libhello.a 已经构建完成,位于build/lib 目录中,但是 libhello.so 去消失了。这个问题的原因是:cmake 在构建一个新的 target 时,会尝试清理掉其他使用这个名字的库,因为,在构建 libhello.a 时,就会清理掉 libhello.so.为了回避这个问题,比如再次使用 SET_TARGET_PROPERTIES 定义CLEAN_DIRECT_OUTPUT 属性。

向 lib/CMakeLists.txt 中添加:

SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

这时候,我们再次进行构建,会发现 build/lib 目录中同时生成了 libhello.so 和libhello.a

动态库版本号

按照规则,动态库是应该包含一个版本号的,我们可以看一下系统的动态库,一般情况是
libhello.so.1.2
libhello.so ->libhello.so.1
libhello.so.1->libhello.so.1.2

为了实现动态库版本号,我们仍然需要使用 SET_TARGET_PROPERTIES 指令。
具体使用方法如下:

SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

VERSION 指代动态库版本,SOVERSION 指代 API 版本。
将上述指令加入 lib/CMakeLists.txt 中,重新构建看看结果。
在 build/lib 目录会生成:
libhello.so.1.2

在这里插入图片描述

安装共享库和头文件

以上面的例子,我们需要将 libhello.a, libhello.so.x 以及 hello.h 安装到系统目录,才能真正让其他人开发使用,在本例中我们将 hello 的共享库安装到/lib目录,将 hello.h 安装到/include/hello 目录。

利用上一节了解到的 INSTALL 指令,我们向 lib/CMakeLists.txt 中添加如下指令:

INSTALL(TARGETS hello hello_staticLIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
INSTALL(FILES hello.h DESTINATION include/hello)

注意,静态库要使用 ARCHIVE 关键字
通过:

cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
make install

我们就可以将头文件和共享库安装到系统目录/usr/lib 和/usr/include/hello 中了。

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

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

相关文章

88-基于stm32单片机空调温湿度控制系统Proteus仿真+源码

资料编号&#xff1a;088 一&#xff1a;功能介绍&#xff1a; 1、采用stm32单片机OLED显示屏DHT11温湿度电机按键&#xff0c;制作一个温湿度采集&#xff0c;OLED显示相关数据&#xff0c;自动制冷制热空调&#xff1b; 2、通过按键设置温度值和工作模式&#xff08;制冷/制热…

MLC LLM:将LLMs部署到消费类硬件的优势、挑战以及解决方案

一、前言 随着生成人工智能&#xff08;AI&#xff09;和大语言模型&#xff08;LLM&#xff09;的快速发展&#xff0c;基于LLM的应用越来越普及。然而&#xff0c;大规模的模型需要密集计算和庞大的资源&#xff0c;使得许多公司无法承担从头开始训练模型的成本。目前&#…

计算机控制技术|17/8|16:27

目录 1. 什么是“纹波”现象&#xff1f;原因为何&#xff1f; 2. 如何解决最小拍控制器的“纹波”问题&#xff1f; 3. 解释“阻尼因子法”&#xff1f; 4. 大林算法控制器设计时&#xff0c;给定闭环系统传递函数模型离散化时为何要加入零阶保持器&#xff1f; 5. 何为“…

86-基于stm32单片机智能家居温湿度监测自动加湿器散热器Proteus仿真+源码

资料编号&#xff1a;086 一&#xff1a;功能介绍&#xff1a; 1、采用stm32单片机OLED显示屏DHT11温湿度电机按键蜂鸣器&#xff0c;制作一个温湿度采集、OLED显示相关数据&#xff0c; 2、通过按键设置温度上限、湿度下限、 3、当采集温度大于设置温度&#xff0c;开启散热电…

【广州华锐视点】VR线上教学资源平台提供定制化虚拟现实学习内容

虚拟现实&#xff08;VR&#xff09;技术的出现为我们提供了一种全新的在线教学方式。由广州华锐视点开发的VR线上教学资源平台&#xff0c;作为一个综合性的学习工具&#xff0c;正在教育领域迅速发展&#xff0c;并被越来越多的教育机构和学生所接受。那么&#xff0c;VR线上…

XDR解决方案成为了新的安全趋势

和当今指数倍增长的安全数据相比&#xff0c;安全人才的短缺带来了潜在的风险。几乎所有的公司&#xff0c;无论规模大小&#xff0c;在安全资源能力上都有限&#xff0c;需要过滤各种告警才能将分析量保持在可接受范围。但这样一来&#xff0c;潜在的威胁线索就可能被埋没&…

在一小时内构建您的深度学习应用程序

一、说明 我已经做了将近十年的数据分析。有时&#xff0c;我使用机器学习技术从数据中获取见解&#xff0c;并且我习惯于使用经典 ML。 虽然我已经通过了神经网络和深度学习的一些MOOC&#xff0c;但我从未在我的工作中使用过它们&#xff0c;这个领域对我来说似乎很有挑战性。…

爬虫的代理IP池写哪里了?

亲爱的程序员小伙伴们&#xff0c;想要提高爬虫效率和稳定性&#xff0c;组建一个强大的代理IP池是非常重要的一步&#xff01;今天我就来和你分享一下&#xff0c;代理IP池到底应该写在哪里&#xff0c;以及如何打造一个令人瞩目的代理IP池&#xff01;准备好了吗&#xff1f;…

【最新可用】VMware中ubuntu与主机window之间使用共享文件夹传输大文件

一、VMware设置共享文件夹 &#xff08;1&#xff09;虚拟机关机情况下&#xff0c;创建一个共享文件夹 &#xff08;2&#xff09;ubuntu中挂载共享文件夹 1、如果之前已经挂载 hgfs&#xff0c;先取消挂载 sudo umount /mnt/hgfs2、重新使用以下命令挂载 sudo /usr/bin/vmh…

11、BigKey

BigKey 阿里广告平台&#xff0c;海量数据里查询某一固定前缀的key 小红书&#xff0c;你如何生产上限制keys */flushdb/flushall等危险命令以防止误删误用&#xff1f; 美团&#xff0c;MEMORY USAGE 命令你用过吗&#xff1f; BigKey问题&#xff0c;多大算big&#xff1f;你…

数据库名字添加中文

Jetbrains 可以呀&#xff0c;这个ui 相当棒 from database import Sqlite3Database from googletrans import Translator import csvif __name__ "__main__":TRANS_EN2ZH Falsetranslator Translator()sqlite Sqlite3Database("./drurmu.db")sqlite.r…

深入篇【C++】手搓模拟实现二叉搜索树(递归/非递归版本)常见应用场景(K模型与KV模型)

深入篇【C】手搓模拟实现二叉搜索树(递归/非递归版本&#xff09;&&常见应用场景 Ⅰ.二叉搜索树概念Ⅱ.二叉搜索树模拟实现(递归与非递归)①.定义结点②.构造二叉树③.插入结点④.删除结点(重要)⑤.查找结点⑥.析构二叉树⑦.拷贝二叉树⑧.二叉树赋值 Ⅲ.二叉搜索树应用…

Cadence+硬件每日学习十个知识点(38)23.8.18 (Cadence的使用,界面介绍)

文章目录 1.Cadence有共享数据库的途径2.Cadence启动3.Cadence界面菜单简介&#xff08;file、edit、view、place、options&#xff09;4.Cadence界面的图标简介5.我的下载资源有三本书 1.Cadence有共享数据库的途径 答&#xff1a; AD缺少共享数据库的途径&#xff0c;目前我…

Apache-DBUtils

目录 封装方法 引出dbutils 案例 当关闭connection后&#xff0c;resultset结果集就无法使用了&#xff0c;这就使得resultset不利于数据的管理 封装方法 我们可以将结果集先存储在一个集合中&#xff0c;当connection关闭后&#xff0c;我们可以通过访问集合来访问结果集 …

Educational Codeforces Round 110 (Rated for Div. 2) C. Unstable String

dp写法&#xff1a;f[i][j]表示第i位&#xff0c;当前位为j&#xff0c;能往前找的最大的合法长度。 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std;typedef pair<int, int> PII; type…

Redis进阶篇 - 04发布订阅、布隆过滤器、过期策略、回收机制、管道...核心知识原理

Redis底层原理篇&#xff0c;​让学习绚丽多彩起来&#xff01;&#xff01;&#xff01;&#xff08;需要原图私信&#xff09;

【服务器】Strace显示后台进程输出

今天有小朋友遇到一个问题 她想把2331509和2854637这两个进程调到前台来&#xff0c;以便于在当前shell查看这两个python进程的实时输出 我第一反应是用jobs -l然后fg &#xff08;参考这里&#xff09; 但是发现jobs -l根本没有输出&#xff1a; 原因是jobs看的是当前ses…

【Docker】Docker Desktop配置资源:cpu、内存等(windows环境下)

Docker Desktop配置资源&#xff1a;cpu、内存等&#xff08;windows环境下&#xff09; 一、WSL2 以及 hyper-v区别&#xff0c;二者安装docker desktop1.WSL2和hyper-v区别2.安装Docker Desktop 二、docker desktop限额配置&#xff0c;资源配置方法 Docker 是指容器化技术&a…

Redis进阶底层原理- Redis结构图与底层数据编码结构

Redis底层原理篇&#xff0c;​让学习绚丽多彩起来&#xff01;&#xff01;&#xff01;&#xff08;需要原图私信&#xff09;

DAMO-YOLO:实时目标检测设计的报告

ReadPaperhttps://readpaper.com/pdf-annotate/note?pdfId4748421678288076801eId1920373270663763712 Abstract 在本报告中&#xff0c;我们提出了一种快速准确的目标检测方法&#xff0c;称为DAMO-YOLO&#xff0c;它比最先进的YOLO系列实现了更高的性能。DAMO-YOLO 通过…