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