You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

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

火山引擎 最新活动