Linux动态库常见问题之-“cannot open shared object file No such file or directory“的解决办法

本文详细解析了Linux环境下动态库加载失败的原因,包括ld找不到动态库或动态库版本不匹配的情况,并提供了多种解决方案,如修改LD_LIBRARY_PATH、使用ldconfig等。同时,文章还介绍了如何通过ldd和readelf检查动态库依赖。

Linux编写程序时,会经常的接触动态库,而在程序运行时可能会遇到类似于:libxxx.so cannot open shared object file No such file or directory的问题,这个代表什么含义,该怎么解决呢?

含义

这个问题代表的含义是,可执行程序在加载libxxx.so库时,找不到该库。至于找不到的情况分为两种:系统里根本不存在libxxx.so库;libxxx.so库在系统中存在,但是ld找不到,即libxxx.so库的位置没有告知ld。

解决办法

对于第一种情况,需要将libxxx.so放到系统ld的搜索路径中;对于第二种情况,通过locate工具定位libxxx.so的位置,然后将其放到ld的搜索路径中。

动态库的搜索路径配置

Linux下ld对于动态库的搜索路径的配置方式包括以下几种方式:

  1. LD_PRELOAD用于动态库的加载,动态库加载的优先级最高
  2. 通过配置gcc编译器的参数-Wl,-rpath指定;
  3. 通过LD_LIBRARY_PATH环境变量指定;
  4. 通过/etc/ld.so.conf指定,切记修改完ld.so.conf之后必须执行/sbin/ldconfig -v同步动态库;
  5. 默认搜素路径/lib、/usr/lib/指定;

同时,上述几种方式存在一定的搜索顺序,按照搜索的先后依次为:1 > 2 > 3 > 4>5。对于动态库的搜索路径的配置可以参考21aspnet的这篇博文

依赖动态库的查看

我们可以通过ldd(x86环境)或者CROSS_COMPILE-readelf -d(ARM环境,CROSS_COMPILE为具体交叉编译前缀,-d 为读取动态库信息的参数)来分析相应平台下可执行程序所依赖的动态库的情况,我们可以举一例:

test.c:

#include <stdio.h>                                                                                                                                                                                                  

void test() 
{
    printf("test()\n");
}

$ $(CC) -fPIC -c test.c //生成test.o,-fPIC(Position-independent code)为了生成位置无关的代码,一般用于动态库编译选项。
$ $(CC) -static -fPIC -o libtest.so test.o

extern void test();                                                                                                                                                                                                 

main.c:

int main()
{
    test();
    return 0;
}

$ $(CC) -c main.c
$ $(CC) main.o -o main -L. -ltest

其中,CC代表不同平台的编译器;

通过,修改CC为gcc或者arm-linux-gnueabi-gcc分别生成X86、ARM平台下的main可执行程序,下面分别通过ldd和arm-linux-gnueabi-readelf查看main所依赖的动态库:

  • X86:

      ldd main
      linux-vdso.so.1 =>  (0x00007ffc98f6a000)
      libtest.so => /home/qihua/develop/linux/static_dynamic_libs/code/libtest.so (0x00007fe850df4000)
      libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe850a10000)
      /lib64/ld-linux-x86-64.so.2 (0x000055950a132000)
    
  • ARM:

      arm-linux-gnueabi-readelf -d  main
      Dynamic section at offset 0xf10 contains 25 entries:
        标记        类型                         名称/值
       0x00000001 (NEEDED)                     共享库:[libtest.so]
       0x00000001 (NEEDED)                     共享库:[libc.so.6]
       0x0000000c (INIT)                       0x10430
       0x0000000d (FINI)                       0x10590
       0x00000019 (INIT_ARRAY)                 0x20f08
       0x0000001b (INIT_ARRAYSZ)               4 (bytes)
       0x0000001a (FINI_ARRAY)                 0x20f0c
       0x0000001c (FINI_ARRAYSZ)               4 (bytes)
       0x00000004 (HASH)                       0x101ac
       0x00000005 (STRTAB)                     0x10300
       0x00000006 (SYMTAB)                     0x10200
       0x0000000a (STRSZ)                      200 (bytes)
       0x0000000b (SYMENT)                     16 (bytes)
       0x00000015 (DEBUG)                      0x0
       0x00000003 (PLTGOT)                     0x21000
       0x00000002 (PLTRELSZ)                   32 (bytes)
       0x00000014 (PLTREL)                     REL
       0x00000017 (JMPREL)                     0x10410
       0x00000011 (REL)                        0x10408
       0x00000012 (RELSZ)                      8 (bytes)
       0x00000013 (RELENT)                     8 (bytes)
       0x6ffffffe (VERNEED)                    0x103e8
       0x6fffffff (VERNEEDNUM)                 1
       0x6ffffff0 (VERSYM)                     0x103c8
       0x00000000 (NULL)                       0x0
    

