ldd
命令wiki解释:Ldd
(List 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
所要求的版本不一致。
在自己编译新的版本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
为特定版本解决了,但是我尝试了这个办法并没有用。
首先认为是tiff
库缺失了没有安装,于是手动安装tiff
库。输入sudo apt install libtiff
,这个命令还没有输完,可以看到候选有libtiff5-dev
和libtiff-dev
,上面报错是缺少tiff4
,这里我也不太懂该安装哪个,就都装上了。
后来又看到一篇博客(对‘TIFFReadDirectory@LIBTIFF_4.0’未定义的引用),说要手动源码编译安装tiff4
的库,于是我又下载手动编译安装到/usr/local
下。但是还是没有解决问题,后面解决问题的时候可以看到,甚至就是这个办法又引出了新问题。
后来看到一篇博客(//usr/local/lib/libopencv_imgcodecs.so.3.4:对‘TIFFReadRGBAStrip@LIBTIFF_4.0’未定义的引用)说是因为安装了anaconda
,anaconda
中也有libtiff
库,这个库和系统的库冲突了。可以在~/.zshrc
中注释掉anaconda
的环境变量,即# export PATH="/home/cc/anaconda3/bin:$PATH"
。或者直接干脆卸载掉anaconda
的libtiff
库,即conda remove libtiff
。对我仍然没用。
使用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
可以看到系统默认的库目录是在/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
我只是删除了原来的库,也没有重新建立软链接,最后问题就解决了!