首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >链接时如何跟踪库的需求?

链接时如何跟踪库的需求?
EN

Stack Overflow用户
提问于 2019-02-02 14:59:12
回答 3查看 280关注 0票数 1

快速版本:为什么gcc要一个特定的图书馆?在执行gcc的过程中,如何跟踪它的依赖性?

长版本:我正在尝试编译使用opencv的c++代码,它使用ffmpeg。编译时出现错误:

代码语言:javascript
复制
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_alloc@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_free@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_is_initialized@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_close@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_init@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_convert@LIBSWRESAMPLE_2' sin definir

我知道libavcodec.so需要libswresample.so,但我希望链接到libavcodec.so.58,而不是57。我想追踪这个依赖性:我想知道gcc为什么要那个文件。

我知道系统中只有libavcodec.so会更好,但是现在我无法摆脱libavcodec.so.57。在我的系统里:

代码语言:javascript
复制
$ ldconfig -p | grep libavcodec
libavcodec.so.58 (libc6,x86-64) => /usr/local/lib/libavcodec.so.58
libavcodec.so.57 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavcodec.so.57
libavcodec.so (libc6,x86-64) => /usr/local/lib/libavcodec.so  <== This is a link to 58)

如果您想知道,gcc命令行是这样的,请注意,这里没有-lavcodec:

代码语言:javascript
复制
g++ -Wl,--trace-symbol=libavcodec -L/usr/local/lib -L"/home/alejandro/Desarrollo eclipse/os1/Thirdparty" -o "os1"  ./src/Converter.o ./src/Frame.o ./src/FrameDrawer.o ./src/Initializer.o ./src/KeyFrame.o ./src/KeyFrameDatabase.o ./src/KeyFrameTriangulacion.o ./src/LocalMapping.o ./src/LoopClosing.o ./src/Map.o ./src/MapDrawer.o ./src/MapPoint.o ./src/ORBextractor.o ./src/ORBmatcher.o ./src/Optimizer.o ./src/PnPsolver.o ./src/PuntoLejano.o ./src/PuntosLejanosDB.o ./src/Sim3Solver.o ./src/System.o ./src/Tracking.o ./src/Video.o ./src/Viewer.o ./src/main.o ./src/osmap.o ./src/osmap.pb.o   -lopencv_core -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_calib3d -lpthread -lpangolin -lGL -lGLU -lDBoW2 -lg2o -lprotobuf

这个命令请求libopencv_videoio.so,而后者又应该查找libavcodec.so.58。扫描所有opencv共享对象:

代码语言:javascript
复制
& ldd -r /usr/local/lib/libopencv_*.so | grep libavcodec
libavcodec.so.58 => /usr/local/lib/libavcodec.so.58 (0x00007f0f03c11000)
libavcodec.so.58 => /usr/local/lib/libavcodec.so.58 (0x00007fb00e3fa000)
libavcodec.so.58 => /usr/local/lib/libavcodec.so.58 (0x00007f916be48000)

奖金:为什么我不能删除libavcodec.so.57

使用Synaptic,该文件属于libavcodec-ex5 7包。当我删除它时,Synaptic会自动安装libavcodec57包。如果我删除它,第一个将被重新安装。因为有很多依赖关系需要这个库。如果有人想分享一种快速的方法来解决问题,我会很感激的。

谢谢您抽时间见我。

如果你想知道,这是gcc的长期输出-跟踪。我在-v -Wl,-v上还有一个,非常类似的,但是没有提到libavcodec。

