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