库的制作 与 使用 (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: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.mfbz.cn/a/714508.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android开发系列:高性能视图组件Surfaceview

一、Surfaceview概述 在Android应用开发领域,面对视频播放、游戏构建及相机实时预览等高性能需求场景,直接操控图像数据并即时展示于屏幕成为必要条件。传统View组件在此类情境下显现局限性: 性能瓶颈:传统View的绘制任务由UI主…

如何充分利用 Postgres 的内存设置

为了充分利用 PostgreSQL 的内存设置,你需要调整多个参数以优化数据库性能。这些参数包括共享缓冲区(shared_buffers)、工作内存(work_mem)、维护工作内存(maintenance_work_mem)、有效缓存大小…

命令词:引导行动的语言工具

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

《全职猎人》

《全职猎人》 [1-2]是日本漫画家富坚义博的作品。 1999年版改编电视动画由日本动画公司负责动画制作,于1999年10月16日-2001年3月30日在富士电视台播出,该动画的故事至贪婪之岛篇章结束,全92话。 该作在富坚义博老师天马行空的想…

markupsafe,一个神奇的 Python 库!

更多Python学习内容:ipengtao.com 大家好,今天为大家分享一个神奇的 Python 库 - markupsafe。 Github地址:https://github.com/pallets/markupsafe 在 Web 开发和模版渲染中,处理用户输入的数据时,防止 HTML 注入是至…

【Java】Object、Objects、包装类、StringBuilder、StringJoiner

目录 1.API2.Object类3.Objects类4.包装类4.1包装类概述4.2包装类的其他常见操作 5.StringBuilder 可变字符串5.1概述5.2StringBuilder案例 6.StringJoiner 1.API API:应用程序编程接口,全称application programing interface,即Java已经写好…

3分钟带手把手带你了解 FL Studio v21.2.3.4004 中文免费版(附中文设置教程)安装指南

3分钟带手把手带你了解 FL Studio v21.2.3.4004 中文免费版(附中文设置教程)安装指南,大家我是兔八哥爱分享,今天你带来的安装FL Studio 21破解版,纯正简体中文支持! FL Studio 21 简称FL21,全称Fruity Loops Studio&a…

消息队列-Rabbit运行机制

Producer(生产者) 和 Consumer(消费者) Producer(生产者) :生产消息的一方(邮件投递者)Consumer(消费者) :消费消息的一方(邮件收件人) 消息一般由 2 部分组成:消息头(或者说是标签 Label)和 …

keystone认证服务

keystone认证服务 1、keystone管理用户 1-1、简介: 在OpenStack云计算平台中,Keystone是一个核心组件,主要用于提供统一的认证服务。其功能包括: 身份验证:Keystone负责验证用户的身份,通常通过用户名和…

记录一个flink跑kafka connector遇到的问题

【报错】 D:\Java\jdk1.8.0_231\bin\java.exe "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2022.2.3\lib\idea_rt.jar56647:D:\Program Files\JetBrains\IntelliJ IDEA 2022.2.3\bin" -Dfile.encodingUTF-8 -classpath D:\Java\jdk1.8.0_231\jre\lib\cha…

本学期嵌入式期末考试的综合项目,我是这么出题的

时间过得真快,临近期末,又到了老师出卷的时候。作为《嵌入式开发及应用》这门课的主讲教师,今年给学生出的题目有一点点难度,最后的综合项目要求如下所示,各位学生朋友和教师同行可以评论一下难度如何,单片…

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

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

[240615] X-CMD 发布 v0.3.11,增加对 elvish 的支持

目录 X-CMD 发布 v0.3.11,增加对 elvish 的支持,并优化对 nushell,fish,xonsh,tcsh 的支持✨ co 模块 - copilot✨ elv 模块✨ hub X-CMD 发布 v0.3.11,增加对 elvish 的支持,并优化对 nushell&…

Python合并文件(dat、mdf、mf4)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

LabVIEW与C#的区别及重新开发自动测试程序的可行性分析

LabVIEW和C#是两种广泛使用的编程语言,各自有不同的应用领域和特点。本文将详细比较LabVIEW与C#在自动测试程序开发中的区别,并分析将已完成的LabVIEW自动测试程序重新用C#开发的合理性。本文帮助评估这种转换的必要性和潜在影响。 LabVIEW与C#的区别 开…

怎么把三列数据相同的号码一起求和?

可以使用excel的合并计算功能。 一、合并计算 将三列求和的数字列标题改成相同的,示例中全改成B1,这个是使用合并计算的关键一步,不改列标题,计算结果会是分开的。 2. 然后选中任意空白单元格作为输入结果的起始位置,…

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

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

Java17 --- SpringSecurity之前后端分离处理

目录 一、实现前后端分离 1.1、导入pom依赖 1.2、认证成功处理 1.3、认证失败处理 1.4、用户注销处理 1.5、请求未认证处理 1.6、跨域处理 1.7、用户认证信息处理 1.8、会话并发处理 一、实现前后端分离 1.1、导入pom依赖 <dependency><groupId>co…

工程设计问题---多盘离合器制动器设计问题

这个问题的主要目的是使多片式离合器制动器的质量最小化。在这个问题中&#xff0c;使用了五个整数决策变量&#xff0c;它们是内半径&#xff08;x1&#xff09;、外半径&#xff08;x2&#xff09;、盘厚度&#xff08;x3&#xff09;、致动器的力&#xff08;x4&#xff09;…

QT属性系统,简单属性功能快速实现 QT属性的简单理解 属性学习如此简单 一文就能读懂QT属性 QT属性最简单的学习

4.4 属性系统 Qt 元对象系统最主要的功能是实现信号和槽机制&#xff0c;当然也有其他功能&#xff0c;就是支持属性系统。有些高级语言通过编译器的 __property 或者 [property] 等关键字实现属性系统&#xff0c;用于提供对成员变量的访问权限&#xff0c;Qt 则通过自己的元对…