aboutsummaryrefslogtreecommitdiff
path: root/docs/integrating_distro_modules_with_luarocks.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/integrating_distro_modules_with_luarocks.md')
-rw-r--r--docs/integrating_distro_modules_with_luarocks.md190
1 files changed, 190 insertions, 0 deletions
diff --git a/docs/integrating_distro_modules_with_luarocks.md b/docs/integrating_distro_modules_with_luarocks.md
new file mode 100644
index 00000000..fb073500
--- /dev/null
+++ b/docs/integrating_distro_modules_with_luarocks.md
@@ -0,0 +1,190 @@
1# Integrating distro modules with LuaRocks
2
3This is documentation on strategies to integrate OS-installed modules (e.g.
4packages such as `luafilesystem` and `lpeg` provided by Linux distros) with
5existing versions of LuaRocks.
6
7This page will list two approaches: the minimal one, and a more complete one
8that extends the first one.
9
10## Assumptions
11
12* The examples below use Lua 5.3 — just change "5.3" to "5.1" or "5.2" and the
13 same applies.
14* Distro-installed modules live at standard Lua locations under `/usr`, such
15 as `/usr/lib/lua/5.3/lfs.so`
16
17## The bare minimum approach
18
19This is the _minimum_ that should be added to distro module packages so that
20they visible as dependencies by LuaRocks:
21
22### The main manifest file
23
24For LuaRocks to be able to find any OS-installed modules, there needs to be an
25index file called `manifest` at `/usr/lib/luarocks/rocks-5.3/`.
26
27This file should be generated running:
28
29```
30luarocks-admin make-manifest --local-tree --tree=/usr
31```
32
33This should be run as a post-install action after installing any module via
34the distro. This file is the LuaRocks "index" and should be kept up-to-date or
35else LuaRocks doesn't know about the installed modules.
36
37### Rock metadata necessary to build the main manifest
38
39For the above command to work, there has to be a directory tree for each rock
40and version, containing, at the bare minimum, a `rock_manifest` file. The
41structure looks like this:
42
43`/usr/lib/luarocks/rocks-$LUA_VERSION/$ROCK_NAME/$ROCK_VERSION-$ROCK_REVISION/`
44
45* $LUA_VERSION with with a dot: "5.3"
46
47* $ROCK_NAME should match the name used in the luarocks.org repository — in other words, `luafilesystem` has to be called `luafilesystem`, not `lfs`. LuaRocks checks dependencies by rock name, not by individual module name.
48
49* $ROCK_VERSION usually matches upstream, so that's not an issue.
50
51* $ROCK_REVISION can always be 0 for our purposes here.
52
53Examples:
54
55* /usr/lib/luarocks/rocks-5.3/lpeg/1.0.0-0/
56* /usr/lib/luarocks/rocks-5.3/luafilesystem/1.6.0-0/
57* /usr/lib/luarocks/rocks-5.3/lua-cjson/2.1.0-0/
58
59### The rock_manifest file
60
61Inside the version directory for a rock there must be a `rock_manifest` file.
62The minimal contents of `rock_manifest` to make `luarocks-admin` not fail is
63simply:
64
65```lua
66rock_manifest = {}
67```
68
69This means that in the above examples, we'd have several identical one-liner files:
70
71* /usr/lib/luarocks/rocks-5.3/lpeg/1.0.0-0/rock_manifest
72* /usr/lib/luarocks/rocks-5.3/luafilesystem/1.6.0-0/rock_manifest
73* /usr/lib/luarocks/rocks-5.3/lua-cjson/2.1.0-0/rock_manifest
74
75### Necessary LuaRocks configuration
76
77With those empty manifests, the post-install operation mentioned above works
78and a later `luarocks install` will the existence of the "rocks" in /usr,
79given the following configuration in `/etc/luarocks/config-5.3.lua`:
80
81```
82rocks_trees = {
83 { name = "user", root = home.."/.luarocks" },
84 { name = "distro-modules", root = "/usr" },
85 { name = "system", root = "/usr/local" },
86}
87deps_mode = "all"
88```
89
90It's important that the "system" tree is the last entry: it is the one used
91for system-wide installation of rocks using LuaRocks (when `sudo luarocks` is
92used). The "distro-modules" tree should never be used directly by the user.
93
94For more info on the deps_mode flag, see the [Dependency
95modes](dependencies.md#dependency-modes) documentation.
96
97### Caveats
98
99*Error messages*: Running with such bare minimum setup will resolve
100dependencies, but running the post-install operation above will output error
101messages when running, such as...
102
103```
104Tree inconsistency detected: luafilesystem 1.6.0-0 has no rockspec. Could not load rockspec file /usr/lib/luarocks/rocks-5.3/luafilesystem/1.6.0-0/luafilesystem-1.6.0-0.rockspec (/usr/lib/luarocks/rocks-5.3/luafilesystem/1.6.0-0/luafilesystem-1.6.0-0.rockspec: No such file or directory)"
105```
106
107...for each entry under `/usr/lib/luarocks/rocks-5.3` (for our purposes, these
108can be simply ignored and silenced away with `&> /dev/null`).
109
110*Failed commands*: this minimal tree will work for solving dependencies, but
111not for much else. In particular, `luarocks list --tree=/usr` will work, but
112`luarocks show lpeg --tree=/user` will not, complaining that it can't find a
113rockspec.
114
115## A more complete approach
116
117A more complete approach to make commands such as `luarocks show` to work
118would entail two steps: adding proper contents to `rock_manifest` and
119including a rockspec file for each module.
120
121### A complete rock_manifest
122
123A workable version of `rock_manifest` with contents would look like this:
124
125```
126rock_manifest = {
127 lib = {
128 ["lpeg.so"] = "136a74c6e472c36a65449184e1820a31"
129 },
130 ["lpeg-1.0.0-0.rockspec"] = "4933a611af43404761002ee139c393e8",
131 lua = {
132 ["re.lua"] = "5f09bb0129b09b6a8e8c1db1b206b1ca"
133 }
134}
135```
136
137The entries under `lib` are the files installed by the package at `/usr/lib/5.3`.
138The entries under `lua` are the files installed by the package at `/usr/share/5.3`.
139The rockspec key is the rockspec file to be stored alongside the `rock_manifest` file.
140The values to these entries are MD5 sums to the files in question.
141
142### Including a rockspec file
143
144For `luarocks show` to display metadata properly, a rockspec file must exist.
145It should be named according to the pattern
146`$ROCK_NAME-$ROCK_VERSION-$ROCK_REVISION.rockspec` (in all lowercase).
147Continuing the examples above:
148
149* /usr/lib/luarocks/rocks-5.3/lpeg/1.0.0-0/lpeg-1.0.0-0.rockspec
150* /usr/lib/luarocks/rocks-5.3/luafilesystem/1.6.0-0/luafilesystem-1.6.0-0.rockspec
151* /usr/lib/luarocks/rocks-5.3/lua-cjson/2.1.0-0/lua-cjson-2.1.0-0.rockspec
152
153For simplicity, I would recommend just copying over the appropriate rockspec
154file from [luarocks.org](http://luarocks.org) and bundling them in the package
155metadata. For completeness, this is how the one for LPeg 1.0 looks like:
156
157```
158package = "LPeg"
159version = "1.0.0-1"
160source = {
161 url = "http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.0.0.tar.gz",
162 md5 = "0aec64ccd13996202ad0c099e2877ece",
163}
164description = {
165 summary = "Parsing Expression Grammars For Lua",
166 detailed = [[
167 LPeg is a new pattern-matching library for Lua, based on Parsing
168 Expression Grammars (PEGs). The nice thing about PEGs is that it
169 has a formal basis (instead of being an ad-hoc set of features),
170 allows an efficient and simple implementation, and does most things
171 we expect from a pattern-matching library (and more, as we can
172 define entire grammars).
173 ]],
174 homepage = "http://www.inf.puc-rio.br/~roberto/lpeg.html",
175 maintainer = "Gary V. Vaughan <gary@vaughan.pe>",
176 license = "MIT/X11"
177}
178dependencies = {
179 "lua >= 5.1"
180}
181build = {
182 type = "builtin",
183 modules = {
184 lpeg = {
185 "lpcap.c", "lpcode.c", "lpprint.c", "lptree.c", "lpvm.c"
186 },
187 re = "re.lua"
188 }
189}
190```