1---
2title: Lua
3author: Matthieu Coudron
4date: 2019-02-05
5---
6
7# User's Guide to Lua Infrastructure
8
9## Using Lua
10
11### Overview of Lua
12
13Several versions of the Lua interpreter are available: luajit, lua 5.1, 5.2, 5.3.
14The attribute `lua` refers to the default interpreter, it is also possible to refer to specific versions, e.g. `lua5_2` refers to Lua 5.2.
15
16Lua libraries are in separate sets, with one set per interpreter version.
17
18The interpreters have several common attributes. One of these attributes is
19`pkgs`, which is a package set of Lua libraries for this specific
20interpreter. E.g., the `busted` package corresponding to the default interpreter
21is `lua.pkgs.busted`, and the lua 5.2 version is `lua5_2.pkgs.busted`.
22The main package set contains aliases to these package sets, e.g.
23`luaPackages` refers to `lua5_1.pkgs` and `lua52Packages` to
24`lua5_2.pkgs`.
25
26### Installing Lua and packages
27
28#### Lua environment defined in separate `.nix` file
29
30Create a file, e.g. `build.nix`, with the following expression
31```nix
32with import <nixpkgs> {};
33
34lua5_2.withPackages (ps: with ps; [ busted luafilesystem ])
35```
36and install it in your profile with
37```shell
38nix-env -if build.nix
39```
40Now you can use the Lua interpreter, as well as the extra packages (`busted`,
41`luafilesystem`) that you added to the environment.
42
43#### Lua environment defined in `~/.config/nixpkgs/config.nix`
44
45If you prefer to, you could also add the environment as a package override to the Nixpkgs set, e.g.
46using `config.nix`,
47```nix
48{ # ...
49
50 packageOverrides = pkgs: with pkgs; {
51 myLuaEnv = lua5_2.withPackages (ps: with ps; [ busted luafilesystem ]);
52 };
53}
54```
55and install it in your profile with
56```shell
57nix-env -iA nixpkgs.myLuaEnv
58```
59The environment is is installed by referring to the attribute, and considering
60the `nixpkgs` channel was used.
61
62#### Lua environment defined in `/etc/nixos/configuration.nix`
63
64For the sake of completeness, here's another example how to install the environment system-wide.
65
66```nix
67{ # ...
68
69 environment.systemPackages = with pkgs; [
70 (lua.withPackages(ps: with ps; [ busted luafilesystem ]))
71 ];
72}
73```
74
75### How to override a Lua package using overlays?
76
77Use the following overlay template:
78
79```nix
80final: prev:
81{
82
83 lua = prev.lua.override {
84 packageOverrides = luaself: luaprev: {
85
86 luarocks-nix = luaprev.luarocks-nix.overrideAttrs(oa: {
87 pname = "luarocks-nix";
88 src = /home/my_luarocks/repository;
89 });
90 };
91
92 luaPackages = lua.pkgs;
93}
94```
95
96### Temporary Lua environment with `nix-shell`
97
98
99There are two methods for loading a shell with Lua packages. The first and recommended method
100is to create an environment with `lua.buildEnv` or `lua.withPackages` and load that. E.g.
101```sh
102$ nix-shell -p 'lua.withPackages(ps: with ps; [ busted luafilesystem ])'
103```
104opens a shell from which you can launch the interpreter
105```sh
106[nix-shell:~] lua
107```
108The other method, which is not recommended, does not create an environment and requires you to list the packages directly,
109
110```sh
111$ nix-shell -p lua.pkgs.busted lua.pkgs.luafilesystem
112```
113Again, it is possible to launch the interpreter from the shell.
114The Lua interpreter has the attribute `pkgs` which contains all Lua libraries for that specific interpreter.
115
116
117## Developing with Lua
118
119Now that you know how to get a working Lua environment with Nix, it is time
120to go forward and start actually developing with Lua. There are two ways to
121package lua software, either it is on luarocks and most of it can be taken care
122of by the luarocks2nix converter or the packaging has to be done manually.
123Let's present the luarocks way first and the manual one in a second time.
124
125### Packaging a library on luarocks
126
127[Luarocks.org](www.luarocks.org) is the main repository of lua packages.
128The site proposes two types of packages, the rockspec and the src.rock
129(equivalent of a [rockspec](https://github.com/luarocks/luarocks/wiki/Rockspec-format) but with the source).
130These packages can have different build types such as `cmake`, `builtin` etc .
131
132Luarocks-based packages are generated in pkgs/development/lua-modules/generated-packages.nix from
133the whitelist maintainers/scripts/luarocks-packages.csv and updated by running maintainers/scripts/update-luarocks-packages.
134
135[luarocks2nix](https://github.com/nix-community/luarocks) is a tool capable of generating nix derivations from both rockspec and src.rock (and favors the src.rock).
136The automation only goes so far though and some packages need to be customized.
137These customizations go in `pkgs/development/lua-modules/overrides.nix`.
138For instance if the rockspec defines `external_dependencies`, these need to be manually added in in its rockspec file then it won't work.
139
140You can try converting luarocks packages to nix packages with the command `nix-shell -p luarocks-nix` and then `luarocks nix PKG_NAME`.
141Nix rely on luarocks to install lua packages, basically it runs:
142`luarocks make --deps-mode=none --tree $out`
143
144#### Packaging a library manually
145
146You can develop your package as you usually would, just don't forget to wrap it
147within a `toLuaModule` call, for instance
148```nix
149mynewlib = toLuaModule ( stdenv.mkDerivation { ... });
150```
151
152There is also the `buildLuaPackage` function that can be used when lua modules
153are not packaged for luarocks. You can see a few examples at `pkgs/top-level/lua-packages.nix`.
154
155## Lua Reference
156
157### Lua interpreters
158
159Versions 5.1, 5.2 and 5.3 of the lua interpreter are available as
160respectively `lua5_1`, `lua5_2` and `lua5_3`. Luajit is available too.
161The Nix expressions for the interpreters can be found in `pkgs/development/interpreters/lua-5`.
162
163
164#### Attributes on lua interpreters packages
165
166Each interpreter has the following attributes:
167
168- `interpreter`. Alias for `${pkgs.lua}/bin/lua`.
169- `buildEnv`. Function to build lua interpreter environments with extra packages bundled together. See section *lua.buildEnv function* for usage and documentation.
170- `withPackages`. Simpler interface to `buildEnv`.
171- `pkgs`. Set of Lua packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
172
173
174#### `buildLuarocksPackage` function
175
176The `buildLuarocksPackage` function is implemented in `pkgs/development/interpreters/lua-5/build-lua-package.nix`
177The following is an example:
178```nix
179luaposix = buildLuarocksPackage {
180 pname = "luaposix";
181 version = "34.0.4-1";
182
183 src = fetchurl {
184 url = "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/luaposix-34.0.4-1.src.rock";
185 sha256 = "0yrm5cn2iyd0zjd4liyj27srphvy0gjrjx572swar6zqr4dwjqp2";
186 };
187 disabled = (luaOlder "5.1") || (luaAtLeast "5.4");
188 propagatedBuildInputs = [ bit32 lua std_normalize ];
189
190 meta = with stdenv.lib; {
191 homepage = "https://github.com/luaposix/luaposix/";
192 description = "Lua bindings for POSIX";
193 maintainers = with maintainers; [ vyp lblasc ];
194 license.fullName = "MIT/X11";
195 };
196};
197```
198
199The `buildLuarocksPackage` delegates most tasks to luarocks:
200
201* it adds `luarocks` as an unpacker for `src.rock` files (zip files really).
202* configurePhase` writes a temporary luarocks configuration file which location
203is exported via the environment variable `LUAROCKS_CONFIG`.
204* the `buildPhase` does nothing.
205* `installPhase` calls `luarocks make --deps-mode=none --tree $out` to build and
206install the package
207* In the `postFixup` phase, the `wrapLuaPrograms` bash function is called to
208 wrap all programs in the `$out/bin/*` directory to include `$PATH`
209 environment variable and add dependent libraries to script's `LUA_PATH` and
210 `LUA_CPATH`.
211
212By default `meta.platforms` is set to the same value as the interpreter unless overridden otherwise.
213
214#### `buildLuaApplication` function
215
216The `buildLuaApplication` function is practically the same as `buildLuaPackage`.
217The difference is that `buildLuaPackage` by default prefixes the names of the packages with the version of the interpreter.
218Because with an application we're not interested in multiple version the prefix is dropped.
219
220#### lua.withPackages function
221
222The `lua.withPackages` takes a function as an argument that is passed the set of lua packages and returns the list of packages to be included in the environment.
223Using the `withPackages` function, the previous example for the luafilesystem environment can be written like this:
224```nix
225with import <nixpkgs> {};
226
227lua.withPackages (ps: [ps.luafilesystem])
228```
229
230`withPackages` passes the correct package set for the specific interpreter version as an argument to the function. In the above example, `ps` equals `luaPackages`.
231But you can also easily switch to using `lua5_2`:
232```nix
233with import <nixpkgs> {};
234
235lua5_2.withPackages (ps: [ps.lua])
236```
237
238Now, `ps` is set to `lua52Packages`, matching the version of the interpreter.
239
240
241### Possible Todos
242
243* export/use version specific variables such as `LUA_PATH_5_2`/`LUAROCKS_CONFIG_5_2`
244* let luarocks check for dependencies via exporting the different rocktrees in temporary config
245
246### Lua Contributing guidelines
247
248Following rules should be respected:
249
250* Make sure libraries build for all Lua interpreters.
251* Commit names of Lua libraries should reflect that they are Lua libraries, so write for example `luaPackages.luafilesystem: 1.11 -> 1.12`.
252