1 # Generic builder for lua packages
6 # Whether the derivation provides a lua module or not.
13 # we need rockspecVersion to find the .rockspec even when version changes
14 , rockspecVersion ? version
16 # by default prefix `name` e.g. "lua5.2-${name}"
17 , namePrefix ? "${lua.pname}${lua.sourceVersion.major}.${lua.sourceVersion.minor}-"
19 # Dependencies for building the package
22 # Dependencies needed for running the checkPhase.
23 # These are added to buildInputs when doCheck = true.
26 # propagate build dependencies so in case we have A -> B -> C,
27 # C can import package A propagated by B
28 , propagatedBuildInputs ? []
30 # used to disable derivation, useful for specific lua versions
31 # TODO move from this setting meta.broken to a 'disabled' attribute on the
32 # package, then use that to skip/include in each lua${ver}Packages set?
35 # Additional arguments to pass to the makeWrapper function, which wraps
37 , makeWrapperArgs ? []
39 # Skip wrapping of lua programs altogether
40 , dontWrapLuaPrograms ? false
46 , doInstallCheck ? false
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>
56 # Appended to the generated luarocks config
58 # Inserted into the generated luarocks config in the "variables" table
60 # The two above arguments have access to builder variables -- e.g. to $out
62 # relative to srcRoot, path to the rockspec to use when using rocks
63 , rockspecFilename ? null
64 # relative to srcRoot, path to folder that contains the expected rockspec
67 # must be set for packages that don't have a rock
68 , knownRockspec ? null
73 # Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
76 generatedRockspecFilename = "${rockspecDir}/${pname}-${rockspecVersion}.rockspec";
78 # TODO fix warnings "Couldn't load rockspec for ..." during manifest
79 # construction -- from initial investigation, appears it will require
80 # upstream luarocks changes to fix cleanly (during manifest construction,
81 # luarocks only looks for rockspecs in the default/system tree instead of all
83 luarocks_config = "luarocks-config.lua";
85 # Filter out the lua derivation itself from the Lua module dependency
86 # closure, as it doesn't have a rock tree :)
87 requiredLuaRocks = lib.filter (d: d ? luaModule)
88 (lua.pkgs.requiredLuaModules (luarocksDrv.nativeBuildInputs ++ luarocksDrv.propagatedBuildInputs));
90 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
91 externalDepsGenerated = lib.unique (lib.filter (drv: !drv ? luaModule) (
92 luarocksDrv.nativeBuildInputs ++ luarocksDrv.propagatedBuildInputs ++ luarocksDrv.buildInputs)
94 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps;
96 luarocksDrv = luaLib.toLuaModule ( lua.stdenv.mkDerivation (self: let
98 rocksSubdir = "${self.pname}-${self.version}-rocks";
99 luarocks_content = let
100 generatedConfig = luaLib.generateLuarocksConfig {
101 externalDeps = externalDeps ++ externalDepsGenerated;
102 inherit extraVariables rocksSubdir requiredLuaRocks;
109 in builtins.removeAttrs attrs ["disabled" "externalDeps" "extraVariables"] // {
111 name = namePrefix + pname + "-" + self.version;
112 inherit rockspecVersion;
114 nativeBuildInputs = [
117 ] ++ lib.optionals doCheck ([ luarocksCheckHook ] ++ self.checkInputs);
119 buildInputs = buildInputs
120 ++ (map (d: d.dep) externalDeps');
123 # propagate lua to active setup-hook in nix-shell
124 propagatedBuildInputs = propagatedBuildInputs ++ [ lua ];
126 # @-patterns do not capture formal argument default values, so we need to
127 # explicitly inherit this for it to be available as a shell variable in the
134 cat > ${luarocks_config} <<EOF
137 export LUAROCKS_CONFIG="$PWD/${luarocks_config}";
139 + lib.optionalString (rockspecFilename == null) ''
140 rockspecFilename="${generatedRockspecFilename}"
142 + lib.optionalString (knownRockspec != null) ''
144 # prevents the following type of error:
145 # Inconsistency between rockspec filename (42fm1b3d7iv6fcbhgm9674as3jh6y2sh-luv-1.22.0-1.rockspec) and its contents (luv-1.22.0-1.rockspec)
146 rockspecFilename="$TMP/$(stripHash ''${knownRockspec})"
147 cp ''${knownRockspec} "$rockspecFilename"
150 runHook postConfigure
156 nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG"
159 if (( ''${NIX_DEBUG:-0} >= 1 )); then
160 LUAROCKS="$LUAROCKS --verbose"
166 postFixup = lib.optionalString (!dontWrapLuaPrograms) ''
168 '' + attrs.postFixup or "";
170 installPhase = attrs.installPhase or ''
173 # work around failing luarocks test for Write access
176 # luarocks make assumes sources are available in cwd
177 # After the build is complete, it also installs the rock.
178 # If no argument is given, it looks for a rockspec in the current directory
179 # but some packages have several rockspecs in their source directory so
180 # we force the use of the upper level since it is
181 # the sole rockspec in that folder
182 # maybe we could reestablish dependency checking via passing --rock-trees
184 nix_debug "ROCKSPEC $rockspecFilename"
185 nix_debug "cwd: $PWD"
186 $LUAROCKS make --deps-mode=all --tree=$out ''${rockspecFilename}
192 checkPhase = attrs.checkPhase or ''
198 LUAROCKS_CONFIG="$PWD/${luarocks_config}";
202 export LUAROCKS_CONFIG="$PWD/${luarocks_config}";
207 inherit lua; # The lua interpreter
208 inherit externalDeps;
209 inherit luarocks_content;
213 platforms = lua.meta.platforms;
214 # add extra maintainer(s) to every package
215 maintainers = (meta.maintainers or []) ++ [ ];