【Linux】软硬链接和动静态库

[复制链接]
发表于 2026-10-3 15:36:37 来自手机 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

软链接、硬链接与动态静态库:一次讲清

这两组概念经常被混着记:软硬链接分不清"inode 换没换",动静态库分不清"什么时候把代码拷进来"。其实抓住 inode 和链接期这两个锚点,就都清楚了。

一、软链接和硬链接

1.1 两者的本质区别

  • 软链接:是一个独立文件,有自己的 inode 和 inode 编号。
  • 硬链接:不是一个独立文件,它和目标文件共用同一个 inode。硬链接就是在指定目录下,给目标文件新增一个"文件名 → inode 编号"的映射关系。

创建命令:

ln -s 文件名 链接文件名   # 创建软链接
ln 文件名 链接文件名       # 创建硬链接

1.2 理解硬链接

真正定位磁盘上文件的是 inode,不是文件名。Linux 允许多个文件名指向同一个 inode:

[root@localhost linux]# touch abc
[root@localhost linux]# ln abc def
[root@localhost linux]# ls -li
abc def 263466 abc
       263466 def

abc 和 def 的链接状态完全相同,它们互称为指向文件的硬链接。内核记录了这个连接数,inode 263466 的硬链接数为 2。

删除文件时实际做了两件事:一是在目录里把对应的记录删掉,二是把硬链接数减 1;减到 0 才释放对应的磁盘空间。

ll 列出的那一串数字就是硬链接数。它本质上是 inode 属性里的一个计数器 count,标识有几个文件名和这个 inode 建立了映射。

1.3 理解软链接

ln -s 文件名 链接文件名

软链接的 inode 明显和原文件不同,它是个独立文件。它的作用更像 Windows 桌面上的快捷方式:比如程序 mytest.exe 在很深的目录下,每次都要 ./lesson18/mytest.exe 跑一次太麻烦,建个软链接到当前目录:

ln -s ./lesson18/mytest.exe my.exe

之后直接 ./my.exe 就行,这就是软链接存在的意义——把深路径变成一个顺手的名字。

1.4 删除

直接 rm 就能删,但更推荐用专门的取消链接指令:

unlink 文件名

用 unlink 的语义更明确:删的是"这个链接",而不是"这个文件本身"。

二、动态库与静态库

2.1 什么是动静态库

  • 动态库 .so:程序运行时才去链接库的代码,多个程序共享使用同一份库代码。
  • 静态库 .a:程序在编译链接阶段就把库代码链接进可执行文件,运行后不再需要静态库。

一个和动态库链接的可执行文件,只保存它用到的函数入口地址表,而不是外部函数所在目标文件的整个机器码。

2.2 动态链接

在可执行文件开始运行之前,外部函数的机器码由操作系统从磁盘上的动态库复制到内存中,这个过程叫动态链接。动态库能在多个程序间共享,所以动态链接让可执行文件更小,省磁盘;操作系统用虚拟内存机制让物理内存中的一份动态库被所有用到它的进程共用,内存和磁盘都省。

2.3 静态链接

静态链接更直接:链接时把目标接口的二进制代码全部拷进原文件,所以静态链接出来的文件天生就大。优缺点很鲜明:

  • 动态链接:文件小、省空间、升级库只需换一份 .so;但库路径中的库丢失或损坏,程序运行时就找不到,直接报错。
  • 静态链接:代码已经拷进程序,不依赖原库,库丢了也不影响;代价是文件大、升级要重新编译。

三、生成动静态库

3.1 生成静态库

ar -rc [静态库] [.o 文件列表]

库命名以 lib 开头、以 .a 结尾。所谓静态库,本质就是把若干源文件编译出的 .o 打包起来,别人用我们的库,就是在库里找到 .o 再丢进可执行文件里。

3.2 生成动态库

gcc -fPIC -c myadd.c -o myadd.o
gcc -shared -o libmyadd.so myadd.o

和静态库唯一的关键差别:生成 .o 时必须加 gcc -fPIC,为了产生与位置无关码,这样该 .o 才能在任意加载地址上跑起来。

四、使用动静态库

站在使用方角度,看三参数怎么传:

  • -I:指定头文件查找路径。
  • -L:指定库文件搜索路径。
  • -l:在 -L 指定的路径下链接哪一个库。
gcc mytest.c -o mytest -I lib-dyl/include/ -L lib-dyl/lib/ -lmymath

4.1 找不到动态库的报错

运行时如果报 error while loading shared libraries,就是进程找不到动态库。解法三条:

  1. 把动态库拷到系统路径下(如 /lib64)安装。
  2. 通过环境变量——程序运行时会到环境变量里查自己需要的库路径,即配置 LD_LIBRARY_PATH。
  3. 写进系统配置文件(如 /etc/ld.so.conf.d/ 下的配置 + ldconfig 刷新缓存)。

五、常见坑

  • 软链接能跨文件系统,硬链接不能:硬链接必须在同一分区同一个文件系统内,跨分区建硬链接会报 Invalid cross-device link。
  • 删了原文件硬链接还在:这正是硬链接数存在的意义,count 不为 0 数据就还在。
  • 软链接指向了相对路径的源:在别处调用时相对路径解析基准会变,建软链接时用绝对路径更稳。
  • 动态库升级后老程序挂了:这正是动态链接的短板,可以用符号链接 libfoo.so → libfoo.so.1 缓解。
  • 忘记 -fPIC:能编译过但一运行就报 segmentation fault 或 cannot open shared object file。

小结

硬链接看 inode——同一个 inode 多个名字,删一个另一个还在;软链接是独立文件——本质是指向目标的快捷方式。静态库在编译期把代码拷进程序,动态库在运行期才链接、可共享。生成动态库必须加 -fPIC,运行时找不到库就走 LD_LIBRARY_PATH 或拷进系统目录。

qidao123.com企服评测-应用市场 编辑提示

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表