这里写目录标题
- [1 背景](#1 背景)
- [2 核心疑问:到底是不是环境变量 LD_LIBRARY_PATH 的问题?](#2 核心疑问:到底是不是环境变量 LD_LIBRARY_PATH 的问题?)
- [2.1 基础原理:Linux 如何找到 .so 共享库](#2.1 基础原理:Linux 如何找到 .so 共享库)
- [2.2 根因拆解(Ubuntu 22.04 Jammy 特有)](#2.2 根因拆解(Ubuntu 22.04 Jammy 特有))
- [3 解决方案](#3 解决方案)
- [3 补充知识:为什么会调用到openblas库](#3 补充知识:为什么会调用到openblas库)
1 背景
在 Jetson(Orin/Nano,JetPack Ubuntu Jammy)远程 SSH 运行 PyTorch 代码时,导入 torch 触发经典共享库报错:libopenblas.so.0: cannot open shared object file: No such file or directory。

很多人误以为是 Python 虚拟环境、LD_LIBRARY_PATH 环境变量配置错误,或是 PyTorch 没安装;本文拆解底层根因、区分系统动态链接器原理、提供临时调试 / 永久修复两套方案,并补充 Jetson 平台特有踩坑点。
2 核心疑问:到底是不是环境变量 LD_LIBRARY_PATH 的问题?
半对半错:本质不是环境变量缺失,是系统库文件部署路径变更 + 动态链接器检索规则不匹配,环境变量只是临时绕开问题的手段,不能根治。
2.1 基础原理:Linux 如何找到 .so 共享库
Linux 程序加载动态库的查找顺序:
- 编译时写入程序内的 rpath
- 环境变量 LD_LIBRARY_PATH(用户自定义路径,终端临时生效)
- 系统动态链接器配置目录 /etc/ld.so.conf 及其 include 文件
- 系统默认库目录:/usr/lib/aarch64-linux-gnu/、/lib/aarch64-linux-gnu/
- 缓存:ldconfig 生成的 /etc/ld.so.cache 索引
注意:动态链接器默认不会递归扫描子文件夹!
2.2 根因拆解(Ubuntu 22.04 Jammy 特有)
执行 find /usr -name "*libopenblas*.so* 后,库文件真实存放路径:
bash
/usr/lib/aarch64-linux-gnu/openblas-pthread/libopenblas.so.0

新版 Ubuntu 将多线程版本 OpenBLAS 放到了openblas-pthread 子目录,不再直接放在顶层 /usr/lib/aarch64-linux-gnu/。
PyTorch(通用 aarch64 wheel)编译阶段,链接器写死依赖 libopenblas.so.0,检索路径为系统顶层库目录,不会自动检索子文件夹。
系统 ldconfig 默认索引顶层目录,子目录不会加入全局缓存,导致运行时找不到文件。
3 解决方案
在系统默认库目录创建软链接,指向子目录内真实的库文件,更新链接缓存:
bash
# 创建软链接
sudo ln -s /usr/lib/aarch64-linux-gnu/openblas-pthread/libopenblas.so.0 /usr/lib/aarch64-linux-gnu/libopenblas.so.0
# 更新系统动态链接缓存
sudo ldconfig

3 补充知识:为什么会调用到openblas库
在我本地的代码中,只调用了torch的库。
python
import torch
import torch.nn as nn
import torch.onnx
在调用torch后,会调用到底层的C++ 底层核心模块 _C.so,而PyTorch CPU 算子(matmul、卷积底层addmm运算)依赖 BLAS 实现。

仅仅执行 import torch,还未编写任何神经网络推理代码,系统就会加载全部依赖的动态库,直接触发本次报错 。
不止 PyTorch,numpy、opencv等科学计算库,同样会依赖 OpenBLAS,这也是我们执行 find 命令时,在 numpy、opencv 目录下看到 openblas 相关文件的原因。