1# Generic builder for lua packages
2{ lib
3, lua
4, stdenv
5, wrapLua
6# Whether the derivation provides a lua module or not.
7, toLuaModule
8}:
9
10{
11name ? "${attrs.pname}-${attrs.version}"
12
13, version
14
15# by default prefix `name` e.g. "lua5.2-${name}"
16, namePrefix ? "lua" + lua.luaversion + "-"
17
18# Dependencies for building the package
19, buildInputs ? []
20
21# Dependencies needed for running the checkPhase.
22# These are added to buildInputs when doCheck = true.
23, checkInputs ? []
24
25# propagate build dependencies so in case we have A -> B -> C,
26# C can import package A propagated by B
27, propagatedBuildInputs ? []
28, propagatedNativeBuildInputs ? []
29
30# used to disable derivation, useful for specific lua versions
31, disabled ? false
32
33# Additional arguments to pass to the makeWrapper function, which wraps
34# generated binaries.
35, makeWrapperArgs ? []
36, external_deps ? propagatedBuildInputs ++ buildInputs
37
38# Skip wrapping of lua programs altogether
39, dontWrapLuaPrograms ? false
40
41, meta ? {}
42
43, passthru ? {}
44, doCheck ? false
45
46# appended to the luarocks generated config
47# in peculiar variables like { EVENT_INCDIR } can be useful to work around
48# luarocks limitations, ie, luarocks consider include/lib folders to be subfolders of the same package in external_deps_dirs
49# as explained in https://github.com/luarocks/luarocks/issues/766
50, extraConfig ? ""
51
52# relative to srcRoot, path to the rockspec to use when using rocks
53, rockspecFilename ? "../*.rockspec"
54
55# must be set for packages that don't have a rock
56, knownRockspec ? null
57
58, ... } @ attrs:
59
60
61# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
62if disabled
63then throw "${name} not supported for interpreter ${lua}"
64else
65
66let
67
68 deps_dirs= lib.concatStringsSep ", " (
69 map (x: "\"${builtins.toString x}\"") external_deps
70 );
71
72 # TODO
73 # - add rocktrees (look at torch-distro.nix/https://github.com/luarocks/luarocks/wiki/Config-file-format)
74 # - silence warnings
75 luarocks_config = "luarocksConfig";
76 luarocks_content = ''
77 local_cache = ""
78 -- array of strings
79 external_deps_dirs = {
80 ${deps_dirs}
81 }
82 rocks_trees = {
83 }
84 ${extraConfig}
85 '';
86in
87toLuaModule ( lua.stdenv.mkDerivation (
88builtins.removeAttrs attrs ["disabled" "checkInputs"] // {
89
90 name = namePrefix + name;
91
92 buildInputs = [ wrapLua lua.pkgs.luarocks ]
93 ++ buildInputs
94 ++ lib.optionals doCheck checkInputs
95 ;
96
97 # propagate lua to active setup-hook in nix-shell
98 propagatedBuildInputs = propagatedBuildInputs ++ [ lua ];
99 doCheck = false;
100
101 # enabled only for src.rock
102 setSourceRoot= let
103 name_only=(builtins.parseDrvName name).name;
104 in
105 lib.optionalString (knownRockspec == null) ''
106 # format is rockspec_basename/source_basename
107 # rockspec can set it via spec.source.dir
108 folder=$(find . -mindepth 2 -maxdepth 2 -type d -path '*${name_only}*/*'|head -n1)
109 sourceRoot="$folder"
110 '';
111
112 configurePhase = ''
113 runHook preConfigure
114
115 cat > ${luarocks_config} <<EOF
116 ${luarocks_content}
117 EOF
118 export LUAROCKS_CONFIG="$PWD/${luarocks_config}";
119 ''
120 + lib.optionalString (knownRockspec != null) ''
121
122 # prevents the following type of error:
123 # Inconsistency between rockspec filename (42fm1b3d7iv6fcbhgm9674as3jh6y2sh-luv-1.22.0-1.rockspec) and its contents (luv-1.22.0-1.rockspec)
124 rockspecFilename="$TMP/$(stripHash ''${knownRockspec})"
125 cp ''${knownRockspec} "$rockspecFilename"
126 ''
127 + ''
128 runHook postConfigure
129 '';
130
131 buildPhase = ''
132 runHook preBuild
133
134 nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG"
135
136 LUAROCKS=luarocks
137 if (( ''${NIX_DEBUG:-0} >= 1 )); then
138 LUAROCKS="$LUAROCKS --verbose"
139 fi
140
141 patchShebangs .
142
143 runHook postBuild
144 '';
145
146 postFixup = lib.optionalString (!dontWrapLuaPrograms) ''
147 wrapLuaPrograms
148 '' + attrs.postFixup or '''';
149
150 installPhase = attrs.installPhase or ''
151 runHook preInstall
152
153 # luarocks make assumes sources are available in cwd
154 # After the build is complete, it also installs the rock.
155 # If no argument is given, it looks for a rockspec in the current directory
156 # but some packages have several rockspecs in their source directory so
157 # we force the use of the upper level since it is
158 # the sole rockspec in that folder
159 # maybe we could reestablish dependency checking via passing --rock-trees
160
161 nix_debug "ROCKSPEC $rockspecFilename"
162 nix_debug "cwd: $PWD"
163 $LUAROCKS make --deps-mode=none --tree $out ''${rockspecFilename}
164
165 # to prevent collisions when creating environments
166 # also added -f as it doesn't always exist
167 # don't remove the whole directory as
168 rm -rf $out/lib/luarocks/rocks/manifest
169
170 runHook postInstall
171 '';
172
173 passthru = {
174 inherit lua; # The lua interpreter
175 } // passthru;
176
177 meta = with lib.maintainers; {
178 platforms = lua.meta.platforms;
179 # add extra maintainer(s) to every package
180 maintainers = (meta.maintainers or []) ++ [ ];
181 } // meta;
182}))