Linux下软硬链接和动静态库制作详解

这篇具有很好参考价值的文章主要介绍了Linux下软硬链接和动静态库制作详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

软硬链接

概念 

软链接的创建

硬链接的创建

软硬链接的本质区别

理解软链接

理解硬链接

小结

动静态库

概念

动静态库的制作

静态库的制作 

动态库的制作 


前言

本文涉及到inode和地址空间等相关概念,不知道的小伙伴可以先阅读以下两篇文章了解一下哦。

 Linux文件系统

Linux进程地址空间

觉得内容对你有所帮助的话可以给博主一键三连哦 

你们的支持将是我继续创作的动力

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

如果内容有错或者不足的话,还望能指出

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

软硬链接

概念 

软链接(Symbolic Link):是一个特殊的文件,它指向另一个文件或目录。

硬链接(Hard Link):是指向文件数据块的另一个文件名。

软链接的创建

命令:ln -s [源文件] [链接文件]

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

从inode编号可以看出软链接其实就是一个独立的文件。

硬链接的创建

命令:ln [源文件] [链接文件]

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

从inode编号可以看出这两个文件其实是同一个,只不过是不同的名字。

软硬链接的本质区别

软硬链接的本质区别就在于有没有独立的inode,软链接有独立的inode,所以软链接是一个独立的文件;硬链接没有独立的inode,所以硬链接不是一个独立的文件。可以这么理解软链接就相当于你在windows下给一个应用创建了一个快捷方式;硬链接就相当于你将一个文件拷贝了一下并且改了一下文件名。

理解软链接

软链接创建时会被占用一定的磁盘空间,它只是一个指向原始文件或目录的指针,如果原始文件或目录被删除,软链接仍然存在,但无法访问到真正的文件或目录。

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

理解硬链接

创建硬链接没有独立的inode,所以不是真正的创建了一个新文件,所以硬链接不占用空间。实际上创建硬链接就是在指定的目录下建立了不同文件名和指定inode的映射关系仅此而已。

再来看看下面的实验

在创建硬链接后,硬链接数由1变为了2

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

删除文件后,硬链接数由2变为了1

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

也可以用unlink进行删除。 

如何理解这里的硬链接数呢?

其实这个硬链接数就是一个引用计数和C++智能指针中的shared_ptr差不多,当创建一个硬链接时,硬链接数会+1,删除文件时也只是在目录中将文件名和inode的映射关系删掉,并且把硬链接数-1,而inode还在并没有被删掉,只有当硬链接数减为0时才是真正意义上的将文件删掉了。

那么我们创建一个目录看一下硬链接数又会有什么现象?

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

为什么这个默认创建的目录,硬链接数是2呢?

在默认创建的目录下会有两个默认的文件.和.. 

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

默认创建的目录硬链接数是2,是因为:自己目录名和inode建立了映射关系,自己目录下的.和inode也建立了关系,所以这个.表示的是当前目录(所表示的就是tmp,只不过名字不同罢了)。

在这个tmp目录下,再创建一个目录硬链接数又会发生什么变化呢?

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

硬链接数由2变为了3 

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

从上图中可以看到dir目录下的..的inode编号是不是和tmp的inode编号一样,所以硬链接数由2又变为了3的原因是在dir目录下的..和指定的tmp的inode也建立了映射关系,而..代表的就是上级目录(所表示的也是tmp,只不过名字不同罢了),所以你在 cd ..时会返回到上级目录。

小结

  • 硬链接就是同一文件的不同文件名,创建硬链接就是在指定目录下建立了不同文件名和指定inode的映射关系仅此而已。
  • 软链接是一个独立的文件,相当与创建了一个快捷方式。
  • 在默认创建的目录下会有两个默认的文件.和..,.代表的就是当前目录,..代表的就是上级目录。
  • 硬链接数本质是一个引用计数。

动静态库

概念

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

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

动态链接

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

静态链接

静态链接是一种将程序所需的所有库函数和外部模块都在编译时候链接到最终的可执行文件中的链接方式。在静态链接中,编译器将程序中所有用到的库函数和外部模块的代码复制一份到最终的可执行文件中,使得最终的可执行文件可以独立运行,不依赖于系统中是否存在相应的库函数和外部模块。

动静态库的制作

这里就写了两个函数——一个累加函数和一个打印函数,用来演示动静态库的制作

累加函数 

mymath.h///
#pragma once

#include <stdio.h>

extern int addToTarget(int from, int to);



/mymath.c
#include "mymath.h"

