已解决:动态库加载失败:error while loading shared libraries: xxx.so: cannot open shared object file: No such file or directory

使用动态库编译链接main.c后,得到名为main的可执行程序。但是在运行main可执行程序时,程序报错:
./main: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory
如下图所示:
在这里插入图片描述

2. 问题出现的原因

首先利用ldd命令查看一下main的动态库依赖关系。

ldd main

 
 
  • 1

结果如下图所示,可以看到,动态库libcalc.so没有被找到。
在这里插入图片描述

至于找不到的情况分为两种:

  • 系统里根本不存在libcalc.so库;
  • libcalc.so库在系统中存在,但是ld-linux.so找不到,即libxxx.so库的位置没有告知ld-linux.so。

由于动态库libcalc.so是自己刚刚创建好的,因此属于第二种情况。

0.1 动态库的工作原理可知,只要把动态库libcalc.so的绝对路径添加到动态载入器ld-linux.so的搜索路径中,那么动态载入器就可以获取到动态库libcalc.so的绝对路径,接着就可以找到动态库文件libcalc.so,将动态库文件载入内存,然后就可以使用动态库里面的代码,最终可执行程序main就可以成功运行,不会报错。

还是由0.1 动态库的工作原理可知,动态载入器搜索动态库绝对路径的搜索顺序为:DT_RPATH段→环境变量LD_LIBRARY_PATH→/etc/ld.so.cache文件列表→/lib/或/usr/lib目录

因此,添加动态库绝对路径的方法也有很多种

接下来,我们就按照上述分析进行操作。

3. 解决问题

3.1 将动态库绝对路径添加至环境变量LD_LIBRARY_PATH

3.1.1 临时环境变量

首先进入存放动态库的文件夹内,然后输入如下命令,获取动态库libcalc.so的绝对路径,然后复制此绝对路径。

  • pwd的全称为Print Working Directory,即显示工作目录的路径。
pwd

 
 
  • 1

输出如下:
在这里插入图片描述
然后输入如下命令,将动态库绝对路径添加至环境变量LD_LIBRARY_PATH中。其中:

  • export的意思是设置一个环境变量。
  • $LD_LIBRARY_PATH的意思是,获取环境变量LD_LIBRARY_PATH当前的值。
  • :/home/veroll/Linux/lesson1.6/library/lib的意思是,在冒号后写上要新加入环境变量的值,即动态库的绝对路径/home/veroll/Linux/lesson1.6/library/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/veroll/Linux/lesson1.6/library/lib

 
 
  • 1

在这里插入图片描述

输入完上述命令后,输入如下命令检查一下环境变量LD_LIBRARY_PATH的值。其中:

  • echo的意思是,输出echo后的内容。有两种用法:1. 直接跟着string,则在界面上打印出string。2. $sth,$表示后面接的是变量,会在界面上显示出sth变量的值。
echo $LD_LIBRARY_PATH

 
 
  • 1

输出结果如下图,可见动态库的绝对路径已经成功添加至环境变量LD_LIBRARY_PATH中了。
在这里插入图片描述
最后再使用ldd命令查看一下main的动态库依赖关系,如下图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。接下来就可以找到动态库文件libcalc.so,然后将动态库文件载入内存,接着就可以使用动态库里面的代码,最终可执行程序main就可以成功运行了。
在这里插入图片描述
我们来试着运行一下main。
在这里插入图片描述
此时main就可以成功运行了。

但是这个方法有一个缺点,就是:刚才配置环境变量时,本质上是在刚才使用的终端中配置的环境变量(临时的环境变量),一旦关闭刚才的终端,再新启动一个终端,再次运行main时,就又会报错。
在这里插入图片描述

因此最好配置一个永久的环境变量。配置永久的环境变量又有两种方法,一种是用户级别,另一种是系统级别。

3.1.2 用户级别:配置永久环境变量

输入命令cd或者命令cd /home/veroll/,进入用户目录(veroll)下。
在这里插入图片描述
输入命令vim ./.bashrc,编辑.bashrc文件。其中:

  • ./的意思是当前目录下。
    在这里插入图片描述

