【Linux系统化学习】动静态库 | 软硬链接

目录

硬链接和软链接

硬链接

软链接 

动态库和静态库

静态库

静态库的生成

静态库的使用

将库打包和使用

动态库

动态库的生成

动态库的使用 

库搜索路径


硬链接和软链接

硬链接

上篇文章我们说到真正找到磁盘上的文件并不是文件名,而是inode。其实在Linux中可以让多个文件名对应同一个inode,这样的方式就是硬链接

指令:ln 

总结: 

  • 硬链接不是一个独立的文件 ,就是在指定目录内部的一组映射关系。相当于引用计数;当没有文件名和inode映射时表示该文件被真正的删除。

  • 硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。

注:硬链接只可以链接文件不可以链接目录;因为引入了对目录的硬连接就有可能在目录中引入循环,在目录遍历的时候系统就会陷入无限循环当中,这样导致无法定位到访问目录。但是我们的Linux系统可以硬链接目录;每个目录文件中含有两个隐藏文件,分别为当前目录和上级目录,当前目录隐藏文件就和当前目录硬链接。

软链接 

硬链接是通过inode引用另外一个文件,软链接是通过名字引用另外一个文件。

指令:ln -s

总结:

软连接是一个独立的文件,有独立的inode;软连接内容时指向目标文件的路径,类似于Windows的快捷方式


动态库和静态库

在之前的文章中我们提到过系统库,当时只是简单的讲解了下静态库和动态库的优缺点;这篇文章我们要从一个库的制作者和使用者来详细介绍第三方库的制作和使用。

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚
  • 拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

静态库

我们以一个库的制作者的角度自己编写一个可以实现整数加减的库;就是将实现整数加减的两个函数声明和定义分开,声明放在头文件中,实现放在源文件中。

头文件

  1 #pragma once 2 #include<stdio.h>                                                        3 extern int Add(int,int);
 1 #pragma once 2 #include<stdio.h>                                                        3 extern int Sub(int,int);

源文件 

  1 #include"Add.h"2 int Add(int x,int y)3 {4     return x+y;                                                          5 }
  1 #include"Sub.h"2 int Sub(int x,int y)3 {4     return x-y;                                                          5 }

当我们以库的制作者的身份将库写好后;我们就以普通程序员的身份使用这个库编写简单的程序。

  1 #include"Add.h"2 #include"Sub.h"3 int main()4 {5     int x =10;6     int y=20;7     printf("%d + %d = %d\n",x,y,Add(x,y));8     printf("%d - %d = %d\n",x,y,Sub(x,y));                               9     return 0;10 }

第一种使用方法就是将我们自己编写的源代码和库的源代码一起编译链接形成一个可执行程序即可。

但是这种使用方法我们要拿到库的源代码;再将库的每个源代码和我们的源代码一起预处理、编译、链接形成可执行程序。对于我们这种小库可能没什么影响,对于一些大的库源文件很多,每个源文件都进行这三部操作的话,很是浪费时间。

静态库的生成

对于上面的问题我们可以很好的解决;不是库的源文件浪费时间么,同时作为库的制作者我们也不想将我们的源代码公开,那我们可以将我们的库先编译成为二进制文件(.O)文件,将二进制文件和库使用者的二进制文件进行连接即可形成可执行程序

  makefile1 test:Add.o Sub.o testmain.o2     gcc -o $@ $^3 %.o:%.c4     gcc -c $<  

但是当我们库很大源文件很多时,形成的二进制文件也特别多;要是我们给库使用者二进制文件少给一个呢?

当我们想要这个库时候是不是只需要将我们的源文件编译成.o文件和库文件进行链接即可。因此我们可以将库的源文件编译成.o文件打包交给程序员即可。

    makefile    static-lib=libmymath.a2 $(static-lib):Add.o Sub.o3     ar -rc $@ $^                                                         6 %.o:%.c7     gcc -c $<8 .PHONY:clean9 clean:10     rm -rf *.o test

指令:ar -rc libmymath.a add.o sub.o
ar是gnu归档工具,rc表示(replace and create)

