库的制作 与 使用 (Linux下)

news2024/12/30 2:49:54

目录

动静态库的制作

前置知识

库的基本构造

问题

分析

要给什么文件

如何更好的让别人使用

库的生成

静态库的生成

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:creat
    
myprint.o:myprint.c
    gcc -c myprint.c -o myprint.o
    # -c:编译
mymath.o:mymath.c
    gcc -c mymath.c -o mymath.o
​
.PHONY:output
output:
    mkdir -p output/lib
    mkdir -p output/include
    cp *.h output/include
    cp *.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.c
        gcc -fPIC -c myprint.c -o myprint_d.o
        # -c:编译
        # -fPIC:生成与位置无关的二进制文件
    ​
    mymath_d.o:mymath.c
        gcc -fPIC -c mymath.c -o mymath_d.o
    • 打包.o文件为.so文件

    liboutput.so:myprint_d.o mymath_d.o
        gcc -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:creat
    
myprint.o:myprint.c
    gcc -c myprint.c -o myprint.o
    # -c:编译
mymath.o:mymath.c
    gcc -c mymath.c -o mymath.o
​
# 动态库
liboutput.so:myprint_d.o mymath_d.o
    gcc -shared -o liboutput.so myprint_d.o mymath_d.o
    
myprint_d.o:myprint.c
    gcc -fPIC -c myprint.c -o myprint_d.o
    # -c:编译
    # -fPIC:生成与位置无关的二进制文件
​
mymath_d.o:mymath.c
    gcc -fPIC -c mymath.c -o mymath_d.o
​
.PHONY:output
output:
    mkdir -p output/lib
    mkdir -p output/include
    cp *.h output/include
    cp *.a output/lib
    cp *.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.coloradmin.cn/o/1828799.html

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

相关文章

【MATLAB】语法

MATLAB 基本语法(%{和%}) 赋值 函数名值&#xff1b;for for i1:10循环语句 end//while x0; sum0; while x<100sumsumx;x; end//if if x > 1f x^2 1; elsef 2 * x endswitch onum input(请输入一个数); switch num case -1 //注意case后面没有冒号disp(I am…

[Linux] TCP协议介绍(3): TCP协议的“四次挥手“过程、状态分析...

TCP协议是面向连接的 上一篇文章简单分析了TCP通信非常重要的建立连接的"三次握手"的过程 本篇文章来分析TCP通信中同样非常重要的断开连接的"四次挥手"的过程 TCP的"四次挥手" TCP协议建立连接 需要"三次握手". "三次挥手&q…

英伟达开源最强通用模型Nemotron-4 340B

英伟达的通用大模型 Nemotron&#xff0c;开源了最新的 3400 亿参数版本。 本周五&#xff0c;英伟达宣布推出 Nemotron-4 340B。它包含一系列开放模型&#xff0c;开发人员可以使用这些模型生成合成数据&#xff0c;用于训练大语言模型&#xff08;LLM&#xff09;&#xff0…

【CICID】GitHub-Actions语法

[TOC] 【CICID】GitHub-Actions语法 1 场景 ​ 当我们开发过程中&#xff0c;经常需要提交代码&#xff0c;打包&#xff0c;部署新代码到对应的环境&#xff0c;整个过程都是人工手动操作&#xff0c;占据开发人员大量时间&#xff0c;并且很繁琐容易出错。所以需要借助一些…

奥特曼谈AI的机遇、挑战与人类自我反思:中国将拥有独特的大语言模型

奥特曼在对话中特别提到&#xff0c;中国将在这个领域扮演重要角色&#xff0c;孕育出具有本土特色的大语言模型。这一预见不仅彰显了中国在全球人工智能领域中日益增长的影响力&#xff0c;也预示着未来技术发展的多元化趋势。 ①奥特曼认为AI在提升生产力方面已显现积极作用&…

蔡崇信“预言”:微软与OpenAI未来极有可能会分道扬镳

近日&#xff0c;在美国投行摩根大通于上海举行的第二十届全球中国峰会上&#xff0c;阿里巴巴集团联合创始人、董事局主席蔡崇信与摩根大通北亚区董事长兼大中华区投资银行业务副主席关金星&#xff08;Kam Shing Kwang&#xff09;进行了一场精彩对话。蔡崇信深入分享了他对公…

【LVGL】Guider 界面分析

文章目录 前言架构创建 UI切换界面空间释放分析创建页面空间变化 前言 分析Gui Guider-1.7.2-GA 生成的 LVGL 界面切换&#xff0c;资源管理等处理 架构 所有控件存放于同一个结构体 lv_ui 内&#xff0c;每个页面都至少包含 screen_xxx 和 screen_xxx_del 两个成员 typede…

