1{ lib
2, stdenv
3, fetchFromGitLab
4, makeWrapper
5, pkg-config
6, libxslt
7, meson
8, ninja
9, python3
10, dbus
11, umockdev
12, libeatmydata
13, gtk-doc
14, docbook-xsl-nons
15, udev
16, libgudev
17, libusb1
18, glib
19, gettext
20, systemd
21, nixosTests
22, useIMobileDevice ? true
23, libimobiledevice
24, withDocs ? withIntrospection
25, mesonEmulatorHook
26, withIntrospection ? lib.meta.availableOn stdenv.hostPlatform gobject-introspection && stdenv.hostPlatform.emulatorAvailable buildPackages
27, buildPackages
28, gobject-introspection
29}:
30
31assert withDocs -> withIntrospection;
32
33stdenv.mkDerivation (finalAttrs: {
34 pname = "upower";
35 version = "1.90.4";
36
37 outputs = [ "out" "dev" "installedTests" ]
38 ++ lib.optionals withDocs [ "devdoc" ];
39
40 src = fetchFromGitLab {
41 domain = "gitlab.freedesktop.org";
42 owner = "upower";
43 repo = "upower";
44 rev = "v${finalAttrs.version}";
45 hash = "sha256-5twHuDLisVF07Y5KYwlqWMi12+p6UpARJvoBN/+tX2o=";
46 };
47
48 patches = lib.optionals (stdenv.hostPlatform.system == "i686-linux") [
49 # Remove when this is fixed upstream:
50 # https://gitlab.freedesktop.org/upower/upower/-/issues/214
51 ./i686-test-remove-battery-check.patch
52 ] ++ [
53 ./installed-tests-path.patch
54 ];
55
56 strictDeps = true;
57
58 depsBuildBuild = [
59 pkg-config
60 ];
61
62 nativeBuildInputs = [
63 meson
64 ninja
65 python3
66 docbook-xsl-nons
67 gettext
68 libxslt
69 makeWrapper
70 pkg-config
71 glib
72 ] ++ lib.optionals withIntrospection [
73 gobject-introspection
74 ] ++ lib.optionals withDocs [
75 gtk-doc
76 ] ++ lib.optionals (withDocs && !stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
77 mesonEmulatorHook
78 ];
79
80 buildInputs = [
81 libgudev
82 libusb1
83 udev
84 systemd
85 # Duplicate from nativeCheckInputs until https://github.com/NixOS/nixpkgs/issues/161570 is solved
86 umockdev
87
88 # For installed tests.
89 (python3.withPackages (pp: [
90 pp.dbus-python
91 pp.python-dbusmock
92 pp.pygobject3
93 pp.packaging
94 ]))
95 ] ++ lib.optionals useIMobileDevice [
96 libimobiledevice
97 ];
98
99 nativeCheckInputs = [
100 python3.pkgs.dbus-python
101 python3.pkgs.python-dbusmock
102 python3.pkgs.pygobject3
103 dbus
104 umockdev
105 libeatmydata
106 python3.pkgs.packaging
107 ];
108
109 propagatedBuildInputs = [
110 glib
111 ];
112
113 mesonFlags = [
114 "--localstatedir=/var"
115 "--sysconfdir=/etc"
116 "-Dos_backend=linux"
117 "-Dsystemdsystemunitdir=${placeholder "out"}/etc/systemd/system"
118 "-Dudevrulesdir=${placeholder "out"}/lib/udev/rules.d"
119 "-Dudevhwdbdir=${placeholder "out"}/lib/udev/hwdb.d"
120 (lib.mesonEnable "introspection" withIntrospection)
121 (lib.mesonBool "gtk-doc" withDocs)
122 "-Dinstalled_test_prefix=${placeholder "installedTests"}"
123 ];
124
125 doCheck = true;
126
127 postPatch = ''
128 patchShebangs src/linux/integration-test.py
129 patchShebangs src/linux/unittest_inspector.py
130
131 substituteInPlace src/linux/integration-test.py \
132 --replace "/usr/share/dbus-1" "$out/share/dbus-1"
133 '';
134
135 preCheck = ''
136 # Our gobject-introspection patches make the shared library paths absolute
137 # in the GIR files. When running tests, the library is not yet installed,
138 # though, so we need to replace the absolute path with a local one during build.
139 mkdir -p "$out/lib"
140 ln -s "$PWD/libupower-glib/libupower-glib.so" "$out/lib/libupower-glib.so.3"
141 '';
142
143 checkPhase = ''
144 runHook preCheck
145
146 # Slow fsync calls can make self-test fail:
147 # https://gitlab.freedesktop.org/upower/upower/-/issues/195
148 eatmydata meson test --print-errorlogs
149
150 runHook postCheck
151 '';
152
153 postCheck = ''
154 # Undo patchShebangs from postPatch so that it can be replaced with runtime shebang
155 # unittest_inspector.py intentionally not reverted because it would trigger
156 # meson rebuild during install and it is not used at runtime anyway.
157 sed -Ei 's~#!.+/bin/python3~#!/usr/bin/python3~' \
158 ../src/linux/integration-test.py
159
160 # Undo preCheck installation since DESTDIR hack expects outputs to not exist.
161 rm "$out/lib/libupower-glib.so.3"
162 rmdir "$out/lib" "$out"
163 '';
164
165 postInstall = ''
166 # Move stuff from DESTDIR to proper location.
167 for o in $(getAllOutputNames); do
168 # devdoc is created later by _multioutDocs hook.
169 if [[ "$o" = "devdoc" ]]; then continue; fi
170 mv "$DESTDIR''${!o}" "$(dirname "''${!o}")"
171 done
172
173 mv "$DESTDIR/var" "$out"
174 # The /etc already exist so we need to merge it.
175 cp --recursive "$DESTDIR/etc" "$out"
176 rm --recursive "$DESTDIR/etc"
177
178 # Ensure we did not forget to install anything.
179 rmdir --parents --ignore-fail-on-non-empty "$DESTDIR${builtins.storeDir}"
180 ! test -e "$DESTDIR"
181 '';
182
183 postFixup = ''
184 wrapProgram "$installedTests/libexec/upower/integration-test.py" \
185 --prefix GI_TYPELIB_PATH : "${lib.makeSearchPath "lib/girepository-1.0" [
186 "$out"
187 umockdev.out
188 ]}" \
189 --prefix PATH : "${lib.makeBinPath [
190 umockdev
191 ]}"
192 '';
193
194 env = {
195 # HACK: We want to install configuration files to $out/etc
196 # but upower should read them from /etc on a NixOS system.
197 # With autotools, it was possible to override Make variables
198 # at install time but Meson does not support this
199 # so we need to convince it to install all files to a temporary
200 # location using DESTDIR and then move it to proper one in postInstall.
201 DESTDIR = "dest";
202 };
203
204 passthru = {
205 tests = {
206 installedTests = nixosTests.installed-tests.upower;
207 };
208 };
209
210 meta = with lib; {
211 homepage = "https://upower.freedesktop.org/";
212 changelog = "https://gitlab.freedesktop.org/upower/upower/-/blob/v${finalAttrs.version}/NEWS";
213 description = "D-Bus service for power management";
214 mainProgram = "upower";
215 maintainers = teams.freedesktop.members;
216 platforms = platforms.linux;
217 license = licenses.gpl2Plus;
218 };
219})