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).
134
135Luarocks-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
136the whitelist maintainers/scripts/luarocks-packages.csv and updated by running
137the package `luarocks-packages-updater`:
138
139```sh
140
141nix-shell -p luarocks-packages-updater --run luarocks-packages-updater
142```
143
144[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).
145The automation only goes so far though and some packages need to be customized.
146These customizations go in [pkgs/development/lua-modules/overrides.nix](https://github.com/NixOS/nixpkgs/tree/master/pkgs/development/lua-modules/overrides.nix).
147For instance if the rockspec defines `external_dependencies`, these need to be manually added to the overrides.nix.
148
149You can try converting luarocks packages to nix packages with the command `nix-shell -p luarocks-nix` and then `luarocks nix PKG_NAME`.
150
151#### Packaging a library manually {#packaging-a-library-manually}
152
153You can develop your package as you usually would, just don't forget to wrap it
154within a `toLuaModule` call, for instance
155
156```nix
157mynewlib = toLuaModule ( stdenv.mkDerivation { ... });
158```
159
160There is also the `buildLuaPackage` function that can be used when lua modules
161are not packaged for luarocks. You can see a few examples at `pkgs/top-level/lua-packages.nix`.
162
163## Lua Reference {#lua-reference}
164
165### Lua interpreters {#lua-interpreters}
166
167Versions 5.1, 5.2, 5.3 and 5.4 of the lua interpreter are available as
168respectively `lua5_1`, `lua5_2`, `lua5_3` and `lua5_4`. Luajit is available too.
169The Nix expressions for the interpreters can be found in `pkgs/development/interpreters/lua-5`.
170
171#### Attributes on lua interpreters packages {#attributes-on-lua-interpreters-packages}
172
173Each interpreter has the following attributes:
174
175- `interpreter`. Alias for `${pkgs.lua}/bin/lua`.
176- `buildEnv`. Function to build lua interpreter environments with extra packages bundled together. See section *lua.buildEnv function* for usage and documentation.
177- `withPackages`. Simpler interface to `buildEnv`.
178- `pkgs`. Set of Lua packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
179
180#### `buildLuarocksPackage` function {#buildluarockspackage-function}
181
182The `buildLuarocksPackage` function is implemented in `pkgs/development/interpreters/lua-5/build-luarocks-package.nix`
183The following is an example:
184```nix
185luaposix = buildLuarocksPackage {
186 pname = "luaposix";
187 version = "34.0.4-1";
188
189 src = fetchurl {
190 url = "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/luaposix-34.0.4-1.src.rock";
191 hash = "sha256-4mLJG8n4m6y4Fqd0meUDfsOb9RHSR0qa/KD5KCwrNXs=";
192 };
193 disabled = (luaOlder "5.1") || (luaAtLeast "5.4");
194 propagatedBuildInputs = [ bit32 lua std_normalize ];
195
196 meta = with lib; {
197 homepage = "https://github.com/luaposix/luaposix/";
198 description = "Lua bindings for POSIX";
199 maintainers = with maintainers; [ vyp lblasc ];
200 license.fullName = "MIT/X11";
201 };
202};
203```
204
205The `buildLuarocksPackage` delegates most tasks to luarocks:
206
207* it adds `luarocks` as an unpacker for `src.rock` files (zip files really).
208* `configurePhase` writes a temporary luarocks configuration file which location
209is exported via the environment variable `LUAROCKS_CONFIG`.
210* the `buildPhase` does nothing.
211* `installPhase` calls `luarocks make --deps-mode=none --tree $out` to build and
212install the package
213* In the `postFixup` phase, the `wrapLuaPrograms` bash function is called to
214 wrap all programs in the `$out/bin/*` directory to include `$PATH`
215 environment variable and add dependent libraries to script's `LUA_PATH` and
216 `LUA_CPATH`.
217
218By default `meta.platforms` is set to the same value as the interpreter unless overridden otherwise.
219
220#### `buildLuaApplication` function {#buildluaapplication-function}
221
222The `buildLuaApplication` function is practically the same as `buildLuaPackage`.
223The difference is that `buildLuaPackage` by default prefixes the names of the packages with the version of the interpreter.
224Because with an application we're not interested in multiple version the prefix is dropped.
225
226#### lua.withPackages function {#lua.withpackages-function}
227
228The `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.
229Using the `withPackages` function, the previous example for the luafilesystem environment can be written like this:
230
231```nix
232with import <nixpkgs> {};
233
234lua.withPackages (ps: [ps.luafilesystem])
235```
236
237`withPackages` passes the correct package set for the specific interpreter version as an argument to the function. In the above example, `ps` equals `luaPackages`.
238But you can also easily switch to using `lua5_2`:
239
240```nix
241with import <nixpkgs> {};
242
243lua5_2.withPackages (ps: [ps.lua])
244```
245
246Now, `ps` is set to `lua52Packages`, matching the version of the interpreter.
247
248### Possible Todos {#possible-todos}
249
250* export/use version specific variables such as `LUA_PATH_5_2`/`LUAROCKS_CONFIG_5_2`
251* let luarocks check for dependencies via exporting the different rocktrees in temporary config
252
253### Lua Contributing guidelines {#lua-contributing-guidelines}
254
255Following rules should be respected:
256
257* Make sure libraries build for all Lua interpreters.
258* Commit names of Lua libraries should reflect that they are Lua libraries, so write for example `luaPackages.luafilesystem: 1.11 -> 1.12`.