int addToTarget(int from, int to)
{
    int sum = 0;
    for(int i = from; i <= to; i++)
    {
        sum += i;
    }

    return sum;
}

打印函数

myprint.h///
#pragma once

#include <stdio.h>
#include <time.h>

extern void Print(const char *str);


myprint.c///

#include "myprint.h"

void Print(const char *str)
{
    printf("%s[%d]\n", str, (int)time(NULL));
}

静态库的制作 

制作的静态库要能被对方使用必须得将上面两个函数编译生成.o文件(目标文件),之后将编译好的.o文件和写好的.h文件打包给别人,别人就能使用了。

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

main.c

#include "myprint.h"
#include "math.h"

int main()
{
    Print("hello world");
    int res = addToTarget(1, 100);

    printf("res: %d\n", res);

    return 0;
}

将上面生成的两个.o文件和main.o文件共同链接形成可执行程序 

 Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

虽然说这样的gcc写法是可以的,但是如果文件一多,编译的时候要把那么多的.o文件都写上去实在是太麻烦了。所以我们可以使用命令ar -rc将两个函数生成的.o文件进行归档。

ar(archive 归档)是gnu归档工具,rc表示的是(replace and create)

制作静态库

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

libhjx.a就是将mymath.o和myprint.o归档后生成的静态库,前面的lib和.a后缀是必带的,而hjx是这个静态库的名字(下面的动态库也是一样的)。所以使用ar -rc归档的过程就是在制作静态库。

查看静态库中的目录列表
Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

t:列出静态库中的文件

v:详细信息

但是我们还想让它自动化的帮我们生成.o文件和静态库,那就需要使用makefile了。

编写makefile

libhjx.a:mymath.o myprint.o
	ar -rc libhjx.a mymath.o myprint.o
mymath.o:mymath.c
	gcc -c mymath.c -o mymath.o
myprint.o:myprint.c
	gcc -c myprint.c -o myprint.o

.PHONY:clean
clean:
	rm -rf *.o libhjx.a

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

我们要怎么将我们制作好的静态库给别人使用呢?

通常情况下,我们会弄一个目录,比如就叫做hjx,目录中包含一个include目录和一个lib目录,include目录下都是库的所有头文件,而lib目录下是对应的静态库文件。最后将这个目录打包给对方使用

因此我们编写的makefile还要添加自动化打包功能

libhjx.a:mymath.o myprint.o
	ar -rc libhjx.a mymath.o myprint.o
mymath.o:mymath.c
	gcc -c mymath.c -o mymath.o
myprint.o:myprint.c
	gcc -c myprint.c -o myprint.o

.PHONY:hjx 
hjx:
	mkdir -p hjx/lib 
	mkdir -p hjx/include
	cp -rf *.h hjx/include
	cp -rf *.a hjx/lib 

.PHONY:clean
clean:
	rm -rf *.o libhjx.a hjx

这样就不需要敲太多指令了,全部交给makefile自动帮我们生成了。 

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

对方拿到了我们的这个hjx目录之后要怎么使用呢?

方法一:将我们的静态库拷贝到系统路径中 

头文件gcc的默认搜索路径是:/usr/include

库文件的默认搜索路径是:/lib64 或者 /usr/lib64

所以我们要把我们的头文件拷贝到/usr/include下,库文件拷贝到/lib64下

  • 拷贝头文件

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

  • 拷贝库文件

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

在编译的时候我们要带上静态库名来表示我们要链接哪个静态库

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

-l:指定库名

而我们上面拷贝头文件和库文件到系统的默认路径下就叫做库的安装

但是这种方法还是不可取的,因为你写的库是没有做任何可靠性验证测试的,而系统的库都是经过大佬们精心打磨过的,你把你写的库拷贝到系统中可能就会造成库的污染。

方法二:手动指定静态库路径和头文件路径

gcc main.c -I ./hjx/include/ -L ./hjx/lib/ -lhjx

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

-I:指定路径搜索头文件

-L:指定库路径

注:一定要加上库名因为你lib目录下的库文件如果有很多,gcc就不知道你究竟要链接哪个库了,所以gcc要求带上库名指定你要链接哪个库。

动态库的制作 

和静态库制作那里一样,我们也是要生成.o文件但是在使用gcc生成的时候要加-fPIC选项表示生成位置无关代码

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

然后再用这里的.o文件来制作我们的动态库。在终端输入以下命令

gcc -shared myprint_d.o mymath_d.o -o libhjx.so
 

这里的-shared选项表示的是生成动态库

