【linux深入剖析】深入理解软硬链接 | 动静态库的制作以及使用


🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

在这里插入图片描述


目录

  • 1.理解软硬链接
    • 1.1 操作观察现象
      • 软链接
      • 硬链接
    • 1.2 软硬链接的原理
      • 测试硬链接
      • 测试软链接
    • 1.3 软硬链接的应用场景
      • 1.3.1软链接
      • 1.3.2 硬链接
  • 2.动静态库
    • 2.1 动静态库的制作和使用
      • 准备工作
      • 生成静态库
      • 生成动态库
    • 2.2 将自己的库打包给别人


1.理解软硬链接

软链接和硬链接是在Linux系统中常见的文件链接方式。

软链接(Symbolic Link): 软链接是一个指向目标文件或目录的特殊文件,类似于Windows系统中的快捷方式。软链接可以跨文件系统,可以链接到目录,也可以链接到文件。软链接的特点是:

  1. 软链接文件有自己的inode和文件名,但是数据块内容是指向目标文件的路径。
  2. 删除软链接不会影响目标文件。
  3. 软链接可以跨文件系统,即可以链接到不同的磁盘分区。

硬链接(Hard Link): 硬链接是指多个文件名指向同一个inode,它们共享同一份数据块内容。硬链接的特点是:

  1. 硬链接文件和目标文件具有相同的inode和数据块内容。
  2. 删除任意一个硬链接文件不会影响其他硬链接文件和目标文件。
  3. 硬链接只能链接到文件,不能链接到目录。
  4. 硬链接不能跨文件系统,即只能在同一个磁盘分区内创建。

1.1 操作观察现象


指令ln -s

ln -s是Linux系统中的一个命令,用于创建软链接(symbolic link)。软链接是一种特殊的文件,它指向另一个文件或目录。通过软链接,可以在不改变原始文件或目录位置的情况下,创建一个指向它的链接。

使用ln -s命令创建软链接的语法如下:

ln -s <原始文件或目录路径> <链接文件路径>

  • 其中,<原始文件或目录路径>是要创建链接的文件或目录的路径,<链接文件路径>是要创建的软链接的路径。
    例如,假设当前目录下有一个文件file.txt,我们可以使用以下命令创建一个指向它的软链接:
    ln -s file.txt link.txt
    这样就创建了一个名为link.txt的软链接,它指向file.txt文件。

需要注意的是,软链接是一个指向原始文件或目录的引用,而不是实际的文件或目录本身。删除软链接不会影响原始文件或目录,但删除原始文件或目录可能会导致软链接失效。


指令ll -li

ll -li是一个Linux命令,用于显示文件或目录的详细信息,并以inode号进行排序。下面是该命令的一些说明:

  • ll是 “ls -l” 的简写,用于显示文件和目录的详细信息。
  • -li是两个选项的组合,其中 -l表示以长格式显示文件信息,包括文件权限、所有者、大小、修改日期等;而 -i表示显示文件的inode号。

通过执行 ll -li 命令,您将看到当前目录下所有文件和目录的详细信息,并按照inode号进行排序。


软链接

在这里插入图片描述结论:软链接本质上就是一个文件,有独立的inode


指令ln

在Linux系统中创建文件硬链接,可以通过ln命令来创建硬链接。ln命令的语法如下:

ln [选项] <源文件或目录> <目标文件或目录>

其中,源文件或目录是要创建链接的文件或目录的路径,目标文件或目录是要创建的链接的路径。

创建硬链接的命令格式为:

ln <源文件> <目标文件>

例如,要在当前目录下创建一个名为linkfile的硬链接,指向源文件sourcefile,可以使用以下命令:
ln sourcefile linkfile

注意,硬链接只能链接到同一个文件系统中的文件,且不能链接到目录。


硬链接

在这里插入图片描述

我们创建了硬链接之后可以发现。前面的文件信息发生了一个微小的变化,也就是文件权限后面的数字由1变成了2,而硬链接新出现的文件其初始数字就是2,这个数字从来没有讲述过

在这里插入图片描述

