1{ pkgs, lib, lua }: 2let 3 requiredLuaModules = drvs: with lib; let 4 modules = filter hasLuaModule drvs; 5 in unique ([lua] ++ modules ++ concatLists (catAttrs "requiredLuaModules" modules)); 6 # Check whether a derivation provides a lua module. 7 hasLuaModule = drv: drv ? luaModule; 8 9 10 /* 11 Use this to override the arguments passed to buildLuarocksPackage 12 */ 13 overrideLuarocks = drv: f: (drv.override (args: args // { 14 buildLuarocksPackage = drv: (args.buildLuarocksPackage drv).override f; 15 })) // { 16 overrideScope = scope: overrideLuarocks (drv.overrideScope scope) f; 17 }; 18 19in 20rec { 21 inherit overrideLuarocks; 22 inherit hasLuaModule requiredLuaModules; 23 24 luaPathList = [ 25 "share/lua/${lua.luaversion}/?.lua" 26 "share/lua/${lua.luaversion}/?/init.lua" 27 ]; 28 luaCPathList = [ 29 "lib/lua/${lua.luaversion}/?.so" 30 ]; 31 32 /* generate paths without a prefix 33 */ 34 luaPathRelStr = lib.concatStringsSep ";" luaPathList; 35 luaCPathRelStr = lib.concatStringsSep ";" luaCPathList; 36 37 /* generate LUA_(C)PATH value for a specific derivation, i.e., with absolute paths 38 */ 39 genLuaPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaPathList; 40 genLuaCPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaCPathList; 41 42 /* Generate a LUA_PATH with absolute paths 43 */ 44 # genLuaPathAbs = drv: 45 # lib.concatStringsSep ";" (map (x: "${drv}/x") luaPathList); 46 47 luaAtLeast = lib.versionAtLeast lua.luaversion; 48 luaOlder = lib.versionOlder lua.luaversion; 49 isLua51 = (lib.versions.majorMinor lua.version) == "5.1"; 50 isLua52 = (lib.versions.majorMinor lua.version) == "5.2"; 51 isLua53 = lua.luaversion == "5.3"; 52 isLuaJIT = lib.getName lua == "luajit"; 53 54 /* generates the relative path towards the folder where 55 seems stable even when using lua_modules_path = "" 56 57 Example: 58 getDataFolder luaPackages.stdlib 59 => stdlib-41.2.2-1-rocks/stdlib/41.2.2-1/doc 60 */ 61 getDataFolder = drv: 62 "${drv.pname}-${drv.version}-rocks/${drv.pname}/${drv.version}"; 63 64 /* Convert derivation to a lua module. 65 so that luaRequireModules can be run later 66 */ 67 toLuaModule = drv: 68 drv.overrideAttrs( oldAttrs: { 69 # Use passthru in order to prevent rebuilds when possible. 70 passthru = (oldAttrs.passthru or {}) // { 71 luaModule = lua; 72 requiredLuaModules = requiredLuaModules drv.propagatedBuildInputs; 73 }; 74 }); 75 76 /* generate luarocks config 77 78 generateLuarocksConfig { 79 externalDeps = [ { name = "CRYPTO"; dep = pkgs.openssl; } ]; 80 rocksSubdir = "subdir"; 81 }; 82 */ 83 generateLuarocksConfig = { 84 externalDeps 85 , requiredLuaRocks 86 , extraVariables ? {} 87 , rocksSubdir 88 }: let 89 rocksTrees = lib.imap0 90 (i: dep: "{ name = [[dep-${toString i}]], root = '${dep}', rocks_dir = '${dep}/${dep.rocksSubdir}' }") 91 requiredLuaRocks; 92 93 # Explicitly point luarocks to the relevant locations for multiple-output 94 # derivations that are external dependencies, to work around an issue it has 95 # (https://github.com/luarocks/luarocks/issues/766) 96 depVariables = lib.concatMap ({name, dep}: [ 97 "${name}_INCDIR='${lib.getDev dep}/include';" 98 "${name}_LIBDIR='${lib.getLib dep}/lib';" 99 "${name}_BINDIR='${lib.getBin dep}/bin';" 100 ]) externalDeps'; 101 102 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ] 103 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps; 104 105 externalDepsDirs = map 106 (x: "'${builtins.toString x}'") 107 (lib.filter (lib.isDerivation) externalDeps); 108 109 extraVariablesStr = lib.concatStringsSep "\n " 110 (lib.mapAttrsToList (k: v: "${k}='${v}';") extraVariables); 111 in '' 112 local_cache = "" 113 -- To prevent collisions when creating environments, we install the rock 114 -- files into per-package subdirectories 115 rocks_subdir = '${rocksSubdir}' 116 -- Then we need to tell luarocks where to find the rock files per 117 -- dependency 118 rocks_trees = { 119 ${lib.concatStringsSep "\n, " rocksTrees} 120 } 121 '' + lib.optionalString lua.pkgs.isLuaJIT '' 122 -- Luajit provides some additional functionality built-in; this exposes 123 -- that to luarock's dependency system 124 rocks_provided = { 125 jit='${lua.luaversion}-1'; 126 ffi='${lua.luaversion}-1'; 127 luaffi='${lua.luaversion}-1'; 128 bit='${lua.luaversion}-1'; 129 } 130 '' + '' 131 -- For single-output external dependencies 132 external_deps_dirs = { 133 ${lib.concatStringsSep "\n, " externalDepsDirs} 134 } 135 variables = { 136 -- Some needed machinery to handle multiple-output external dependencies, 137 -- as per https://github.com/luarocks/luarocks/issues/766 138 ${lib.optionalString (lib.length depVariables > 0) '' 139 ${lib.concatStringsSep "\n " depVariables}''} 140 ${extraVariablesStr} 141 } 142 ''; 143}