当我们库的源文件很多时,我们可以使用makefile,将我们的源代码自动生成二进制文件,再将我们的二进制文件全部形成我们的静态库。这里我们库的源文件很少,我就直接给大家手动生成。

通过上面的操作我们就可以将库的源文件生成二进制文件,进行生成静态库。

静态库的使用

将生成好的二进制文件和头文件拷贝到,我们的使用者编写的源代码下就可以使用库了。但是我们在使用静态库时还有很多小细节要注意。

将静态库和我们的源文件进行链接时首先要表用链接库的名称,和静态库的路径。其中库的名称是去掉后缀(.a)和lib。

  • -l 静态库的名称   代表我们链接哪一个静态库
  • -L 路径    代表所要链接静态库的所在路径

将库打包和使用

上面只是进行了二进制文件的打包当我们库源文件很多时,头文件也很多;因此我们可以将头文件和二进制文件分开存储在一个目录中打包交给使用的程序员。这里我们就不打包了,我们只将其放在同一个目录中使用。

    static-lib=libmymath.a2 $(static-lib):Add.o Sub.o3     ar -rc $@ $^6 %.o:%.c7     gcc -c $<8 .PHONY:output9 output:10     mkdir -p mymath_lib/include11     mkdir -p mymath_lib/lib 12     cp -f *.h mymath_lib/include13     cp -f *.a mymath_lib/lib14 .PHONY:clean15 clean:16     rm -rf *.o test mymath_lib

但是打包好的头文件和二进制文件在统一目录下,而我们的源文件并不在统一目录下,因此我们在使用的时候还要加上一些选项。

注:头文件的查找在当前目录下或者指定目录下查找,因此我们加上头文件的路径。

-I 头文件路径

 

动态库

动态库的生成

动态库也是将所有的的源文件形成二进制文件文件生成的;但是和动态库的生成方式和使用方式略有差异。 

注意:动态库的生成是使用gcc编译器来完成的,因此比较重要

makefile1 dy-lib=libmymath.so 2 $(dy-lib):Add.o Sub.o3     gcc -shared -o $@ $^4 %.o:%.c5     gcc -fPIC -c $<6 .PHONY:output7 output:8     mkdir -p mymath_lib/include9     mkdir -p mymath_lib/lib 10     cp -f *.h mymath_lib/include11     cp -f *.a mymath_lib/lib12 .PHONY:clean13 clean:14     rm -rf *.o *.so mymath_lib                                
~                                   

  • shared: 表示生成共享库格式
  • fPIC:产生位置无关码(position independent code)
  • 库名规则:libxxx.so

有了上面静态库的生成,静态库的生成我们就不过多赘述,只是生成动态库执行的选项不一样而已。

动态库的使用 

动态库的使用也是有很多的小细节,使用不当也会产生找不到动态库或者找不到头文件的问题。 

就像下面我们直接使用使用静态库的方法使用动态库,系统还是找不到我们的库在哪里。 

 

原因:

静态库是直接和我们的可执行程序链接在一起的,在连接的时候告诉我们的编译器我们库的路径编译器就可以找到。但是对于动态库不是链接在可执行程序中,可执行程序和库必须都加载到内存中,我们告诉了gcc编译器我们的库在哪里,但是操作系统要将我们的库加载到内存中,操作系统却不知道我们的库在哪里,系统默认找不到。因此我们要解决系统找不到我们库的问题。

库搜索路径

方法一:将头文件和库文件安装到系统中 

  • /usr/include
  • /lib64

在我们这两个系统路径下分别存放着库的头文件和二进制文件,我们可以将我们的二进制文件和头文件分别拷贝到上面的系统路径下即可。

方法二:建立一个软链接

在生成可执行程序的目录下建立一个库的软链接即可。

方法三:修改环境变量

LD_LIBRARY_PATH

执行我们的可执行程序系统不仅会在指定的路径下寻找我们的动态库,还会在一个环境变量中寻找。Linux中存在这样一个环境变量记录着动态库的存储路径。我们可以将我们的动态库添加到这一环境变量中即可。

