加载lua-cjson模块遇undefined symbol: lua_rotate错误求助
问题分析与解决办法
从你给出的错误信息undefined symbol: lua_rotate来看,核心问题是Lua版本不兼容导致的动态链接符号缺失,具体原因和解决办法如下:
为什么会出现这个错误?
lua_rotate这个函数是在Lua 5.1.5及更高版本中才新增的API,而你系统里安装的是Lua 5.1.4。但你的Nginx中使用的Lua模块(比如ngx_lua)要么是基于更高版本的标准Lua编译,要么是使用了LuaJIT,这就导致你用系统Lua 5.1.4编译出来的cjson.so,在Nginx加载时找不到对应的符号。
另外,你当前的nginx.conf只配置了lua_package_path(用于加载.lua脚本),缺少针对C扩展库(.so)的lua_package_cpath配置,这也可能加剧加载问题。
解决步骤
第一步:确认Nginx的Lua模块类型
先执行以下命令查看Nginx编译时的Lua相关参数:
nginx -V
从输出中判断是用的标准Lua还是LuaJIT:
- 如果看到
--with-luajit:说明用的是LuaJIT - 如果看到
--with-lua:说明用的是标准Lua,注意查看对应的版本
情况1:Nginx使用的是LuaJIT
你需要用LuaJIT的头文件和库来重新编译lua-cjson,步骤如下:
- 进入lua-cjson源码目录,清理之前的编译产物:
cd lua-cjson-2.1.0.7 make clean - 指定LuaJIT的路径编译(如果是OpenResty自带的LuaJIT,路径通常是
/usr/local/openresty/luajit/,如果是单独安装的,替换成对应路径):make LUA_INCLUDE_DIR=/usr/local/openresty/luajit/include/luajit-2.1 LUA_LIB_DIR=/usr/local/openresty/luajit/lib sudo make install - 重新复制编译好的
cjson.so到目标目录并设置权限:cp cjson.so /usr/local/lib/lua/5.1/ chmod 755 /usr/local/lib/lua/5.1/cjson.so - 修改
nginx.conf,添加lua_package_cpath配置(和lua_package_path放在一起):lua_package_path "/usr/local/lib/lua/?.lua;;"; lua_package_cpath "/usr/local/lib/lua/5.1/?.so;;"; - 重启Nginx:
sudo systemctl restart nginx.service
情况2:Nginx使用的是标准Lua(版本高于5.1.4)
有两种解决方式:
方式A:升级系统Lua到5.1.5或更高版本
- 卸载旧版本Lua(如果是包管理器安装的):
# Debian/Ubuntu系统 sudo apt remove lua5.1 # CentOS/RHEL系统 sudo yum remove lua - 下载并编译Lua 5.1.5:
wget https://www.lua.org/ftp/lua-5.1.5.tar.gz tar zxf lua-5.1.5.tar.gz cd lua-5.1.5 make linux test sudo make install - 回到lua-cjson目录重新编译安装:
cd ../lua-cjson-2.1.0.7 make clean make sudo make install - 复制文件、修改
nginx.conf添加lua_package_cpath、重启Nginx(步骤同情况1的3-5)
方式B:修改lua-cjson源码,移除对lua_rotate的依赖
如果你不想升级Lua,可以修改lua-cjson的源码,用Lua 5.1.4兼容的代码替换lua_rotate调用:
- 打开lua-cjson目录下的
lua_cjson.c文件,找到调用lua_rotate(L, -1)的代码(通常在json_encode_array函数内) - 将
lua_rotate(L, -1);替换为:lua_pushvalue(L, -1); lua_remove(L, -2); - 重新编译安装lua-cjson,后续步骤同情况1的3-5
内容的提问来源于stack exchange,提问作者Satscreate




