问题分析
在Linux系统上运行项目经常遇到无法打开某个shared object file
的问题,错误提示信息类似下面:
some_program error while loading shared libraries: xxx.so:
cannot open shared object file: No such file or directory
翻译一下就是,some_program
在运行时,找不到依赖的xxx.so
这个文件。
但是你确定,xxx.so
这个文件的确被安装在了系统上,怎么会找不到呢?!
例如,下图中libjetson-inference.so
安装在了/usr/local/lib/
目录中,但是在运行detectnet-camera
程序时依然找不到:
这是在building software时可能遇到的经典问题。。。你的software依赖某个library,这个library也已经安装在系统上,但是为什么还是找不到呢?我们首先要搞清楚,系统是如何给某个你在building的software找依赖的libraries的。答案是动态链接器(dynamic linker)。
如果链接器不知道你安装的libraries在哪里,那么它确实找不到。。。所以,我们要告诉它去哪里找。默认情况下,链接器会搜索/usr/lib
,如果找到了你需要的libraries,一切Okay,找不到就自然报错。在解决问题之前,让我们先用ldd
命令看看我们的software需要链接哪些libraries(以上面的detectnet-camera
程序为例):
如果上图中某个
.so
文件后面出现=> not found
就表明链接器没发现该文件。
所以,解决方式也很简单:1)把依赖的所有libraries放系统默认的搜索路径中/usr/lib
;或者 2)给链接器添加正确的搜索路径。
把libraries放到默认搜索路径
把/usr/local/lib
中的文件复制到 /usr/lib
:
$ sudo cp /usr/local/lib/libxx.* /usr/lib
$ sudo ldconfig
或者用软链接的方式,而不是真正复制文件:
$ sudo ln -s /usr/local/lib/libxx.so /usr/lib/libxx.so
$ sudo ldconfig
给链接器添加正确的搜索路径
直接把/usr/local/lib
添加到链接器的候选搜索路径,系统全局的搜索路径在/etc/ld.so.conf
文件中配置,我们只需把/usr/local/lib
加入到文件的最后一行,再执行sudo ldconfig
命令。接着验证一下是否添加成功了:
$ ldconfig -p | grep local
上面的几种方法,都需要root权限。非root用户怎么办呢?接下来的这种方式通过给当前用户的环境中添加library路径而起作用。在用户使用的shell中(yiban )加入usr/local/lib
:
# 打开.bashrc或者.zshr等(视用户的shell而定)
# 添加以下行
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
然后source
被修改的配置文件,使其生效(或者重启shell):
# 以.bashrc为例
source .bashrc