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`.