我们查看一下inode也可以发现,新出现的文件与旧文件inode竟然是一样的!

在这里插入图片描述
结论:硬链接本质不是一个独立的文件,因为它的inode编号和目标文件相同


1.2 软硬链接的原理

测试硬链接

  • 我们将硬链接的目标文件写入点数据
    在这里插入图片描述

可以看到我们修改目标文件的同时,硬链接生成的文件也会发生变化,其大小与目标文件同样是12,且修改时间相同,inode也没有改变

  • 我们删除目标文件
    在这里插入图片描述

可以看到,我们的硬链接产生的文件并没有什么变化,我们查看其文件数据可以清楚的看到,这个数据就是我们当初输入到目标文件的数据,这是什么情况?

其实也可以理解,其inode和目标文件是一摸一样的,也就是说他们对应的都是同一个文件,我们硬链接的工作特别像给目标文件进行一个重命名,并且源文件不改变。

硬链接的本质:一定没有新建文件,因为没有新的inode,只是新建了一个文件名,与目标文件inode相同的映射关系。


这个时候我们再看当初的这个2
在这里插入图片描述

其实这就是一个硬链接数,表明有多少个硬链接,表明了有多少个文件名与这一块数据有相同的映射关系,同时也叫引用计数

同时可以看到,硬链接就是建立了一个映射关系同时对引用计数++即可。

我们删掉文件后可以看到,引用计数从2变成了1
在这里插入图片描述


测试软链接

在这里插入图片描述
软链接创建的文件有独立的inode,有独立的inode那么就有独立的属性以及独立的数据内容。

软链接本质就是一个独立文件,软链接内容里面放的目标文件的路径!

软链接就相当于我们Windows里面的快捷方式,其存储的就是其可执行程序的路径

1.3 软硬链接的应用场景

1.3.1软链接

  • 我们创建一系列文件并输入内容给test.c

在这里插入图片描述

#include<stdio.h>
int main()
{printf("hello world\n");return 0;
}
  • 将文件编译,并把可执行文件移动到bin目录下

在这里插入图片描述

  • 我们想访问这个可执行文件就只能访问绝对路径访问

在这里插入图片描述

  • 我们还可以采用软链接的方式访问到这个可执行文件

在这里插入图片描述
我们就可以使用软链接的方式,在当前目录创建一个软链接的文件,这样就可以直接访问到深路径的文件,我们使用起来就更加方便


我们也可以采用硬链接的方式来达到访问深路径的文件
在这里插入图片描述

软链接使用起来还是更加方便一些,一般推荐软链接


系统有很多的软链接

ls -l /lib64/

在这里插入图片描述


1.3.2 硬链接

  • 我们创建一个普通文件以及一个目录
    在这里插入图片描述

可以发现普通文件的硬链接数是1,而目录一创建出来硬链接数就是2。

  • 我们进入empty目录下

在这里插入图片描述

我们可以看到empty目录下有隐藏的点文件,我们之前讲过,这个就是指的当前目录,它的inode与empty目录的inode是一模一样的,而它就是除了empty外另一个硬链接。

  • 我们进入empty目录下再创建一个a目录

在这里插入图片描述

这里可以看到我们的empty目录的硬链接数变成了3,这就是因为我们empty目录里的a目录里有一个自带的点点文件,这代表的是上级目录,它就是第三个empty目录的硬链接

由此得知:一个目录下有多少个子目录:硬链接数-2即可计算得到

注意:Linux中不允许给目录建立硬链接,但是可以建立软链接


2.动静态库

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库

  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码

  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)

  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。


我们是很经常使用库的,我们创建一个普通C文件,并编写简单代码

在这里插入图片描述

这里就是利用了C语言的库的,之前进行简单的讲解过,这是C语言的动态库

在这里插入图片描述


关于库我们有过一定的使用经验
库分为静态库以及动态库-----大部分的系统默认安装的是动态库,云服务器是静态库–(C标准库)默认是没有安装的
默认编译程序,用的是动态链接的,如果要静态要加-static

库的真实名字:lib. XXXX -a/so 去掉前缀以及后缀

