1 # Generic builder for lua packages
8 # Whether the derivation provides a lua module or not.
15 # we need rockspecVersion to find the .rockspec even when version changes
16 , rockspecVersion ? version
18 # by default prefix `name` e.g. "lua5.2-${name}"
19 , namePrefix ? "${lua.pname}${lib.versions.majorMinor lua.version}-"
21 # Dependencies for building the package
24 # Dependencies needed for running the checkPhase.
25 # These are added to nativeBuildInputs when doCheck = true.
26 , nativeCheckInputs ? []
28 # propagate build dependencies so in case we have A -> B -> C,
29 # C can import package A propagated by B
30 , propagatedBuildInputs ? []
32 # used to disable derivation, useful for specific lua versions
33 # TODO move from this setting meta.broken to a 'disabled' attribute on the
34 # package, then use that to skip/include in each lua${ver}Packages set?
37 # Additional arguments to pass to the makeWrapper function, which wraps
39 , makeWrapperArgs ? []
41 # Skip wrapping of lua programs altogether
42 , dontWrapLuaPrograms ? false
44 # Non-Lua / system (e.g. C library) dependencies. Is a list of deps, where
45 # each dep is either a derivation, or an attribute set like
46 # { name = "rockspec external_dependencies key"; dep = derivation; }
47 # The latter is used to work-around luarocks having a problem with
48 # multiple-output derivations as external deps:
49 # https://github.com/luarocks/luarocks/issues/766<Paste>
52 # Appended to the generated luarocks config
55 # transparent mapping nix <-> lua used as LUAROCKS_CONFIG
56 # Refer to https://github.com/luarocks/luarocks/wiki/Config-file-format for specs
59 # relative to srcRoot, path to the rockspec to use when using rocks
60 , rockspecFilename ? null
62 # must be set for packages that don't have a rock
63 , knownRockspec ? null
68 # Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
72 # TODO fix warnings "Couldn't load rockspec for ..." during manifest
73 # construction -- from initial investigation, appears it will require
74 # upstream luarocks changes to fix cleanly (during manifest construction,
75 # luarocks only looks for rockspecs in the default/system tree instead of all
77 luarocks_config = "luarocks-config.lua";
79 luarocksDrv = luaLib.toLuaModule ( lua.stdenv.mkDerivation (self: attrs // {
81 name = namePrefix + self.pname + "-" + self.version;
82 inherit rockspecVersion;
84 __structuredAttrs = true;
86 LUAROCKS_CONFIG = self.configFile;
89 generatedRockspecFilename = "./${self.pname}-${self.rockspecVersion}.rockspec";
97 inherit doCheck extraConfig rockspecFilename knownRockspec externalDeps nativeCheckInputs;
100 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
101 externalDeps' = lib.filter (dep: !lib.isDerivation dep) self.externalDeps;
102 in [ luarocks_bootstrap ]
104 ++ lib.optionals self.doCheck ([ luarocksCheckHook ] ++ self.nativeCheckInputs)
105 ++ (map (d: d.dep) externalDeps')
108 # propagate lua to active setup-hook in nix-shell
109 propagatedBuildInputs = propagatedBuildInputs ++ [ lua ];
111 # @-patterns do not capture formal argument default values, so we need to
112 # explicitly inherit this for it to be available as a shell variable in the
114 rocksSubdir = "${self.pname}-${self.version}-rocks";
116 configFile = writeTextFile {
117 name = self.pname + "-luarocks-config.lua";
118 text = self.luarocks_content;
122 (lib.generators.toLua { asBindings = true; } self.luarocksConfig) +
128 # TODO make it the default variable
130 externalDepsGenerated = lib.filter (drv: !drv ? luaModule)
131 (self.nativeBuildInputs ++ self.propagatedBuildInputs ++ self.buildInputs);
133 generatedConfig = luaLib.generateLuarocksConfig {
134 externalDeps = lib.unique (self.externalDeps ++ externalDepsGenerated);
137 # To prevent collisions when creating environments, we install the rock
138 # files into per-package subdirectories
139 rocks_subdir = self.rocksSubdir;
141 # Filter out the lua derivation itself from the Lua module dependency
142 # closure, as it doesn't have a rock tree :)
143 # luaLib.hasLuaModule
144 requiredLuaRocks = lib.filter luaLib.hasLuaModule
145 (lua.pkgs.requiredLuaModules (self.nativeBuildInputs ++ self.propagatedBuildInputs));
148 luarocksConfig' = lib.recursiveUpdate luarocksConfig
149 (lib.optionalAttrs (attrs ? extraVariables) (lib.warn "extraVariables in buildLuarocksPackage is deprecated, use luarocksConfig instead"
151 variables = attrs.extraVariables;
154 in lib.recursiveUpdate generatedConfig luarocksConfig';
160 + lib.optionalString (self.rockspecFilename == null) ''
161 rockspecFilename="${self.generatedRockspecFilename}"
163 + lib.optionalString (self.knownRockspec != null) ''
164 # prevents the following type of error:
165 # Inconsistency between rockspec filename (42fm1b3d7iv6fcbhgm9674as3jh6y2sh-luv-1.22.0-1.rockspec) and its contents (luv-1.22.0-1.rockspec)
166 rockspecFilename="$TMP/$(stripHash ${self.knownRockspec})"
167 cp ${self.knownRockspec} "$rockspecFilename"
170 runHook postConfigure
176 source ${lua}/nix-support/utils.sh
177 nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG"
179 LUAROCKS_EXTRA_ARGS=""
180 if (( ''${NIX_DEBUG:-0} >= 1 )); then
181 LUAROCKS_EXTRA_ARGS=" --verbose"
187 postFixup = lib.optionalString (!dontWrapLuaPrograms) ''
189 '' + attrs.postFixup or "";
194 # work around failing luarocks test for Write access
197 # luarocks make assumes sources are available in cwd
198 # After the build is complete, it also installs the rock.
199 # If no argument is given, it looks for a rockspec in the current directory
200 # but some packages have several rockspecs in their source directory so
201 # we force the use of the upper level since it is
202 # the sole rockspec in that folder
203 # maybe we could reestablish dependency checking via passing --rock-trees
205 nix_debug "ROCKSPEC $rockspecFilename"
206 luarocks $LUAROCKS_EXTRA_ARGS make --deps-mode=all --tree=$out ''${rockspecFilename}
219 export LUAROCKS_CONFIG="$PWD/${luarocks_config}";
225 } // attrs.passthru or { };
228 platforms = lua.meta.platforms;
229 # add extra maintainer(s) to every package
230 maintainers = (attrs.meta.maintainers or []) ++ [ ];
232 } // attrs.meta or {};