nixpkgs/doc/languages-frameworks/lua.section.md
Matthieu Coudron 5cfcfc300b doc: update lua documentation
Reflects the recent changes to the lua infrastructure.
Packaging from luarocks should be encouraged.
2020-06-06 17:33:37 +02:00

8.6 KiB

title author date
Lua Matthieu Coudron 2019-02-05

User's Guide to Lua Infrastructure

Using Lua

Overview of Lua

Several versions of the Lua interpreter are available: luajit, lua5.1, 5.2, 5.3. The attribute lua refers to the default interpreter, it is also possible to refer to specific versions, e.g. lua_52 refers to Lua 5.2.

Lua libraries are in separate sets, with one set per interpreter version.

The interpreters have several common attributes. One of these attributes is pkgs, which is a package set of Lua libraries for this specific interpreter. E.g., the busted package corresponding to the default interpreter is lua.pkgs.busted, and the lua 5.2 version is lua_52.pkgs.busted. The main package set contains aliases to these package sets, e.g. luaPackagesrefers tolua_51.pkgsandlua_52Packagestolua_52.pkgs`.

Installing Lua and packages

Lua environment defined in separate .nix file

Create a file, e.g. build.nix, with the following expression

with import <nixpkgs> {};

lua_52.withPackages (ps: with ps; [ busted luafilesystem ])

and install it in your profile with

nix-env -if build.nix

Now you can use the Lua interpreter, as well as the extra packages (busted, luafilesystem) that you added to the environment.

Lua environment defined in ~/.config/nixpkgs/config.nix

If you prefer to, you could also add the environment as a package override to the Nixpkgs set, e.g. using config.nix,

{ # ...

  packageOverrides = pkgs: with pkgs; {
    myLuaEnv = lua_52.withPackages (ps: with ps; [ busted luafilesystem ]);
  };
}

and install it in your profile with

nix-env -iA nixpkgs.myLuaEnv

The environment is is installed by referring to the attribute, and considering the nixpkgs channel was used.

Lua environment defined in /etc/nixos/configuration.nix

For the sake of completeness, here's another example how to install the environment system-wide.

{ # ...

  environment.systemPackages = with pkgs; [
    (lua.withPackages(ps: with ps; [ busted luafilesystem ]))
  ];
}

Temporary Lua environment with nix-shell

For development you may need to use multiple environments. nix-shell gives the possibility to temporarily load another environment, akin to virtualenv.

There are two methods for loading a shell with Lua packages. The first and recommended method is to create an environment with lua.buildEnv or lua.withPackages and load that. E.g.

$ nix-shell -p 'lua.withPackages(ps: with ps; [ busted luafilesystem ])'

opens a shell from which you can launch the interpreter

[nix-shell:~] lua

The other method, which is not recommended, does not create an environment and requires you to list the packages directly,

$ nix-shell -p lua.pkgs.busted lua.pkgs.luafilesystem

Again, it is possible to launch the interpreter from the shell. The Lua interpreter has the attribute pkgs which contains all Lua libraries for that specific interpreter.

Developing with Lua

Now that you know how to get a working Lua environment with Nix, it is time to go forward and start actually developing with Lua. There are two ways to package lua software, either it is on luarocks and most of it can be taken care of by the luarocks2nix converter or the packaging has to be done manually. Let's present the luarocks way first and the manual one in a second time.

Packaging a library on luarocks

Luarocks.org is the main repository of lua packages. The site proposes two types of packages, the rockspec and the src.rock (equivalent of a rockspec but with the source). These packages can have different build types such as cmake, builtin etc (See https://github.com/luarocks/luarocks/wiki/Rockspec-format).

Luarocks-based packages are generated in pkgs/development/lua-modules/generated-packages.nix from the whitelist maintainers/scripts/luarocks-packages.csv and updated by running maintainers/scripts/update-luarocks-packages.

luarocks2nix is a tool capable of generating nix derivations from both rockspec and src.rock (and favors the src.rock). The automation only goes so far though and some packages need some customization. These go in pkgs/development/lua-modules/generated-packages.nix nix won't work with all packages. If the package lists external_dependencies in its rockspec file then it won't work.

You can run nix-shell -p luarocks-nix and then luarocks nix PKG_NAME. Nix rely on luarocks to install lua packages, basically it runs: luarocks make --deps-mode=none --tree $out

Packaging a library manually

You can develop your package as you usually would, just don't forget to wrap it within a toLuaModule call, for instance

mynewlib = toLuaModule ( stdenv.mkDerivation { ... });

Lua Reference

Lua interpreters

Versions 5.1, 5.2 and 5.3 of the lua interpreter are available as respectively lua_51, lua_52 and lua_53. The luajit interpreter is also available. The Nix expressions for the interpreters can be found in pkgs/development/interpreters/lua.

Attributes on lua interpreters packages

Each interpreter has the following attributes:

  • interpreter. Alias for ${lua}/bin/lua.
  • buildEnv. Function to build python interpreter environments with extra packages bundled together. See section python.buildEnv function for usage and documentation.
  • withPackages. Simpler interface to buildEnv.
  • pkgs. Set of Lua packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing packageOverrides.

buildLuarocksPackage function

The buildLuarocksPackage function is implemented in pkgs/development/interpreters/lua-5/build-lua-package.nix The following is an example:

luaexpat = buildLuaPackage rec {
  pname = "luaexpat";
  version = "1.3.0-1";

  src = fetchurl {
    url    = https://luarocks.org/luaexpat-1.3.0-1.src.rock;
    sha256 = "15jqz5q12i9zvjyagzwz2lrpzya64mih8v1hxwr0wl2gsjh86y5a";
  };
  disabled = luaOlder "5.1";

  propagatedBuildInputs = [ lua ];

  buildType="builtin";

  meta = {
    homepage = http://www.keplerproject.org/luaexpat/;
    description="XML Expat parsing";
    license = {
      fullName = "MIT/X11";
    };
  };
};

The buildLuarocksPackage delegates most tasks to luarocks:

  • it adds luarocks as an unpacker for src.rock files (in fact zip files)
  • configurePhasewrites a temporary luarocks configuration file which location is exported via the environment variableLUAROCKS_CONFIG`.
  • In the buildPhase, nothing is done.
  • installPhase calls luarocks make --deps-mode=none --tree $out to build and install the package
  • In the postFixup phase, the wrapLuaPrograms bash function is called to wrap all programs in the $out/bin/* directory to include $PATH environment variable and add dependent libraries to script's LUA_PATH and LUA_CPATH.

By default meta.platforms is set to the same value as the interpreter unless overridden otherwise.

buildLuaApplication function

The buildLuaApplication function is practically the same as buildLuaPackage. The difference is that buildLuaPackage by default prefixes the names of the packages with the version of the interpreter. Because with an application we're not interested in multiple version the prefix is dropped.

lua.withPackages function

The lua.withPackages function provides a simpler interface to the python.buildEnv functionality. It takes a function as an argument that is passed the set of python packages and returns the list of the packages to be included in the environment. Using the withPackages function, the previous example for the luafilesystem environment can be written like this:

with import <nixpkgs> {};

lua.withPackages (ps: [ps.luafilesystem])

withPackages passes the correct package set for the specific interpreter version as an argument to the function. In the above example, ps equals luaPackages. But you can also easily switch to using lua_52:

with import <nixpkgs> {};

lua_52.withPackages (ps: [ps.lua])

Now, ps is set to lua_52Packages, matching the version of the interpreter.

Possible Todos

  • export/use version specific variables such as LUA_PATH_5_2/LUAROCKS_CONFIG_5_2
  • let luarocks check for dependencies via exporting the different rocktrees in temporary config

Lua Contributing guidelines

Following rules should be respected:

  • Make sure libraries build for all Lua interpreters.
  • Commit names of Lua libraries should reflect that they are Lua libraries, so write for example lua.luafilesystem: 1.11 -> 1.12.