You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Erlang load_nif/2在项目导入后无法找到共享库问题求助

Elixir NIF加载失败:重复测试时找不到共享库文件

问题概述

某Elixir应用通过NIF调用C++代码,原项目运行正常,但集成到其他项目后出现加载错误:

Failed to load NIF library: '<relative_path_to_lib>/<lib_name>.so: cannot open shared object file: No such file or directory'

已尝试调整.so文件位置、使用绝对路径等操作,均未解决。关键现象为:编译后首次测试正常,重复运行测试时出错;同一测试内重复调用函数无问题,仅跨测试运行时触发错误。

系统环境:

  • Ubuntu 22.04
  • Elixir 1.13.0(基于Erlang/OTP 24编译)

原因分析与解决方法

1. 相对路径基准偏移

当应用作为依赖集成到主项目后,测试运行时的工作目录可能切换为主项目根目录,导致原有的相对路径指向错误。即使首次测试时路径有效,后续测试可能因工作目录变化失效。

解决办法:使用Application.app_dir/1获取应用的安装目录,拼接出绝对路径加载NIF,确保路径始终指向依赖项目中的共享库:

def load_nifs do
  # 替换:your_app_name为你的依赖应用名,priv/lib为.so文件实际存放路径
  lib_path = Application.app_dir(:your_app_name, "priv/lib/<lib_name>")
  :erlang.load_nif(lib_path, 0)
  :ok
end

2. 测试运行时路径验证

可以在加载代码中添加调试输出,确认工作目录和文件状态,定位路径问题:

def load_nifs do
  target_path = "<relative_path_to_lib>/<lib_name>"
  IO.inspect(File.cwd!(), label: "Current Working Directory")
  IO.inspect(File.exists?(target_path), label: "Library File Exists")
  IO.inspect(File.readable?(target_path), label: "Library File Readable")
  :erlang.load_nif(target_path, 0)
  :ok
end

运行测试时查看输出,就能明确是路径指向错误还是文件权限问题。

3. 动态链接库依赖缺失

部分情况下,系统提示“找不到文件”实际是因为.so文件依赖的其他共享库缺失,而非目标文件本身不存在。

解决办法:使用ldd命令检查目标.so文件的依赖情况:

ldd /path/to/your/lib_name.so

若输出中存在not found的条目,需安装对应依赖库,或通过LD_LIBRARY_PATH环境变量指定依赖库路径。

4. 依赖项目的NIF编译配置问题

主项目构建时,若依赖项目的NIF未正确编译生成.so文件,也会导致后续测试时文件缺失。

解决办法:确认依赖项目的mix.exs中正确配置了NIF编译规则:

def project do
  [
    # 启用elixir_make编译器
    compilers: [:elixir_make | Mix.compilers()],
    # 配置elixir_make的编译目标
    elixir_make: [make_args: ["all"]]
  ]
end

确保主项目执行mix deps.get和mix compile时,会自动编译C++代码生成.so文件。

内容的提问来源于stack exchange,提问作者TheLastEngineer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:01:12