库的制作 与 使用 (Linux下)

目录

动静态库的制作

前置知识

库的基本构造

问题

分析

要给什么文件

如何更好的让别人使用

库的生成

静态库的生成

makefile参考

动态库的生成

makefile参考(包含动态库和静态库生成)

库的使用

法一:放入系统路径

弊端

法二:放入环境变量

弊端

法三:放入配置文件

动静态库的制作

前置知识

要学会制作动态库,必须要有软硬链接知识的基础,大家可以移步至该文章:软链接和硬链接的详解 (Linux系统下)-CSDN博客

库的基本构造

问题

问题:

我们都知道代码有源文件,头文件,那么请问我们要将自己实现的代码给他人使用时,应该给哪些文件给他们呢?🤨🤔

分析

要给什么文件

1、头文件要给别人吗

  • 答:肯定要,我们使用库里面的函数,一定需要包含头文件才能使用🙂😲

2、源文件要给别人吗?

  • 答:情况分两种🤔😯

    • 愿意开源,和别人一起进步:可以😆

    • 保护自己的知识产权(暂不开源):不要😶

3、源文件不给别人的时候,应该怎么做呢?

  • 答:给编译后的文件(别人看不了你的代码实现)ψ(`∇´)ψ

    • 也就是gcc -c 源文件名 -o 编译后的文件名.o后形成的文件,这样的文件属于二进制文件,别人看不了你的代码实现,但是计算机看得懂

如何更好的让别人使用

我们通常不会只有一个头文件和源文件,因此生成的.h文件和编译后生成的.o文件不止一个,因此需要对各个文件分类进行打包压缩,我们通常采用如下处理办法:

  • 头文件:

    放入一个名为include的文件夹

  • .o文件:

    打包成库,分为静态库和动态库,静态库以.a结尾,动态库以.so结尾

库的生成

静态库的生成

  • 问题:

    若我们有如下文件:myprint.c,mymath.c,myprint.h,mymath.h,请问我们要干什么呢🤔,想想前面讲的哦😶

答案:

  • 头文件放入一个include文件夹下

  • 库文件:

    • 先都gcc -c 源文件名 -o 编译后的文件名.o生成.o文件

    • 将所有.o文件打包为.a文件,也就是静态库

下面的问题就是:

怎么打包生成.a文件??

答:

当我们的.o文件都生成后,我们要输入一下命令,来打包

ar -rc liboutput.a myprint.o mymath.o
  • 命令解析

    • ar:tar的缩写

    • r:replace

    • c:creat

    • liboutput.a:命名规范

      • lib:库文件前缀,这是命名要求

      • output:库文件名     ( ̄︶ ̄)↗敲重点

      • .a:静态库后缀,也是命名要求

    • .o:要被打包的.o文件列表

makefile参考

以上的各个步骤可以用makefile来完成,以下是makefile的参考

# 静态库
liboutput.a:myprint.o mymath.o
# .a:静态库后缀ar -rc liboutput.a myprint.o mymath.o# ar:归档# -rc: #       r:replace#       c:creatmyprint.o:myprint.cgcc -c myprint.c -o myprint.o# -c:编译
mymath.o:mymath.cgcc -c mymath.c -o mymath.o
​
.PHONY:output
output:mkdir -p output/libmkdir -p output/includecp *.h output/includecp *.a output/lib
​
.PHONY:clean 
clean:rm -f *.o *.a
  • 起始

  • 输入make后会生成.o文件和.a文件

  • 输入make output后会生成output文件夹,下面是

    • include文件夹

      存放.h文件

    • lib文件夹

      存放.a文件

  • 输入make clean就会清除那些不需要的文件啦

我们发布库给别人用的时候,只需要将output给别人就好啦

动态库的生成

同样,我们也是要将.o文件打包,但是动态库是打包为.so文件

  • 生成.o命令

    gcc -fPIC -c 源文件名 -o 要生成的.o文件名
  • 打包.o文件

    gcc -shared .o文件列表 lib库文件名.so
  • 用上面的的myprint.c,mymath.c举例

    • 生成.o文件

    myprint_d.o:myprint.cgcc -fPIC -c myprint.c -o myprint_d.o# -c:编译# -fPIC:生成与位置无关的二进制文件
    ​
    mymath_d.o:mymath.cgcc -fPIC -c mymath.c -o mymath_d.o
    • 打包.o文件为.so文件

    liboutput.so:myprint_d.o mymath_d.ogcc -shared -o liboutput.so myprint_d.o mymath_d.o
makefile参考(包含动态库和静态库生成)

注意里面的all的妙用

.PHONY:all
all:liboutput.a liboutput.so
# 静态库
liboutput.a:myprint.o mymath.o
# .a:静态库后缀ar -rc liboutput.a myprint.o mymath.o# ar:归档# -rc: #       r:replace#       c:creatmyprint.o:myprint.cgcc -c myprint.c -o myprint.o# -c:编译
mymath.o:mymath.cgcc -c mymath.c -o mymath.o
​
# 动态库
liboutput.so:myprint_d.o mymath_d.ogcc -shared -o liboutput.so myprint_d.o mymath_d.omyprint_d.o:myprint.cgcc -fPIC -c myprint.c -o myprint_d.o# -c:编译# -fPIC:生成与位置无关的二进制文件
​
mymath_d.o:mymath.cgcc -fPIC -c mymath.c -o mymath_d.o
​
.PHONY:output
output:mkdir -p output/libmkdir -p output/includecp *.h output/includecp *.a output/libcp *.so output/lib
​
.PHONY:clean 
clean:rm -f *.o *.a *.so

现在我们的库就可以拿给别人去使用啦(还没有完哦)😉

库的使用

我们直接将刚刚制作的output文件夹给用户使用就好啦~~~

自己制作的库的使用有三种办法

  • 放进系统查找库函数的路径下(静态库)

  • 导入环境变量(动态库)

  • 放入/etc/ld.so.conf.d/的配置文件中

法一:放入系统路径

编译器编译时默认去以下路径查找文件

  • 头文件:/usr/include

  • 库文件:/lib64/usr/lib64

大家将自己的头文件和库文件分别放入这两个路径就好啦

脑子不好的小菜鸟就不演示啦,因为这样子有弊端哦~( ̄▽ ̄)~*

弊端

放在系统路径下的文件都是经过了长时间的检验的,其可靠性非常强,但是我们自己的头文件和库文件并没有经过检验,如果我们在后续长期使用中发现这个文件有问题,那将是非常非常麻烦的,有如下原因

  • 库函数不止一个人使用,因为通常是整个小组甚至是整个公司使用,如果这个库函数出了问题,则将影响公司

  • 时间久了,你也搞不清楚是哪个文件的问题,这就需要运维人员去查找日志信息,这花费时间和精力

法二:放入环境变量

要输入以下命令:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:该动态库的路径
  • 注意:(o゚v゚)ノ

    要的是路径不需要带上该动态库文件名 (´▽`ʃƪ)

