depot/third_party/nixpkgs/pkgs/development/lua-modules/lib.nix

179 lines
5.5 KiB
Nix

{
pkgs,
lib,
lua,
}:
let
inherit (lib.generators) toLua;
requiredLuaModules =
drvs:
let
modules = lib.filter hasLuaModule drvs;
in
lib.unique ([ lua ] ++ modules ++ lib.concatLists (lib.catAttrs "requiredLuaModules" modules));
# Check whether a derivation provides a lua module.
hasLuaModule = drv: drv ? luaModule;
# Use this to override the arguments passed to buildLuarocksPackage
overrideLuarocks =
drv: f:
(drv.override (
args:
args
// {
buildLuarocksPackage = drv: (args.buildLuarocksPackage drv).override f;
}
))
// {
overrideScope = scope: overrideLuarocks (drv.overrideScope scope) f;
};
in
rec {
inherit overrideLuarocks;
inherit hasLuaModule requiredLuaModules;
luaPathList = [
"share/lua/${lua.luaversion}/?.lua"
"share/lua/${lua.luaversion}/?/init.lua"
];
luaCPathList = [
"lib/lua/${lua.luaversion}/?.so"
];
# generate paths without a prefix
luaPathRelStr = lib.concatStringsSep ";" luaPathList;
luaCPathRelStr = lib.concatStringsSep ";" luaCPathList;
# generate LUA_(C)PATH value for a specific derivation, i.e., with absolute paths
genLuaPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaPathList;
genLuaCPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaCPathList;
# Generate a LUA_PATH with absolute paths
# genLuaPathAbs = drv:
# lib.concatStringsSep ";" (map (x: "${drv}/x") luaPathList);
luaAtLeast = lib.versionAtLeast lua.luaversion;
luaOlder = lib.versionOlder lua.luaversion;
isLua51 = (lib.versions.majorMinor lua.version) == "5.1";
isLua52 = (lib.versions.majorMinor lua.version) == "5.2";
isLua53 = lua.luaversion == "5.3";
isLuaJIT = lib.getName lua == "luajit";
/*
generates the relative path towards the folder where
seems stable even when using lua_modules_path = ""
Example:
getDataFolder luaPackages.stdlib
=> stdlib-41.2.2-1-rocks/stdlib/41.2.2-1/doc
*/
getDataFolder = drv: "${drv.pname}-${drv.version}-rocks/${drv.pname}/${drv.version}";
/*
Convert derivation to a lua module.
so that luaRequireModules can be run later
*/
toLuaModule =
drv:
drv.overrideAttrs (oldAttrs: {
# Use passthru in order to prevent rebuilds when possible.
passthru = (oldAttrs.passthru or { }) // {
luaModule = lua;
requiredLuaModules = requiredLuaModules drv.propagatedBuildInputs;
};
});
/*
generate a luarocks config conforming to:
https://github.com/luarocks/luarocks/wiki/Config-file-format
The config lists folders where to find lua dependencies
Example:
generateLuarocksConfig {
externalDeps = [ { name = "CRYPTO"; dep = pkgs.openssl; } ];
rocksSubdir = "subdir";
};
Type:
generateLuarocksConfig :: AttrSet -> String
*/
generateLuarocksConfig =
{
externalDeps ? [ ],
# a list of lua derivations
requiredLuaRocks ? [ ],
...
}@args:
let
rocksTrees = lib.imap0 (i: dep: {
name = "dep-${toString i}";
root = "${dep}";
# packages built by buildLuaPackage or luarocks doesn't contain rocksSubdir
# hence a default here
rocks_dir =
if dep ? rocksSubdir then "${dep}/${dep.rocksSubdir}" else "${dep.pname}-${dep.version}-rocks";
}) requiredLuaRocks;
# Explicitly point luarocks to the relevant locations for multiple-output
# derivations that are external dependencies, to work around an issue it has
# (https://github.com/luarocks/luarocks/issues/766)
depVariables = zipAttrsWithLast (
lib.lists.map (
{ name, dep }:
{
"${name}_INCDIR" = "${lib.getDev dep}/include";
"${name}_LIBDIR" = "${lib.getLib dep}/lib";
"${name}_BINDIR" = "${lib.getBin dep}/bin";
}
) externalDeps'
);
zipAttrsWithLast = lib.attrsets.zipAttrsWith (name: lib.lists.last);
# example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps;
externalDepsDirs = map (x: builtins.toString x) (lib.filter (lib.isDerivation) externalDeps);
generatedConfig = (
{
# first tree is the default target where new rocks are installed,
# any other trees in the list are treated as additional sources of installed rocks for matching dependencies.
rocks_trees = (
[
{
name = "current";
root = "${placeholder "out"}";
rocks_dir = "current";
}
]
++ rocksTrees
);
}
// lib.optionalAttrs lua.pkgs.isLuaJIT {
# Luajit provides some additional functionality built-in; this exposes
# that to luarock's dependency system
rocks_provided = {
jit = "${lua.luaversion}-1";
ffi = "${lua.luaversion}-1";
luaffi = "${lua.luaversion}-1";
bit = "${lua.luaversion}-1";
};
}
// {
# For single-output external dependencies
external_deps_dirs = externalDepsDirs;
# Some needed machinery to handle multiple-output external dependencies,
# as per https://github.com/luarocks/luarocks/issues/766
variables = depVariables;
}
// removeAttrs args [
"requiredLuaRocks"
"externalDeps"
]
);
in
generatedConfig;
}