2.1 动静态库的制作和使用

一般我们的程序执行会经历几个阶段

  1. a.h + a.c ---> a.o
  2. b.h + b.c ---> b.o
  3. c.h + c.c ---> c.o
  4. d.h + d.c ---> d.o
  5. 再结合libc.so/libc.a
  6. 最后main.c ------>main.o

库则是不提供.c文件

  1. a.h + a.o
  2. b.h + b.o
  3. c.h + c.o
  4. d.h + d.o

你只需要将main.c ------>main.o
注:这里的a、b、c、d只是概念文件

所谓的库就是将所有的.o文件用特定的方式,进行打包,形成一个文件

库的存在的意义:

  1. 提高开发效率
  2. 隐藏源代码

准备工作

在了解库的使用原理后我们来模拟实现一个

  1. 创建五个文件
    在这里插入图片描述
  2. 编写文件

add.c

#include "add.h"
int add(int a, int b)
{return a + b;
}

add.h

#ifndef __ADD_H__
#define __ADD_H__ 
int add(int a, int b); 
#endif // __ADD_H__

sub.h

#ifndef __SUB_H__
#define __SUB_H__ 
int sub(int a, int b); 
#endif // __SUB_H

sub.c

#include "add.h"
int sub(int a, int b)
{return a - b;
}

main.c

#include <stdio.h>
#include "add.h"
#include "sub.h"int main()
{int a = 10;int b = 20;printf("add(%d, %d)=%d\n", a, b, add(a, b));a = 100;b = 20;printf("sub(%d,%d)=%d\n", a, b, sub(a, b));
}

生成.o文件
在这里插入图片描述

生成静态库

指令ar -rc

ar -rc是一个用于创建或更新静态库的命令。它是GNU工具链中的一个工具,用于将一组目标文件打包成一个静态库文件。下面是ar -rc命令的一些常见用法:

  • 创建静态库:可以使用ar -rc命令将多个目标文件打包成一个静态库文件。例如,要将文件1.o、文件2.o和文件3.o打包成一个名为libexample.a的静态库,可以执行以下命令:

ar -rc libexample.a 1.o 2.o 3.o

  • 更新静态库:如果已经存在一个静态库文件,可以使用ar -rc命令向其中添加新的目标文件或替换已有的目标文件。例如,要向名为libexample.a的静态库中添加一个新的目标文件file.o,可以执行以下命令:

ar -rc libexample.a file.o

  • 替换静态库中的目标文件:如果要替换静态库中已有的目标文件,可以使用ar -rc命令指定相同的目标文件名。例如,要替换名为libexample.a的静态库中的目标文件file.o,可以执行以下命令:

ar -rc libexample.a file.o

  • 查看静态库内容:可以使用ar -t命令来查看静态库中包含的目标文件列表。例如,要查看名为libexample.a的静态库中包含的目标文件列表,可以执行以下命令:

ar -t libexample.a


输入指令ar -rc libmymath.a add.o sub.o生成静态库
查看静态库中的目录列表 ar -tv libmymath.a
t:列出静态库中的文件
v:verbose 详细信息

在这里插入图片描述
所以库的本质就是把一堆.o打包形成一个文件,然后通过头文件来调用库。注意,库中不能包含main函数。

编译一下,即可运行

gcc (要形成的可执行文件名) main.c(所依赖的文件) -L .(-L + 路径表示myc这个库在哪个路径下)-lmymath(指明要链接mymath这个静态库)

在这里插入图片描述


生成动态库

fPIC:产生位置无关码,在将.c或者.cpp形成.o文件时,需要加上-fPIC。要形成动态库必须加上-fPIC。
在这里插入图片描述

形成动态库不需要用到其它指令,gcc编译器就可以形成动态库,只不过要加上-shared命令。

gcc -shared -o libmymath.so(名字,真正的库名要去掉lib和.so)sub.o add.o (所依赖的.o文件)

在这里插入图片描述
直接使用我们的这个动态库,那么就同样要告诉编译器我们库的名字和所在的路径(参考上面静态库路径的写法)。

在这里插入图片描述

