linux中ldd命令查看二进制文件(程序或库)所依赖的其他库(LIBTIFF_4.0未定义的引用问题)

文章目录

  • 1.`ldd`命令
  • 2.使用ldd命令排查动态库依赖错误的实例
    • 2.1.问题描述
    • 2.2.解决问题流程

1.ldd命令

wiki解释:LddList Dynamic Dependencies,意译为列出动态库依赖关系)是一款在类Unix系统的实用工具,负责在命令行内输出程序或共享库所依赖的函数库。此工具由罗兰·麦克格拉斯及乌尔里希·德雷佩尔开发。Ldd在指定的程序缺少部分函数库的情况下将无法显示结果。

用法示例如下,下面的ldd /usr/bin/mp3blaster语句就是查看mp3blaster这个可执行文件所使用的动态链接库,可以看到它所使用的动态链接库都是一些软链接,然后软链接指向了真正链接的库。

user@home ~/ $ ldd /usr/bin/mp3blaster
        linux-vdso.so.1 =>  (0x00007fff8fdff000)
        libsidplay.so.1 => /usr/lib/libsidplay.so.1 (0x00007f4ea98ec000)
        libvorbisfile.so.3 => /usr/lib/libvorbisfile.so.3 (0x00007f4ea96e4000)
        libvorbis.so.0 => /usr/lib/libvorbis.so.0 (0x00007f4ea94b6000)
        libncurses.so.5 => /lib/libncurses.so.5 (0x00007f4ea9273000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007f4ea9056000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f4ea8d41000)
        libm.so.6 => /lib/libm.so.6 (0x00007f4ea8abe000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f4ea88a7000)
        libc.so.6 => /lib/libc.so.6 (0x00007f4ea8523000)
        libogg.so.0 => /usr/lib/libogg.so.0 (0x00007f4ea831c000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007f4ea8118000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4ea9b59000)

注意ldd不仅能看可执行文件的动态库依赖关系,还可以查看动态库所依赖的其他动态库。因此当编译程序链接的时候出现aaa.so undefined reference to bbb.so这种错误的时候,即aaa.so对bbb.so未定义的引用这种错误的时候,说明aaa.so这个动态库依赖bbb.so这个动态库,并且链接到bbb.so这个动态库的时候出现了错误。这个错误有可能是bbb.so根本就不存在,也有可能是bbb.so这个库的版本和aaa.so所要求的版本不一致。

2.使用ldd命令排查动态库依赖错误的实例

2.1.问题描述

在自己编译新的版本OpenCV的时候,甚至在编译ros工程包链接原本编译好的Opencv的时候,都出现了/usr/local/lib/libopencv_imgcodecs.so.3.2.0:对‘TIFFReadDirectory@LIBTIFF_4.0’未定义的引用的错误,可以发现这个是编译opencv的时候本身的错误。但是后面还出现了大量的//usr/lib/libgdal.so.20:对‘TIFFWriteRawStrip@LIBTIFF_4.0’未定义的引用这中错误,如下所示。这个就不是OpenCV的错误了,是gdal这个库链接tiff这个库的时候出现了错误。

/usr/bin/ld: warning: libopencv_imgproc.so.3.4, needed by /home/kk/vins_fusion_catkin_ws/devel/lib/libcamera_models.so, may conflict with libopencv_imgproc.so.3.2
/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0:对‘TIFFReadDirectory@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFLastDirectory@LIBTIFF_4.0’未定义的引用
/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0:对‘TIFFWriteEncodedStrip@LIBTIFF_4.0’未定义的引用
/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0:对‘TIFFIsTiled@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFSwabArrayOfShort@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFIsByteSwapped@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFFlushData@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFFreeDirectory@LIBTIFF_4.0’未定义的引用
/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0:对‘TIFFScanlineSize@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFWriteEncodedTile@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFWriteBufferSetup@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFTileSize@LIBTIFF_4.0’未定义的引用
/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0:对‘TIFFRGBAImageOK@LIBTIFF_4.0’未定义的引用
/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0:对‘TIFFClose@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFWriteRawStrip@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFSetTagExtender@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFGetFieldDefaulted@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFSwabArrayOfLong@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFTileSize64@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFReadRGBATileExt@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFStripSize@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFMergeFieldInfo@LIBTIFF_4.0’未定义的引用
/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0:对‘TIFFSetWarningHandler@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFGetConfiguredCODECs@LIBTIFF_4.0’未定义的引用
//usr/lib/x86_64-linux-gnu/libgeotiff.so.2:对‘_TIFFmalloc@LIBTIFF_4.0’未定义的引用
//usr/lib/x86_64-linux-gnu/libgeotiff.so.2:对‘_TIFFmemcpy@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFClientdata@LIBTIFF_4.0’未定义的引用
//usr/lib/x86_64-linux-gnu/libgeotiff.so.2:对‘_TIFFrealloc@LIBTIFF_4.0’未定义的引用
//usr/lib/x86_64-linux-gnu/libgeotiff.so.2:对‘_TIFFmemset@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFReadRGBAStripExt@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFWriteCheck@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFSetWriteOffset@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFDefaultStripSize@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFScanlineSize64@LIBTIFF_4.0’未定义的引用
//usr/lib/libgdal.so.20:对‘TIFFIsBigEndian@LIBTIFF_4.0’未定义的引用
//usr/lib/x86_64-linux-gnu/libpoppler.so.73:对‘TIFFFdOpen@LIBTIFF_4.0’未定义的引用