在这里插入图片描述
然后在当前模式(命令模式)下输入shift+g(也就是G)移动到这个文件的最后一行,然后输入o(小写的o),即在目前光标所在的下一行处输入新的一行,进入输入模式。
(更多vim指令请见博客:Linux vi/vim命令大全)
在这里插入图片描述
在这里输入配置环境变量的命令export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/veroll/Linux/lesson1.6/library/lib
在这里插入图片描述
然后按一下esc见进入命令模式,输入命令:wq,按回车,保存并退出。
在这里插入图片描述
接着输入如下命令,使修改生效。其中:

  • source的用法语句为source filename,意思是通知当前shell读入路径为filename的文件并依次执行文件中的所有语句。该命令通常用.替代,如:source ./.bashrc. ./.bashrc是等价的。详细用法见博客:Linux中的source命令(.命令)的用法
source ./.bashrc

 
 
  • 1

如下图所示运行完此命令后,.bashrc文件的修改就生效了,也就是说环境变量添加成功了。
在这里插入图片描述
然后进入main的目录中,使用ldd命令查看一下main的动态库依赖关系。
在这里插入图片描述
如上图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。

运行一下main。
在这里插入图片描述
运行成功。

3.1.3 系统级别:配置永久环境变量

在系统级别下配置永久环境变量时,需要获取权限。

在任意目录下,输入如下命令,然后输入用户密码。

sudo vim /etc/profile

 
 
  • 1

在这里插入图片描述
在这里插入图片描述
然后在当前模式(命令模式)下输入shift+g(也就是G)移动到这个文件的最后一行,然后输入o(小写的o),即在目前光标所在的下一行处输入新的一行,进入输入模式。
(更多vim指令请见博客:Linux vi/vim命令大全)
在这里插入图片描述

在这里输入配置环境变量的命令export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/veroll/Linux/lesson1.6/library/lib

在这里插入图片描述

然后按一下esc见进入命令模式,输入命令:wq,按回车,保存并退出。
在这里插入图片描述

接着输入如下命令,使修改生效。

source /etc/profile

 
 
  • 1

在这里插入图片描述
使用ldd命令查看一下main的动态库依赖关系。
在这里插入图片描述
如上图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。

运行一下main。
在这里插入图片描述
运行成功。

3.2 将动态库绝对路径添加至/etc/ld.so.cache文件列表中

首先输入如下命令查看一下ld.so.cache文件,并尝试对其进行修改

vim /etc/ld.so.cache

 
 
  • 1

在这里插入图片描述

发现是二进制文件,无法直接对其进行修改,因此需要间接修改文件内容。输入:q!,不保存直接退出。

接着,输入如下命令,对ld.so.conf文件进行编辑,间接修改ld.so.cache文件内容。

sudo vim /etc/ld.so.conf

 
 
  • 1

在这里插入图片描述
在这里插入图片描述
输入o(小写的o)进入输入模式,输入动态库的绝对路径/home/veroll/Linux/lesson1.6/library/lib。输入完成后,按下esc键,然后输入:wq,保存并退出。
在这里插入图片描述
然后输入如下命令,进行更新

sudo ldconfig

 
 
  • 1

在这里插入图片描述
进入main所在目录后,使用ldd命令查看一下main的动态库依赖关系。
在这里插入图片描述

如上图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。

运行一下main。
在这里插入图片描述
运行成功。

3.3 将动态库添加至/lib/或/usr/lib目录

如本节标题所示,直接将需要用到的动态库添加至/lib//usr/lib目录中,即可使用动态库。

查看一下/lib//usr/lib目录中的内容,发现里面存放有系统的动态库文件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

若用户自己制作的动态库文件名与系统的动态库文件名重名的话,当把用户自己制作的动态库文件移动至上述两个文件夹内,会将系统的动态库文件覆盖掉,造成损失。因此不推荐使用此方法。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