nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at 21.05 251 lines 8.0 kB view raw
1# Generic builder for lua packages 2{ lib 3, lua 4, wrapLua 5# Whether the derivation provides a lua module or not. 6, toLuaModule 7}: 8 9{ 10name ? "${attrs.pname}-${attrs.version}" 11 12, version 13 14# by default prefix `name` e.g. "lua5.2-${name}" 15, namePrefix ? if lua.pkgs.isLuaJIT 16 then lua.name + "-" 17 else "lua" + lua.luaversion + "-" 18 19# Dependencies for building the package 20, buildInputs ? [] 21 22# Dependencies needed for running the checkPhase. 23# These are added to buildInputs when doCheck = true. 24, checkInputs ? [] 25 26# propagate build dependencies so in case we have A -> B -> C, 27# C can import package A propagated by B 28, propagatedBuildInputs ? [] 29, propagatedNativeBuildInputs ? [] 30 31# used to disable derivation, useful for specific lua versions 32# TODO move from this setting meta.broken to a 'disabled' attribute on the 33# package, then use that to skip/include in each lua${ver}Packages set? 34, disabled ? false 35 36# Additional arguments to pass to the makeWrapper function, which wraps 37# generated binaries. 38, makeWrapperArgs ? [] 39 40# Skip wrapping of lua programs altogether 41, dontWrapLuaPrograms ? false 42 43, meta ? {} 44 45, passthru ? {} 46, doCheck ? false 47 48# Non-Lua / system (e.g. C library) dependencies. Is a list of deps, where 49# each dep is either a derivation, or an attribute set like 50# { name = "rockspec external_dependencies key"; dep = derivation; } 51# The latter is used to work-around luarocks having a problem with 52# multiple-output derivations as external deps: 53# https://github.com/luarocks/luarocks/issues/766<Paste> 54, externalDeps ? lib.unique (lib.filter (drv: !drv ? luaModule) (propagatedBuildInputs ++ buildInputs)) 55 56# Appended to the generated luarocks config 57, extraConfig ? "" 58# Inserted into the generated luarocks config in the "variables" table 59, extraVariables ? {} 60# The two above arguments have access to builder variables -- e.g. to $out 61 62# relative to srcRoot, path to the rockspec to use when using rocks 63, rockspecFilename ? "../*.rockspec" 64 65# must be set for packages that don't have a rock 66, knownRockspec ? null 67 68, ... } @ attrs: 69 70 71# Keep extra attributes from `attrs`, e.g., `patchPhase', etc. 72 73let 74 # TODO fix warnings "Couldn't load rockspec for ..." during manifest 75 # construction -- from initial investigation, appears it will require 76 # upstream luarocks changes to fix cleanly (during manifest construction, 77 # luarocks only looks for rockspecs in the default/system tree instead of all 78 # configured trees) 79 luarocks_config = "luarocks-config.lua"; 80 luarocks_content = let 81 extraVariablesStr = lib.concatStringsSep "\n " 82 (lib.mapAttrsToList (k: v: "${k}='${v}';") extraVariables); 83 in '' 84 local_cache = "" 85 -- To prevent collisions when creating environments, we install the rock 86 -- files into per-package subdirectories 87 rocks_subdir = '${rocksSubdir}' 88 -- Then we need to tell luarocks where to find the rock files per 89 -- dependency 90 rocks_trees = { 91 ${lib.concatStringsSep "\n, " rocksTrees} 92 } 93 '' + lib.optionalString lua.pkgs.isLuaJIT '' 94 -- Luajit provides some additional functionality built-in; this exposes 95 -- that to luarock's dependency system 96 rocks_provided = { 97 jit='${lua.luaversion}-1'; 98 ffi='${lua.luaversion}-1'; 99 luaffi='${lua.luaversion}-1'; 100 bit='${lua.luaversion}-1'; 101 } 102 '' + '' 103 -- For single-output external dependencies 104 external_deps_dirs = { 105 ${lib.concatStringsSep "\n, " externalDepsDirs} 106 } 107 variables = { 108 -- Some needed machinery to handle multiple-output external dependencies, 109 -- as per https://github.com/luarocks/luarocks/issues/766 110 ${lib.optionalString (lib.length depVariables > 0) '' 111 ${lib.concatStringsSep "\n " depVariables}''} 112 ${extraVariablesStr} 113 } 114 ${extraConfig} 115 ''; 116 117 rocksSubdir = "${attrs.pname}-${version}-rocks"; 118 119 externalDepsDirs = map 120 (x: "'${builtins.toString x}'") 121 (lib.filter (lib.isDerivation) externalDeps); 122 123 rocksTrees = lib.imap0 124 (i: dep: "{ name = [[dep-${toString i}]], root = '${dep}', rocks_dir = '${dep}/${dep.rocksSubdir}' }") 125 requiredLuaRocks; 126 127 # Filter out the lua derivation itself from the Lua module dependency 128 # closure, as it doesn't have a rock tree :) 129 requiredLuaRocks = lib.filter (d: d ? luaModule) 130 (lua.pkgs.requiredLuaModules propagatedBuildInputs); 131 132 # Explicitly point luarocks to the relevant locations for multiple-output 133 # derivations that are external dependencies, to work around an issue it has 134 # (https://github.com/luarocks/luarocks/issues/766) 135 depVariables = lib.concatMap ({name, dep}: [ 136 "${name}_INCDIR='${lib.getDev dep}/include';" 137 "${name}_LIBDIR='${lib.getLib dep}/lib';" 138 "${name}_BINDIR='${lib.getBin dep}/bin';" 139 ]) externalDeps'; 140 141 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ] 142 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps; 143in 144toLuaModule ( lua.stdenv.mkDerivation ( 145builtins.removeAttrs attrs ["disabled" "checkInputs" "externalDeps" "extraVariables"] // { 146 147 name = namePrefix + name; 148 149 buildInputs = [ wrapLua lua.pkgs.luarocks ] 150 ++ buildInputs 151 ++ lib.optionals doCheck checkInputs 152 ++ (map (d: d.dep) externalDeps') 153 ; 154 155 # propagate lua to active setup-hook in nix-shell 156 propagatedBuildInputs = propagatedBuildInputs ++ [ lua ]; 157 inherit doCheck; 158 159 # @-patterns do not capture formal argument default values, so we need to 160 # explicitly inherit this for it to be available as a shell variable in the 161 # builder 162 inherit rockspecFilename; 163 inherit rocksSubdir; 164 165 # enabled only for src.rock 166 setSourceRoot= let 167 name_only= lib.getName name; 168 in 169 lib.optionalString (knownRockspec == null) '' 170 # format is rockspec_basename/source_basename 171 # rockspec can set it via spec.source.dir 172 folder=$(find . -mindepth 2 -maxdepth 2 -type d -path '*${name_only}*/*'|head -n1) 173 sourceRoot="$folder" 174 ''; 175 176 configurePhase = '' 177 runHook preConfigure 178 179 cat > ${luarocks_config} <<EOF 180 ${luarocks_content} 181 EOF 182 export LUAROCKS_CONFIG="$PWD/${luarocks_config}"; 183 '' 184 + lib.optionalString (knownRockspec != null) '' 185 186 # prevents the following type of error: 187 # Inconsistency between rockspec filename (42fm1b3d7iv6fcbhgm9674as3jh6y2sh-luv-1.22.0-1.rockspec) and its contents (luv-1.22.0-1.rockspec) 188 rockspecFilename="$TMP/$(stripHash ''${knownRockspec})" 189 cp ''${knownRockspec} "$rockspecFilename" 190 '' 191 + '' 192 runHook postConfigure 193 ''; 194 195 buildPhase = '' 196 runHook preBuild 197 198 nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG" 199 200 LUAROCKS=luarocks 201 if (( ''${NIX_DEBUG:-0} >= 1 )); then 202 LUAROCKS="$LUAROCKS --verbose" 203 fi 204 205 runHook postBuild 206 ''; 207 208 postFixup = lib.optionalString (!dontWrapLuaPrograms) '' 209 wrapLuaPrograms 210 '' + attrs.postFixup or ""; 211 212 installPhase = attrs.installPhase or '' 213 runHook preInstall 214 215 # work around failing luarocks test for Write access 216 mkdir -p $out 217 218 # luarocks make assumes sources are available in cwd 219 # After the build is complete, it also installs the rock. 220 # If no argument is given, it looks for a rockspec in the current directory 221 # but some packages have several rockspecs in their source directory so 222 # we force the use of the upper level since it is 223 # the sole rockspec in that folder 224 # maybe we could reestablish dependency checking via passing --rock-trees 225 226 nix_debug "ROCKSPEC $rockspecFilename" 227 nix_debug "cwd: $PWD" 228 $LUAROCKS make --deps-mode=all --tree=$out ''${rockspecFilename} 229 230 runHook postInstall 231 ''; 232 233 234 checkPhase = attrs.checkPhase or '' 235 runHook preCheck 236 $LUAROCKS test 237 runHook postCheck 238 ''; 239 240 passthru = { 241 inherit lua; # The lua interpreter 242 inherit externalDeps; 243 } // passthru; 244 245 meta = with lib.maintainers; { 246 platforms = lua.meta.platforms; 247 # add extra maintainer(s) to every package 248 maintainers = (meta.maintainers or []) ++ [ ]; 249 broken = disabled; 250 } // meta; 251}))