NOTE

  1. 如果一个可执行程序(常见于第三方库提供的bin)依赖了某些动态库,但可执行程序的CPU架构与本地的CPU架构不同(例如,可执行程序为32位,但本地系统为64位,本地系统安装的动态库也为64位的),那么程序运行时,通过会提示:libxxx.so cannot open shared object file No such file or directory。这是,我们通过locate是可以定位到libxxx.so库,并且libxxx.so处于合适的ld搜索路径之下,这是我们通过修改libxxx.so路径是没有用的。解决问题的方式有这么几种:

    1)下载与本地系统CPU架构相匹配的程序;

    2)在本地系统重新编译该程序;

    3)编译、更新与可执行程序CPU架构相匹配的动态库;

### 解决 Linux 系统中 `cannot open shared object file: No such file or directory` 的问题 当遇到错误提示 `OSError: libopencv_world.so.4.4: cannot open shared object file: No such file or directory` 或类似的共享对象文件找不到的情况时,通常是因为系统未能正确加载所需的动态链接库。以下是可能的原因以及解决方案: #### 1. **确认共享库是否存在** 首先需要验证目标共享库是否确实存在于系统中。可以通过以下命令查找指定的 `.so` 文件: ```bash find / -name "libopencv_world.so.4.4" 2>/dev/null ``` 如果未找到该文件,则说明缺少必要的依赖项。此时可以尝试重新安装相关软件包或手动下载并放置到适当位置。 对于 OpenCV 特定版本缺失的问题,可考虑通过官方源码编译或者使用包管理器安装对应版本[^1]: ```bash sudo apt-get update && sudo apt-get install libopencv-dev ``` #### 2. **更新动态链接器缓存配置** 即使存在所需共享库,但如果其所在目录不在标准搜索路径范围内,仍会出现上述错误消息。因此需检查 `/etc/ld.so.conf` 配置文件及其关联子目录列表是否已包含自定义安装路径 (如 `/usr/local/lib`) 。如果没有,请执行如下操作将其添加进去,并刷新全局可见范围内的变更记录: ```bash echo "/usr/local/lib" | sudo tee -a /etc/ld.so.conf.d/usr_local_lib.conf >/dev/null sudo ldconfig ``` 此过程会通知操作系统新增加了一个潜在可用资源集合地址供后续调用解析参考依据[^2]。 #### 3. **虚拟环境冲突排查** 有时开发人员会在不同项目间切换频繁而导致某些特定框架内部组件相互干扰现象发生;特别是像 PyTorch 这样高度依赖 GPU 加速支持的技术栈更是如此。为了防止此类情况再次重现建议定期审查当前工作区下的全部第三方扩展模块清单以便及时发现异常状况的存在迹象: ```bash conda list | grep -E 'torch|cuda' ``` 理想状态下应该仅仅展示那些源自于可信供应商所提供的正式发行版条目而已而不是混杂着其他来源不明的东西在里面混淆视听造成困扰[^3]. 综上所述,针对本案例描述中的具体表现形式采取相应措施之后应当能够有效缓解乃至彻底消除之前所遭遇过的难题. ```python import cv2 print(cv2.__version__) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值