代码语言:javascript
复制
$ g++ -Wl,--trace -L/usr/local/lib -L"/home/alejandro/Desarrollo eclipse/os1/Thirdparty" -o "os1"  ./src/Converter.o ./src/Frame.o ./src/FrameDrawer.o ./src/Initializer.o ./src/KeyFrame.o ./src/KeyFrameDatabase.o ./src/KeyFrameTriangulacion.o ./src/LocalMapping.o ./src/LoopClosing.o ./src/Map.o ./src/MapDrawer.o ./src/MapPoint.o ./src/ORBextractor.o ./src/ORBmatcher.o ./src/Optimizer.o ./src/PnPsolver.o ./src/PuntoLejano.o ./src/PuntosLejanosDB.o ./src/Sim3Solver.o ./src/System.o ./src/Tracking.o ./src/Video.o ./src/Viewer.o ./src/main.o ./src/osmap.o ./src/osmap.pb.o   -lopencv_core -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_calib3d -lpthread -lpangolin -lGL -lGLU -lDBoW2 -lg2o -lprotobuf
/usr/bin/ld: modo elf_x86_64
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
./src/Converter.o
./src/Frame.o
./src/FrameDrawer.o
./src/Initializer.o
./src/KeyFrame.o
./src/KeyFrameDatabase.o
./src/KeyFrameTriangulacion.o
./src/LocalMapping.o
./src/LoopClosing.o
./src/Map.o
./src/MapDrawer.o
./src/MapPoint.o
./src/ORBextractor.o
./src/ORBmatcher.o
./src/Optimizer.o
./src/PnPsolver.o
./src/PuntoLejano.o
./src/PuntosLejanosDB.o
./src/Sim3Solver.o
./src/System.o
./src/Tracking.o
./src/Video.o
./src/Viewer.o
./src/main.o
./src/osmap.o
./src/osmap.pb.o
-lopencv_core (/usr/local/lib/libopencv_core.so)
-lopencv_features2d (/usr/local/lib/libopencv_features2d.so)
-lopencv_highgui (/usr/local/lib/libopencv_highgui.so)
-lopencv_videoio (/usr/local/lib/libopencv_videoio.so)
-lopencv_imgcodecs (/usr/local/lib/libopencv_imgcodecs.so)
-lopencv_imgproc (/usr/local/lib/libopencv_imgproc.so)
-lopencv_calib3d (/usr/local/lib/libopencv_calib3d.so)
/lib/x86_64-linux-gnu/libpthread.so.0
-lpangolin (/usr/local/lib/libpangolin.so)
-lGL (/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libGL.so)
-lGLU (/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libGLU.so)
-lDBoW2 (/home/alejandro/Desarrollo eclipse/os1/Thirdparty/libDBoW2.so)
-lg2o (/home/alejandro/Desarrollo eclipse/os1/Thirdparty/libg2o.so)
-lprotobuf (/usr/local/lib/libprotobuf.so)
-lstdc++ (/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so)
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libmvec.so.1
/lib/x86_64-linux-gnu/libmvec.so.1
libgcc_s.so.1 (/usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so.1)
/lib/x86_64-linux-gnu/libc.so.6
(/usr/lib/x86_64-linux-gnu/libc_nonshared.a)elf-init.oS
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
libgcc_s.so.1 (/usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so.1)
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_alloc@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_free@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_is_initialized@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_close@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_init@LIBSWRESAMPLE_2' sin definir
//usr/lib/x86_64-linux-gnu/libavcodec.so.57: referencia a `swr_convert@LIBSWRESAMPLE_2' sin definir
/usr/bin/ld: se encontraron errores de enlace, se borra el ejecutable `os1'
collect2: error: ld returned 1 exit status
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-02-02 20:17:19

几乎可以肯定的是,您正在加载的共享库之一需要另一个共享库。这将被编码到ELF头中的共享库本身中。使用共享库上的readelf -d查看此。寻找NEEDED线路。ld将以这种方式处理它发现的库,但它们不会出现在--trace的输出中。

我不知道自动查找源的方法,但是尝试在跟踪中出现的库中找到readelf,您应该找到一个需要libavcodec的库,或者需要一个需要libavcodec的库,等等。

当你找到所需的线时,要小心地注意它里面到底有什么。是libavcodec.so还是libavcodec.so.57?它只是一个文件名还是有一个绝对路径?这会影响链接器在搜索它时会发现什么。

对于链接器搜索路径,请查看ld的rpath-link选项的文档。该路径中名为libavcodec.so的第一个文件(可能是一个符号链接)是什么?请记住,链接器搜索所需行中出现的内容。它不会将libavcodec.so.57缩短为libavcodec.so并搜索后者。

票数 2
EN

Stack Overflow用户

发布于 2019-02-03 00:08:23

在@TrentP回答之后,显然没有一种简单的方法可以做到,所以我按照他的建议做了,困难的是,我递归地遍历了所有共享对象,寻找依赖项。我使用的是ldd -r,而不是readelf。ldd -r递归地列出依赖项(直接和间接)。

在文本文件中,我将gcc输出中出现的共享对象的完整路径列表放入其中。然后跑:

代码语言:javascript
复制
while read -r line; do echo "Library $line has these dependencies:\n $(ldd -r $line)"; done <textfile.txt

我在列出的输出中找到libavcodec.so.57,并检测到哪个共享对象需要它。

票数 1
EN

Stack Overflow用户

发布于 2019-02-02 15:05:03

有两种方法可以解决这一问题:

  • 阅读手册;总是一个好主意。
  • 安装依赖关系管理器。我使用MacPorts,但是有几种不同的。他们有一个他们管理的库的数据库,当您安装或构建他们的库时,管理器也会安装或构建您正在安装的库所依赖的所有库(如果它们还没有出现),以及它们所依赖的库等等。
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54494231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档