nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1# Updating? Keep $out/etc synchronized with passthru keys
2
3{
4 lib,
5 stdenv,
6 fetchpatch,
7
8 # runPythonCommand
9 runCommand,
10 python3,
11
12 # test-firmware
13 fetchFromGitHub,
14 unstableGitUpdater,
15
16 # fwupd
17 pkg-config,
18 pkgsBuildBuild,
19
20 # propagatedBuildInputs
21 json-glib,
22
23 # nativeBuildInputs
24 ensureNewerSourcesForZipFilesHook,
25 gettext,
26 gi-docgen,
27 gobject-introspection,
28 meson,
29 ninja,
30 protobuf,
31 protobufc,
32 shared-mime-info,
33 vala,
34 wrapGAppsNoGuiHook,
35 writableTmpDirAsHomeHook,
36 mesonEmulatorHook,
37
38 # buildInputs
39 bash-completion,
40 curl,
41 elfutils,
42 fwupd-efi,
43 gnutls,
44 gusb,
45 libarchive,
46 libcbor,
47 libdrm,
48 libgudev,
49 libjcat,
50 libmbim,
51 libmnl,
52 libqmi,
53 libuuid,
54 libxmlb,
55 libxml2,
56 modemmanager,
57 pango,
58 polkit,
59 readline,
60 sqlite,
61 tpm2-tss,
62 valgrind,
63 xz, # for liblzma
64 flashrom,
65
66 # mesonFlags
67 hwdata,
68
69 # env
70 makeFontsConf,
71 freefont_ttf,
72
73 # preCheck
74 libredirect,
75
76 # preFixup
77 bubblewrap,
78 efibootmgr,
79 tpm2-tools,
80
81 # passthru
82 nixosTests,
83 nix-update-script,
84
85 enableFlashrom ? false,
86 enablePassim ? false,
87}:
88
89let
90 isx86 = stdenv.hostPlatform.isx86;
91
92 # Experimental
93 haveFlashrom = isx86 && enableFlashrom;
94
95 runPythonCommand =
96 name: buildCommandPython:
97
98 runCommand name
99 {
100 nativeBuildInputs = [ python3 ];
101 inherit buildCommandPython;
102 }
103 ''
104 exec python3 -c "$buildCommandPython"
105 '';
106
107 test-firmware =
108 let
109 version = "0-unstable-2022-04-02";
110 src = fetchFromGitHub {
111 name = "fwupd-test-firmware-${version}";
112 owner = "fwupd";
113 repo = "fwupd-test-firmware";
114 rev = "39954e434d63e20e85870dd1074818f48a0c08b7";
115 hash = "sha256-d4qG3fKyxkfN91AplRYqARFz+aRr+R37BpE450bPxi0=";
116 passthru = {
117 inherit src version; # For update script
118 updateScript = unstableGitUpdater {
119 url = "${test-firmware.meta.homepage}.git";
120 };
121 };
122 };
123 in
124 src
125 // {
126 meta = src.meta // {
127 # For update script
128 position =
129 let
130 pos = builtins.unsafeGetAttrPos "updateScript" test-firmware;
131 in
132 pos.file + ":" + toString pos.line;
133 };
134 };
135in
136stdenv.mkDerivation (finalAttrs: {
137 pname = "fwupd";
138 version = "2.0.19";
139
140 # libfwupd goes to lib
141 # daemon, plug-ins and libfwupdplugin go to out
142 # CLI programs go to out
143 outputs = [
144 "out"
145 "lib"
146 "dev"
147 "devdoc"
148 "man"
149 "installedTests"
150 ];
151
152 src = fetchFromGitHub {
153 owner = "fwupd";
154 repo = "fwupd";
155 tag = finalAttrs.version;
156 hash = "sha256-DjO+7CEOef5KMbYEPtDr3GrnXTDUO/jwwZ4P17o4oDg=";
157 };
158
159 patches = [
160 # Install plug-ins and libfwupdplugin to $out output,
161 # they are not really part of the library.
162 ./0001-Install-fwupdplugin-to-out.patch
163
164 # Installed tests are installed to different output
165 # we also cannot have fwupd-tests.conf in $out/etc since it would form a cycle.
166 ./0002-Add-output-for-installed-tests.patch
167
168 # Since /etc is the domain of NixOS, not Nix,
169 # we cannot install files there.
170 # Let’s install the files to $prefix/etc
171 # while still reading them from /etc.
172 # NixOS module for fwupd will take take care of copying the files appropriately.
173 ./0003-Add-option-for-installation-sysconfdir.patch
174
175 # EFI capsule is located in fwupd-efi now.
176 ./0004-Get-the-efi-app-from-fwupd-efi.patch
177 ];
178
179 postPatch = ''
180 patchShebangs \
181 generate-build/generate-version-script.py \
182 generate-build/generate-man.py \
183 po/test-deps \
184 plugins/uefi-capsule/tests/grub2-mkconfig \
185 plugins/uefi-capsule/tests/grub2-reboot
186 ''
187 # in nixos test tries to chmod 0777 $out/share/installed-tests/fwupd/tests/redfish.conf
188 + ''
189 substituteInPlace plugins/redfish/meson.build \
190 --replace-fail "get_option('tests')" "false"
191 '';
192
193 strictDeps = true;
194
195 depsBuildBuild = [
196 pkg-config # for finding build-time dependencies
197 (pkgsBuildBuild.callPackage ./build-time-python.nix { })
198 ];
199
200 propagatedBuildInputs = [
201 json-glib
202 ];
203
204 nativeBuildInputs = [
205 ensureNewerSourcesForZipFilesHook # required for firmware zipping
206 gettext
207 gi-docgen
208 gobject-introspection
209 libxml2
210 meson
211 ninja
212 pkg-config
213 protobuf # for protoc
214 protobufc # for protoc-gen-c
215 shared-mime-info
216 vala
217 wrapGAppsNoGuiHook
218
219 # jcat-tool at buildtime requires a home directory
220 writableTmpDirAsHomeHook
221 ]
222 ++ lib.optionals (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
223 mesonEmulatorHook
224 ];
225
226 buildInputs = [
227 bash-completion
228 curl
229 elfutils
230 fwupd-efi
231 gnutls
232 gusb
233 libarchive
234 libcbor
235 libdrm
236 libgudev
237 libjcat
238 libmbim
239 libmnl
240 libqmi
241 libuuid
242 libxmlb
243 modemmanager
244 pango
245 polkit
246 protobufc
247 readline
248 sqlite
249 tpm2-tss
250 valgrind
251 xz # for liblzma
252 ]
253 ++ lib.optionals haveFlashrom [
254 flashrom
255 ];
256
257 mesonFlags = [
258 (lib.mesonEnable "docs" true)
259 # We are building the official releases.
260 (lib.mesonEnable "supported_build" true)
261 (lib.mesonOption "systemd_root_prefix" "${placeholder "out"}")
262 (lib.mesonOption "installed_test_prefix" "${placeholder "installedTests"}")
263 "--localstatedir=/var"
264 "--sysconfdir=/etc"
265 (lib.mesonOption "sysconfdir_install" "${placeholder "out"}/etc")
266 (lib.mesonOption "efi_os_dir" "nixos")
267 (lib.mesonEnable "plugin_modem_manager" true)
268 (lib.mesonBool "vendor_metadata" true)
269 (lib.mesonBool "plugin_uefi_capsule_splash" false)
270 # TODO: what should this be?
271 (lib.mesonOption "vendor_ids_dir" "${hwdata}/share/hwdata")
272 (lib.mesonEnable "umockdev_tests" false)
273 # We do not want to place the daemon into lib (cyclic reference)
274 "--libexecdir=${placeholder "out"}/libexec"
275 ]
276 ++ lib.optionals (!enablePassim) [
277 (lib.mesonEnable "passim" false)
278 ]
279 ++ lib.optionals (!haveFlashrom) [
280 (lib.mesonEnable "plugin_flashrom" false)
281 ];
282
283 # TODO: wrapGAppsHook3 wraps efi capsule even though it is not ELF
284 dontWrapGApps = true;
285
286 doCheck = true;
287
288 # Environment variables
289 env = {
290 # Fontconfig error: Cannot load default config file
291 FONTCONFIG_FILE =
292 let
293 fontsConf = makeFontsConf {
294 fontDirectories = [ freefont_ttf ];
295 };
296 in
297 fontsConf;
298
299 # error: “PolicyKit files are missing”
300 # https://github.com/NixOS/nixpkgs/pull/67625#issuecomment-525788428
301 PKG_CONFIG_POLKIT_GOBJECT_1_ACTIONDIR = "/run/current-system/sw/share/polkit-1/actions";
302 };
303
304 nativeCheckInputs = [
305 polkit
306 libredirect.hook
307 ];
308
309 preCheck = ''
310 addToSearchPath XDG_DATA_DIRS "${shared-mime-info}/share"
311
312 echo "12345678901234567890123456789012" > machine-id
313 export NIX_REDIRECTS=/etc/machine-id=$(realpath machine-id) \
314 '';
315
316 postInstall = ''
317 # These files have weird licenses so they are shipped separately.
318 cp --recursive --dereference "${test-firmware}/installed-tests/tests" "$installedTests/libexec/installed-tests/fwupd"
319 '';
320
321 preFixup =
322 let
323 binPath = [
324 bubblewrap
325 efibootmgr
326 tpm2-tools
327 ];
328 in
329 ''
330 gappsWrapperArgs+=(
331 --prefix XDG_DATA_DIRS : "${shared-mime-info}/share"
332 # See programs reached with fu_common_find_program_in_path in source
333 --prefix PATH : "${lib.makeBinPath binPath}"
334 )
335 '';
336
337 postFixup = ''
338 # Since we had to disable wrapGAppsHook, we need to wrap the executables manually.
339 find -L "$out/bin" "$out/libexec" -type f -executable -print0 \
340 | while IFS= read -r -d ''' file; do
341 if [[ "$file" != *.efi ]]; then
342 echo "Wrapping program $file"
343 wrapGApp "$file"
344 fi
345 done
346
347 # Cannot be in postInstall, otherwise _multioutDocs hook in preFixup will move right back.
348 moveToOutput "share/doc" "$devdoc"
349 moveToOutput "etc/doc" "$devdoc"
350 '';
351
352 separateDebugInfo = true;
353
354 passthru = {
355 updateScript = nix-update-script { };
356 filesInstalledToEtc = [
357 "fwupd/fwupd.conf"
358 "fwupd/remotes.d/lvfs-testing.conf"
359 "fwupd/remotes.d/lvfs.conf"
360 "fwupd/remotes.d/vendor.conf"
361 "fwupd/remotes.d/vendor-directory.conf"
362 "pki/fwupd/GPG-KEY-Linux-Foundation-Firmware"
363 "pki/fwupd/GPG-KEY-Linux-Vendor-Firmware-Service"
364 "pki/fwupd/LVFS-CA-2025PQ.pem"
365 "pki/fwupd/LVFS-CA.pem"
366 "pki/fwupd-metadata/GPG-KEY-Linux-Foundation-Metadata"
367 "pki/fwupd-metadata/GPG-KEY-Linux-Vendor-Firmware-Service"
368 "pki/fwupd-metadata/LVFS-CA-2025PQ.pem"
369 "pki/fwupd-metadata/LVFS-CA.pem"
370 "grub.d/35_fwupd"
371 ];
372
373 # For updating.
374 inherit test-firmware;
375
376 # For downstream consumers that need the fwupd-efi this was built with.
377 inherit fwupd-efi;
378
379 tests =
380 let
381 listToPy = list: "[${lib.concatMapStringsSep ", " (f: "'${f}'") list}]";
382 in
383 {
384 installedTests = nixosTests.installed-tests.fwupd;
385
386 passthruMatches = runPythonCommand "fwupd-test-passthru-matches" ''
387 import itertools
388 import configparser
389 import os
390 import pathlib
391
392 etc = '${finalAttrs.finalPackage}/etc'
393 package_etc = set(itertools.chain.from_iterable([[os.path.relpath(os.path.join(prefix, file), etc) for file in files] for (prefix, dirs, files) in os.walk(etc)]))
394 passthru_etc = set(${listToPy finalAttrs.passthru.filesInstalledToEtc})
395 assert len(package_etc - passthru_etc) == 0, f'fwupd package contains the following paths in /etc that are not listed in passthru.filesInstalledToEtc: {package_etc - passthru_etc}'
396 assert len(passthru_etc - package_etc) == 0, f'fwupd package lists the following paths in passthru.filesInstalledToEtc that are not contained in /etc: {passthru_etc - package_etc}'
397
398 pathlib.Path(os.getenv('out')).touch()
399 '';
400 };
401 };
402
403 meta = {
404 homepage = "https://fwupd.org/";
405 changelog = "https://github.com/fwupd/fwupd/releases/tag/${finalAttrs.version}";
406 maintainers = with lib.maintainers; [
407 rvdp
408 johnazoidberg
409 ];
410 license = lib.licenses.lgpl21Plus;
411 platforms = lib.platforms.linux;
412 };
413})