同样的这样让我们手动去将文件一个个写上去太麻烦了,所以我们需要重新编写makefile,让它自动化生成。

.PHONY:all
all:libhjx.so libhjx.a

libhjx.so:mymath_d.o myprint_d.o
	gcc -shared mymath_d.o myprint_d.o -o libhjx.so 
mymath_d.o:mymath.c
	gcc -c -fPIC mymath.c -o mymath_d.o
myprint_d.o:myprint.c
	gcc -c -fPIC myprint.c -o myprint_d.o

libhjx.a:mymath.o myprint.o
	ar -rc libhjx.a mymath.o myprint.o
mymath.o:mymath.c
	gcc -c mymath.c -o mymath.o
myprint.o:myprint.c
	gcc -c myprint.c -o myprint.o

.PHONY:output
output:
	mkdir -p output/lib 
	mkdir -p output/include
	cp -rf *.h output/include
	cp -rf *.a output/lib 
	cp -rf *.so output/lib 

.PHONY:clean
clean:
	rm -rf *.o *.a *.so output

使用动态库

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

可以看到output文件中是我们制作的动态库

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

我们和静态库一样,手动指定库路径和头文件路径,但是静态库和动态库的名字都是一样的,那么gcc会使用哪一个库呢?

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

可以看到当我们运行生成的可执行程序时报错了,报错的内容是不能打开动态库,并且使用ldd来查看链接的动态库时法相libhjx.so没有找。但是我们可以得出结论gcc默认优先使用的是动态库,既然gcc默认优先使用的是动态库,那么我们想使用静态库怎么办,可以加-static选项。

 gcc main.c -I ./output/include/ -L ./output/lib/ -lhjx -static

-static的意义摒弃默认优先使用动态库的原则,而是直接使用静态库的方案。 

可是话说回来为什么上面会报错呢,output里面明明就有动态库啊?

首先要了解我们的可执行程序和动态库是分批加载的,可执行程序加载时,是先到地址空间中的代码区,然后通过页表映射到内存中,当我们的动态库加载时,先到内存中,然后通过页表映射到地址空间中的共享区(共享区存放的是库的起始加载虚拟地址+函数的偏移量),之后操作系统就可以通过共享区来拿到我们的动态库。因此虽然我们指出了动态库路径,但是是给gcc指出的,而我们的操作系统并不知道动态库在哪,所以导致了运行的时候会报错。

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

那么我们该怎样正确的使用动态库呢?

方法一:将我们的动态库拷贝到系统路径中 

这个方法在静态库的制作那里演示过了,这里就不再演示了。

方法二:将动态库的路径添加到环境变量LD_LIBRARY_PATH中

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库路径

注意:一定要加上之前的环境变量并且带上冒号进行分隔,否则之前的环境变量会被覆盖掉。 

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

所以我们的动态库路径就添加进环境变量LD_LIBRARY_PATH了。

那么我们再运行一下试试

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

运行成功了

但是这个方法有个缺点,它只在本次登录有效,你下次登录时你添加的环境变量就会被抹去。

方法三:创建.conf文件将动态库的路径添加到/etc/ld.so.conf.d/目录下

1、创建hjx.conf文件 

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

2、将动态库路径添加到/etc/ld.so.conf.d/hjx.conf中

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

3、ldconfig将我们的配置文件生效一下

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

这个方法可以永久有效

方法四:建立软链接

Linux下软硬链接和动静态库制作详解,linux笔记,linux,运维,服务器

除了以上的方法外,还有其它方式可以用比如修改系统的配置文件等等。有兴趣的小伙伴可以自己去了解一下。 

最后再来回答最后一个问题:为什么要有库呢?

站在使用库的角度,库的存在可以减少我们的开发周期,极大地提高开发效率,避免重复造轮子,同时也能够利用已有的经过测试和优化的代码提高系统的性能和稳定性。

站在编写库的人的角度,库使用起来非常简单,方便开发人员进行快速开发,并且库中的实现对方看不到,从而实现了代码的安全。此外库只需提供一些标准的接口和协议,就可以使不同的组件和系统之间能够进行有效的通信和交互。文章来源地址https://www.toymoban.com/news/detail-861065.html

