Eleveldb NIF库加载失败求助:项目构建时无法编译该库
问题分析与解决方案
针对你遇到的eleveldb NIF库编译失败、启动时找不到eleveldb.so的问题,结合你的环境信息,从以下几个方向排查:
1. eleveldb版本与OTP 26兼容性问题
eleveldb-riak_kv-3.0.12发布时间较早,可能未适配OTP 26的NIF API变化。OTP 24+对NIF的部分接口做了调整,旧版本eleveldb可能因API不兼容导致编译失败,无法生成eleveldb.so。
- 排查:查看该版本eleveldb的CHANGELOG或README,确认是否支持OTP 26;或者在OTP 25环境下编译测试,验证是否能正常生成so文件。
- 解决:更换适配OTP 26的eleveldb版本,比如升级到riak_kv最新分支对应的eleveldb版本,或使用社区维护的兼容OTP 26的eleveldb分支。
2. 编译阶段依赖缺失或cmake配置失败
CentOS 7默认缺少部分编译依赖,cmake 3.12.3版本也可能无法满足eleveldb的编译要求。
- 排查:执行
rebar3 compile --verbose查看详细编译日志,定位eleveldb编译阶段的具体报错,比如是否提示找不到snappy、openssl等依赖,或cmake配置失败。 - 解决:
- 安装基础编译依赖:
yum install -y libstdc++-devel openssl-devel snappy-devel zlib-devel - 升级cmake版本:cmake 3.12.3较旧,eleveldb通常需要3.16+版本,可从源码编译安装cmake 3.20+后重新编译eleveldb。
- 安装基础编译依赖:
3. Rebar3未正确复制NIF产物到priv目录
即使eleveldb编译成功,Rebar3的port配置可能未将生成的eleveldb.so复制到指定priv目录。
- 排查:进入
_build/default/lib/eleveldb-riak_kv-3.0.12目录,查看是否有编译生成的eleveldb.so(通常在build或cmake_build目录下);检查该库rebar.config中的port_specs配置是否正确指定输出路径。 - 解决:
- 手动将编译生成的
eleveldb.so复制到/opt/acq-work/_build/default/rel/dev/lib/eleveldb-riak_kv-3.0.12/priv/目录,再启动系统测试。 - 若为
rebar.config配置问题,修改port_specs确保编译产物被复制到priv目录,示例配置:{port_specs, [{"priv/eleveldb.so", ["c_src/*.cpp"], [{env, [{"CFLAGS", "-O2 -Wall"}, {"CXXFLAGS", "-O2 -Wall"}]}]}]}.
- 手动将编译生成的
4. 动态链接库依赖不兼容
CentOS 7默认系统libstdc版本较低,用gcc 11编译的eleveldb.so依赖高版本libstdc,导致运行时无法找到依赖。
- 排查:找到编译生成的
eleveldb.so文件,执行ldd eleveldb.so查看依赖,若出现not found项即为缺失依赖。 - 解决:
- 启动Erlang前设置环境变量,指定gcc 11的库路径:
export LD_LIBRARY_PATH=/usr/local/gcc-11.2.1/lib64:$LD_LIBRARY_PATH - 编译eleveldb时使用静态链接选项,将依赖库打包到so文件中(修改cmake配置添加
-static或-static-libstdc++参数)。
- 启动Erlang前设置环境变量,指定gcc 11的库路径:
5. 权限问题
Erlang运行用户没有读取eleveldb.so文件或所在目录的权限。
- 排查:执行
ls -l /opt/acq-work/_build/default/rel/dev/lib/eleveldb-riak_kv-3.0.12/priv/,检查文件权限是否允许Erlang用户读取。 - 解决:修改文件权限:
chmod 644 /opt/acq-work/_build/default/rel/dev/lib/eleveldb-riak_kv-3.0.12/priv/eleveldb.so,并确保上级目录权限正常。
内容的提问来源于stack exchange,提问作者Aleksey Samotokin
相关产品推荐
相关产品推荐

