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