
目录
1.理解软硬链接
软链接和硬链接是在Linux系统中常见的文件链接方式。
软链接(Symbolic Link): 软链接是一个指向目标文件或目录的特殊文件,类似于Windows系统中的快捷方式。软链接可以跨文件系统,可以链接到目录,也可以链接到文件。软链接的特点是:
- 软链接文件有自己的inode和文件名,但是数据块内容是指向目标文件的路径。
- 删除软链接不会影响目标文件。
- 软链接可以跨文件系统,即可以链接到不同的磁盘分区。
硬链接(Hard Link): 硬链接是指多个文件名指向同一个inode,它们共享同一份数据块内容。硬链接的特点是:
- 硬链接文件和目标文件具有相同的inode和数据块内容。
- 删除任意一个硬链接文件不会影响其他硬链接文件和目标文件。
- 硬链接只能链接到文件,不能链接到目录。
- 硬链接不能跨文件系统,即只能在同一个磁盘分区内创建。
1.1 操作观察现象
指令ln -s
使用ln -s命令创建软链接的语法如下:
- 其中,<原始文件或目录路径>是要创建链接的文件或目录的路径,<链接文件路径>是要创建的软链接的路径。
例如,假设当前目录下有一个文件file.txt,我们可以使用以下命令创建一个指向它的软链接:
ln -s file.txt link.txt
这样就创建了一个名为link.txt的软链接,它指向file.txt文件。
需要注意的是,软链接是一个指向原始文件或目录的引用,而不是实际的文件或目录本身。删除软链接不会影响原始文件或目录,但删除原始文件或目录可能会导致软链接失效。
指令ll -li
ll
是 “ls -l” 的简写,用于显示文件和目录的详细信息。-li
是两个选项的组合,其中-l
表示以长格式显示文件信息,包括文件权限、所有者、大小、修改日期等;而-i
表示显示文件的inode号。
通过执行 ll -li
命令,您将看到当前目录下所有文件和目录的详细信息,并按照inode号进行排序。
软链接
结论:软链接本质上就是一个文件,有独立的inode
指令ln
在Linux系统中创建文件硬链接,可以通过ln
命令来创建硬链接。ln
命令的语法如下:
其中,源文件或目录是要创建链接的文件或目录的路径,目标文件或目录是要创建的链接的路径。
创建硬链接的命令格式为:
例如,要在当前目录下创建一个名为linkfile的硬链接,指向源文件sourcefile,可以使用以下命令:
ln sourcefile linkfile
注意,硬链接只能链接到同一个文件系统中的文件,且不能链接到目录。
硬链接
结论:硬链接本质不是一个独立的文件,因为它的inode编号和目标文件相同
1.2 软硬链接的原理
测试硬链接
- 我们将硬链接的目标文件写入点数据
- 我们删除目标文件
其实也可以理解,其inode和目标文件是一摸一样的,也就是说他们对应的都是同一个文件,我们硬链接的工作特别像给目标文件进行一个重命名,并且源文件不改变。
硬链接的本质:一定没有新建文件,因为没有新的inode,只是新建了一个文件名,与目标文件inode相同的映射关系。
其实这就是一个硬链接数,表明有多少个硬链接,表明了有多少个文件名与这一块数据有相同的映射关系,同时也叫引用计数
同时可以看到,硬链接就是建立了一个映射关系同时对引用计数++即可。
我们删掉文件后可以看到,引用计数从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 硬链接
- 我们创建一个普通文件以及一个目录
- 我们进入empty目录下
- 我们进入empty目录下再创建一个a目录
由此得知:一个目录下有多少个子目录:硬链接数-2即可计算得到
注意:Linux中不允许给目录建立硬链接,但是可以建立软链接
2.动静态库
-
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
-
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
-
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
-
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
-
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
关于库我们有过一定的使用经验
库分为静态库以及动态库-----大部分的系统默认安装的是动态库,云服务器是静态库–(C标准库)默认是没有安装的
默认编译程序,用的是动态链接的,如果要静态要加-static
库的真实名字:lib. XXXX -a/so 去掉前缀以及后缀
2.1 动静态库的制作和使用
所谓的库就是将所有的.o
文件用特定的方式,进行打包,形成一个文件
库的存在的意义:
- 提高开发效率
- 隐藏源代码
准备工作
在了解库的使用原理后我们来模拟实现一个
- 创建五个文件
- 编写文件
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是一个用于创建或更新静态库的命令。它是GNU工具链中的一个工具,用于将一组目标文件打包成一个静态库文件。下面是ar -rc命令的一些常见用法:
- 创建静态库:可以使用ar -rc命令将多个目标文件打包成一个静态库文件。例如,要将文件1.o、文件2.o和文件3.o打包成一个名为libexample.a的静态库,可以执行以下命令:
- 更新静态库:如果已经存在一个静态库文件,可以使用ar -rc命令向其中添加新的目标文件或替换已有的目标文件。例如,要向名为libexample.a的静态库中添加一个新的目标文件file.o,可以执行以下命令:
- 替换静态库中的目标文件:如果要替换静态库中已有的目标文件,可以使用ar -rc命令指定相同的目标文件名。例如,要替换名为libexample.a的静态库中的目标文件file.o,可以执行以下命令:
- 查看静态库内容:可以使用ar -t命令来查看静态库中包含的目标文件列表。例如,要查看名为libexample.a的静态库中包含的目标文件列表,可以执行以下命令:
所以库的本质就是把一堆.o打包形成一个文件,然后通过头文件来调用库。注意,库中不能包含main函数。
编译一下,即可运行
生成动态库
形成动态库不需要用到其它指令,gcc编译器就可以形成动态库,只不过要加上-shared命令。
直接使用我们的这个动态库,那么就同样要告诉编译器我们库的名字和所在的路径(参考上面静态库路径的写法)。
2.2 将自己的库打包给别人
假设在我当前目录下有libmymath.so动态库,add.h,sub.h两个头文件,如果我想将这三个文件一起交给别人,就可以把它们打包一起放在一个目录下,一起压缩完再交给别人。
Makefile
1 libmymath.so:add.o sub.o
2 gcc -shared -o $@ $^
3 .o:.c
4 gcc -shared -c $<
5 #add.o:add.c
6 # gcc -c -fPIC $< -o $@
7 #sub.o:sub.c
8 # gcc -c -fPIC $< -o $@
9 .PHONY:clean
10 clean:
11 rm -f *.o libmymath.so
12
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