注意

当我们退出我们的云服务器,重新登录后添加的环境变量就将会重置。 

方法四:更改配置文件

Linux下含有一个文件夹其中包含有关动态库加载的配置文件,里面只含有一个路径。我们可以在其目录下创建一个相同格式的空白文件,再将我们库的路径填入其中保存即可。


今天对Linux下动静态库的分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法;个人主页还有很多精彩的内容。您三连的支持就是我前进的动力,感谢大家的支持!!!  

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

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

相关文章

Day 6.文件属性和权限的获取

时间获取 1.time time_t time(time_t *tloc); 功能&#xff1a; 返回1907-1-1到现在的秒数&#xff08;格林威治时间&#xff09; 参数&#xff1a; tloc&#xff1a;存放秒数空间的首地址 返回值&#xff1a; 成功返回秒数 失败返回-1 2.localtime struct tm *loca…

Python入门:常用模块—logging模块

logging日志的分级&#xff1a; debug(),info(),warning(),error(),critical() 5个级别 最简单用法 1 2 3 4 import logging logging.warning("user [mike] attempted wrong password more than 3 times") logging.critical("server is down") 输出&…

普中51单片机学习(二)

51单片机介绍 所需基础知识 基础数模电知识&#xff0c;简单的C语言。 PS&#xff1a;如果有不懂的直接通义千问。。。 什么是单片机 在一片集成电路芯片上集成微处理器、存储器、I/O接口电路&#xff0c;从而构成了单芯片微型计算机&#xff0c;即单片机。 学习方法 多实…

Sqoop 入门基础

简介 Sqoop&#xff08;SQL to Hadoop&#xff09;是一个开源工具&#xff0c;用于在关系型数据库和Hadoop之间传输数据。它提供了一种快速高效的方式&#xff0c;将数据从关系型数据库导入到Hadoop集群进行分析&#xff0c;并支持将Hadoop集群中的数据导出到关系型数据库中。本…

智慧社区管理系统:构建未来的生活模式

在这个信息化、智能化的时代&#xff0c;我们期待的不再是简单的居住空间&#xff0c;而是一个集安全、便捷、舒适、环保于一体的智能化社区。为此&#xff0c;我们推出了全新的智慧社区管理系统&#xff0c;旨在将先进的科技力量引入社区管理&#xff0c;为居民提供更优质的生…

OpenProject + Rocky8安装

文章目录 1、概要2、整体架构流程3、准备4、安装5、openproject 配置5.1、第一步&#xff1a;OpenProject 版本选择5.2、第二步&#xff1a;PostgreSQL 支持5.3、第三步&#xff1a;Apache2 Web 服务器支持5.4、第四步&#xff1a;hostname 支持5.5、 第五步&#xff1a;服务器…

【Docker】Docker存储卷

文章目录 一、什么是存储卷二、为什么需要存储卷三、存储卷分类四、管理卷Volume创建卷方式一&#xff1a;Volume 命令操作方式二&#xff1a;-v 或者--mount 指定方式三&#xff1a;Dockerfile 匿名卷 操作案例Docker 命令创建管理卷Docker -v 创建管理卷Docker mount 创建管理…

unity学习(32)——跳转到角色选择界面(父子类问题)

新问题 应该是两个脚本之间缺少继承关系 its children 解决起来很简单&#xff0c;把ResceneScript也绑到canvas上就可以了 。 此时&#xff0c;在账号密码正确的情况下&#xff0c;是可以完成场景切换。 对应的代码如下&#xff1a; TMP_Text d GameObject.FindWithTag(&…

接口测试(postman/jmeter)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是接口测试 通常做的接口测试指的是系统对外的接口&am…

Window部署Nacos

Nacos 现在压缩包解压后&#xff0c;修改conf/application.properties 文件 取消注释&#xff0c;修改mysql连接方式 节点nacos.core.auth.enabled 改成true 设置节点nacos.core.auth.server.identity.key、nacos.core.auth.server.identity.value 设置secret秘钥&#xff0c;…

十大常见web漏洞及防范