到了这里,关于Linux下软硬链接和动静态库制作详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Linux]理解文件系统!动静态库详细制作使用!(缓冲区、inode、软硬链接、动静态库)

            hello,大家好,这里是bang___bang_,今天来谈谈的文件系统知识,包含有缓冲区、inode、软硬链接、动静态库。本篇旨在分享记录知识,如有需要,希望能有所帮助。 目录 1️⃣缓冲区 🍙缓冲区的意义 🍙常见缓冲区刷新策略 🍙缓冲区位置猜想 🍥现象猜测 🍥现象解

    2024年02月13日
    浏览(37)
  • linux之文件系统、inode和动静态库制作和发布

    1.没有被打开的文件都在磁盘上  --- 磁盘级文件 2.对磁盘级别的文件,我们的侧重点 单个文件角度 -- 这个文件在哪里,有多大,其他属性是什么? 站在系统角度 --  一共有多少文件?各自属性在哪里?如何快速找到?可以存储多少个文件?如何快速找到指定文件?如何对此

    2024年04月10日
    浏览(34)
  • 【Linux】软硬链接 / 动静态库

    硬链接(hard link) 可以将它理解为原始文件的别名, 和原始文件使用相同的 inode 编号和 data block.(inode 是文件在该磁盘分区内的唯一标识, 记录着文件的属性等内容; data block 是文件的内容) 可以使用 ln 指令为文件创建一个硬链接. 当创建一个新的硬链接时, 该文件的硬链接数就会

    2024年04月08日
    浏览(33)
  • 【Linux】软硬链接与动静态库

    相关文章: 【Linux】动静态库以及动静态链接 【Linux】基础IO_文件系统 我们知道,每一个文件都会有自己的inode编号,我们可以通过如下指令来查看:  我们发现, 每一个不同文件的inode编号都不相同,所以inode可以说是用来标识文件的标识符 。接下来,我们通过下面指令来

    2024年02月10日
    浏览(39)
  • 【看表情包学Linux】软硬链接 | 软连接数 | 创建软硬链接 | 动静态库 | 生成静态库 | 生成动态库

       🤣  爆笑 教程  👉 《看表情包学Linux》👈   猛戳订阅     🔥 💭 写在前面: 上一章我们讲解了 inode,为文件系统收了尾,这几章我们充分地讲解完了文件系统的知识点,现在我们开始开始学习软硬链接了。如果没有文件系统的铺垫,想直接理解软硬链接难免有些困

    2024年02月14日
    浏览(31)
  • 【看表情包学Linux】软硬链接 | 动静态库

       🤣  爆笑 教程  👉 《看表情包学Linux》👈   猛戳订阅     🔥 💭 写在前面: 上一章我们讲解了 inode,为文件系统收了尾,这几章我们充分地讲解完了文件系统的知识点,现在我们开始开始学习软硬链接了。如果没有文件系统的铺垫,想直接理解软硬链接难免有些困

    2024年02月16日
    浏览(31)
  • 【Linux】基础IO——文件系统|软硬链接|动静态库

    基于上篇博客所写到的文件各种操作都是基于被打开文件所进行操作的,那么如果一个文件没有被打开它存在哪里呢?这个答案毫无疑问肯定是存在于磁盘上的。那么,对于一个没有打开的文件(也就是磁盘文件)我们应该如何理解呢? 这里我们所要讲的磁盘是机械硬盘、即

    2024年02月04日
    浏览(35)
  • Linux基础IO【软硬链接与动静态库】

    ✨个人主页: 北 海 🎉所属专栏: Linux学习之旅 🎃操作环境: CentOS 7.6 阿里云远程服务器 假设你下载了一款游戏,你是否会跑到游戏所在目录中双击 .exe 打开游戏?答案是不会,大多数人都会通过桌面的快捷方式直接打开文件,而这个快捷方式实际就是对 .exe 的 软链接 文

    2024年02月02日
    浏览(27)
  • 【Linux】—— 详解软硬链接

    前言: 本期,我将要给大家讲解的是有关 Linux下 软硬链接 的相关知识!!! 目录 前言 (一)理解硬链接 1.什么是硬链接 2.创建硬链接  3.硬链接的使用场景 (二)理解软链接 1.什么是软链接 2.创建软链接 3.软链接使用场景 (三)硬链接和软链接的对比 总结 文件共享可以

    2024年02月03日
    浏览(26)
  • 【探索Linux】—— 强大的命令行工具 P.13(文件系统 | 软硬链接 | 动态库和静态库)

    在计算机科学领域中,Linux 系统一直以来都是备受推崇的操作系统之一。其中,文件系统、软硬链接、动态库和静态库是 Linux 系统中非常重要的概念,在实际应用中扮演着不可或缺的角色。 在上一篇文章中,我们了解了 Linux 系统中文件描述符、重定向以及基础 IO 操作的相关

    2024年02月04日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包