这里到底是什么问题不太清楚,关键是之前使用都没有问题,因此gdal这个库链接tiff这个库应该也不存在问题啊,问什么突然报错呢?有一篇博客(对‘TIFFLastDirectory@LIBTIFF_4.0’未定义的引用)在编译vins-mono的代码时也报了同样的错误,但是它通过指定opencv为特定版本解决了,但是我尝试了这个办法并没有用。

2.2.解决问题流程

  1. 首先认为是tiff库缺失了没有安装,于是手动安装tiff库。输入sudo apt install libtiff,这个命令还没有输完,可以看到候选有libtiff5-devlibtiff-dev,上面报错是缺少tiff4,这里我也不太懂该安装哪个,就都装上了。
    在这里插入图片描述

  2. 后来又看到一篇博客(对‘TIFFReadDirectory@LIBTIFF_4.0’未定义的引用),说要手动源码编译安装tiff4的库,于是我又下载手动编译安装到/usr/local下。但是还是没有解决问题,后面解决问题的时候可以看到,甚至就是这个办法又引出了新问题

  3. 后来看到一篇博客(//usr/local/lib/libopencv_imgcodecs.so.3.4:对‘TIFFReadRGBAStrip@LIBTIFF_4.0’未定义的引用)说是因为安装了anacondaanaconda中也有libtiff库,这个库和系统的库冲突了。可以在~/.zshrc中注释掉anaconda的环境变量,即# export PATH="/home/cc/anaconda3/bin:$PATH"。或者直接干脆卸载掉anacondalibtiff库,即conda remove libtiff。对我仍然没用。

  4. 使用ldd命令查看出错的libgdal.so库依赖的库中包含的libtiff.so库的情况

cd /usr/lib
ldd libgdal.so | grep libtiff.so

终于找到问题所在!如下图所示,显示libtiff.so.5: no version information available ,也就是调用的libtiff.so文件的版本对应不上!参考博客:linux下Matlab调用及库链接问题no version information available
在这里插入图片描述
最终解决
先查看libtiff.so的库存在哪些路径下:

locate libtiff.so

linux中ldd命令查看二进制文件(程序或库)所依赖的其他库(LIBTIFF_4.0未定义的引用问题)_第1张图片

可以看到系统默认的库目录是在/usr/lib/x86_64-linux-gnu下的,注意这个目录,这个目录下的库是在安装了gnu 编译器后生成的,很多默认的库都在里面。所以原来没有出现libtiff库的链接错误,说明之前使用的应该就是这个目录下的libtiff库。而/usr/local/lib下的库则是后来自己编译源码安装的,并且libgdal最后也是连接到了这个库上,所以应该就是这里出现了错误!

解决

sudo rm -rf /usr/local/lib/libtiff*   # 删除自己安装的所有libtiff库

# 下面类似的重新建立软链接的命令我没有执行
sudo ln -s /usr/lib/x86_64-linux-gnu/libtiff.so.5.2.4 /usr/local/MATLAB/R2017a/bin/glnxa64/libtiff.so.5

我只是删除了原来的库,也没有重新建立软链接,最后问题就解决了!

再看编译opencv的时候,cmake自动找到的libtiff库,就是系统默认的库了:
linux中ldd命令查看二进制文件(程序或库)所依赖的其他库(LIBTIFF_4.0未定义的引用问题)_第2张图片

你可能感兴趣的:(Linux工具操作笔记,linux)