我有一个Linux C++程序,它可以构建&链接(使用-Wl,--no-undefined ),但是当我尝试运行它时却无法加载它的所有库。我一直试图用ldd检查它的依赖关系,但我不知道为什么它会被失败的库绊倒:
$ ldd standalone_test
... lots of libraries that are found ...
libPythia6.so => not found现在,根据嵌入在可执行文件中的RUNPATH,应该在一个地方找到这个库:
$ readelf -d ./standalone_test | grep "RUNPATH"
0x000000000000001d (RUNPATH) Library runpath: [/home/jeremy/code/NOvARwgt/cmake-build-debug/src:/home/jeremy/code/genie-2.12.2/lib:/opt/genie/GENIESupport/pythia6/v6_424/lib:/opt/root/lib:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug]
$ ls /opt/genie/GENIESupport/pythia6/v6_424/lib
liblund.a libPythia6.so pydata.o(可执行的standalone_test和库libPythia6.so都是ELF64,所以我不认为这是处理器体系结构不匹配之类的。)
我已经尝试深入了解在库加载期间发生了什么,并且我注意到在同一个可执行文件下加载不同库(其中一些是由可执行文件请求的库请求的“链”加载)报告了不同的RUNPATH:
$ LD_DEBUG=libs,files ./standalone_test 2>&1 | ack RUNPATH
# this one is the 'correct' RUNPATH (the one from the executable)
19553: search path=/opt/root/lib/tls/haswell/x86_64:/opt/root/lib/tls/haswell:/opt/root/lib/tls/x86_64:/opt/root/lib/tls:/opt/root/lib/haswell/x86_64:/opt/root/lib/haswell:/opt/root/lib/x86_64:/opt/root/lib (RUNPATH from file ./standalone_test)
# next one has been 'augmented' with processor architecture subdirs
19553: search path=/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/haswell/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/haswell:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/haswell/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/haswell:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src:/home/jeremy/code/genie-2.12.2/lib/tls/haswell/x86_64:/home/jeremy/code/genie-2.12.2/lib/tls/haswell:/home/jeremy/code/genie-2.12.2/lib/tls/x86_64:/home/jeremy/code/genie-2.12.2/lib/tls:/home/jeremy/code/genie-2.12.2/lib/haswell/x86_64:/home/jeremy/code/genie-2.12.2/lib/haswell:/home/jeremy/code/genie-2.12.2/lib/x86_64:/home/jeremy/code/genie-2.12.2/lib:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/haswell/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/haswell:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls:/opt/genie/GENIESupport/pythia6/v6_424/lib/haswell/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/haswell:/opt/genie/GENIESupport/pythia6/v6_424/lib/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib:/opt/root/lib:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/haswell/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/haswell:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/haswell/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/haswell:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug (RUNPATH from file ./standalone_test)
... more variants of these two ...
# this one contains only a single entry from the real runpath??
19553: search path=/opt/root/lib (RUNPATH from file ./standalone_test)在最后一种情况下,库不被定位,可执行文件由于cannot open shared object file: No such file or directory错误而失败,它也将继续查看系统搜索路径。
我的问题是:RUNPATH 上的这些变体是如何配制的?--据我所知,它们是由请求它们的各种库修改的,但我似乎在googleweb上找不到任何解释。(也许我在寻找错误的东西?)如果我理解了这里发生了什么,我就能倒过来理解为什么库一开始就找不到了。
发布于 2018-10-28 18:11:26
我的问题是: RUNPATH上的这些变体是如何配制的?
与较早的RPATH不同,RUNPATH仅在搜索二进制文件的直接依赖项时应用。
也就是说,如果a.out有RUNPATH of /foo和NEEDED of libfoo.so (位于/foo中),那么libfoo.so就会被找到。但是如果libfoo.so本身依赖于libbar.so (也位于/foo中),而如果libfoo.so没有RUNPATH,那么就找不到libbar.so。
这种行为促进“每个ELF二进制应该是自给自足的”。在上述情况下,libfoo.so不是自给自足的(需要libbar.so,但没有说明在哪里可以找到它)。
如果您使用RPATH,那么那里的路径将适用于每个搜索,libbar.so也会被找到。在链接-Wl,--disable-new-dtags时,您可以使用a.out实现这一点。
https://stackoverflow.com/questions/52993692
复制相似问题