弊端

xshell退出后这个环境变量中就没有我们加的路径,因为这是内存级环境变量,所以这种方法不适用于长期使用的库

法三:放入配置文件

这种方法是推荐的,Linux中有一个专门让我们放置配置文件的,/etc/ld.so.conf.d/这个路径是保存自定义配置搜索库路径的解决方案

步骤

  • 进入该目录下

    cd /etc/ld.so.conf.d/

  • 创建一个后缀为.conf的文件(需要sudo权限)

    sudo touch zi_ji_de_ku.conf

  • vim该文件(要sudo权限)

    sudo vim zi_ji_de_ku.conf

    将动态库的路径放入该文件中,保存退出

  • 退出后,ldconfig

    使得该配置文件生效

这样子我们就可以直接使用这个库啦

使用库的命令

gcc main.c -I 自己的库的头文件的路径 -L 自己的库的库文件路径 -l库文件名

命令解析

  • -I:表示包含头文件

  • -L:表示链接库

    注意

    • 后面跟的都是路径,路径是不带文件名的,实在搞不清楚,可以先进入lib文件夹下,再用pwd命令显示路径😉( •̀ ω •́ )

  • -l库文件名

    注意

    • 库文件名,去掉了库中的lib前缀和.a或者.so后缀    -------   再次敲重点(●ˇ∀ˇ●)

将之前的文件进行演示:

  • 输入gcc main.c -I ./output/include -L ./output/lib -loutput -o main

    • 注意这里的-I-L后面都是路径哦,路径是不带文件名的哦~

    • -l后面是库文件名哦,并不是图片中的liboutput.so去掉了lib前缀和.so后缀哦

  • 这样就会生成main这个可执行程序啦

完结撒花~~~~ ♪(^∇^*) ヾ(≧ ▽ ≦)ゝ你太棒啦~~~~,给你大大的赞    d=====( ̄▽ ̄*)b

记得点个关注和收藏哦

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

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

相关文章

半导体芯片结构以及译码驱动

