rpath 与patchelf
在Nuitka>=2.7.4
打包含有GDAL
的Python 代码时,会遇到rpath
错误的问题。虽然尚未解决,但是先学一下相关知识备用。
rpath
rpath
(runtime library search path) 是ELF 文件中的一个字段,用于指定程序运行时查找共享库(动态链接库)的路径。
共享库查找顺序
程序运行时,Linux 动态链接器会按一下顺序查找依赖库:
- 编译时指定
-Wl,-rpath='.'
,灵活性较差; LD_LIBRARY_PATH
环境变量指定的路径;runpath
属性(推荐);- ldconfig的缓存:配置文件/etc/ld.so.conf中指定的动态库搜索路径;(系统默认情况下未设置)
- 系统默认路径:
/lib
、/usr/lib
等;
查看RPATH
可以使用$ readelf -d filename | grep PATH
查看RPATH。
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/]
- 一般情况下,RPATH为空,而RUNPATH不为空;
$ORIGIN
表示该elf文件自身所在的目录;- 如需从多个位置查找共享库,则需设置多个RPATH。
patchelf
patchelf
可以用来查看和修改elf 文件的一些属性。
# 修改 rpath
patchelf --set-rpath /new/lib/path myapp
patchelf --set-rpath '$ORIGIN/' myapp
# 移除 rpath
patchelf --remove-rpath myapp
# 修改动态链接的库(比如替换依赖的某个.so 文件)
patchelf --replace-needed libold.so libnew.so myapp
# 设置 interpreter(动态链接器)
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 myapp
# 查看当前设置:
patchelf --print-rpath myapp
patchelf --print-needed myapp