2.2 将自己的库打包给别人

假设在我当前目录下有libmymath.so动态库,add.h,sub.h两个头文件,如果我想将这三个文件一起交给别人,就可以把它们打包一起放在一个目录下,一起压缩完再交给别人。
在这里插入图片描述

Makefile

 1 libmymath.so:add.o sub.o2     gcc -shared -o $@ $^3 .o:.c4     gcc -shared -c $<5 #add.o:add.c6 #   gcc -c -fPIC $< -o $@7 #sub.o:sub.c8 #   gcc -c -fPIC $< -o $@9 .PHONY:clean10 clean:11   rm -f *.o libmymath.so12 13 .PHONY:output                                                                                                                                                                           14 output:15         mkdir -p ./user/mylib/16         mkdir -p ./user/Headfile/17         cp -rf libmymath.so ./user/mylib/18         cp -rf add.h sub.h ./user/Headfile/19         tar -czf user.tgz user

在这里插入图片描述

user目录是通过user.tgz解压得到的,下面是user目录下的文件:

在这里插入图片描述

将两个头文件拷贝到usr/include目录下(编译器默认会到include目录下去寻找头文件),将库文件拷贝到usr/lib目录下,编译时指定库链接,就能够运行了。
在这里插入图片描述

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

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

相关文章

pyqt和opencv结合01:读取图像、显示

在这里插入图片描述 1 、opencv读取图像用于pyqt显示 # image cv2.imread(file_path)image cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 将图像转换为 Qt 可接受的格式height, width, channel image.shapebytes_per_line 3 * widthq_image QImage(image.data, width, hei…

vue3 uniapp微信登录

根据最新的微信小程序官方的规定&#xff0c;uniapp中的uni.getUserInfo方法不再返回用户头像和昵称、以及手机号 首先&#xff0c;需获取appID&#xff0c;appSecret&#xff0c;如下图 先调用uni.getUserInfo方法获取code&#xff0c;然后调用后台的api&#xff0c;传入code&…

ssm049基于Vue.js的在线购物系统的设计与实现+vue

在线购物系统 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线购物系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线购物系统&#xff0c;它彻底改…

【氮化镓】GaN HEMTs结温和热阻测试方法

文章《Temperature rise detection in GaN high-electron-mobility transistors via gate-drain Schottky junction forward-conduction voltages》&#xff0c;由Xiujuan Huang, Chunsheng Guo, Qian Wen, Shiwei Feng, 和 Yamin Zhang撰写&#xff0c;发表在《Microelectroni…

Linux调试器之gdb

前言 我们前面介绍了几个基本的环境开发工具。例如通过yum我们可以安装和卸载软件、通过vim我们可以写代码、通过gcc和g我们可以编译代码成可执行程序。但是如何在Linux下调试代码呢&#xff1f;我们并未介绍&#xff0c;本期我们将来介绍最后一个工具 --- 调试器gdb。 本期内…

Tomcat服务器入门介及用postman工具简单接收数据 2024详解

Tomcat服务器 简介 Tomcat是一个开源的Servlet容器&#xff0c;也是一个支持Java Servlet和JSP技术的Web服务器。它由Apache软件基金会开发和维护。Tomcat的主要作用是将Java Servlet和JavaServer Pages&#xff08;JSP&#xff09;等动态网页技术部署到服务器上&#xff0c;…

基于Python豆瓣电影数据可视化分析系统的设计与实现

大数据可视化项目——基于Python豆瓣电影数据可视化分析系统的设计与实现 2024最新项目 项目介绍 本项目旨在通过对豆瓣电影数据进行综合分析与可视化展示&#xff0c;构建一个基于Python的大数据可视化系统。通过数据爬取收集、清洗、分析豆瓣电影数据&#xff0c;我们提供了…

13.多通道视频流缓存以及显示架构

1 简介 多通道视频流缓存以及显示架构是一个在数字图像处理中很基础也很重要的一个架构。在图像拼接以及高分辨率图像显示方面应用范围较为广泛。本文将介绍一个四通道的图像显示。可以四个图像信息输入以及拼接到一个显示屏里面。使用的开发板为A7 2 框架图 架构图如下图所示…

