为什么会忽略运行路径?
Why would runpath be ignored?
在 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 26 14:35 /opt/ProductName/lib/libhdf5.so.9.0.0
设置 LD_LIBRARY_PATH
暂时修复它:
$ LD_LIBRARY_PATH=/opt/ProductName/lib ./app
...
OK
我已经能够解决这个问题。对我来说,这是因为未找到的库是一个间接库,而 runpath
实际上并没有解决间接依赖关系。我通过将额外的 -Wl,--disable-new-dtags
链接器选项传递给编译器来使用 rpath
而不是 runpath
来修复它。
这里有一个很好很详细的解释:
为了找到共享对象,dlopen() 按以下顺序搜索:
- 链接二进制文件时使用 ld 的 -rpath 选项设置的运行时库搜索路径(请参阅实用程序参考)
- LD_LIBRARY_PATH 环境变量指定的目录
- _CS_LIBPATH 配置字符串指定的目录
似乎 dlopen()
没有检查 RUNPATH
。
http://www.qnx.com/developers/docs/6.5.0SP1.update/com.qnx.doc.neutrino_lib_ref/d/dlopen.html
在 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 26 14:35 /opt/ProductName/lib/libhdf5.so.9.0.0
设置 LD_LIBRARY_PATH
暂时修复它:
$ LD_LIBRARY_PATH=/opt/ProductName/lib ./app
...
OK
我已经能够解决这个问题。对我来说,这是因为未找到的库是一个间接库,而 runpath
实际上并没有解决间接依赖关系。我通过将额外的 -Wl,--disable-new-dtags
链接器选项传递给编译器来使用 rpath
而不是 runpath
来修复它。
这里有一个很好很详细的解释:
为了找到共享对象,dlopen() 按以下顺序搜索:
- 链接二进制文件时使用 ld 的 -rpath 选项设置的运行时库搜索路径(请参阅实用程序参考)
- LD_LIBRARY_PATH 环境变量指定的目录
- _CS_LIBPATH 配置字符串指定的目录
似乎 dlopen()
没有检查 RUNPATH
。
http://www.qnx.com/developers/docs/6.5.0SP1.update/com.qnx.doc.neutrino_lib_ref/d/dlopen.html