一.半导体芯片结构 可能并不是只有一个芯片,有多个芯片就需要片选线了。 二.半导体存储芯片的译码驱动 主要有两种方式:线选法和重合法 线选法:每一个存储单元都用一根字选择线选中,直接选中存储单元的各位。(一维…

《人生海海》读后感

麦家是写谍战的高手,《暗算》《风声》等等作品被搬上荧屏后,掀起了一阵一阵的收视狂潮。麦家声名远扬我自然是知道的,然而我对谍战似乎总是提不起兴趣,因此从来没有拜读过他的作品。这几天无聊时在网上找找看看,发现了…

C++11完美转发(引用折叠、万能引用)

完美转发是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。 函数模板在向其他函数传递自身形参时,如果相应实参是左值,它就应该被转发为左值;如果相 应实参是右值,它…

大数据入门实践一:mac安装Hadoop,Hbase,FLume

一、安装Hadoop 安装hadoop参考此文,关键点是安装JDK和Hadoop的配置,为避免引用文章变收费,我把关键信息摘录如下: jdk安装和配置就不说了(我本机安装了1.8/15/17/21,以17为主),hadoop安装过程…

技巧解析,如何向Kimi提问才能写出更好的论文?

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 今天为大家整理、分享的Kimi提问技巧,将对论文写作的各个阶段提供帮助,可以以此来辅助学术论文撰写。 在此之前,先为大家科普一个概念——信息熵&am…

Python学习笔记11:入门终结篇

前言 入门知识到这里基本结束了,这里主要讲一下input和range。这两个讲完,讲讲后面进阶学些啥。 range函数 之前将循环的时候讲过一点,这个函数是Python内置的函数,主要用来生成一系列数字,简单方便。 这里重新&…

非连续分配管理方式(重点)

目录 一. 基本分页存储管理1.1 什么是分页存储1.2 页表 二. 基本地址变换机构三. 具有快表的地址变换机构3.1 什么是快表3.2 引入快表后, 地址的变换过程3.3 局部性原理 四. 两级页表4.1 单级页表存在什么问题?如何解决?4.2 两级页表的原理、逻辑地址结构4.3 如何实现地址变换…

Windows11安装并使用Gstreamer-1.0

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、下载二、使用步骤1.安装2.命令行测试 总结 前言 Gstreamer这个工具的重要性就不用多说了吧,在一些视频播放和解码领域大放异彩。以前更多的是在…

Python | 中心极限定理介绍及实现

统计学是数据科学项目的重要组成部分。每当我们想从数据集的样本中对数据集的总体进行任何推断,从数据集中收集信息,或者对数据集的参数进行任何假设时,我们都会使用统计工具。 中心极限定理 定义:中心极限定理,通俗…

C | 在ubuntu22下开发的一些配置

目录 VScode设置 要下载的插件: 卸载VScode的话就是哪装的哪删。 浅用gcc 预处理指令 使用gcc 语言编译过程 1. 预处理(Preprocessing) 2. 编译(Compilation) 3. 汇编(Assembly) 4. …

基于Itô扩散过程的交易策略偏微分方程matlab求解与仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于It扩散过程的交易策略偏微分方程,提出了一种确定It扩散过程。通过根据的第一次通过时间来确定问题在这个过程中,我们推导出交易长度的分布函数和密…

树状数组练习

先看一下最后一题&#xff0c;这是一个树状数组的题目&#xff0c;那就水一下吧,但是由于没有注意问题&#xff0c;wa了很多次 const int N (int)1e5 5; int n; int flag[N]; int dp[N]; class Solution { public:vector<int> countOfPeaks(vector<int>& num…

趣味C语言——【猜数字】小游戏

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 感谢 目录 代码…

重生之 SpringBoot3 入门保姆级学习(20、场景整合 Docker 的 Redis 对接与基础使用)

重生之 SpringBoot3 入门保姆级学习&#xff08;20、场景整合 Docker 的 Redis 对接与基础使用&#xff09; 6.3 整合 Redis 6.3 整合 Redis 1、创建新项目编写 application.properties 配置文件 # redis 配置 spring.data.redis.host192.168.1.4 spring.data.redis.port6379如…

SVM-SMO算法

SMO算法思想 上面这个优化式子比较复杂&#xff0c;里面有m个变量组成的向量α&#x1d6fc;需要在目标函数极小化的时候求出。直接优化时很难的。SMO算法则采用了一种启发式的方法。它每次只优化两个变量&#xff0c;将其他的变量都视为常数。由于 ∑ i 1 m α i y i 0 \su…

DataWhale - 吃瓜教程学习笔记(一)

学习视频&#xff1a;第1章-绪论_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 第一章 机器学习三观 What&#xff1a;什么是机器学习&#xff1f; 关键词&#xff1a;“学习算法” Why: 为什么要学机器学习&#xff1f; #### 1. 机器学习理论研究#### 2. 机器学习系统开…

C语言实现动态栈

#include<stdio.h> #include<stdlib.h> #include<stdbool.h>// 每一个节点的数据类型 typedef struct Node {int data;struct Node * pNext; }NODE, * PNODE; // NODE等价 struct Node PNODE等价于 struct Node *// 栈 typedef struct Stack {PNODE pTop;P…

【数据库编程-SQLite3(一)】sqlite3数据库在Windows下的配置及测试

学习分析 1、资源准备2、环境配置2.1、将资源包下载解压缩保存。2.2、在QT中创建工程,配置环境 3、测试配置3.1、 sqlite3_open函数3.2、sqlite3_close函数3.3、代码测试 1、资源准备 资源包 2、环境配置 2.1、将资源包下载解压缩保存。 解压缩得到以下文件 2.2、在QT中创建…

力扣每日一题 6/13 反悔贪心算法

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;IT竞赛 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 2813.子序列最大优雅度【困难】 题目&#xff1a; 给你一个长度为 n 的二…

上海2024年二手房最新成交历史数据

标签: 上海2024年二手房最新成交历史数据; 二手房; 时间: 2024年 上海市4月二手房网签套数:18230套 上海市5月二手房网签套数:19396套 上海市6月二手房网签套数: 6月1日:924套 6月2日:886套 6月3日:720套 6月4日:750套 6月5日:823套 6月6日:902套 6月7日:968套…