4/11 QT_day5

服务器端 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QMessageBox> #include <QTcpSocket> #include <QList> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass …

专题十三、预处理器

预处理器 1. 预处理器的工作原理2. 预处理指令3. 宏定义3.1 简单的宏3.2 带参数的宏3.3 # 运算符3.4 ## 运算符3.5 宏的通用属性3.6 宏定义中的圆括号3.7 创建较长的宏3.8 预定义宏3.9 C99 中新增的预定义宏3.10 空的宏参数3.11 参数个数可变的宏3.12 __func__ 标识符 4. 条件编…

SAP SD学习笔记06 - 受注的据否,受注的理由,简易变更(一括处理)

上文讲了一括处理和Block&#xff08;冻结&#xff09;处理。 SAP SD学习笔记05 - SD中的一括处理&#xff08;集中处理&#xff09;&#xff0c;出荷和请求的冻结&#xff08;替代实现承认功能&#xff09;-CSDN博客 本章继续讲SAP的流程中一些常用的操作。 1&#xff0c;受注…

IoC与Spring

目录 IoC控制反转 现实案例 特点 目的 DI依赖注入 小总结 介绍Spring 狭义和广义上的Spring 传统编码方式的不足 需求引入 弊端分析 IoC控制反转 现实案例 1、买水果问老板各种水果的口感而不是自己去挨个尝试一遍。 2、买房子找中介而不是自己去花时间找房东。…

.cur 鼠标光标编辑器

详解透明贴图和三元光栅操作 - CodeBus 鼠标指针文件格式解析——Windows&#xff08;二&#xff09; (qq.com) [C/C] RGBA数组生成Windows下的ico文件_c ico格式-CSDN博客 色环设计 - CodeBus 左键绘制 右键选颜色 ctrl右键设置鼠标热点 F1导出.cur文件 //代码来源&…

Unity类银河恶魔城学习记录12-14 p136 Merge Skill Tree with Sword skill源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili CharacterStats.cs using System.Collections; using System.Collections.…

代码随想录算法训练营第三十七天|738.单调递增的数字、968.监控二叉树

代码随想录算法训练营第三十七天|738.单调递增的数字、968.监控二叉树 738.单调递增的数字 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈…

Finetuning vs. Prompting:大语言模型两种使用方式

目录 前言1. 对于大型语言模型的两种不同期待2. Finetune(专才)3. Prompt(通才)3.1 In-context Learning3.2 Instruction-tuning3.3 Chain of Thought(COT) Prompting3.4 用机器来找Prompt 总结参考 前言 这里和大家分享下关于大语言模型的两种使用方式&#xff0c;一种是 Fine…

英语技术会议常用语

个人整理。 自我介绍&#xff1a; Hello everyone, Im [Your Name], and Im excited to be here today. I work as [Your Position] at [Your Company/Organization], where I focus on [Brief Description of Your Role or Expertise]. Im looking forward to our discussion…

数据库数据恢复—Sql Server数据库文件丢失如何恢复数据?

服务器数据恢复环境&#xff1a; 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5&#xff0c;划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检&#xff1a; 由于未知原因&#xf…

Android 13 aosp 预置三方应用apk

前提条件 编译启动 launch 选择了 sdk_pc_x86_64-userdebug 该版本 添加一个三方预置应用 Android_source/vendor/third_party/MdmLib/MdmLib.apk 配置三方应用对应的Android.mk Android_source/vendor/third_party/MdmLib/Android.mk LOCAL_PATH : $(call my-dir)include $(CL…

配置香橙派摄像头服务每次开机自动启动

目录 1.创建一个mjpg.sh脚本 2.在脚本中添加以下内容 3.增加可执行权限 4.在/etc/xdg/autostart/下创建mjpg.desktop 文件输入以下内容 1.创建一个mjpg.sh脚本 touch mjpg.sh 2.在脚本中添加以下内容 #!/bin/bash cd /home/orangepi/Myorangepi/zhinenglajitong/mjpg-stre…