Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 链接时如何跟踪库的需求?_C++_Linux_Opencv_Gcc_Ld - Fatal编程技术网

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

C++ 链接时如何跟踪库的需求?,c++,linux,opencv,gcc,ld,C++,Linux,Opencv,Gcc,Ld,快速版本:为什么gcc需要一个特定的库?如何在执行gcc时跟踪其依赖关系 长版本:我尝试编译使用OpenCV的C++代码,使用FFMPEG。编译时出现错误: //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@LIBSW

快速版本:为什么gcc需要一个特定的库?如何在执行gcc时跟踪其依赖关系

长版本:我尝试编译使用OpenCV的C++代码,使用FFMPEG。编译时出现错误:

//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。在我的系统中:

$ 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)
此命令要求libopencv_videoio.so,而libopencv_videoio.so反过来应该查找libavcodec.so.58。扫描所有opencv共享对象:

& 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-extra57包。当我删除它时,Synaptic会自动安装libavcodec57包。如果我将其卸下,则会重新安装第一个。因为有很多依赖项需要这个库。如果有人想分享一个快速修复它的方法,我将不胜感激

谢谢你抽出时间

如果您想知道,下面是gcc的长输出--trace。我有另一个更长的-v-Wl,-v,与此非常相似,但没有新提到libavcodec

$ 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

有两种方法可以实现这一点:

  • 阅读手册;总是个好主意
  • 安装依赖项管理器。我使用MacPorts,但也有一些 各种各样的。他们有一个图书馆数据库 当您安装或构建其中一个 库管理员还将安装或生成所有库 您正在安装的那个取决于它们是否已经存在,以及它们所安装的那个 依靠

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

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

当你找到所需的线路时,请仔细注意线路上到底有什么。是
libavcodec.so
,还是
libavcodec.so.57
?它只是一个文件名还是有一个绝对路径?这会影响链接器在搜索时将找到的内容


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

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

在一个文本文件中,我放置了gcc输出中出现的共享对象的完整路径列表。然后运行:

while read -r line; do echo "Library $line has these dependencies:\n $(ldd -r $line)"; done <textfile.txt

读取-r行时
;do echo“库$line具有以下依赖项:\n$(ldd-r$line)”;我也看到了手册页。我很感激你们的奉献精神,我认为这并不能真正回答我的问题。我想调试ld进程。
ldd-r
的递归特性在工作时非常方便,但是可能会遇到一些问题。首先,您不能在交叉编译时使用它,因为库需要是可以由系统的动态加载程序实际加载的东西。另一个是查找库时使用的
ldd
搜索路径与尝试链接时使用的
ld
搜索路径不同。因此,ldd发现的内容(右侧与左侧查找的内容)可能不正确,而它递归发现的内容也可能不正确。
while read -r line; do echo "Library $line has these dependencies:\n $(ldd -r $line)"; done <textfile.txt