lua的包管理工具是:LuaRocks。本文内容基于MacOS系统。
luarocks
> cd 你预期的安装目录
> wget https://luarocks.org/releases/luarocks-3.9.2.tar.gz
> tar zxpf luarocks-3.9.2.tar.gz
> cd luarocks-3.9.2
> ./configure && make && sudo make install
luarocks
参考官方文档:Using LuaRocks
可用的模块在luarocks官网搜索即可。例如现在我们安装一个luasocket
模块。
sudo luarocks install luasocket # 安装luasocket模块
注意:不知道是luarocks
故意为之,还是因为有bug
。在luarocks
的安装目录(以及任意子目录)执行luarocks
命令,和在其它目录下执行luarocks
命令时,产生的行为并不一致。例如:
在luarocks
安装目录下执行luarocks install ...
,模块会被安装到luarocks安装目录/lua_modules/
;而在其它目录执行此命令,模块会被安装到/usr/local/
。具体的子路径则都符合rock的树结构。
执行luarocks path
命令,可以得到适用于lua的模块搜索路径规则(稍后会讲到)。然而只有在luarocks
的安装目录中执行此命令,得到的规则中才会包含匹配luarocks安装目录/lua_modules/
路径的项。
就像这两种目录对应了两个不同的环境一样。我提了一个issue询问此现象。
如果你并不是在luarocks
安装目录下执行的模块安装命令,那么现在就可以直接在lua代码中使用require("socket")
成功使用此模块了。
注意,通常模块安装命令中使用的模块名就是在lua代码中用
require
加载时填写的模块名,但也有一些例外的模块。比如luasocket
在加载时的模块名是socket
,即要使用require("socket")
,而不是require("luasocket")
。
2.1 分析
为什么直接就可以使用,这么简单?作为一个经常遭到"挑战"的程序员,你可能原本已经做好了"和luarocks
大战三百回合,不破luarocks
终不还!"的准备,结果没想到刀还没拔出来,敌人就吓跑了。如果你一时接受不了这么简单的战斗,那么可以继续阅读,识破luarocks
的诡计~
(非战斗人员请迅速撤离!)
注意:继续阅读需要对Lua的模块加载知识有一定的基础了解,如果有需要的话,可以在评论区留言,我会抽时间整理一篇关于Lua模块加载的文章,你也点击CSDN文末的推广码,我很乐意分享这些知识。
其实这是因为luarocks
将模块安装在了/usr/local/share/lua/5.4/
,具体见luarocks树结构。而这个树结构恰好匹配了package.path
和package.cpath
的默认规则。
print(package.path) -- `package.path`规则专门用于查找lua模块
-- /usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua;/usr/local/lib/lua/5.4/?.lua;/usr/local/lib/lua/5.4/?/init.lua;./?.lua;./?/init.lua
print(package.cpath) -- `package.cpath`规则专门用来查找C模块
-- /usr/local/lib/lua/5.4/?.so;/usr/local/lib/lua/5.4/loadall.so;./?.so
但是,如果你是在luarocks
安装目录下执行的模块安装命令,就会像一开始说的那样,模块会被安装在luarocks安装目录/lua_modules/share/lua/5.4/
,这并不在package.path
或package.cpath
的默认规则中。
因此,需要手动配置LUA_PATH_5_4
或LUA_PATH
,或者LUA_CPATH_5_4
或LUA_CPATH
环境变量。按照惯例,前两个环境变量专门用来配置.lua
模块,后两个专门用来配置C模块(.so
)。
注意,以下对环境变量的设置命令,只在当前shell会话有效,然后你可以通过执行
lua
命令开启命令行交互模式使用lua,运行require("socket")
验证是否成功。如果想要永久设置环境变量,应该把它们写到shell的启动文件中,bash
可以写到~/.bashrc
,zsh
可以写到~/.zshrc
。
如果对shell的这些基础知识感兴趣,可以阅读我的另一篇博客(篇幅较长):【Linux基础】理解并善用Shell – Shell精讲
于是我们可以配置LUA_PATH
:
# ;;会被替换为默认路径,作用是保留默认路径,这很有必要。
export LUA_PATH=";;/Users/wushu/Develop/luarocks-3.9.2/lua_modules/share/lua/5.4/?.lua
但此时你若是尝试使用require("socket")
,会发现依然报错。仔细观察报错信息可以发现:其实socket.lua
已经找到了,报错的原因是,socket.lua
中还require
了其它的模块。结合luarocks树结构观察模块的安装目录,以及socket.lua
中的require
,会发现其实是core.so
没有被加载到。所以还需要配置LUA_CPATH
:
export LUA_CPATH=";;/Users/wushu/Develop/luarocks-3.9.2/lua_modules/lib/lua/5.4/?.so"
然后再尝试require("socket")
,就可以啦。
2.2 luarocks path
其实,luarocks提供了一种更简单的方式来配置环境变量。
luarocks提供了一种半自动化的方式:luarocks path
命令。此命令能够打印出适合当前平台的、用于设置环境变量的命令。
并且,此命令得到的模块搜索路径规则中,会包含默认规则;另外还有一个PATH
,也会拼接原有的PATH
。因此不必担心自己的环境会被覆盖。
~/Develop/luarocks-3.9.2 » luarocks path
export LUA_PATH='/Users/wushu/Develop/luarocks-3.9.2/./lua_modules/share/lua/5.4/?.lua;/Users/wushu/Develop/luarocks-3.9.2/./lua_modules/share/lua/5.4/?/init.lua;/usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua;/usr/local/lib/lua/5.4/?.lua;/usr/local/lib/lua/5.4/?/init.lua;./?.lua;./?/init.lua;/Users/wushu/Develop/luarocks-3.9.2/lua_modules/share/lua/5.4/?.lua;/Users/wushu/.luarocks/share/lua/5.4/?.lua;/Users/wushu/.luarocks/share/lua/5.4/?/init.lua'
export LUA_CPATH='/Users/wushu/Develop/luarocks-3.9.2/./lua_modules/lib/lua/5.4/?.so;/usr/local/lib/lua/5.4/?.so;/usr/local/lib/lua/5.4/loadall.so;./?.so;/Users/wushu/Develop/luarocks-3.9.2/lua_modules/lib/lua/5.4/?.so;/Users/wushu/.luarocks/lib/lua/5.4/?.so'
export PATH='/Users/wushu/.luarocks/bin:(原PATH环境变量)'
然后通过**eval "$(luarocks path)"
**命令,就可以一键设置环境变量。注意,此命令只在当前shell会话有效,如果想要永久有效,需要把此命令写到shell启动文件中。
但正如一开始所说,luarocks path
命令在不同目录下产生的行为并不一致。只有在luarocks
安装目录(及其任意子目录)下执行,得到的规则中才会包含匹配luarocks安装目录/lua_modules/
路径的项。而现在我们之所以需要配置环境变量,就是因为luarocks安装的模块不在默认目录下,而是在luarocks安装目录/lua_modules
目录下。
所以,我们必须在shell启动文件中使用这种方式配置环境变量:
current_dir=$(pwd)
cd /Users/wushu/Develop/luarocks-3.9.2
# 在luarocks安装目录下获取环境变量命令并执行
eval "$(luarocks path)"
cd $current_dir
然后尝试require("socket")
,Bingo!
至此,战斗结束,你就可以对luarocks
宣布:KO!
查看模块信息描述:查看已安装模块的信息描述。
~/Desktop » luarocks show luasocket
LuaSocket 3.1.0-1 - Network support for the Lua language
LuaSocket is a Lua extension library composed of two parts: a set of C modules
that provide support for the TCP and UDP transport layers, and a set of Lua
modules that provide functions commonly needed by applications that deal with
the Internet.
License: MIT
Homepage: https://github.com/lunarmodules/luasocket
Installed in: /usr/local
Modules:
......
移除模块
sudo luarocks remove luasocket
luarocks存在两点问题:
require
应该使用的名字不一致。如luarocks install luasocket
-> require("socket")
这在协同开发、长期开发时,会有些困难。
这是我在luarocks仓库提的issue。