diff options
Diffstat (limited to 'docs/integrating_distro_modules_with_luarocks.md')
-rw-r--r-- | docs/integrating_distro_modules_with_luarocks.md | 190 |
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 | |||
3 | This is documentation on strategies to integrate OS-installed modules (e.g. | ||
4 | packages such as `luafilesystem` and `lpeg` provided by Linux distros) with | ||
5 | existing versions of LuaRocks. | ||
6 | |||
7 | This page will list two approaches: the minimal one, and a more complete one | ||
8 | that 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 | |||
19 | This is the _minimum_ that should be added to distro module packages so that | ||
20 | they visible as dependencies by LuaRocks: | ||
21 | |||
22 | ### The main manifest file | ||
23 | |||
24 | For LuaRocks to be able to find any OS-installed modules, there needs to be an | ||
25 | index file called `manifest` at `/usr/lib/luarocks/rocks-5.3/`. | ||
26 | |||
27 | This file should be generated running: | ||
28 | |||
29 | ``` | ||
30 | luarocks-admin make-manifest --local-tree --tree=/usr | ||
31 | ``` | ||
32 | |||
33 | This should be run as a post-install action after installing any module via | ||
34 | the distro. This file is the LuaRocks "index" and should be kept up-to-date or | ||
35 | else LuaRocks doesn't know about the installed modules. | ||
36 | |||
37 | ### Rock metadata necessary to build the main manifest | ||
38 | |||
39 | For the above command to work, there has to be a directory tree for each rock | ||
40 | and version, containing, at the bare minimum, a `rock_manifest` file. The | ||
41 | structure 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 | |||
53 | Examples: | ||
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 | |||
61 | Inside the version directory for a rock there must be a `rock_manifest` file. | ||
62 | The minimal contents of `rock_manifest` to make `luarocks-admin` not fail is | ||
63 | simply: | ||
64 | |||
65 | ```lua | ||
66 | rock_manifest = {} | ||
67 | ``` | ||
68 | |||
69 | This 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 | |||
77 | With those empty manifests, the post-install operation mentioned above works | ||
78 | and a later `luarocks install` will the existence of the "rocks" in /usr, | ||
79 | given the following configuration in `/etc/luarocks/config-5.3.lua`: | ||
80 | |||
81 | ``` | ||
82 | rocks_trees = { | ||
83 | { name = "user", root = home.."/.luarocks" }, | ||
84 | { name = "distro-modules", root = "/usr" }, | ||
85 | { name = "system", root = "/usr/local" }, | ||
86 | } | ||
87 | deps_mode = "all" | ||
88 | ``` | ||
89 | |||
90 | It's important that the "system" tree is the last entry: it is the one used | ||
91 | for system-wide installation of rocks using LuaRocks (when `sudo luarocks` is | ||
92 | used). The "distro-modules" tree should never be used directly by the user. | ||
93 | |||
94 | For more info on the deps_mode flag, see the [Dependency | ||
95 | modes](dependencies.md#dependency-modes) documentation. | ||
96 | |||
97 | ### Caveats | ||
98 | |||
99 | *Error messages*: Running with such bare minimum setup will resolve | ||
100 | dependencies, but running the post-install operation above will output error | ||
101 | messages when running, such as... | ||
102 | |||
103 | ``` | ||
104 | Tree 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 | ||
108 | can be simply ignored and silenced away with `&> /dev/null`). | ||
109 | |||
110 | *Failed commands*: this minimal tree will work for solving dependencies, but | ||
111 | not 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 | ||
113 | rockspec. | ||
114 | |||
115 | ## A more complete approach | ||
116 | |||
117 | A more complete approach to make commands such as `luarocks show` to work | ||
118 | would entail two steps: adding proper contents to `rock_manifest` and | ||
119 | including a rockspec file for each module. | ||
120 | |||
121 | ### A complete rock_manifest | ||
122 | |||
123 | A workable version of `rock_manifest` with contents would look like this: | ||
124 | |||
125 | ``` | ||
126 | rock_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 | |||
137 | The entries under `lib` are the files installed by the package at `/usr/lib/5.3`. | ||
138 | The entries under `lua` are the files installed by the package at `/usr/share/5.3`. | ||
139 | The rockspec key is the rockspec file to be stored alongside the `rock_manifest` file. | ||
140 | The values to these entries are MD5 sums to the files in question. | ||
141 | |||
142 | ### Including a rockspec file | ||
143 | |||
144 | For `luarocks show` to display metadata properly, a rockspec file must exist. | ||
145 | It should be named according to the pattern | ||
146 | `$ROCK_NAME-$ROCK_VERSION-$ROCK_REVISION.rockspec` (in all lowercase). | ||
147 | Continuing 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 | |||
153 | For simplicity, I would recommend just copying over the appropriate rockspec | ||
154 | file from [luarocks.org](http://luarocks.org) and bundling them in the package | ||
155 | metadata. For completeness, this is how the one for LPeg 1.0 looks like: | ||
156 | |||
157 | ``` | ||
158 | package = "LPeg" | ||
159 | version = "1.0.0-1" | ||
160 | source = { | ||
161 | url = "http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.0.0.tar.gz", | ||
162 | md5 = "0aec64ccd13996202ad0c099e2877ece", | ||
163 | } | ||
164 | description = { | ||
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 | } | ||
178 | dependencies = { | ||
179 | "lua >= 5.1" | ||
180 | } | ||
181 | build = { | ||
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 | ``` | ||