linux中ldd命令查看二进制文件(程序或库)所依赖的其他库(LIBTIFF_4.0未定义的引用问题)
文章目錄
- 1.`ldd`命令
- 2.使用ldd命令排查動態(tài)庫依賴錯誤的實例
- 2.1.問題描述
- 2.2.解決問題流程
1.ldd命令
wiki解釋:Ldd(List Dynamic Dependencies,意譯為列出動態(tài)庫依賴關系)是一款在類Unix系統(tǒng)的實用工具,負責在命令行內(nèi)輸出程序或共享庫所依賴的函數(shù)庫。此工具由羅蘭·麥克格拉斯及烏爾里希·德雷佩爾開發(fā)。Ldd在指定的程序缺少部分函數(shù)庫的情況下將無法顯示結(jié)果。
用法示例如下,下面的ldd /usr/bin/mp3blaster語句就是查看mp3blaster這個可執(zhí)行文件所使用的動態(tài)鏈接庫,可以看到它所使用的動態(tài)鏈接庫都是一些軟鏈接,然后軟鏈接指向了真正鏈接的庫。
user@home ~/ $ ldd /usr/bin/mp3blasterlinux-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不僅能看可執(zhí)行文件的動態(tài)庫依賴關系,還可以查看動態(tài)庫所依賴的其他動態(tài)庫。因此當編譯程序鏈接的時候出現(xiàn)aaa.so undefined reference to bbb.so這種錯誤的時候,即aaa.so對bbb.so未定義的引用這種錯誤的時候,說明aaa.so這個動態(tài)庫依賴bbb.so這個動態(tài)庫,并且鏈接到bbb.so這個動態(tài)庫的時候出現(xiàn)了錯誤。這個錯誤有可能是bbb.so根本就不存在,也有可能是bbb.so這個庫的版本和aaa.so所要求的版本不一致。
2.使用ldd命令排查動態(tài)庫依賴錯誤的實例
2.1.問題描述
在自己編譯新的版本OpenCV的時候,甚至在編譯ros工程包鏈接原本編譯好的Opencv的時候,都出現(xiàn)了/usr/local/lib/libopencv_imgcodecs.so.3.2.0:對‘TIFFReadDirectory@LIBTIFF_4.0’未定義的引用的錯誤,可以發(fā)現(xiàn)這個是編譯opencv的時候本身的錯誤。但是后面還出現(xiàn)了大量的//usr/lib/libgdal.so.20:對‘TIFFWriteRawStrip@LIBTIFF_4.0’未定義的引用這中錯誤,如下所示。這個就不是OpenCV的錯誤了,是gdal這個庫鏈接tiff這個庫的時候出現(xiàn)了錯誤。
/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.解決問題流程
首先認為是tiff庫缺失了沒有安裝,于是手動安裝tiff庫。輸入sudo apt install libtiff,這個命令還沒有輸完,可以看到候選有l(wèi)ibtiff5-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中也有l(wèi)ibtiff庫,這個庫和系統(tǒng)的庫沖突了。可以在~/.zshrc中注釋掉anaconda的環(huán)境變量,即# export PATH="/home/cc/anaconda3/bin:$PATH"。或者直接干脆卸載掉anaconda的libtiff庫,即conda remove libtiff。對我仍然沒用。
使用ldd命令查看出錯的libgdal.so庫依賴的庫中包含的libtiff.so庫的情況
終于找到問題所在!如下圖所示,顯示libtiff.so.5: no version information available ,也就是調(diào)用的libtiff.so文件的版本對應不上!參考博客:linux下Matlab調(diào)用及庫鏈接問題no version information available
最終解決:
先查看libtiff.so的庫存在哪些路徑下:
可以看到系統(tǒng)默認的庫目錄是在/usr/lib/x86_64-linux-gnu下的,注意這個目錄,這個目錄下的庫是在安裝了gnu 編譯器后生成的,很多默認的庫都在里面。所以原來沒有出現(xiàn)libtiff庫的鏈接錯誤,說明之前使用的應該就是這個目錄下的libtiff庫。而/usr/local/lib下的庫則是后來自己編譯源碼安裝的,并且libgdal最后也是連接到了這個庫上,所以應該就是這里出現(xiàn)了錯誤!
解決:
sudo rm -rf /usr/local/lib/libtiff* # 刪除自己安裝的所有l(wèi)ibtiff庫# 下面類似的重新建立軟鏈接的命令我沒有執(zhí)行 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庫,就是系統(tǒng)默認的庫了:
總結(jié)
以上是生活随笔為你收集整理的linux中ldd命令查看二进制文件(程序或库)所依赖的其他库(LIBTIFF_4.0未定义的引用问题)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 段错误、内存泄漏、内存溢出、堆溢出、栈溢
- 下一篇: C语言中指针的地址和内容