nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 stdenv,
3 lib,
4 makeSetupHook,
5 makeWrapper,
6 gobject-introspection,
7 isGraphical ? false,
8 gtk3,
9 librsvg,
10 dconf,
11 withDconf ? !stdenv.targetPlatform.isDarwin && lib.meta.availableOn stdenv.targetPlatform dconf,
12 callPackage,
13 wrapGAppsHook3,
14 targetPackages,
15}:
16
17makeSetupHook {
18 name = "wrap-gapps-hook";
19 propagatedBuildInputs = [
20 # We use the wrapProgram function.
21 makeWrapper
22 ]
23 ++ lib.optionals isGraphical [
24 # TODO: remove this, packages should depend on GTK explicitly.
25 gtk3
26
27 librsvg
28 ];
29
30 # depsTargetTargetPropagated will essentially be buildInputs when wrapGAppsHook3 is placed into nativeBuildInputs
31 # the librsvg and gtk3 above should be removed but kept to not break anything that implicitly depended on its binaries
32 depsTargetTargetPropagated =
33 assert (lib.assertMsg (!targetPackages ? raw) "wrapGAppsHook3 must be in nativeBuildInputs");
34 lib.optionals isGraphical [
35 # librsvg provides a module for gdk-pixbuf to allow rendering
36 # SVG icons. Most icon themes are SVG-based and so are some
37 # graphics in GTK (e.g. cross for closing window in window title bar)
38 # so it is pretty much required for applications using GTK.
39 librsvg
40
41 # TODO: remove this, packages should depend on GTK explicitly.
42 gtk3
43 ]
44 ++ lib.optionals withDconf [
45 # It is highly probable that a program will use GSettings,
46 # at minimum through GTK file chooser dialogue.
47 # Let’s add a GIO module for “dconf” GSettings backend
48 # to avoid falling back to “memory” backend. This is
49 # required for GSettings-based settings to be persisted.
50 # Unfortunately, it also requires the user to have dconf
51 # D-Bus service enabled globally (e.g. through a NixOS module).
52 dconf.lib
53 ];
54 passthru = {
55 tests =
56 let
57 sample-project = ./tests/sample-project;
58
59 testLib = callPackage ./tests/lib.nix { };
60 inherit (testLib) expectSomeLineContainingYInFileXToMentionZ;
61 in
62 rec {
63 # Simple derivation containing a program and a daemon.
64 basic = stdenv.mkDerivation {
65 name = "basic";
66
67 src = sample-project;
68
69 strictDeps = true;
70 nativeBuildInputs = [ wrapGAppsHook3 ];
71
72 installFlags = [
73 "bin-foo"
74 "libexec-bar"
75 ];
76 };
77
78 # The wrapper for executable files should add path to dconf GIO module.
79 basic-contains-dconf =
80 let
81 tested = basic;
82 in
83 testLib.runTest "basic-contains-dconf" (
84 testLib.skip stdenv.hostPlatform.isDarwin ''
85 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GIO_EXTRA_MODULES"
86 "${dconf.lib}/lib/gio/modules"
87 }
88 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GIO_EXTRA_MODULES"
89 "${dconf.lib}/lib/gio/modules"
90 }
91 ''
92 );
93
94 basic-contains-gdk-pixbuf =
95 let
96 tested = basic;
97 in
98 testLib.runTest "basic-contains-gdk-pixbuf" (
99 testLib.skip stdenv.hostPlatform.isDarwin ''
100 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GDK_PIXBUF_MODULE_FILE"
101 "${lib.getLib librsvg}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
102 }
103 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GDK_PIXBUF_MODULE_FILE"
104 "${lib.getLib librsvg}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
105 }
106 ''
107 );
108
109 # Simple derivation containing a gobject-introspection typelib.
110 typelib-Mahjong = stdenv.mkDerivation {
111 name = "typelib-Mahjong";
112
113 src = sample-project;
114
115 strictDeps = true;
116
117 installFlags = [ "typelib-Mahjong" ];
118 };
119
120 # Simple derivation using a typelib.
121 typelib-user = stdenv.mkDerivation {
122 name = "typelib-user";
123
124 src = sample-project;
125
126 strictDeps = true;
127 nativeBuildInputs = [
128 gobject-introspection
129 wrapGAppsHook3
130 ];
131
132 buildInputs = [
133 typelib-Mahjong
134 ];
135
136 installFlags = [
137 "bin-foo"
138 "libexec-bar"
139 ];
140 };
141
142 # Testing cooperation with gobject-introspection setup hook,
143 # which should populate GI_TYPELIB_PATH variable with paths
144 # to typelibs among the derivation’s dependencies.
145 # The resulting GI_TYPELIB_PATH should be picked up by the wrapper.
146 typelib-user-has-gi-typelib-path =
147 let
148 tested = typelib-user;
149 in
150 testLib.runTest "typelib-user-has-gi-typelib-path" ''
151 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH"
152 "${typelib-Mahjong}/lib/girepository-1.0"
153 }
154 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH"
155 "${typelib-Mahjong}/lib/girepository-1.0"
156 }
157 '';
158
159 # Simple derivation containing a gobject-introspection typelib in lib output.
160 typelib-Bechamel = stdenv.mkDerivation {
161 name = "typelib-Bechamel";
162
163 outputs = [
164 "out"
165 "lib"
166 ];
167
168 src = sample-project;
169
170 strictDeps = true;
171
172 makeFlags = [
173 "LIBDIR=${placeholder "lib"}/lib"
174 ];
175
176 installFlags = [ "typelib-Bechamel" ];
177 };
178
179 # Simple derivation using a typelib from non-default output.
180 typelib-multiout-user = stdenv.mkDerivation {
181 name = "typelib-multiout-user";
182
183 src = sample-project;
184
185 strictDeps = true;
186 nativeBuildInputs = [
187 gobject-introspection
188 wrapGAppsHook3
189 ];
190
191 buildInputs = [
192 typelib-Bechamel
193 ];
194
195 installFlags = [
196 "bin-foo"
197 "libexec-bar"
198 ];
199 };
200
201 # Testing cooperation with gobject-introspection setup hook,
202 # which should populate GI_TYPELIB_PATH variable with paths
203 # to typelibs among the derivation’s dependencies,
204 # even when they are not in default output.
205 # The resulting GI_TYPELIB_PATH should be picked up by the wrapper.
206 typelib-multiout-user-has-gi-typelib-path =
207 let
208 tested = typelib-multiout-user;
209 in
210 testLib.runTest "typelib-multiout-user-has-gi-typelib-path" ''
211 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH"
212 "${typelib-Bechamel.lib}/lib/girepository-1.0"
213 }
214 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH"
215 "${typelib-Bechamel.lib}/lib/girepository-1.0"
216 }
217 '';
218
219 # Simple derivation that contains a typelib as well as a program using it.
220 typelib-self-user = stdenv.mkDerivation {
221 name = "typelib-self-user";
222
223 src = sample-project;
224
225 strictDeps = true;
226 nativeBuildInputs = [
227 gobject-introspection
228 wrapGAppsHook3
229 ];
230
231 installFlags = [
232 "typelib-Cow"
233 "bin-foo"
234 "libexec-bar"
235 ];
236 };
237
238 # Testing cooperation with gobject-introspection setup hook,
239 # which should add the path to derivation’s own typelibs
240 # to GI_TYPELIB_PATH variable.
241 # The resulting GI_TYPELIB_PATH should be picked up by the wrapper.
242 # https://github.com/NixOS/nixpkgs/issues/85515
243 typelib-self-user-has-gi-typelib-path =
244 let
245 tested = typelib-self-user;
246 in
247 testLib.runTest "typelib-self-user-has-gi-typelib-path" ''
248 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH"
249 "${typelib-self-user}/lib/girepository-1.0"
250 }
251 ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH"
252 "${typelib-self-user}/lib/girepository-1.0"
253 }
254 '';
255 };
256 };
257} ./wrap-gapps-hook.sh