一桩动态库链接错误引发的血案
之前写过一篇PCL安装的博文,原本以为驾轻就熟,谁曾想,竟然也翻了车。
pcl make怎么都不给过,提示:
make[2]: *** No rule to make target '/usr/lib/x86_64-linux-gnu/libGL.so', needed by'***'
中文提示是:make: *** 没有规则可以创建“XXX.o”需要的目标“***”。 停止
这是由于动态库链接中断造成的,我们在相应的文件目录下看看该文件的状态
cd /usr/lib/x86_64-linux-gnu/
然后发现,libGL.so文件是存在的。这里,用ls查看本目录下的所有文件,会发现libGL.so文件名是红的,
这也是其链接断开的表现,右键其属性发现显示为链接中断。
如何恢复呢?首先,要知道它正确的链接方式的什么,我在另一台pcl可用的电脑上查看
wrx@wrx:/usr/lib/x86_64-linux-gnu$ ls -l libGL.so
lrwxrwxrwx 1 root root 14 5月 10 20:17 libGL.so -> libGL.so.1.0.0
由此可见,libGL.so正确的链接方式是与libGL.so.1.0.0链接,但其实这里我并不知道这个文件在哪里,所以要先用全局搜索找到其所在目录:
sudo find / -iname "*libGL.so*"
注意,如果这里提示
**find: ‘/run/user/1000/gvfs’: Permission denied**
sudo不管用,甚至用root权限也没用,参考说这是官方的BUG,该文件夹是空的,我们只需要删掉它之后就可以正常全局查找了:
umount /run/user/1000/gvfs
rm -rf /run/user/1000/gvfs
继续上面的查找,得到如下结果:
wrx@wrx:/usr/lib/x86_64-linux-gnu$ sudo find / -iname "*libGL.so*"
[sudo] wrx 的密码:
/snap/gnome-3-26-1604/90/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
/snap/gnome-3-26-1604/90/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0
/snap/gnome-3-26-1604/88/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
/snap/gnome-3-26-1604/88/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0
/snap/cloudcompare/200/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
/snap/cloudcompare/200/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0
/snap/electronic-wechat/7/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
/snap/electronic-wechat/7/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0
/snap/gnome-3-28-1804/67/usr/lib/x86_64-linux-gnu/libGL.so.1
/snap/gnome-3-28-1804/67/usr/lib/x86_64-linux-gnu/libGL.so.1.0.0
/snap/gnome-3-28-1804/71/usr/lib/x86_64-linux-gnu/libGL.so.1
/snap/gnome-3-28-1804/71/usr/lib/x86_64-linux-gnu/libGL.so.1.0.0
/usr/lib/x86_64-linux-gnu/libGL.so
/usr/lib/x86_64-linux-gnu/libGL.so.1
/usr/lib/x86_64-linux-gnu/libGL.so.1.0.0
/usr/lib/i386-linux-gnu/libGL.so.1
/usr/lib/i386-linux-gnu/libGL.so.1.0.0
OK,找到了libGL.so.1.0.0,手动链接即可,命令如下:
sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so /usr/lib/x86_64-linux-gnu/libGL.so.1.0.0
若提示无法创建符号链接,文件已经存在,就把已经存在的那个文件用sudo rm删掉,
直接删掉不太放心,先sudo cp备份一下
在/usr/lib/x86_64-linux-gnu目录下 sudo cp libGL.so DestDir发现有报错:
符号连接的层数过多
这是因为涉及到这些符号链接文件需要用绝对路径,也就是说,即使你在该目录下,也不要用./libGL.so这种方式,而是要老老实实带上/urs/lib/x86…
ok, 备份之后,手动链接
sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so /usr/lib/x86_64-linux-gnu/libGL.so.1.0.0
这里的两个文件之间似乎没有顺序之分(不确定)
完了之后,一方面可以右键文件属性查看是否链接成功,一方面可以ls -n /usr/lib/x86_64-linux-gnu/libGL.so 查看其链接状态,一方面可以ls该目录下的所有文件看是否有红名存在。
P了个S,最好不要用自动链接,sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so
省去后面的参数就是自动链接,因为这里自动链接到另外一个so文件,且链接完了之后还是红名+链接断开状态(这也是我自己踩了半天的坑)。
总结一下,正确的处理方式应该是:
1.查找libxxx.so文件是否存在
2.查看该文件链接状态
3.修改其链接状态为正确形式
至此,就解决了没有规则可以创建xxx的问题了。pcl也可以愉快地安装下去啦~
BTW,发现了一个神奇的工具apt-file,可以用来解决linux 下任何 lib 文件缺失的情况,
sudo apt-get install apt-file
sudo apt-file update
这样,就装好了该工具,如果要搜索什么lib,如本文的libGL.so,则键入:
sudo apt-file search libGL.so
返回结果如下:
wrx@wrx:/usr/lib/x86_64-linux-gnu$ sudo apt-file search libGL.so
[sudo] wrx 的密码:
libgl1: /usr/lib/x86_64-linux-gnu/libGL.so.1
libgl1: /usr/lib/x86_64-linux-gnu/libGL.so.1.0.0
libglvnd-dev: /usr/lib/x86_64-linux-gnu/libGL.so
nvidia-340: /usr/lib/i386-linux-gnu/libGL.so
nvidia-340: /usr/lib/i386-linux-gnu/libGL.so.1
nvidia-340: /usr/lib/i386-linux-gnu/libGL.so.340.106
nvidia-340: /usr/lib/i386-linux-gnu/libGL.so.340.107
nvidia-340: /usr/lib/x86_64-linux-gnu/libGL.so
nvidia-340: /usr/lib/x86_64-linux-gnu/libGL.so.1
nvidia-340: /usr/lib/x86_64-linux-gnu/libGL.so.340.106
nvidia-340: /usr/lib/x86_64-linux-gnu/libGL.so.340.107
primus-libs: /usr/lib/x86_64-linux-gnu/primus/libGL.so.1
virtualbox-guest-x11: /usr/lib/virtualbox/additions/libGL.so
virtualbox-guest-x11: /usr/lib/virtualbox/additions/libGL.so.1
virtualbox-guest-x11-hwe: /usr/lib/virtualbox/additions/libGL.so
virtualbox-guest-x11-hwe: /usr/lib/virtualbox/additions/libGL.so.1
可以看到你可能是什么包缺失,然后装上就好,比如这里我当时怀疑是libglvnd-dev没装,装了以后发现还是有上面的问题,其实应该先查该so文件是否存在才对,不要像无头苍蝇。
References:
https://blog.csdn.net/fb_941219/article/details/83549720
https://blog.csdn.net/wuguangbin1230/article/details/77816299
https://www.jianshu.com/p/289205fae296
https://zhidao.baidu.com/question/306489700.html