C语言:文件系统

一、目录和文件 在当前目录下使用touch 创建一个名为 -a的文件: touch -a ; // 错误&#xff0c; touch -- -a//正确 touch ./-a 正确 ls -n可以看到对象的用户id&#xff0c;可以在/etc/passwd中查看&#xff0c;/etc/group可以看到组号 获取文件属性 #include <sys/ty…

苹果加大AI布局,上海新店开业昭示中国市场新动向

随着全球科技巨头纷纷进军人工智能领域&#xff0c;苹果公司亦不甘示弱&#xff0c;近期在上海静安新店的开业以及CEO蒂姆库克的一系列动作&#xff0c;都显示出苹果在AI方面的雄心壮志。这不仅是对未来技术趋势的积极回应&#xff0c;更是对市场竞争态势的精准把握。 库克的访…

Gone框架介绍26 - Gone v1.x 版本 正式发布,更加强大的依赖注入,更加卓越的执行效率

gone是可以高效开发Web服务的Golang依赖注入框架 github地址&#xff1a;https://github.com/gone-io/gone 文档地址&#xff1a;https://goner.fun/zh/ 文章目录 优化和新特性gone 核心功能增强内置Goners覆盖测试 后续计划 优化和新特性 gone 核心功能增强 重构了函数参数依…

Qt项目天气预报(1) - ui界面搭建

ui中部 效果演示 ui效果 显示效果 控件列表 配合右图查看 居中对齐-label 设置label居中对齐(别傻傻的空格对齐了) 间距配置 widget03 外围的widget对象: 包含label 和 widget0301&#xff0c;如下图 widget0301 内围的widget对象&#xff0c;如下图 样式表 widget03 …

Java与数据库连接技术JDBC关键核心之PreparedStatement以及SQL注入演示解决和原理

PreparedStatement SQL注入 执行预编译的SQL对象 这样也能登录成功 模拟 SQL注入是这个原因 现在基本上不存在SQL注入的问题 解决 SQL注入就是传一些语句导致原来的SQL语句改变了 修改代码 通过设置参数的方式 就能防止SQL注入 实际上我们进行了一个转化 将字符和关键字进…

【归并排序】| 详解归并排序核心代码之合并两个有序数组 力扣88

&#x1f397;️ 主页&#xff1a;小夜时雨 &#x1f397;️专栏&#xff1a;动态规划 &#x1f397;️如何活着&#xff0c;是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/merge-sorted-array/description/ 本道题是归并排序的…

Python学习打卡:day07

day7 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day753、列表的常用操作课后练习题54、列表的循环遍历列表的遍历—— while 循环列表的遍历—— for 循环while 循环和 for 循环的对比练习 55、元组…

回归预测 | Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限…

Kotlin 协程真的轻量吗?

前言 在官方文档的介绍中,提到了: 协程是轻量的 并给出了一个例子: fun main() = runBlocking {repeat(50_000) {// 启动大量的协程launch {delay

模型算法—线性回归

线性回归是统计学中最常见的一种回归分析方法&#xff0c;用于建立自变量&#xff08;解释变量&#xff09;和因变量&#xff08;响应变量&#xff09;之间的线性关系。线性回归模型可以用来预测一个或多个自变量对应的因变量的值。 线性回归的基本形式如下&#xff1a; &…

【麒麟虚拟机】NetworkManager没有运行

麒麟V10 建linux麒麟虚拟机&#xff0c;发现&#xff0c;网络没有配置 提示&#xff0c;NetworkManager没有运行。编辑联接也不能配置 解决方法&#xff0c;在终端输入命令&#xff1a; sudo systemctl start NetworkManager 启动以后&#xff0c;编辑连接选自动以太网&…

从 Linux 逻辑地址 线性地址 物理地址 内存管理设计,感受Linux kernel 设计的精妙

1&#xff0c;机器解析的思路 发现网络上大量的教程&#xff0c;多是以讹传讹地讲解 Linux 内存管理&#xff1b; 都是在讲&#xff1a; 逻辑地址 -> 线性地址 -> 物理地址 如果谙熟 Linux 制定的GPT和编译原理或对二进制分析比较熟练的话&#xff0c;会发现线性地…

[AIGC] Python的Range函数

Python的range()函数是一个内置函数&#xff0c;常常用于编程中生成数列。这个函数可以生成一个整数序列&#xff0c;这个序列通常用在循环中。 文章目录 基本用法详细用法注意事项 基本用法 range()函数的基本形式为 range(stop) —— 这将生成一个从0开始&#xff0c;到stop…