十大常见web漏洞 一、SQL注入漏洞 SQL注入攻击&#xff08;SQL Injection&#xff09;&#xff0c;简称注入攻击、SQL注入&#xff0c;被广泛用于非法获取网站控制权&#xff0c;是发生在应用程序的数据库层上的安全漏洞。在设计程序&#xff0c;忽略了对输入字符串中夹带的S…

javascript选择器大全

目录 1.getElementsByTagName 2.getElementsByName 3.getElementById 4.getElementsByClassName 5.querySelector 6.querySelectorAll 1.getElementsByTagName 俗称标签选择器&#xff0c;可以根据标签名查找匹配到页面的元素对象&#xff0c;返回为一个数组。 <div&…

如何使用静态住宅ip代理进行Facebook群控?

在进行Facebook群控时&#xff0c;ip地址的管理是非常重要的&#xff0c;因为Facebook通常会检测ip地址的使用情况&#xff0c;如果发现有异常的使用行为&#xff0c;比如从同一个ip地址频繁进行登录、发布内容或者在短时间内进行大量的活动等等&#xff0c;就会视为垃圾邮件或…

springcloud-远程调用

微服务的远程调用 RestTemplate 在项目中&#xff0c;当我们需要远程调用一个 HTTP 接口时&#xff0c;我们经常会用到 RestTemplate 这个类。这个类是 Spring 框架提供的一个工具类。 实例化RestTemplate 创建配置类&#xff0c;实例化RestTemplate Configuration public clas…

【递归】:原理、应用与案例解析 ,助你深入理解递归核心思想

递归 1.基础简介 递归在计算机科学中&#xff0c;递归是一种解决计算问题的方法&#xff0c;其中解决方案取决于同一类问题的更小子集 例如 递归遍历环形链表 基本情况&#xff08;Base Case&#xff09;&#xff1a;基本情况是递归函数中最简单的情况&#xff0c;它们通常是递…

揭示端侧大语言模型的无限潜力:多种量化模型,可以在个人电脑或者手机上安装部署使用,几行代码进行调研可以离线使用

揭示端侧大语言模型的无限潜力:多种量化模型,可以在个人电脑或者手机上安装部署使用,几行代码进行调研可以离线使用。 MiniCPM 是面壁智能与清华大学自然语言处理实验室共同开源的系列端侧大模型,主体语言模型 MiniCPM-2B 仅有 24亿(2.4B)的非词嵌入参数量, 总计2.7B参数…

频段划分学习射频知识的意义

一、射频电路设计与低频电路设计的不同点 随着频率提高&#xff0c;相应电磁波的波长与变得可与分立电路元件的尺寸相比拟时&#xff0c;电阻、电容和电感这些元件的电响应&#xff0c;将偏离他们的理想频率特性。以 WIFI 2.4G 频段为例&#xff0c;当频率为 2437MHz&#xff0…

Ubuntu安装wireguard服务端,windows连接

需求&#xff1a;想要随时随地远程到ubuntu电脑的内网中&#xff0c;ping通所有的内网ip&#xff0c;方便通过内网ip进行远程 一、ubuntu上安装配置wireguard服务 1&#xff0c;更新软件包并安装wireguard服务端软件 sudo apt update sudo apt install wireguard 2&#xff0…

Flutter学习1 - Android开发者快速上手

1、对应关系 概念对应关系 AndroidFlutter页面Activity和FragmentWidget视图ViewWidget页面跳转IntentNavigater网络库okHttphttp数据存储SharedPreference和SQLiteshared_preferences和sqflite 布局对应关系 AndroidFlutter布局文件xmlWidget线性布局LinearLayoutRow和Col…

在线图片生成工具:定制化占位图片的利器

title: 在线图片生成工具&#xff1a;定制化占位图片的利器 date: 2024/2/20 14:08:16 updated: 2024/2/20 14:08:16 tags: 占位图片网页布局样式展示性能测试响应式设计在线生成开发工具 在现代的网页设计和开发中&#xff0c;占位图片扮演着重要的角色。占位图片是指在开发过…