7.理解文件系统

理解文件系统

​ 系统中被打开的文件,OS都会创建它对应的struct_file的结构体对象来对其进行管理,再将多个struct_file的结构体对象用数据结构的方式将其链接起来进行管理(先描述,再组织的方式)。

那么,如果一个文件没有被打开,操作系统该如何对其进行管理呢?

  • 没有被打开的文件,都被存储在磁盘上面。
  • 磁盘上面有大量的文件,也是需要被静态管理起来的,方便我们随时打开(也就是说,当我们想要打开磁盘上面的文件,我们如何获取这个文件在磁盘上对应的路径呢!这就需要我们对其进行管理)
  • 举一个简单的例子,我们购买的快递都在快递站,而每个快递都有其对应的编号,当我们取快递时,根据编号就可以准确的拿到相对应的快递,而磁盘中未被打开的文件是一样的道理。

磁盘的物理结构

a. 目前的电脑使用的基本都是固态硬盘,很少有使用磁盘

磁盘是计算机中唯一的一个机械结构,且硬盘属于外设。因此,磁盘的访问速度是非常慢的(相对于内存来说)。

b.企业端,磁盘存储依旧是主流(主要是由于磁盘低廉的价格,且存储空间大)

image-20230530131331128

磁盘的存储结构

image-20230530141329021

磁盘的逻辑结构

image-20230530151240932

**思考:**为什么操作系统要进行逻辑抽象,直接使用CHS不可以吗?

  1. 首先,逻辑抽象便于我们管理磁盘
  2. 其次,不想让OS的代码和硬件强耦合。(也就是说如果存储结构不是磁盘,我们也可以用OS的LBA来进行管理, 而不是让OS和CHS地址直接关联,这样的话我们如果底层存储使用的不是磁盘,那么还需要创建对应的代码来进行管理,而如果是通过LBA进行转化成对应结构的地址,不论底层使用那种结构(磁盘、固态硬盘),OS都可以通过LBA来管理

IO读取的大小:

​ 虽然对应的磁盘的访问的基本单位是512byte,但是依旧是很小的。OS内文件系统定制的进行多个扇区的读取,一般是以4KB为基本单位,哪怕是指向读取或者修改1bit,也必须将4KB的数据load到内存中进行读取或者修改,如果必要再写回到磁盘。

  • 内存被划分为4KB大小的空间,我们称其为页框
  • 磁盘中的文件,尤其是可执行文件,按照4KB大小划分好块(如将40KB的代码区数据,划分为10个4KB的块),我们称其为页帧。
  • 将可执行文件加载到内存,也就是将页帧加载到页框。

image-20230530163316486

​ 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。

image-20230530171443146

  • 文件内容存储在数据块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已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。

inode详解链接

  • **Data block:**保存的是分组内部所有文件的数据块。(以4KB为基本单位)

  • **inode bitmap:**是inode对应的位图结构,位图中比特位的位置和当前文件对应的inode的位置是一 一对应的。

  • **Block bitmap:**数据块对应的位图结构,位图中的比特位位置和当前data block对应的数据块位置时一 一对应的。

  • **GDT(group discriptor table):**块组描述表,对应分组的宏观的属性信息。(如inode被使用了多少个,多少个inode未被使用,数据块一共有多少个,多少已经使用,多少未被使用等等)

如何用inode查找和删除一个文件

  • 当我们查找一个文件时,统一使用的是inode编号。

image-20230530191409737

  • 删除一个文件,只需要将这个文件inode对应的的inode bitmap中的比特位由1置为0,将Block bitmap中文件数据块对应的比特位,置为0就可以将这个文件的属性和内容都删除了。

  • 但是我们平时查找文件和删除文件都是用的是文件名,这是为什么呢?

  • 首先我们需要了解目录的数据块存放的是什么呢?

  • 目录的数据块存放的是当前目录下,文件名和inode的映射关系,因此我们用文件名,其实是使用的inode。

  • 这也就是为什么同一目录下不可以创建相同名称的文件的原因,因为对应的inode只有一个,也是在目录下创建文件需要目录写入权限的原因,因为想要在目录下创建文件,那么就必须将这个映射关系写入到目录对应的数据块当中,这就需要目录的写入权限。

理解硬链接

创建软硬链接

image-20230530203401565

ls -li 是一个 Linux/Unix 命令,用于列出当前目录中的所有文件和子目录,并显示它们的 inode 号和权限等信息。其中,-li 选项表示以长格式列出文件,包括文件的 inode 号和权限等信息。

image-20230530203819768

  • 自己来操作一下:

image-20230530204126398

软硬链接的区别:是否具有独立的inode

  • 软链接具有独立的inode,可以被当做独立文件看待。
  • 硬链接没有独立的inode

如何理解硬链接

  1. 建立一个硬链接究竟是做了什么?
  • 建立硬链接,根本没有创建新文件,因为没有给硬链接分配独立的inode,既然没有创建新文件,那么一定是没有属于硬链接的属性集合和内容集合的,硬链接用的一定是其目标文件的inode和内容。

  • 建立硬链接,其实就是在指定路径下,新增文件名和inode编号的映射关系。

  • 当有两个文件名都对应同一个inode时,inode内部是由一个计数器的,此时计数器的值为2,也称之为硬链接数。

  • 因此得出一个结论,想要真正的删除一个文件,只有当这个文件的硬链接数为0时,这个文件才算被真正删除。

演示如下:

image-20230530210243115

如何理解软链接

image-20230530215132858

  • mkdir -p是一个Linux/Unix命令,用于创建目录,如果目录已经存在则不会报错,也不会进行任何操作。其中,"-p"选项表示递归创建目录,即如果父级目录不存在,则会自动创建父级目录。例如,如果要创建一个名为"/home/user1/test"的目录,可以使用命令"mkdir -p /home/user1/test"

image-20230530215728161

软链接的应用场景

[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具有一个映射关系。

image-20230531104841658

为什么创建一个目录,其硬链接数天然为2?

image-20230531105508440

为什么下图的硬链接数为3?

image-20230531111517435

注:

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)。

  1. 访问时间(access time):也称为atime,指的是文件或目录最后一次被访问的时间。例如,如果你打开一个文件并查看了它的内容,这个文件的访问时间就会被更新为当前时间。
  2. 修改时间(modify time):也称为mtime,指的是文件或目录最后一次被修改的时间。例如,如果你编辑了一个文件并保存了修改,这个文件的修改时间就会被更新为当前时间。
  3. 更改时间(change time):也称为ctime,指的是文件或目录的属性最后一次被修改的时间。例如,如果你使用chmod命令改变了一个文件的权限,这个文件的更改时间就会被更新为当前时间。

需要注意的是,访问时间和修改时间只针对文件内容的访问和修改,而更改时间则包括了文件内容的修改以及文件属性的修改。

演示如下:

  • Change:属性最后修改的时间

image-20230531152250096

  • Modify :文件最后修改的时间

image-20230531152811319

  • Access :最后访问的时间

image-20230531154207365

动态库和静态库

概念

  • 静态库(静态库的文件后缀为.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.ofile2.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所依赖的动态链接库。

image-20230602220859539

第五步:将静态库安装到系统路径下

  • 安装
[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命令的一般步骤如下:

  1. 将共享库文件复制到系统的共享库目录中,或者将共享库目录添加到/etc/ld.so.conf文件中。
  2. 运行ldconfig命令更新共享库缓存。
  3. 使用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 

静态库的加载

image-20230603162454156

动静态库的加载

image-20230603170231054
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)]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值