Linux下pybind11封装库pydmy加载libabc.so失败求助
解决Linux下pybind11封装库无法加载同目录依赖库的问题
可能的原因及对应解决办法
1. 确认$ORIGIN的传递是否正确
在Makefile中添加-Wl,-rpath,$$ORIGIN时,要确保这个参数确实被传递给链接器。可以用以下命令检查pydmy库的rpath设置:
readelf -d pydmy.so | grep RPATH
如果输出里没有$ORIGIN,说明参数没加对。正确的Makefile链接段应该类似:
pydmy.so: pydmy.o $(CXX) -shared -o $@ $^ $(PYBIND11_LDFLAGS) -Wl,-rpath,$$ORIGIN -labc
注意这里的$$ORIGIN是Makefile里的转义写法,实际传递给链接器的是$ORIGIN。
2. 排查Python导入时的目录影响
Python导入扩展库时,可能会改变进程当前工作目录,导致$ORIGIN(库所在目录)的解析出问题。可以先在脚本里打印当前目录再导入:
import os print(os.getcwd()) import pydmy as tp
如果当前目录不是pydmy所在目录,可临时设置环境变量解决:
export LD_LIBRARY_PATH=/path/to/pydmy/dir:$LD_LIBRARY_PATH python myscript.py
或者在Python脚本里提前设置(必须在导入pydmy之前):
import os import sys # 获取pydmy所在目录 pydmy_dir = os.path.dirname(os.path.abspath(__file__)) os.environ['LD_LIBRARY_PATH'] = f"{pydmy_dir}:{os.environ.get('LD_LIBRARY_PATH', '')}" import pydmy as tp
3. 检查libabc.so的Soname设置
如果libabc.so的Soname带版本号(比如libabc.so.1),pydmy会优先找对应版本的文件,即使同目录有libabc.so也会报错。用以下命令查看Soname:
readelf -d libabc.so | grep SONAME
如果Soname是带版本的,要么创建符号链接:
ln -s libabc.so libabc.so.1
要么编译libabc.so时指定正确的Soname:
g++ -shared -Wl,-soname,libabc.so -o libabc.so abc.o
4. 用patchelf手动修改rpath
如果上面的方法都无效,可直接用patchelf工具修改pydmy.so的rpath:
patchelf --set-rpath '$ORIGIN' pydmy.so
修改后再用readelf命令检查是否生效。
内容的提问来源于stack exchange,提问作者Taitai




