我知道可以使用readelf -d <elf> | grep RPATH从shell检查给定的二进制文件,但是可以在一个进程中执行此操作吗?
像(我的完全系统调用):
/* get a copy of current rpath into buffer */
sys_get_current_rpath(&buffer);
Run Code Online (Sandbox Code Playgroud)
我正在尝试在代码库中诊断一些可疑的SO链接问题,并且如果可能的话,我希望以这种方式检查RPATH(我宁愿不必生成外部脚本).
这个页面 - http://labs.qt.nokia.com/2011/10/28/rpath-and-runpath/ - 说明了ld.so中的库搜索顺序:
Unless loading object has RUNPATH:
RPATH of the loading object,
then the RPATH of its loader (unless it has a RUNPATH), ...,
until the end of the chain, which is either the executable
or an object loaded by dlopen
Unless executable has RUNPATH:
RPATH of the executable
LD_LIBRARY_PATH
RUNPATH of the loading object
ld.so.cache
default dirs
Run Code Online (Sandbox Code Playgroud)
然后建议:
当您发送二进制文件时,要么使用RPATH而不是RUNPATH,要么确保在运行之前设置LD_LIBRARY_PATH.
因此,使用RPATHwith RUNPATH是不好的,因为RUNPATH取消了类似的RPATH间接动态加载不能按预期工作?但为什么然后RPATH被弃用RUNPATH呢?
有人可以解释一下情况吗?
我正在使用 CMake 构建跨平台项目。目前我正在尝试在 Linux 上运行它。我最近添加了一个用于运行测试的项目,但它无法运行,因为它找不到共享库之一,特别是libtbbmalloc.so.2:
/tests: error while loading shared libraries: libtbbmalloc.so.2: cannot open shared object file: No such file or directory`
Run Code Online (Sandbox Code Playgroud)
当我ldd在可执行文件上运行时,我得到以下信息:
linux-vdso.so.1 (0x00007fffeb572000)
libtbbmalloc_proxy.so.2 => /home/username/dev/tbb/libtbbmalloc_proxy.so.2 (0x00007f50afe00000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f50afa70000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f50af6d0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f50af4b0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f50af0a0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f50aee90000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f50aec70000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f50aea60000)
/lib64/ld-linux-x86-64.so.2 (0x00007f50b0400000)
libtbbmalloc.so.2 => not found
Run Code Online (Sandbox Code Playgroud)
我的测试项目的 CMakeLists.txt 如下所示:
set(test_sourcefiles main_tests.cpp)
add_executable(tests ${test_sourcefiles})
target_link_libraries(tests Catch2::Catch2 MyLib)
Run Code Online (Sandbox Code Playgroud)
MyLib 使用 tbb,我想这就是我的可执行文件( …
在CentOS 7.2,我已经建立了与G ++ 4.8.5应用程序,因为它不能找到一个库,无法运行确实存在的runpath。我很确定它在两周前有效。什么可能导致这种情况?
$ ./app
./app: error while loading shared libraries: libhdf5.so.9: cannot open shared object file: No such file or directory
$ ldd ./app | grep libhdf5
libhdf5.so.9 => not found
$ readelf app -d | grep path
0x000000000000001d (RUNPATH) Library runpath: [/opt/ProductName/lib:/opt/ProductName/lib/private]
$ ll /opt/ProductName/lib/libhdf5.so*
lrwxrwxrwx. 1 fotechd fotechd 16 Oct 26 14:38 /opt/ProductName/lib/libhdf5.so -> libhdf5.so.9.0.0
lrwxrwxrwx. 1 fotechd fotechd 16 Oct 26 14:38 /opt/ProductName/lib/libhdf5.so.9 -> libhdf5.so.9.0.0
-rwxr-xr-x. 1 fotechd fotechd 3316074 Oct …Run Code Online (Sandbox Code Playgroud) 有无数的线程描述了它们是什么RPATH,RUNPATH以及LD_LIBRARY_PATH它们如何交互以解决库的位置.
要设置RPATH使用gcc选项:
-Wl,-rpath,/path/to/dir
Run Code Online (Sandbox Code Playgroud)
要设置LD_LIBRARY_PATH,请使用:
export LD_LIBRARY_PATH= <path of lib>
Run Code Online (Sandbox Code Playgroud)
我找不到的是如何设置RUNPATH?
我对共享库的二级依赖有疑问。\n假设我们有以下依赖树:
\nlibA.so\n\xe2\x94\x9c\xe2\x94\x80libB.so\n\xe2\x94\x94\xe2\x94\x80libC.so\n \xe2\x94\x94\xe2\x94\x80libD.so\nRun Code Online (Sandbox Code Playgroud)\n也就是说,共享库 A 依赖于共享库 B 和 C,而共享库 C 本身依赖于共享库 D。一个很好的例子是libCGSL共享库,它依赖于 CBLAS。
为了制作一个自给自足的易于使用的包并避免安装的共享库的不同版本出现问题,我将库libB、libC和libD与libA、 和 一起打包,如 Drepper\xe2\x80\x99s文章, \xe2中所述\x80\x9c如何编写共享库\xe2\x80\x9d (2011),我添加了链接标志-Wl,-rpath,\\$ORIGIN --enable-new-dtags来设置 的RUN_PATH,libA.so这样动态加载器就可以在相应目录中找到 的依赖项libA,而不需要设置LD_LIBRARY_PATH(其中有它的缺点)。
问题是,设置RUN_PATHinlibA对辅助依赖项没有帮助,例如libD.so。\n打开动态加载程序调试消息(通过设置)表明加载程序尝试仅在标准LD_DEBUG库位置中查找,而不是在(与查找或 的作用相反)。libD.solibAlibBlibC
有办法解决这个问题吗?
\n事实上,如果我有源代码或正确编译的静态库,我可以静态链接库 C 和 D。
\n但是有更好的办法吗?
解决方案:
\n正如Employed Russian …