理解文件系统
系统中被打开的文件,OS都会创建它对应的struct_file的结构体对象来对其进行管理,再将多个struct_file的结构体对象用数据结构的方式将其链接起来进行管理(先描述,再组织的方式)。
那么,如果一个文件没有被打开,操作系统该如何对其进行管理呢?
- 没有被打开的文件,都被存储在磁盘上面。
- 磁盘上面有大量的文件,也是需要被静态管理起来的,方便我们随时打开(也就是说,当我们想要打开磁盘上面的文件,我们如何获取这个文件在磁盘上对应的路径呢!这就需要我们对其进行管理)
- 举一个简单的例子,我们购买的快递都在快递站,而每个快递都有其对应的编号,当我们取快递时,根据编号就可以准确的拿到相对应的快递,而磁盘中未被打开的文件是一样的道理。
磁盘的物理结构
a. 目前的电脑使用的基本都是固态硬盘,很少有使用磁盘
磁盘是计算机中唯一的一个机械结构,且硬盘属于外设。因此,磁盘的访问速度是非常慢的(相对于内存来说)。
b.企业端,磁盘存储依旧是主流(主要是由于磁盘低廉的价格,且存储空间大)
磁盘的存储结构
磁盘的逻辑结构
**思考:**为什么操作系统要进行逻辑抽象,直接使用CHS不可以吗?
- 首先,逻辑抽象便于我们管理磁盘
- 其次,不想让OS的代码和硬件强耦合。(也就是说如果存储结构不是磁盘,我们也可以用OS的LBA来进行管理, 而不是让OS和CHS地址直接关联,这样的话我们如果底层存储使用的不是磁盘,那么还需要创建对应的代码来进行管理,而如果是通过LBA进行转化成对应结构的地址,不论底层使用那种结构(磁盘、固态硬盘),OS都可以通过LBA来管理)
IO读取的大小:
虽然对应的磁盘的访问的基本单位是512byte,但是依旧是很小的。OS内文件系统定制的进行多个扇区的读取,一般是以4KB为基本单位,哪怕是指向读取或者修改1bit,也必须将4KB的数据load到内存中进行读取或者修改,如果必要再写回到磁盘。
- 内存被划分为4KB大小的空间,我们称其为页框
- 磁盘中的文件,尤其是可执行文件,按照4KB大小划分好块(如将40KB的代码区数据,划分为10个4KB的块),我们称其为页帧。
- 将可执行文件加载到内存,也就是将页帧加载到页框。
Linux ext2文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被划分为一个个的block。**一个block的大小是由格式化的时候确定的,并且不可以更改。例如mke2fs
的-b选项可以设定block大小为1024、2048或4096字节。而上图中启动块(Boot Block)**的大小是确定的(目前不需要了解启动块)。
-
**Super Block:**存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了,因此为了防止Super Block的信息被破坏,我们在每一个分组中都对Super Block的信息进行备份,如果有分组的Super Block的信息被破坏,可以拷贝其他分组Super Block的信息来进行修复。
-
文件 = 内容 + 属性;
Linux的文件属性和文件内容是分批存储的。
- 文件属性存储在inode中,inode的大小是固定的(一般是128字节或256字节),一个文件对应一个inode,文件几乎所有的属性都存储在inode中,但是文件名并不在inode中存储。
inode为了进行区分彼此,每一个inode都有其对应的编号,使用 ls -li
来查看对应文件或者文件夹的inode。
-
文件内容存储在数据块
data Block
中,随着应用类型的变化,数据块的大小也在变化(也就是说内容越多,所需要的数据块的容量要越大) -
**inode Table:**inode Table 保存了分组内部所有的可用inode(包括已使用的和未使用的inode)。每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。
-
**Data block:**保存的是分组内部所有文件的数据块。(以4KB为基本单位)
-
**inode bitmap:**是inode对应的位图结构,位图中比特位的位置和当前文件对应的inode的位置是一 一对应的。
-
**Block bitmap:**数据块对应的位图结构,位图中的比特位位置和当前data block对应的数据块位置时一 一对应的。
-
**GDT(group discriptor table):**块组描述表,对应分组的宏观的属性信息。(如inode被使用了多少个,多少个inode未被使用,数据块一共有多少个,多少已经使用,多少未被使用等等)
如何用inode查找和删除一个文件
- 当我们查找一个文件时,统一使用的是inode编号。
-
删除一个文件,只需要将这个文件inode对应的的inode bitmap中的比特位由1置为0,将Block bitmap中文件数据块对应的比特位,置为0就可以将这个文件的属性和内容都删除了。
-
但是我们平时查找文件和删除文件都是用的是文件名,这是为什么呢?
-
首先我们需要了解目录的数据块存放的是什么呢?
-
目录的数据块存放的是当前目录下,文件名和inode的映射关系,因此我们用文件名,其实是使用的inode。
-
这也就是为什么同一目录下不可以创建相同名称的文件的原因,因为对应的inode只有一个,也是在目录下创建文件需要目录写入权限的原因,因为想要在目录下创建文件,那么就必须将这个映射关系写入到目录对应的数据块当中,这就需要目录的写入权限。
理解硬链接
创建软硬链接
ls -li
是一个 Linux/Unix 命令,用于列出当前目录中的所有文件和子目录,并显示它们的 inode 号和权限等信息。其中,-li
选项表示以长格式列出文件,包括文件的 inode 号和权限等信息。
- 自己来操作一下:
软硬链接的区别:是否具有独立的inode
- 软链接具有独立的inode,可以被当做独立文件看待。
- 硬链接没有独立的inode
如何理解硬链接
- 建立一个硬链接究竟是做了什么?
-
建立硬链接,根本没有创建新文件,因为没有给硬链接分配独立的inode,既然没有创建新文件,那么一定是没有属于硬链接的属性集合和内容集合的,硬链接用的一定是其目标文件的inode和内容。
-
建立硬链接,其实就是在指定路径下,新增文件名和inode编号的映射关系。
-
当有两个文件名都对应同一个inode时,inode内部是由一个计数器的,此时计数器的值为2,也称之为硬链接数。
-
因此得出一个结论,想要真正的删除一个文件,只有当这个文件的硬链接数为0时,这个文件才算被真正删除。
演示如下:
如何理解软链接
mkdir -p
是一个Linux/Unix命令,用于创建目录,如果目录已经存在则不会报错,也不会进行任何操作。其中,"-p"
选项表示递归创建目录,即如果父级目录不存在,则会自动创建父级目录。例如,如果要创建一个名为"/home/user1/test"
的目录,可以使用命令"mkdir -p /home/user1/test"
。
软链接的应用场景
[qwy@VM-4-3-centos lesson20]$ mkdir -p ./bin/exe/qwy
[qwy@VM-4-3-centos lesson20]$ cd ./bin/exe/qwy
[qwy@VM-4-3-centos mytest.c]$ vim mytest.c
[qwy@VM-4-3-centos mytest.c]$ cat mytest.c
#include<stdio.h>
int main()
{
printf("hello qwy\n");
return 0;
}
[qwy@VM-4-3-centos mytest.c]$ gcc mytest.c -o mytest
[qwy@VM-4-3-centos mytest.c]$ ll
total 16
-rwxrwxr-x 1 qwy qwy 8360 May 30 22:43 mytest
-rw-rw-r-- 1 qwy qwy 76 May 30 22:40 mytest.c
[qwy@VM-4-3-centos mytest.c]$ cd -
/home/qwy/lesson20
[qwy@VM-4-3-centos lesson20]$ ln -s ./bin/exe/qwy/mytest mytest
[qwy@VM-4-3-centos lesson20]$ ll
total 4
drwxrwxr-x 3 qwy qwy 4096 May 30 22:38 bin
lrwxrwxrwx 1 qwy qwy 20 May 30 22:48 mytest -> ./bin/exe/qwy/mytest
[qwy@VM-4-3-centos lesson20]$ ./mytest // 此时mytest为./bin/exe/qwy/mytest的快捷方式
hello qwy
// 当我们删除掉./bin/exe/qwy/mytest时,软链接就会爆出警告,因为无法找到目标文件对应的路径
硬链接的应用场景
"ls -lina"
命令与"ls -li"
命令类似,不同之处在于它会显示更多的文件信息。具体来说,它会列出当前目录中的所有文件和子目录,并显示它们的inode号、权限、硬链接数、所有者、所属组、大小、修改时间和文件名等信息。其中,“-i"选项表示显示inode号,”-n"选项表示以数字形式显示所有者和所属组的ID,而"-a"选项表示显示所有文件,包括隐藏文件。
为什么创建一个普通文件,其硬链接数天然就为1?
一个普通文件,本身有一个文件名和自己的inode具有一个映射关系。
为什么创建一个目录,其硬链接数天然为2?
为什么下图的硬链接数为3?
注:
Linux是不允许普通用户来建立目录的硬链接的,这是为什么呢?
-
Linux不允许普通用户来建立目录的硬链接,这是出于安全考虑。目录的硬链接会导致目录的树形结构被破坏,可能会导致系统出现死循环,极易引发安全漏洞。因此,Linux只允许超级用户(root)来建立目录的硬链接,以确保系统的稳定性和安全性。
-
在Linux中,普通用户创建根目录的硬链接可能会导致死循环,这是因为根目录是整个文件系统的起点,它的硬链接会影响到整个文件系统。当一个普通用户创建根目录的硬链接时,这个硬链接会被视为一个新的目录,而这个新的目录又会包含一个指向根目录的硬链接,这样就形成了一个循环引用的结构,导致文件系统进入死循环状态。
三个文件时间的区别
- Access :最后访问的时间
- Modify :文件最后修改的时间
- Change :属性最后修改的时间
要查看Linux中文件的修改时间,可以使用stat
命令。在终端中输入以下命令:
stat filename
其中,filename
是要查看修改时间的文件名。执行该命令后,会显示文件的详细信息,包括Access Time、Modify Time和Change Time等时间戳属性。其中,Modify Time对应的是文件最后一次修改的时间戳。
在Linux/Unix系统中,每个文件和目录都有三个时间戳,分别是访问时间(access time)、修改时间(modify time)和更改时间(change time)。
- 访问时间(access time):也称为atime,指的是文件或目录最后一次被访问的时间。例如,如果你打开一个文件并查看了它的内容,这个文件的访问时间就会被更新为当前时间。
- 修改时间(modify time):也称为mtime,指的是文件或目录最后一次被修改的时间。例如,如果你编辑了一个文件并保存了修改,这个文件的修改时间就会被更新为当前时间。
- 更改时间(change time):也称为ctime,指的是文件或目录的属性最后一次被修改的时间。例如,如果你使用chmod命令改变了一个文件的权限,这个文件的更改时间就会被更新为当前时间。
需要注意的是,访问时间和修改时间只针对文件内容的访问和修改,而更改时间则包括了文件内容的修改以及文件属性的修改。
演示如下:
- Change:属性最后修改的时间
- Modify :文件最后修改的时间
- Access :最后访问的时间:
动态库和静态库
概念
-
静态库(静态库的文件后缀为.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
-
动态库(动态库的文件后缀为.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
生成一个静态库
先了解一些基础知识:
第一步:使用.c文件生成可执行文件
[qwy@VM-4-3-centos lesson20]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 May 31 16:26 main.c
-rw-rw-r-- 1 qwy qwy 116 May 31 16:19 my_add.c
-rw-rw-r-- 1 qwy qwy 71 May 31 16:19 my_add.h
-rw-rw-r-- 1 qwy qwy 116 May 31 16:21 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:21 my_sub.h
[qwy@VM-4-3-centos lesson20]$ cat my_add.h
#pragma once
#include <stdio.h>
extern int Add(int a, int b);
[qwy@VM-4-3-centos lesson20]$ cat add.c
cat: add.c: No such file or directory
[qwy@VM-4-3-centos lesson20]$ cat my_add.c
#include "my_add.h"
int Add(int a, int b)
{
printf("enter Add func, %d + %d = ?\n", a, b);
return a + b;
}
[qwy@VM-4-3-centos lesson20]$ cat my_sub.h
#pragma once
#include <stdio.h>
extern int Sub(int a, int b);
[qwy@VM-4-3-centos lesson20]$ cat my_sub.c
#include "my_sub.h"
int Sub(int a, int b)
{
printf("enter Sub func, %d - %d = ?\n", a, b);
return a - b;
}
[qwy@VM-4-3-centos lesson20]$ cat main.c
#include "my_add.h"
#include "my_sub.h"
int main()
{
int a = 10;
int b = 20;
int res = Sub(a, b);
printf("result: %d\n", res);
res = Add(a, b);
printf("result: %d\n", res);
return 0;
}
// 第一种方式:通过gcc -o 的方式直接生成可执行文件
[qwy@VM-4-3-centos lesson20]$ gcc -o main main.c my_add.c my_sub.c
[qwy@VM-4-3-centos lesson20]$ ll
total 32
-rwxrwxr-x 1 qwy qwy 8480 May 31 16:27 main
-rw-rw-r-- 1 qwy qwy 216 May 31 16:26 main.c
-rw-rw-r-- 1 qwy qwy 116 May 31 16:19 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:27 my_add.h
-rw-rw-r-- 1 qwy qwy 116 May 31 16:21 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:21 my_sub.h
[qwy@VM-4-3-centos lesson20]$ ./main
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
=========================================================================================
// 第二种方式:通过gcc -c 的方式生成.o文件,再将.o文件链接生成可执行文件
[qwy@VM-4-3-centos lesson20]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 May 31 16:26 main.c
-rw-rw-r-- 1 qwy qwy 116 May 31 16:19 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:27 my_add.h
-rw-rw-r-- 1 qwy qwy 116 May 31 16:21 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:21 my_sub.h
[qwy@VM-4-3-centos lesson20]$ gcc -c main.c
[qwy@VM-4-3-centos lesson20]$ gcc -c my_add.c
[qwy@VM-4-3-centos lesson20]$ gcc -c my_sub.c
[qwy@VM-4-3-centos lesson20]$ ll
total 32
-rw-rw-r-- 1 qwy qwy 216 May 31 16:26 main.c
-rw-rw-r-- 1 qwy qwy 1736 May 31 16:45 main.o
-rw-rw-r-- 1 qwy qwy 116 May 31 16:19 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:27 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:46 my_add.o
-rw-rw-r-- 1 qwy qwy 116 May 31 16:21 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:21 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:46 my_sub.o
[qwy@VM-4-3-centos lesson20]$ gcc -o mymath main.o my_add.o my_sub.o
[qwy@VM-4-3-centos lesson20]$ ll
total 44
-rw-rw-r-- 1 qwy qwy 216 May 31 16:26 main.c
-rw-rw-r-- 1 qwy qwy 1736 May 31 16:45 main.o
-rw-rw-r-- 1 qwy qwy 116 May 31 16:19 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:27 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:46 my_add.o
-rwxrwxr-x 1 qwy qwy 8480 May 31 16:46 mymath
-rw-rw-r-- 1 qwy qwy 116 May 31 16:21 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:21 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:46 my_sub.o
[qwy@VM-4-3-centos lesson20]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
第二步:使用.o文件生成可执行文件
// 将部分文件拷贝到另一个目录进行如下的操作
[qwy@VM-4-3-centos test]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 May 31 17:01 main.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:59 my_add.o
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:59 my_sub.o
[qwy@VM-4-3-centos test]$ gcc -c main.c
[qwy@VM-4-3-centos test]$ ll
total 24
-rw-rw-r-- 1 qwy qwy 216 May 31 17:01 main.c
-rw-rw-r-- 1 qwy qwy 1736 May 31 17:03 main.o
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:59 my_add.o
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:59 my_sub.o
// 将所有的.o文件进行链接
[qwy@VM-4-3-centos test]$ gcc -o mymath main.o my_add.o my_sub.o
[qwy@VM-4-3-centos test]$ ll
total 36
-rw-rw-r-- 1 qwy qwy 216 May 31 17:01 main.c
-rw-rw-r-- 1 qwy qwy 1736 May 31 17:03 main.o
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:59 my_add.o
-rwxrwxr-x 1 qwy qwy 8480 May 31 17:04 mymath
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 16:59 my_sub.o
// 依旧是可以正常运行的
[qwy@VM-4-3-centos test]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
- 当有其他人想要用我们的代码,但是我们又不想给他提供源代码,那么只需要提供给他
.o
文件和相应的.h
文件,他直接将其与他的代码进行链接就可以了。
由上面的演示,我们可以得出:
-
库的本质就是:
.o
文件的集合 -
.o
文件(方法的实现),.h
文件(都有什么方法) -
我们将所有的
.o
文件打包,这就是库文件
第三步:生成静态库文件
ar -rc
命令用于创建或更新一个静态库文件。其中,r
选项表示将文件插入到库中,如果文件已经存在,则替换掉原来的文件;c
选项表示创建一个库文件。示例命令如下:ar -rc libexample.a file1.o file2.o
- 上述命令将
file1.o
和file2.o
两个目标文件打包成一个静态库libexample.a
。如果库文件已经存在,则覆盖原有的库文件。
在Linux中,file命令用于判断文件类型。具体来说,file命令可以通过读取文件的头部信息来判断文件的类型,比如文本文件、二进制文件、压缩文件等等。使用file命令非常简单,只需要在终端中输入file命令,后面跟上要判断类型的文件路径即可。例如:
file /path/to/file
执行该命令后,终端会返回该文件的类型信息。如果是文本文件,还会返回该文件的编码格式。如果是压缩文件,还会返回压缩算法和压缩方式。
[qwy@VM-4-3-centos test]$ ll
total 16
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
[qwy@VM-4-3-centos test]$ vim makefile
// ar ==> archive n.档案 v.归档
// $@ :表示目标文件,也就是 libmymath.a
//$^ : 表示依赖文件列表,也就是 my_add.o my_sub.o
[qwy@VM-4-3-centos test]$ cat makefile
libmymath.a:my_add.o my_sub.o
ar -rc $@ $^
my_add.o:my_add.c
gcc -c my_add.c -o my_add.o
my_sub.o:my_sub.c
gcc -c my_sub.c -o my_sub.o
.PHONY:clean
clean:
rm -rf *.o libmymath.a
[qwy@VM-4-3-centos test]$ make
gcc -c my_add.c -o my_add.o
gcc -c my_sub.c -o my_sub.o
ar -rc libmymath.a my_add.o my_sub.o
[qwy@VM-4-3-centos test]$ ll
total 32
-rw-rw-r-- 1 qwy qwy 3296 May 31 17:34 libmymath.a
-rw-rw-r-- 1 qwy qwy 138 May 31 17:33 makefile
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:34 my_add.o
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:34 my_sub.o
// 查看libmymath.a 的类型为归档文件
[qwy@VM-4-3-centos test]$ file libmymath.a
libmymath.a: current ar archive
第四步:链接静态库文件
我们使用的头文件stdio.h在Linux中,是在如下的目录中
[qwy@VM-4-3-centos test]$ ls /usr/include/stdio.h /usr/include/stdio.h
我们使用的动静态库则是在如下的目录中:
[qwy@VM-4-3-centos test]$ ls /lib64/libc.a /lib64/libc.a [qwy@VM-4-3-centos test]$ ls /lib64/libc.so /lib64/libc.so
tar -czf是一个Linux命令,用于将多个文件或目录打包成一个.tar.gz压缩文件。其中,选项-c表示创建新的归档文件,-z表示使用gzip压缩算法,-f表示指定归档文件的名字。因此,tar -czf命令的完整语法为:
tar -czf archive.tar.gz file1 file2 ... fileN tar -czf archive.tar.gz directory1 directory2 ... directoryN
其中,archive.tar.gz为生成的压缩文件名,file1fileN和directory1directoryN为要打包的文件或目录名。
tar -xzf是一个常用的Linux命令,用于解压缩tar压缩文件。其中,-x表示解压缩,-z表示使用gzip压缩,-f表示指定要解压缩的文件名。因此,tar -xzf命令的完整语法为:
tar -xzf filename.tar.gz
其中,filename.tar.gz是要解压缩的文件名。执行该命令后,tar将会自动解压缩该文件,并将解压缩后的文件放置在当前目录下。
-I
是gcc编译器的一个选项,用于指定头文件的搜索路径。当编译器在编译源代码时遇到#include
指令时,会在指定的路径中查找头文件。例如,如果有一个头文件header.h
存放在/usr/local/include
目录下,那么可以使用以下命令编译源代码:gcc -I/usr/local/include source.c -o program
这样,编译器就能够正确地找到
header.h
头文件并将其包含到编译过程中。
gcc -l
是 gcc 编译器的一个选项,用于指定需要链接的库文件。具体来说,-l
选项后面需要跟上需要链接的库文件名(不需要包含前缀lib
和后缀.a
或.so
),例如:-lmath
表示链接数学库。如果需要链接多个库文件,可以在选项后面多次使用-l
,例如:-lmath -lm
表示链接数学库和标准数学库。
gcc命令中的-L选项用于指定编译器在哪些目录中查找库文件。例如,如果您的程序需要使用一个名为libfoo.so的共享库文件,而该文件位于/usr/local/lib目录中,您可以使用以下命令编译您的程序:
gcc -o myprogram myprogram.c -L/usr/local/lib -lfoo
这将告诉gcc在编译myprogram时,在/usr/local/lib目录中查找名为libfoo.so的库文件。注意,库文件名需要以"lib"开头,以".so"结尾。在编译时,您还需要使用-l选项指定库的名称(不包括前缀"lib"和后缀".so")。
因此,我们需要将我们生成的静态库文件进行打包,并放在指定的目录下:
[qwy@VM-4-3-centos test]$ ll
total 32
-rw-rw-r-- 1 qwy qwy 3296 May 31 17:45 libmymath.a
-rw-rw-r-- 1 qwy qwy 184 May 31 17:44 makefile
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:45 my_add.o
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:45 my_sub.o
[qwy@VM-4-3-centos test]$ cat makefile
libmymath.a:my_add.o my_sub.o
ar -rc $@ $^
my_add.o:my_add.c
gcc -c my_add.c -o my_add.o
my_sub.o:my_sub.c
gcc -c my_sub.c -o my_sub.o
// 将我们的静态库进行发布
.PHONY:output
output:
mkdir -p mylib/include // 创建目录mylib/include
mkdir -p mylib/lib // 创建目录mylib/lib
cp -f *.a mylib/lib // 将所有的.a文件,也就是静态库,都放在mylib/lib目录下
cp -f *.h mylib/include // 将所有的.h文件,也就是头文件,都放在mylib/include目录下
.PHONY:clean
clean:
rm -rf *.o libmymath.a mylib
// 将我们写的库进行发布
[qwy@VM-4-3-centos test]$ make output
mkdir -p mylib/include
mkdir -p mylib/lib
cp -f *.a mylib/lib
cp -f *.h mylib/include
[qwy@VM-4-3-centos test]$ ll
total 36
-rw-rw-r-- 1 qwy qwy 3296 May 31 17:45 libmymath.a
-rw-rw-r-- 1 qwy qwy 303 May 31 18:10 makefile
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:45 my_add.o
drwxrwxr-x 4 qwy qwy 4096 May 31 18:10 mylib // 生成了目录mylib
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:45 my_sub.o
// 生成压缩文件mylib.tgz
[qwy@VM-4-3-centos test]$ tar -czf mylib.tgz mylib
[qwy@VM-4-3-centos test]$ ll
total 40
-rw-rw-r-- 1 qwy qwy 3296 May 31 17:45 libmymath.a
-rw-rw-r-- 1 qwy qwy 303 May 31 18:10 makefile
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:45 my_add.o
drwxrwxr-x 4 qwy qwy 4096 May 31 18:10 mylib
-rw-rw-r-- 1 qwy qwy 937 May 31 18:14 mylib.tgz
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1544 May 31 17:45 my_sub.o
=========================================================================================
// 当其他人想要使用我们的库,只需要在网上将我们生成的压缩文件mylib.tgz,下载到他的本地,并进行解压,就可以进行使用了,具体操作如下:
// 已经将压缩文件mylib.tgz,下载到了本地
[qwy@VM-4-3-centos test1]$ ll
total 8
-rw-rw-r-- 1 qwy qwy 216 May 31 18:22 main.c
-rw-rw-r-- 1 qwy qwy 937 May 31 18:22 mylib.tgz
// 将压缩文件mylib.tgz进行解压
[qwy@VM-4-3-centos test1]$ tar -xzf mylib.tgz
[qwy@VM-4-3-centos test1]$ ll
total 12
-rw-rw-r-- 1 qwy qwy 216 May 31 18:22 main.c
drwxrwxr-x 4 qwy qwy 4096 May 31 18:10 mylib
-rw-rw-r-- 1 qwy qwy 937 May 31 18:22 mylib.tgz
[qwy@VM-4-3-centos test1]$ tree mylib
mylib
|-- include
| |-- my_add.h
| `-- my_sub.h
`-- lib
`-- libmymath.a
2 directories, 3 files
=========================================================================================
// -L 后面加静态库的路径
// -l 后面加静态库的名称(名称要去掉前缀lib,和后缀.a)
// -I 后面加头文件的路径,头文件不需要指定名称
[qwy@VM-4-3-centos test1]$ gcc -o mymath main.c -L ./mylib/lib -l mymath -I ./mylib/include
[qwy@VM-4-3-centos test1]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 21:49 mylib
-rwxrwxr-x 1 qwy qwy 8480 Jun 2 21:51 mymath
[qwy@VM-4-3-centos test1]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
=========================================================================================
[qwy@VM-4-3-centos test1]$ ldd mymath
linux-vdso.so.1 => (0x00007ffd5bb3b000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6d5ae92000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6d5b260000)
[qwy@VM-4-3-centos test1]$ file mymath
mymath: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=be2c7b2aba7c79092939d411067c84073bb89349, not stripped
// 为什么我们查看所使用的的库时,是动态链接的库呢?
// 这是因为形成一个可执行程序,可不仅仅只依赖一个库
// gcc默认是动态链接的(建议行为)
// 对于一个特定的库,究竟是动态库还是静态库,取决于你提供的是静态库还是动态库
// 如果你提供的库有动态库,也有静态库,那就取决于gcc的默认行为
// 因为查询mymath链接的是动态库
ldd
是一个Linux命令,用于打印一个可执行文件或共享库所依赖的动态链接库。它的全称是"List Dynamic Dependencies",可以帮助用户查看一个程序运行时需要加载哪些共享库。在终端中输入ldd
命令,后面跟上可执行文件或共享库的路径,即可显示出它所依赖的动态链接库列表。例如:ldd /usr/bin/python3.8
这个命令会显示Python 3.8所依赖的动态链接库。
第五步:将静态库安装到系统路径下
- 安装
[qwy@VM-4-3-centos test1]$ ll
total 8
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 21:49 mylib
[qwy@VM-4-3-centos test1]$ tree mylib
mylib
|-- include
| |-- my_add.h
| `-- my_sub.h
`-- lib
`-- libmymath.a
2 directories, 3 files
// 将头文件拷贝到系统目录/usr/include/下,也就是所谓的安装
[qwy@VM-4-3-centos test1]$ sudo cp mylib/include/* /usr/include/
[sudo] password for qwy:
[qwy@VM-4-3-centos test1]$ ls /usr/include/my_*
/usr/include/my_add.h /usr/include/my_sub.h
// 将静态库拷贝到系统目录/lib64/下,也就是将其安装
[qwy@VM-4-3-centos test1]$ sudo cp mylib/lib/*.a /lib64/
[qwy@VM-4-3-centos test1]$ ls /lib64/libmymath.a
/lib64/libmymath.a
- 形成可执行文件
// 由于系统目录/lib64/下存在大量的库,因此我们在编译时需要指明库的路径
[qwy@VM-4-3-centos test1]$ gcc main.c -l mymath
[qwy@VM-4-3-centos test1]$ ll
total 20
-rwxrwxr-x 1 qwy qwy 8480 Jun 2 22:33 a.out
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 21:49 mylib
[qwy@VM-4-3-centos test1]$ ./a.out
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
=========================================================================================
// 为了不污染系统库,因此,在演示完之后我们将这个静态库删除,也就是将其卸载
[qwy@VM-4-3-centos test1]$ sudo rm /usr/include/my_*
[qwy@VM-4-3-centos test1]$ sudo rm /lib64/libmymath.a
生成一个动态库
gcc -shared -o libmymath.so my_add.o my_sub.o
这个命令使用gcc编译器将两个目标文件 my_add.o 和 my_sub.o 合并成一个共享库文件 libmymath.so。具体参数的含义如下:
- -shared:生成共享库文件,也就是动态链接库文件。
- -o:指定输出文件的名称。
- libmymath.so:指定输出文件的名称为 libmymath.so。
- my_add.o 和 my_sub.o:指定需要合并的目标文件。
需要注意的是,这个命令必须在包含目标文件的目录下执行,否则需要使用 -L 选项指定目标文件所在的路径。
// -fPIC选项表示生成位置无关代码
[qwy@VM-4-3-centos test]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 303 May 31 19:31 makefile
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
[qwy@VM-4-3-centos test]$ gcc -c -fPIC my_add.c
[qwy@VM-4-3-centos test]$ gcc -c -fPIC my_sub.c
[qwy@VM-4-3-centos test]$ ll
total 28
-rw-rw-r-- 1 qwy qwy 303 May 31 19:31 makefile
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1592 Jun 2 22:54 my_add.o
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1592 Jun 2 22:54 my_sub.o
[qwy@VM-4-3-centos test]$ gcc -shared -o libmymath.so my_add.o my_sub.o
[qwy@VM-4-3-centos test]$ ll
total 36
-rwxrwxr-x 1 qwy qwy 8096 Jun 2 22:59 libmymath.so
-rw-rw-r-- 1 qwy qwy 303 May 31 19:31 makefile
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_add.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_add.h
-rw-rw-r-- 1 qwy qwy 1592 Jun 2 22:54 my_add.o
-rw-rw-r-- 1 qwy qwy 116 May 31 17:33 my_sub.c
-rw-rw-r-- 1 qwy qwy 64 May 31 16:59 my_sub.h
-rw-rw-r-- 1 qwy qwy 1592 Jun 2 22:54 my_sub.o
[qwy@VM-4-3-centos test]$ file libmymath.so
libmymath.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=dfe313c708e3e4738d5325236c35a855710a606f, not stripped
=========================================================================================
// 将库文件和头文件打包,并进行压缩,再上传到服务器,由使用者将其下载到他们的本地,解压后进行使用
// 和上述静态库是一样的,因此这里对这些步骤进行了省略
[qwy@VM-4-3-centos test]$ ll
total 8
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 23:09 mylib
[qwy@VM-4-3-centos test]$ tree mylib
mylib
|-- include
| |-- my_add.h
| `-- my_sub.h
`-- lib
`-- libmymath.so
2 directories, 3 files
[qwy@VM-4-3-centos test1]$ gcc -o mymath main.c -Lmylib/lib -lmymath -Imylib/include
[qwy@VM-4-3-centos test1]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 23:14 mylib
-rwxrwxr-x 1 qwy qwy 8432 Jun 2 23:16 mymath
// 运行可执行程序时,出现了报错,这是为什么呢?
[qwy@VM-4-3-centos test1]$ ./mymath
./mymath: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
// 原因:
// 虽然在编译时,库文件的路径和库文件的名称,以及头文件的路径,我们告诉了gcc编译器,编译器可以进行链接,并生成可执行文件,但是可执行文件再运行时,还需要链接动态库,那么OS和shell就需要知道库在哪里,但是此时的库并不在系统路径下,因此OS是无法找到这个库的,因此程序出现了报错。
// 对于静态库,在生成可执行文件时,就已经将对应的代码从静态库中拷贝到了相应的位置处,因此运行可执行文件时,是不需要跳转到静态库进行链接的,所以并不会报错
添加环境变量
// 系统在执行我们的程序时,除了在系统默认路径下去寻找库之外,还会在环境变量 $LD_LIBRARY_PATH中去搜索
[qwy@VM-4-3-centos test1]$ echo $LD_LIBRARY_PATH
:/home/qwy/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
// 我们的动态库所在的路径为 /home/qwy/test1/mylib/lib/,我们需要将这条路径添加到环境变量$LD_LIBRARY_PATH中,这样,当我们运行程序时,OS就可以在对应的环境变量中找到这个动态库来链接了
[qwy@VM-4-3-centos test1]$ ls /home/qwy/test1/mylib/lib/
libmymath.so
// 使用export添加环境变量
[qwy@VM-4-3-centos test1]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/qwy/test1/mylib/lib/
[qwy@VM-4-3-centos test1]$ echo $LD_LIBRARY_PATH
:/home/qwy/.VimForCpp/vim/bundle/YCM.so/el7.x86_64:/home/qwy/test1/mylib/lib/
// 此时再来运行mymath就可以链接到对应的动态库了
[qwy@VM-4-3-centos test1]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
[qwy@VM-4-3-centos test1]$ ldd mymath
linux-vdso.so.1 => (0x00007ffcce3eb000)
libmymath.so => /home/qwy/test1/mylib/lib/libmymath.so (0x00007f2742259000)
libc.so.6 => /lib64/libc.so.6 (0x00007f2741e8b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f274245b000)
=========================================================================================
// 但是当我们将xshell重启之后,我们的程序又链接不到动态库了
// 这是因为我们设置的环境变量只在本次登录是有效的,想要永久的修改环境变量,必须要去修改配置文件
// 或者是将动态库放在系统的默认路径下也是可以的,和静态库是相似的,这里不做赘述
修改配置文件
ldconfig是用于更新共享库缓存的命令。在Linux系统中,程序运行时需要依赖一些共享库,这些共享库存放在系统的特定目录中。当系统更新或安装新的共享库时,需要使用ldconfig命令来更新共享库缓存,使得系统能够正确地找到新的共享库。
ldconfig的常用选项包括:
- -v:显示详细信息,包括共享库的路径和版本号。
- -n:仅打印要更新的共享库的列表,而不实际更新缓存。
- -X:不要处理默认的共享库目录,只处理指定的目录。
- -f file:指定要处理的共享库文件,而不是默认的共享库目录。
- -C file:指定要使用的缓存文件,而不是默认的缓存文件。
使用ldconfig命令的一般步骤如下:
- 将共享库文件复制到系统的共享库目录中,或者将共享库目录添加到/etc/ld.so.conf文件中。
- 运行ldconfig命令更新共享库缓存。
- 使用ldd命令检查程序所依赖的共享库是否已被正确加载。
需要注意的是,修改/etc/ld.so.conf文件后,必须运行ldconfig命令才能使修改生效。
[qwy@VM-4-3-centos test1]$ cd /etc/ld.so.conf.d/
[qwy@VM-4-3-centos ld.so.conf.d]$ ll
total 16
-rw-r--r-- 1 root root 26 Feb 24 2022 bind-export-x86_64.conf
-rw-r--r-- 1 root root 19 Aug 9 2019 dyninst-x86_64.conf
-r--r--r-- 1 root root 63 Jun 28 2022 kernel-3.10.0-1160.71.1.el7.x86_64.conf
-rw-r--r-- 1 root root 17 Oct 2 2020 mariadb-x86_64.conf
// 创建我们自己的配置文件
[qwy@VM-4-3-centos ld.so.conf.d]$ sudo touch my.conf
[sudo] password for qwy:
[qwy@VM-4-3-centos ld.so.conf.d]$ ll
total 16
-rw-r--r-- 1 root root 26 Feb 24 2022 bind-export-x86_64.conf
-rw-r--r-- 1 root root 19 Aug 9 2019 dyninst-x86_64.conf
-r--r--r-- 1 root root 63 Jun 28 2022 kernel-3.10.0-1160.71.1.el7.x86_64.conf
-rw-r--r-- 1 root root 17 Oct 2 2020 mariadb-x86_64.conf
-rw-r--r-- 1 root root 0 Jun 3 15:00 my.conf
// 将我们库的对应路径写入到配置文件中
[qwy@VM-4-3-centos ld.so.conf.d]$ sudo vim my.conf
[qwy@VM-4-3-centos ld.so.conf.d]$ cat my.conf
/home/qwy/test1/mylib/lib/
// 更新共享库缓存
[qwy@VM-4-3-centos ld.so.conf.d]$ sudo ldconfig
[qwy@VM-4-3-centos ld.so.conf.d]$ cd -
/home/qwy/test1
[qwy@VM-4-3-centos test1]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 23:14 mylib
-rwxrwxr-x 1 qwy qwy 8432 Jun 2 23:16 mymath
[qwy@VM-4-3-centos test1]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
[qwy@VM-4-3-centos test1]$ ldd mymath
linux-vdso.so.1 => (0x00007fffd35f9000)
libmymath.so => /home/qwy/test1/mylib/lib/libmymath.so (0x00007fada5b9c000)
libc.so.6 => /lib64/libc.so.6 (0x00007fada57ce000)
/lib64/ld-linux-x86-64.so.2 (0x00007fada5d9e000)
// 退出xshell重新登陆,依旧是可以正常运行的
=========================================================================================
// 测试完之后,依旧是删除掉我们自己建立的配置文件,防止污染系统
[qwy@VM-4-3-centos test1]$ cd -
/etc/ld.so.conf.d
[qwy@VM-4-3-centos ld.so.conf.d]$ ll
total 20
-rw-r--r-- 1 root root 26 Feb 24 2022 bind-export-x86_64.conf
-rw-r--r-- 1 root root 19 Aug 9 2019 dyninst-x86_64.conf
-r--r--r-- 1 root root 63 Jun 28 2022 kernel-3.10.0-1160.71.1.el7.x86_64.conf
-rw-r--r-- 1 root root 17 Oct 2 2020 mariadb-x86_64.conf
-rw-r--r-- 1 root root 28 Jun 3 15:03 my.conf
[qwy@VM-4-3-centos ld.so.conf.d]$ sudo rm my.conf
[qwy@VM-4-3-centos ld.so.conf.d]$ ll
total 16
-rw-r--r-- 1 root root 26 Feb 24 2022 bind-export-x86_64.conf
-rw-r--r-- 1 root root 19 Aug 9 2019 dyninst-x86_64.conf
-r--r--r-- 1 root root 63 Jun 28 2022 kernel-3.10.0-1160.71.1.el7.x86_64.conf
-rw-r--r-- 1 root root 17 Oct 2 2020 mariadb-x86_64.conf
// 更新共享库缓存
[qwy@VM-4-3-centos ld.so.conf.d]$ sudo ldconfig
建立软链接
[qwy@VM-4-3-centos test1]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 23:14 mylib
-rwxrwxr-x 1 qwy qwy 8432 Jun 2 23:16 mymath
// 建立库的软链接在程序所在的目录下
// 建立库文件的软链接到当前目录下,程序运行时,会在当前目录下搜索动态库,因此是可以链接到的
[qwy@VM-4-3-centos test1]$ ln -s /home/qwy/test1/mylib/lib/libmymath.so libmymath.so
[qwy@VM-4-3-centos test1]$ ll
total 20
lrwxrwxrwx 1 qwy qwy 38 Jun 3 15:25 libmymath.so -> /home/qwy/test1/mylib/lib/libmymath.so
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 23:14 mylib
-rwxrwxr-x 1 qwy qwy 8432 Jun 2 23:16 mymath
[qwy@VM-4-3-centos test1]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
=========================================================================================
// 建立库的软链接到系统默认路径下
[qwy@VM-4-3-centos test1]$ unlink libmymath.so
[qwy@VM-4-3-centos test1]$ ll
total 20
-rw-rw-r-- 1 qwy qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 23:14 mylib
-rwxrwxr-x 1 qwy qwy 8432 Jun 2 23:16 mymath
[qwy@VM-4-3-centos test1]$ sudo ln -s /home/qwy/test1/mylib/lib/libmymath.so /lib64/libmymath.so
[qwy@VM-4-3-centos test1]$ ls /lib64/libmymath.so
/lib64/libmymath.so
[qwy@VM-4-3-centos test1]$ ls /lib64/libmymath.so -l
lrwxrwxrwx 1 root root 38 Jun 3 15:29 /lib64/libmymath.so -> /home/qwy/test1/mylib/lib/libmymath.so
[qwy@VM-4-3-centos test1]$ ldd /lib64/libmymath.so
linux-vdso.so.1 => (0x00007fff285b2000)
libc.so.6 => /lib64/libc.so.6 (0x00007f8a2e023000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8a2e5f3000)
[qwy@VM-4-3-centos test1]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
// 删除软链接,防止污染系统
[qwy@VM-4-3-centos test1]$ sudo unlink /lib64/libmymath.so
静态库的加载
动静态库的加载
qwy 216 Jun 2 21:49 main.c
drwxrwxr-x 4 qwy qwy 4096 Jun 2 23:14 mylib
-rwxrwxr-x 1 qwy qwy 8432 Jun 2 23:16 mymath
[qwy@VM-4-3-centos test1]$ sudo ln -s /home/qwy/test1/mylib/lib/libmymath.so /lib64/libmymath.so
[qwy@VM-4-3-centos test1]$ ls /lib64/libmymath.so
/lib64/libmymath.so
[qwy@VM-4-3-centos test1]$ ls /lib64/libmymath.so -l
lrwxrwxrwx 1 root root 38 Jun 3 15:29 /lib64/libmymath.so -> /home/qwy/test1/mylib/lib/libmymath.so
[qwy@VM-4-3-centos test1]$ ldd /lib64/libmymath.so
linux-vdso.so.1 => (0x00007fff285b2000)
libc.so.6 => /lib64/libc.so.6 (0x00007f8a2e023000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8a2e5f3000)
[qwy@VM-4-3-centos test1]$ ./mymath
enter Sub func, 10 - 20 = ?
result: -10
enter Add func, 10 + 20 = ?
result: 30
// 删除软链接,防止污染系统
[qwy@VM-4-3-centos test1]$ sudo unlink /lib64/libmymath.so
# 静态库的加载
[外链图片转存中...(img-3pdMinFd-1743560870562)]
# 动静态库的加载
[外链图片转存中...(img-5OcLjMnB-1743560870563)]