快速版本:为什么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)如果您想知道,gcc命令行是这样的,请注意,这里没有-lavcodec:
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共享对象:
& 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。
$ 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发布于 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并搜索后者。
发布于 2019-02-03 00:08:23
在@TrentP回答之后,显然没有一种简单的方法可以做到,所以我按照他的建议做了,困难的是,我递归地遍历了所有共享对象,寻找依赖项。我使用的是ldd -r,而不是readelf。ldd -r递归地列出依赖项(直接和间接)。
在文本文件中,我将gcc输出中出现的共享对象的完整路径列表放入其中。然后跑:
while read -r line; do echo "Library $line has these dependencies:\n $(ldd -r $line)"; done <textfile.txt我在列出的输出中找到libavcodec.so.57,并检测到哪个共享对象需要它。
发布于 2019-02-02 15:05:03
有两种方法可以解决这一问题:
https://stackoverflow.com/questions/54494231
复制相似问题