Linux中的Hard Link、Symbolic Link,以及/usr/bin/ld: cannot find -lxxx错误的解决

链接有两种,一种被称为硬链接(Hard Link),另一种被称为软链接或符号链接(Symbolic Link)。符号链接是一类特殊的文件, 其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用。符号链接最早在4.2BSD版本中出现(1983年)。今天POSIX操作系统标准、大多数类Unix系统都支持符号链接。

 

一、Linux中Hard Link与Symbolic Link:基本概念

在Linux的文件系统中,一个文件对应一个inode与若干个data block。inode与data block都通过编号来标识,例如第917931个inode,第20112个data block。inode中记录着文件的属性,如文件的所有者、所属用户组、对文件的权限以及指向data block的指针。文件的真正内容是存放在data block中的。一个文件的内容,被分割成若干部分保存在不同的data block中,通过inode可以找到文件对应的所有data block。使用ls命令并打开-i选项就可以查看文件的inode编号:

*使用ls --help命令可以看到其中一行内容是:

-i, --inode                print the index number of each file

A hard link: a mapping from a file name to some file’s data。这种Link不会占用磁盘空间。例如,现在有一个名为JonathanFileHL的Hard Link指向JonathanFile.txt,实际上,JonathanFileHL和JonathanFile.txt具有相同的inode。如下面的示意图(图片来自【1】):

A soft/symbolic link: a mapping from a file name to another file name; whenever you refer to a symbolic link, the system will automatically translate it to the target name。Symbolic Link:这种Link会实际赞用磁盘空间。例如,现在有一个名为JonathanFileSL的Symbolic Link指向JonathanFile.txt,JonathanFileSL将会有独立的inode以及data block。源文件的文件名保存在Symbolic Link的。对源文件重命名或者删除,将会导致Symbolic Link失效。Symbolic Link的示意图如下:

创建Link的命令为ln,如果指定了-s选项,那么将会创建Symbolic Link,否则就是Hard Link。

首先创建文件original.txt,创建original.txt的硬连接 hard.txt(使用ln命令),并查看所有文件的属性。可以发现,original.txt和 hard.txt的属性完全一致(它们的inode完全一致,若两个文件,拥有同样的inode,那么就产生了所谓的硬连接。红框标出),注意其中蓝色圈标出的数字表示的就是该文件的硬连接数。这也告诉我们查看soft link的方法:

  1. Open a terminal and move to that directory.
  2. Type the command: ls -la. This shall long list all the files in the directory even if they are hidden.
  3. The files that start with l are your symbolic link files——最后一行中lrwxrwxrwx中第一个字母l就表示soft link,而且后面紫色圈中也示出了soft link的指向。

二、深入理解Hard Link与Symbolic Link

inode block: this is the formal name used to refer to “the first block of a file” in Linux; 

Hard link: another directory entry for a given file

上图中的link count记录了有多少个hard link指向这个文件。只有当所有的hard link都被删除后(即link count变为0),文件才真的被删除。

The inode of a symbolic file contains:

  • A flag saying that “I am symbolic link”
  • A file name of the target file

Soft Link存在的意义是什么呢?Very important for software upgrade——After upgrade, you just redirect the symbolic link to the new version.

三、/usr/bin/ld: cannot find -lxxx 错误

这是在Linux中编译程序的时候,可能会出现的一个错误。这个错误是因为链接程序ld在指定目录里找不到libxxx.so这个库。而且,你在使用gcc编译程序的时候一定使用了-l这个参数:它用来指定程序要链接的库,-l参数紧接着就是库名。这里的库名并非真正的库文件名。以库名为math的库为例,他的库文件名是libmath.so或者libmath.a(Linux下的库文件都要以lib开头,其中.so是动态库,.a是静态库)。可见,把库文件名的头lib和尾.so去掉就是库名了。
 
 
现在,如果我们要用到一个第三方提供的库libtest.so,那么只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,就能用上libtest.so库了。实际上,以下两个命令是等价的:
 
gcc -o mytest mytest.c /usr/lib/libtest.so
gcc -o mytest mytest.c -ltest

放在/lib/usr/lib/usr/local/lib里的库直接用-l参数就能链接了(如果是标准C语言库,可以不指定其库路径和库名称)。

如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:

/usr/bin/ld: cannot find -lxxx

也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest。

另外,其实大部分libxxxx.so只是一个soft link,比如libgfortran.so链接到/lib/x86_64-linux-gnu/libgfortran.so.4,libgfortran.so.4又链接到libgfortran.so.4.0.0,

如果没有这样的链接,则会出错,因为ld只会找libxxxx.so,所以如果你要用到xxxx库,而只有libxxxx.so.x或者libxxxx-x.x.x.so,就需要创造一个soft link。

 
总的来说,如果编译程序时遇到/usr/bin/ld: cannot find -lxxx,那么发生这种错误的原因有以下三种情形:
  1. 系统没有安装相对应的lib
  2. 相对应的lib版本不对
  3. lib(.so档)的symbolic link不正确,没有连结到正确的函式库文件(.so)
解决方法:
  1. 先判断在/usr/lib 下的相对应的函式库文件(.so) 的symbolic link 是否正确,若不正确改成正确的连结目标即可解决问题。
  2. 若不是symbolic link 的问题引起,而是系统缺少相对应的lib,那么安装lib即可解决。

 

 
【本文完】

参考文献与推荐阅读材料

【1】Hard Link与Symbolic Link

【2】gcc的-l参数和-L参数

 

 

这个错误信息通常出现在尝试创建一个新的符号链接symbolic link)时,提示目标文件或目录已经存在。在Linux或类Unix系统符号链接是一种特殊的文件类型,它指向另一个文件或目录的位置,可以理解为快捷方式或别名。 错误信息 "ln: failed to create symbolic link '/usr/local/bin/node': File exists" 的含义是,在执行 `ln` 命令创建一个名为 `/usr/local/bin/node` 的符号链接时,由于 `/usr/local/bin/node` 已经存在,所以无法创建。 处理这类问题的方法通常有以下几种: 1. 如果你确定 `/usr/local/bin/node` 是一个旧的、不再需要的符号链接,你可以先删除它,然后再创建新的链接: ``` rm /usr/local/bin/node ln -s 新的目标文件或目录 /usr/local/bin/node ``` 2. 如果 `/usr/local/bin/node` 是一个旧的符号链接,但是指向了正确的文件,而你只是想要更新它指向的文件,可以先删除旧的符号链接,然后重新创建: ``` rm /usr/local/bin/node ln -s 新的目标文件或目录 /usr/local/bin/node ``` 3. 如果 `/usr/local/bin/node` 是一个普通文件,并且你想要将其转换为符号链接,你需要先删除该文件,然后创建新的符号链接: ``` rm /usr/local/bin/node ln -s 新的目标文件或目录 /usr/local/bin/node ``` 4. 如果 `/usr/local/bin/node` 是一个普通文件,并且你只想创建一个符号链接而保留原文件,你需要选择另一个名字来创建符号链接,例如: ``` ln -s 新的目标文件或目录 /usr/local/bin/node_new ``` 在执行删除和创建符号链接的操作之前,建议确认 `/usr/local/bin/node` 的确是一个不再需要的符号链接,或者你完全知道为什么要更新它。避免误删重要文件或链接
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白马负金羁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值