at master 5.6 kB view raw
1{ 2 pkgs, 3 lib, 4 lua, 5}: 6let 7 inherit (lib.generators) toLua; 8 requiredLuaModules = 9 drvs: 10 let 11 modules = lib.filter hasLuaModule drvs; 12 in 13 lib.unique ([ lua ] ++ modules ++ lib.concatLists (lib.catAttrs "requiredLuaModules" modules)); 14 # Check whether a derivation provides a lua module. 15 hasLuaModule = drv: drv ? luaModule; 16 17 # Use this to override the arguments passed to buildLuarocksPackage 18 overrideLuarocks = 19 drv: f: 20 (drv.override ( 21 args: 22 args 23 // { 24 buildLuarocksPackage = drv: (args.buildLuarocksPackage drv).override f; 25 } 26 )) 27 // { 28 overrideScope = scope: overrideLuarocks (drv.overrideScope scope) f; 29 }; 30 31in 32rec { 33 inherit overrideLuarocks; 34 inherit hasLuaModule requiredLuaModules; 35 36 luaPathList = [ 37 "share/lua/${lua.luaversion}/?.lua" 38 "share/lua/${lua.luaversion}/?/init.lua" 39 ]; 40 luaCPathList = [ 41 "lib/lua/${lua.luaversion}/?.so" 42 ]; 43 44 # generate paths without a prefix 45 luaPathRelStr = lib.concatStringsSep ";" luaPathList; 46 luaCPathRelStr = lib.concatStringsSep ";" luaCPathList; 47 48 # generate LUA_(C)PATH value for a specific derivation, i.e., with absolute paths 49 genLuaPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaPathList; 50 genLuaCPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaCPathList; 51 52 # Generate a LUA_PATH with absolute paths 53 # genLuaPathAbs = drv: 54 # lib.concatStringsSep ";" (map (x: "${drv}/x") luaPathList); 55 56 luaAtLeast = lib.versionAtLeast lua.luaversion; 57 luaOlder = lib.versionOlder lua.luaversion; 58 isLua51 = (lib.versions.majorMinor lua.version) == "5.1"; 59 isLua52 = (lib.versions.majorMinor lua.version) == "5.2"; 60 isLua53 = lua.luaversion == "5.3"; 61 isLuaJIT = lib.getName lua == "luajit"; 62 63 /* 64 generates the relative path towards the folder where 65 seems stable even when using lua_modules_path = "" 66 67 Example: 68 getDataFolder luaPackages.stdlib 69 => stdlib-41.2.2-1-rocks/stdlib/41.2.2-1/doc 70 */ 71 getDataFolder = drv: "${drv.pname}-${drv.version}-rocks/${drv.pname}/${drv.version}"; 72 73 /* 74 Convert derivation to a lua module. 75 so that luaRequireModules can be run later 76 */ 77 toLuaModule = 78 drv: 79 drv.overrideAttrs (oldAttrs: { 80 # Use passthru in order to prevent rebuilds when possible. 81 passthru = (oldAttrs.passthru or { }) // { 82 luaModule = lua; 83 requiredLuaModules = requiredLuaModules drv.propagatedBuildInputs; 84 }; 85 }); 86 87 /* 88 generate a luarocks config conforming to: 89 https://github.com/luarocks/luarocks/wiki/Config-file-format 90 91 The config lists folders where to find lua dependencies 92 93 Example: 94 generateLuarocksConfig { 95 externalDeps = [ { name = "CRYPTO"; dep = pkgs.openssl; } ]; 96 rocksSubdir = "subdir"; 97 }; 98 99 Type: 100 generateLuarocksConfig :: AttrSet -> String 101 */ 102 generateLuarocksConfig = 103 { 104 externalDeps ? [ ], 105 # a list of lua derivations 106 requiredLuaRocks ? [ ], 107 ... 108 }@args: 109 let 110 rocksTrees = lib.imap0 (i: dep: { 111 name = "dep-${toString i}"; 112 root = "${dep}"; 113 # packages built by buildLuaPackage or luarocks doesn't contain rocksSubdir 114 # hence a default here 115 rocks_dir = 116 if dep ? rocksSubdir then "${dep}/${dep.rocksSubdir}" else "${dep.pname}-${dep.version}-rocks"; 117 }) requiredLuaRocks; 118 119 # Explicitly point luarocks to the relevant locations for multiple-output 120 # derivations that are external dependencies, to work around an issue it has 121 # (https://github.com/luarocks/luarocks/issues/766) 122 depVariables = zipAttrsWithLast ( 123 lib.lists.map ( 124 { name, dep }: 125 { 126 "${name}_INCDIR" = "${lib.getDev dep}/include"; 127 "${name}_LIBDIR" = "${lib.getLib dep}/lib"; 128 "${name}_BINDIR" = "${lib.getBin dep}/bin"; 129 } 130 ) externalDeps' 131 ); 132 zipAttrsWithLast = lib.attrsets.zipAttrsWith (name: lib.lists.last); 133 134 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ] 135 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps; 136 137 externalDepsDirs = map (x: builtins.toString x) (lib.filter (lib.isDerivation) externalDeps); 138 139 generatedConfig = ( 140 { 141 142 # first tree is the default target where new rocks are installed, 143 # any other trees in the list are treated as additional sources of installed rocks for matching dependencies. 144 rocks_trees = ( 145 [ 146 { 147 name = "current"; 148 root = "${placeholder "out"}"; 149 rocks_dir = "current"; 150 } 151 ] 152 ++ rocksTrees 153 ); 154 } 155 // lib.optionalAttrs lua.pkgs.isLuaJIT { 156 # Luajit provides some additional functionality built-in; this exposes 157 # that to luarock's dependency system 158 rocks_provided = { 159 jit = "${lua.luaversion}-1"; 160 ffi = "${lua.luaversion}-1"; 161 luaffi = "${lua.luaversion}-1"; 162 bit = "${lua.luaversion}-1"; 163 }; 164 } 165 // { 166 # For single-output external dependencies 167 external_deps_dirs = externalDepsDirs; 168 # Some needed machinery to handle multiple-output external dependencies, 169 # as per https://github.com/luarocks/luarocks/issues/766 170 variables = depVariables; 171 } 172 // removeAttrs args [ 173 "requiredLuaRocks" 174 "externalDeps" 175 ] 176 ); 177 in 178 generatedConfig; 179}