1{
2 stdenv,
3 lib,
4 nixosTests,
5 pkgsCross,
6 testers,
7 fetchFromGitHub,
8 fetchzip,
9 buildPackages,
10 makeBinaryWrapper,
11 ninja,
12 meson,
13 m4,
14 pkg-config,
15 coreutils,
16 gperf,
17 getent,
18 glibcLocales,
19 autoPatchelfHook,
20 fetchpatch,
21
22 # glib is only used during tests (test-bus-gvariant, test-bus-marshal)
23 glib,
24 gettext,
25 python3Packages,
26
27 # Mandatory dependencies
28 libcap,
29 util-linux,
30 kbd,
31 kmod,
32 libxcrypt,
33
34 # Optional dependencies
35 pam,
36 cryptsetup,
37 audit,
38 acl,
39 lz4,
40 openssl,
41 libgcrypt,
42 libgpg-error,
43 libidn2,
44 curl,
45 gnutar,
46 gnupg,
47 zlib,
48 xz,
49 zstd,
50 tpm2-tss,
51 libuuid,
52 libapparmor,
53 intltool,
54 bzip2,
55 pcre2,
56 elfutils,
57 linuxHeaders ? stdenv.cc.libc.linuxHeaders,
58 gnutls,
59 iptables,
60 withSelinux ? false,
61 libselinux,
62 withLibseccomp ? lib.meta.availableOn stdenv.hostPlatform libseccomp,
63 libseccomp,
64 withKexectools ? lib.meta.availableOn stdenv.hostPlatform kexec-tools,
65 kexec-tools,
66 bashInteractive,
67 bash,
68 libmicrohttpd,
69 libfido2,
70 p11-kit,
71 libpwquality,
72 qrencode,
73 libarchive,
74 llvmPackages,
75
76 # the (optional) BPF feature requires bpftool, libbpf, clang and llvm-strip to
77 # be available during build time.
78 # Only libbpf should be a runtime dependency.
79 # Note: llvmPackages is explicitly taken from buildPackages instead of relying
80 # on splicing. Splicing will evaluate the adjacent (pkgsHostTarget) llvmPackages
81 # which is sometimes problematic: llvmPackages.clang looks at targetPackages.stdenv.cc
82 # which, in the unfortunate case of pkgsCross.ghcjs, `throw`s. If we
83 # explicitly take buildPackages.llvmPackages, this is no problem because
84 # `buildPackages.targetPackages.stdenv.cc == stdenv.cc` relative to
85 # us. Working around this is important, because systemd is in the dependency
86 # closure of GHC via emscripten and jdk.
87 bpftools,
88 libbpf,
89
90 # Needed to produce a ukify that works for cross compiling UKIs.
91 targetPackages,
92
93 withAcl ? true,
94 withAnalyze ? true,
95 withApparmor ? true,
96 withAudit ? true,
97 # compiles systemd-boot, assumes EFI is available.
98 withBootloader ?
99 withEfi
100 && !stdenv.hostPlatform.isMusl
101 # "Unknown 64-bit data model"
102 && !stdenv.hostPlatform.isRiscV32,
103 # adds bzip2, lz4, xz and zstd
104 withCompression ? true,
105 withCoredump ? true,
106 withCryptsetup ? true,
107 withRepart ? true,
108 withDocumentation ? true,
109 withEfi ? stdenv.hostPlatform.isEfi,
110 withFido2 ? true,
111 withFirstboot ? true,
112 withGcrypt ? true,
113 withHomed ? !stdenv.hostPlatform.isMusl,
114 withHostnamed ? true,
115 withHwdb ? true,
116 withImportd ? !stdenv.hostPlatform.isMusl,
117 withIptables ? true,
118 withKmod ? true,
119 withLibBPF ?
120 lib.versionAtLeast buildPackages.llvmPackages.clang.version "10.0"
121 # assumes hard floats
122 && (
123 stdenv.hostPlatform.isAarch
124 ->
125 stdenv.hostPlatform.parsed.cpu ? version
126 && lib.versionAtLeast stdenv.hostPlatform.parsed.cpu.version "6"
127 )
128 # see https://github.com/NixOS/nixpkgs/pull/194149#issuecomment-1266642211
129 && !stdenv.hostPlatform.isMips64
130 # https://reviews.llvm.org/D43106#1019077
131 && (stdenv.hostPlatform.isRiscV32 -> stdenv.cc.isClang)
132 # buildPackages.targetPackages.llvmPackages is the same as llvmPackages,
133 # but we do it this way to avoid taking llvmPackages as an input, and
134 # risking making it too easy to ignore the above comment about llvmPackages.
135 && lib.meta.availableOn stdenv.hostPlatform buildPackages.targetPackages.llvmPackages.compiler-rt,
136 withLibidn2 ? true,
137 withLocaled ? true,
138 withLogind ? true,
139 withMachined ? true,
140 withNetworkd ? true,
141 withNss ? !stdenv.hostPlatform.isMusl,
142 withOomd ? true,
143 withOpenSSL ? true,
144 withPam ? true,
145 withPasswordQuality ? true,
146 withPCRE2 ? true,
147 withPolkit ? true,
148 withPortabled ? !stdenv.hostPlatform.isMusl,
149 withQrencode ? true,
150 withRemote ? !stdenv.hostPlatform.isMusl,
151 withResolved ? true,
152 withShellCompletions ? true,
153 withSysusers ? true,
154 withSysupdate ? true,
155 withTimedated ? true,
156 withTimesyncd ? true,
157 withTpm2Tss ? true,
158 # adds python to closure which is too much by default
159 withUkify ? false,
160 withUserDb ? true,
161 withUtmp ? !stdenv.hostPlatform.isMusl,
162 withVmspawn ? true,
163 # kernel-install shouldn't usually be used on NixOS, but can be useful, e.g. for
164 # building disk images for non-NixOS systems. To save users from trying to use it
165 # on their live NixOS system, we disable it by default.
166 withKernelInstall ? false,
167 withLibarchive ? true,
168 # tests assume too much system access for them to be feasible for us right now
169 withTests ? false,
170 # build only libudev and libsystemd
171 buildLibsOnly ? false,
172
173 # yes, pname is an argument here
174 pname ? "systemd",
175
176 libxslt,
177 docbook_xsl,
178 docbook_xml_dtd_42,
179 docbook_xml_dtd_45,
180 withLogTrace ? false,
181}:
182
183assert withImportd -> withCompression;
184assert withCoredump -> withCompression;
185assert withHomed -> withCryptsetup;
186assert withHomed -> withPam;
187assert withHomed -> withOpenSSL;
188assert withFido2 -> withOpenSSL;
189assert withSysupdate -> withOpenSSL;
190assert withImportd -> (withGcrypt || withOpenSSL);
191assert withUkify -> (withEfi && withBootloader);
192assert withRepart -> withCryptsetup;
193assert withBootloader -> withEfi;
194
195let
196 wantCurl = withRemote || withImportd;
197
198 version = "257.6";
199
200 # Use the command below to update `releaseTimestamp` on every (major) version
201 # change. More details in the commentary at mesonFlags.
202 # command:
203 # $ curl -s https://api.github.com/repos/systemd/systemd/releases/latest | \
204 # jq '.created_at|strptime("%Y-%m-%dT%H:%M:%SZ")|mktime'
205 releaseTimestamp = "1734643670";
206in
207stdenv.mkDerivation (finalAttrs: {
208 inherit pname version;
209
210 # We use systemd/systemd-stable for src, and ship NixOS-specific patches inside nixpkgs directly
211 # This has proven to be less error-prone than the previous systemd fork.
212 src = fetchFromGitHub {
213 owner = "systemd";
214 repo = "systemd";
215 rev = "v${version}";
216 hash = "sha256-Myb/ra7NQTDzN7B9jn8svbhTrLSfiqWaSxREe/nDyYo=";
217 };
218
219 # On major changes, or when otherwise required, you *must* :
220 # 1. reformat the patches,
221 # 2. `git am path/to/00*.patch` them into a systemd worktree,
222 # 3. rebase to the more recent systemd version,
223 # 4. and export the patches again via
224 # `git -c format.signoff=false format-patch v${version} --no-numbered --zero-commit --no-signature`.
225 # Use `find . -name "*.patch" | sort` to get an up-to-date listing of all
226 # patches
227 patches = [
228 ./0001-Start-device-units-for-uninitialised-encrypted-devic.patch
229 ./0002-Don-t-try-to-unmount-nix-or-nix-store.patch
230 ./0003-Fix-NixOS-containers.patch
231 ./0004-Add-some-NixOS-specific-unit-directories.patch
232 ./0005-Get-rid-of-a-useless-message-in-user-sessions.patch
233 ./0006-hostnamed-localed-timedated-disable-methods-that-cha.patch
234 ./0007-Change-usr-share-zoneinfo-to-etc-zoneinfo.patch
235 ./0008-localectl-use-etc-X11-xkb-for-list-x11.patch
236 ./0009-add-rootprefix-to-lookup-dir-paths.patch
237 ./0010-systemd-shutdown-execute-scripts-in-etc-systemd-syst.patch
238 ./0011-systemd-sleep-execute-scripts-in-etc-systemd-system-.patch
239 ./0012-path-util.h-add-placeholder-for-DEFAULT_PATH_NORMAL.patch
240 ./0013-inherit-systemd-environment-when-calling-generators.patch
241 ./0014-core-don-t-taint-on-unmerged-usr.patch
242 ./0015-tpm2_context_init-fix-driver-name-checking.patch
243 ./0016-systemctl-edit-suggest-systemdctl-edit-runtime-on-sy.patch
244 ./0017-meson.build-do-not-create-systemdstatedir.patch
245 ./0018-Revert-bootctl-update-list-remove-all-instances-of-s.patch # https://github.com/systemd/systemd/issues/33392
246 # systemd tries to link the systemd-ssh-proxy ssh config snippet with tmpfiles
247 # if the install prefix is not /usr, but that does not work for us
248 # because we include the config snippet manually
249 ./0019-meson-Don-t-link-ssh-dropins.patch
250 ./0020-install-unit_file_exists_full-follow-symlinks.patch
251 ]
252 ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isGnu) [
253 ./0021-timesyncd-disable-NSCD-when-DNSSEC-validation-is-dis.patch
254 ]
255 ++ lib.optionals (stdenv.hostPlatform.isPower64) [
256 # Auto-detect ELF ABI instead of hardcoding ELFv2 for BPF build
257 # Fixes targeting ELFv1
258 # https://github.com/systemd/systemd/pull/38307#issuecomment-3120543119
259 (fetchpatch {
260 name = "0101-systemd-meson.build-Detect-ELF-ABI-version-for-bpf-build-on-ppc64.patch";
261 url = "https://github.com/systemd/systemd/commit/f9509192512a4c4b9e3915a096333d4b6b297956.patch";
262 hash = "sha256-OGUw+hRCKZm+1EcR64M67QJ9c/PbS2Lk/A+1B3q4Jzs=";
263 })
264 ]
265 ++ lib.optionals stdenv.hostPlatform.isMusl (
266 let
267 # NOTE: the master-next branch does not have stable URLs.
268 # If we need patches that aren't in master yet, they'll have to be
269 # vendored.
270 oe-core = fetchzip {
271 url = "https://git.openembedded.org/openembedded-core/snapshot/openembedded-core-4891f47cdaf919033bf1c02cc12e4805e5db99a0.tar.gz";
272 hash = "sha256-YKL/oC+rPZ2EEVNidEV+pJihZgUv7vLb0OASplgktn4=";
273 };
274 in
275 map (patch: "${oe-core}/meta/recipes-core/systemd/systemd/${patch}") [
276 "0003-missing_type.h-add-comparison_fn_t.patch"
277 "0004-add-fallback-parse_printf_format-implementation.patch"
278 "0005-don-t-fail-if-GLOB_BRACE-and-GLOB_ALTDIRFUNC-is-not-.patch"
279 "0006-add-missing-FTW_-macros-for-musl.patch"
280 "0007-Use-uintmax_t-for-handling-rlim_t.patch"
281 "0008-Define-glibc-compatible-basename-for-non-glibc-syste.patch"
282 "0009-Do-not-disable-buffering-when-writing-to-oom_score_a.patch"
283 "0010-distinguish-XSI-compliant-strerror_r-from-GNU-specif.patch"
284 "0011-avoid-redefinition-of-prctl_mm_map-structure.patch"
285 "0012-do-not-disable-buffer-in-writing-files.patch"
286 "0013-Handle-__cpu_mask-usage.patch"
287 "0014-Handle-missing-gshadow.patch"
288 "0015-missing_syscall.h-Define-MIPS-ABI-defines-for-musl.patch"
289 "0016-pass-correct-parameters-to-getdents64.patch"
290 "0017-Adjust-for-musl-headers.patch"
291 "0018-test-bus-error-strerror-is-assumed-to-be-GNU-specifi.patch"
292 "0019-errno-util-Make-STRERROR-portable-for-musl.patch"
293 "0020-sd-event-Make-malloc_trim-conditional-on-glibc.patch"
294 "0021-shared-Do-not-use-malloc_info-on-musl.patch"
295 "0022-avoid-missing-LOCK_EX-declaration.patch"
296 "0023-include-signal.h-to-avoid-the-undeclared-error.patch"
297 "0024-undef-stdin-for-references-using-stdin-as-a-struct-m.patch"
298 "0025-adjust-header-inclusion-order-to-avoid-redeclaration.patch"
299 "0026-build-path.c-avoid-boot-time-segfault-for-musl.patch"
300 ]
301 ++ [
302 # add a missing include
303 (fetchpatch {
304 url = "https://github.com/systemd/systemd/commit/34fcd3638817060c79e1186b370e46d9b3a7409f.patch";
305 hash = "sha256-Uaewo3jPrZGJttlLcqO6cCj1w3IGZmvbur4+TBdIPxc=";
306 excludes = [ "src/udev/udevd.c" ];
307 })
308 ]
309 );
310
311 postPatch = ''
312 substituteInPlace src/basic/path-util.h --replace "@defaultPathNormal@" "${placeholder "out"}/bin/"
313 ''
314 + lib.optionalString withLibBPF ''
315 substituteInPlace meson.build \
316 --replace "find_program('clang'" "find_program('${stdenv.cc.targetPrefix}clang'"
317 ''
318 + lib.optionalString withUkify ''
319 substituteInPlace src/ukify/ukify.py \
320 --replace \
321 "'readelf'" \
322 "'${targetPackages.stdenv.cc.bintools.targetPrefix}readelf'" \
323 --replace \
324 "/usr/lib/systemd/boot/efi" \
325 "$out/lib/systemd/boot/efi"
326 ''
327 # Finally, patch shebangs in scripts used at build time. This must not patch
328 # scripts that will end up in the output, to avoid build platform references
329 # when cross-compiling.
330 + ''
331 shopt -s extglob
332 patchShebangs tools test src/!(rpm|kernel-install|ukify) src/kernel-install/test-kernel-install.sh
333 '';
334
335 outputs = [
336 "out"
337 "dev"
338 ]
339 ++ (lib.optional (!buildLibsOnly) "man");
340 separateDebugInfo = true;
341 __structuredAttrs = true;
342
343 hardeningDisable = [
344 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111523
345 "trivialautovarinit"
346 ]
347 ++ (lib.optionals withLibBPF [
348 # breaks clang -target bpf; should be fixed to not use
349 # a wrapped clang?
350 "zerocallusedregs"
351 "shadowstack"
352 "pacret"
353 ]);
354
355 nativeBuildInputs = [
356 pkg-config
357 makeBinaryWrapper
358 gperf
359 ninja
360 meson
361 glibcLocales
362 getent
363 m4
364 autoPatchelfHook
365
366 intltool
367 gettext
368
369 libxslt
370 docbook_xsl
371 docbook_xml_dtd_42
372 docbook_xml_dtd_45
373 bash
374 (buildPackages.python3Packages.python.withPackages (
375 ps:
376 with ps;
377 [
378 lxml
379 jinja2
380 ]
381 ++ lib.optional withEfi ps.pyelftools
382 ))
383 ]
384 ++ lib.optionals withLibBPF [
385 bpftools
386 buildPackages.llvmPackages.clang
387 buildPackages.llvmPackages.libllvm
388 ];
389
390 autoPatchelfFlags = [ "--keep-libc" ];
391
392 buildInputs = [
393 libxcrypt
394 libcap
395 libuuid
396 linuxHeaders
397 bashInteractive # for patch shebangs
398 ]
399
400 ++ lib.optionals withGcrypt [
401 libgcrypt
402 libgpg-error
403 ]
404 ++ lib.optionals withOpenSSL [ openssl ]
405 ++ lib.optional withTests glib
406 ++ lib.optional withAcl acl
407 ++ lib.optional withApparmor libapparmor
408 ++ lib.optional withAudit audit
409 ++ lib.optional wantCurl (lib.getDev curl)
410 ++ lib.optionals withCompression [
411 zlib
412 bzip2
413 lz4
414 xz
415 zstd
416 ]
417 ++ lib.optional withCoredump elfutils
418 ++ lib.optional withCryptsetup (lib.getDev cryptsetup.dev)
419 ++ lib.optional withKexectools kexec-tools
420 ++ lib.optional withKmod kmod
421 ++ lib.optional withLibidn2 libidn2
422 ++ lib.optional withLibseccomp libseccomp
423 ++ lib.optional withIptables iptables
424 ++ lib.optional withPam pam
425 ++ lib.optional withPCRE2 pcre2
426 ++ lib.optional withSelinux libselinux
427 ++ lib.optionals withRemote [
428 libmicrohttpd
429 gnutls
430 ]
431 ++ lib.optionals (withHomed || withCryptsetup) [ p11-kit ]
432 ++ lib.optionals (withHomed || withCryptsetup) [ libfido2 ]
433 ++ lib.optionals withLibBPF [ libbpf ]
434 ++ lib.optional withTpm2Tss tpm2-tss
435 ++ lib.optional withUkify (python3Packages.python.withPackages (ps: with ps; [ pefile ]))
436 ++ lib.optionals withPasswordQuality [ libpwquality ]
437 ++ lib.optionals withQrencode [ qrencode ]
438 ++ lib.optionals withLibarchive [ libarchive ]
439 ++ lib.optional (withBootloader && stdenv.targetPlatform.useLLVM or false) (
440 llvmPackages.compiler-rt.override {
441 doFakeLibgcc = true;
442 }
443 );
444
445 mesonBuildType = "release";
446
447 mesonFlags = [
448 # Options
449
450 # We bump this attribute on every (major) version change to ensure that we
451 # have known-good value for a timestamp that is in the (not so distant)
452 # past. This serves as a lower bound for valid system timestamps during
453 # startup. Systemd will reset the system timestamp if this date is +- 15
454 # years from the system time.
455 # See the systemd v250 release notes for further details:
456 # https://github.com/systemd/systemd/blob/60e930fc3e6eb8a36fbc184773119eb8d2f30364/NEWS#L258-L266
457 (lib.mesonOption "time-epoch" releaseTimestamp)
458
459 (lib.mesonOption "version-tag" version)
460 (lib.mesonOption "mode" "release")
461 (lib.mesonOption "tty-gid" "3") # tty in NixOS has gid 3
462 (lib.mesonOption "debug-shell" "${bashInteractive}/bin/bash")
463 (lib.mesonOption "pamconfdir" "${placeholder "out"}/etc/pam.d")
464 (lib.mesonOption "shellprofiledir" "${placeholder "out"}/etc/profile.d")
465 (lib.mesonOption "kmod-path" "${kmod}/bin/kmod")
466
467 # Attempts to check /usr/sbin and that fails in macOS sandbox because
468 # permission is denied. If /usr/sbin is not a symlink, it defaults to true.
469 # We set it to false since stdenv moves sbin/* to bin and creates a symlink,
470 # that is, we do not have split bin.
471 (lib.mesonOption "split-bin" "false")
472
473 # D-Bus
474 (lib.mesonOption "dbuspolicydir" "${placeholder "out"}/share/dbus-1/system.d")
475 (lib.mesonOption "dbussessionservicedir" "${placeholder "out"}/share/dbus-1/services")
476 (lib.mesonOption "dbussystemservicedir" "${placeholder "out"}/share/dbus-1/system-services")
477
478 # pkgconfig
479 (lib.mesonOption "pkgconfiglibdir" "${placeholder "dev"}/lib/pkgconfig")
480 (lib.mesonOption "pkgconfigdatadir" "${placeholder "dev"}/share/pkgconfig")
481
482 # Keyboard
483 (lib.mesonOption "loadkeys-path" "${kbd}/bin/loadkeys")
484 (lib.mesonOption "setfont-path" "${kbd}/bin/setfont")
485
486 # SBAT
487 (lib.mesonOption "sbat-distro" "nixos")
488 (lib.mesonOption "sbat-distro-summary" "NixOS")
489 (lib.mesonOption "sbat-distro-url" "https://nixos.org/")
490 (lib.mesonOption "sbat-distro-pkgname" pname)
491 (lib.mesonOption "sbat-distro-version" version)
492
493 # Users
494 (lib.mesonOption "system-uid-max" "999")
495 (lib.mesonOption "system-gid-max" "999")
496
497 # SysVinit
498 (lib.mesonOption "sysvinit-path" "")
499 (lib.mesonOption "sysvrcnd-path" "")
500
501 # Login
502 (lib.mesonOption "sulogin-path" "${util-linux.login}/bin/sulogin")
503 (lib.mesonOption "nologin-path" "${util-linux.login}/bin/nologin")
504
505 # Mount
506 (lib.mesonOption "mount-path" "${lib.getOutput "mount" util-linux}/bin/mount")
507 (lib.mesonOption "umount-path" "${lib.getOutput "mount" util-linux}/bin/umount")
508
509 # SSH
510 (lib.mesonOption "sshconfdir" "")
511 (lib.mesonOption "sshdconfdir" "no")
512
513 # Features
514
515 # Tests
516 (lib.mesonBool "tests" withTests)
517 (lib.mesonEnable "glib" withTests)
518 (lib.mesonEnable "dbus" withTests)
519
520 # Compression
521 (lib.mesonEnable "bzip2" withCompression)
522 (lib.mesonEnable "lz4" withCompression)
523 (lib.mesonEnable "xz" withCompression)
524 (lib.mesonEnable "zstd" withCompression)
525 (lib.mesonEnable "zlib" withCompression)
526
527 # NSS
528 (lib.mesonEnable "nss-mymachines" (withNss && withMachined))
529 (lib.mesonEnable "nss-resolve" withNss)
530 (lib.mesonBool "nss-myhostname" withNss)
531 (lib.mesonBool "nss-systemd" withNss)
532
533 # Cryptsetup
534 (lib.mesonEnable "libcryptsetup" withCryptsetup)
535 (lib.mesonEnable "libcryptsetup-plugins" withCryptsetup)
536 (lib.mesonEnable "p11kit" (withHomed || withCryptsetup))
537
538 # FIDO2
539 (lib.mesonEnable "libfido2" withFido2)
540 (lib.mesonEnable "openssl" withOpenSSL)
541
542 # Password Quality
543 (lib.mesonEnable "pwquality" withPasswordQuality)
544 (lib.mesonEnable "passwdqc" false)
545
546 # Remote
547 (lib.mesonEnable "remote" withRemote)
548 (lib.mesonEnable "microhttpd" withRemote)
549
550 (lib.mesonEnable "pam" withPam)
551 (lib.mesonEnable "acl" withAcl)
552 (lib.mesonEnable "audit" withAudit)
553 (lib.mesonEnable "apparmor" withApparmor)
554 (lib.mesonEnable "gcrypt" withGcrypt)
555 (lib.mesonEnable "importd" withImportd)
556 (lib.mesonEnable "homed" withHomed)
557 (lib.mesonEnable "polkit" withPolkit)
558 (lib.mesonEnable "elfutils" withCoredump)
559 (lib.mesonEnable "libcurl" wantCurl)
560 (lib.mesonEnable "libidn" false)
561 (lib.mesonEnable "libidn2" withLibidn2)
562 (lib.mesonEnable "libiptc" withIptables)
563 (lib.mesonEnable "repart" withRepart)
564 (lib.mesonEnable "sysupdate" withSysupdate)
565 (lib.mesonEnable "seccomp" withLibseccomp)
566 (lib.mesonEnable "selinux" withSelinux)
567 (lib.mesonEnable "tpm2" withTpm2Tss)
568 (lib.mesonEnable "pcre2" withPCRE2)
569 (lib.mesonEnable "bpf-framework" withLibBPF)
570 (lib.mesonEnable "bootloader" withBootloader)
571 (lib.mesonEnable "ukify" withUkify)
572 (lib.mesonEnable "kmod" withKmod)
573 (lib.mesonEnable "qrencode" withQrencode)
574 (lib.mesonEnable "vmspawn" withVmspawn)
575 (lib.mesonEnable "libarchive" withLibarchive)
576 (lib.mesonEnable "xenctrl" false)
577 (lib.mesonEnable "gnutls" false)
578 (lib.mesonEnable "xkbcommon" false)
579 (lib.mesonEnable "man" true)
580
581 (lib.mesonBool "analyze" withAnalyze)
582 (lib.mesonBool "logind" withLogind)
583 (lib.mesonBool "localed" withLocaled)
584 (lib.mesonBool "hostnamed" withHostnamed)
585 (lib.mesonBool "machined" withMachined)
586 (lib.mesonBool "networkd" withNetworkd)
587 (lib.mesonBool "oomd" withOomd)
588 (lib.mesonBool "portabled" withPortabled)
589 (lib.mesonBool "hwdb" withHwdb)
590 (lib.mesonBool "timedated" withTimedated)
591 (lib.mesonBool "timesyncd" withTimesyncd)
592 (lib.mesonBool "userdb" withUserDb)
593 (lib.mesonBool "coredump" withCoredump)
594 (lib.mesonBool "firstboot" withFirstboot)
595 (lib.mesonBool "resolve" withResolved)
596 (lib.mesonBool "sysusers" withSysusers)
597 (lib.mesonBool "efi" withEfi)
598 (lib.mesonBool "utmp" withUtmp)
599 (lib.mesonBool "log-trace" withLogTrace)
600 (lib.mesonBool "kernel-install" withKernelInstall)
601 (lib.mesonBool "quotacheck" false)
602 (lib.mesonBool "ldconfig" false)
603 (lib.mesonBool "install-sysconfdir" false)
604 (lib.mesonBool "create-log-dirs" false)
605 (lib.mesonBool "smack" true)
606 (lib.mesonBool "b_pie" true)
607
608 ]
609 ++ lib.optionals (withShellCompletions == false) [
610 (lib.mesonOption "bashcompletiondir" "no")
611 (lib.mesonOption "zshcompletiondir" "no")
612 ]
613 ++ lib.optionals stdenv.hostPlatform.isMusl [
614 (lib.mesonBool "gshadow" false)
615 (lib.mesonBool "idn" false)
616 ];
617 preConfigure =
618 let
619 # A list of all the runtime binaries referenced by the source code (plus
620 # scripts and unit files) of systemd executables, tests and libraries.
621 # As soon as a dependency is lo longer required we should remove it from
622 # the list.
623 # The `where` attribute for each of the replacement patterns must be
624 # exhaustive. If another (unhandled) case is found in the source code the
625 # build fails with an error message.
626 binaryReplacements = [
627 {
628 search = "/usr/bin/getent";
629 replacement = "${getent}/bin/getent";
630 where = [ "src/nspawn/nspawn-setuid.c" ];
631 }
632 {
633 search = "/sbin/mkswap";
634 replacement = "${lib.getBin util-linux}/sbin/mkswap";
635 where = [
636 "man/systemd-makefs@.service.xml"
637 ];
638 }
639 {
640 search = "/sbin/swapon";
641 replacement = "${lib.getOutput "swap" util-linux}/sbin/swapon";
642 where = [
643 "src/core/swap.c"
644 "src/basic/unit-def.h"
645 ];
646 }
647 {
648 search = "/sbin/swapoff";
649 replacement = "${lib.getOutput "swap" util-linux}/sbin/swapoff";
650 where = [ "src/core/swap.c" ];
651 }
652 {
653 search = "/bin/echo";
654 replacement = "${coreutils}/bin/echo";
655 where = [
656 "man/systemd-analyze.xml"
657 "man/systemd.service.xml"
658 "man/systemd-run.xml"
659 "src/analyze/test-verify.c"
660 "src/test/test-env-file.c"
661 "src/test/test-fileio.c"
662 "src/test/test-load-fragment.c"
663 ];
664 }
665 {
666 search = "/bin/cat";
667 replacement = "${coreutils}/bin/cat";
668 where = [
669 "test/test-execute/exec-noexecpaths-simple.service"
670 "src/journal/cat.c"
671 ];
672 }
673 {
674 search = "/usr/lib/systemd/systemd-fsck";
675 replacement = "$out/lib/systemd/systemd-fsck";
676 where = [ "man/systemd-fsck@.service.xml" ];
677 }
678 ]
679 ++ lib.optionals withImportd [
680 {
681 search = "\"gpg\"";
682 replacement = "\\\"${gnupg}/bin/gpg\\\"";
683 where = [ "src/import/pull-common.c" ];
684 }
685 {
686 search = "\"tar\"";
687 replacement = "\\\"${gnutar}/bin/tar\\\"";
688 where = [
689 "src/import/export-tar.c"
690 "src/import/import-common.c"
691 "src/import/import-tar.c"
692 ];
693 ignore = [
694 # occurrences here refer to the tar sub command
695 "src/sysupdate/sysupdate-resource.c"
696 "src/sysupdate/sysupdate-transfer.c"
697 "src/import/pull.c"
698 "src/import/export.c"
699 "src/import/import.c"
700 "src/import/importd.c"
701 # runs `tar` but also also creates a temporary directory with the string
702 "src/import/pull-tar.c"
703 # tar referenced as file suffix
704 "src/shared/import-util.c"
705 ];
706 }
707 ]
708 ++ lib.optionals withKmod [
709 {
710 search = "/sbin/modprobe";
711 replacement = "${lib.getBin kmod}/sbin/modprobe";
712 where = [ "units/modprobe@.service" ];
713 }
714 ];
715
716 # { replacement, search, where, ignore } -> List[str]
717 mkSubstitute =
718 {
719 replacement,
720 search,
721 where,
722 ignore ? [ ],
723 }:
724 map (path: "substituteInPlace ${path} --replace '${search}' \"${replacement}\"") where;
725 mkEnsureSubstituted =
726 {
727 replacement,
728 search,
729 where,
730 ignore ? [ ],
731 }:
732 let
733 ignore' = lib.concatStringsSep "|" (
734 ignore
735 ++ [
736 "^test"
737 "NEWS"
738 ]
739 );
740 in
741 ''
742 set +e
743 search=$(grep '${search}' -r | grep -v "${replacement}" | grep -Ev "${ignore'}")
744 set -e
745 if [[ -n "$search" ]]; then
746 echo "Not all references to '${search}' have been replaced. Found the following matches:"
747 echo "$search"
748 exit 1
749 fi
750 '';
751 in
752 ''
753 mesonFlagsArray+=(-Dntp-servers="0.nixos.pool.ntp.org 1.nixos.pool.ntp.org 2.nixos.pool.ntp.org 3.nixos.pool.ntp.org")
754 export LC_ALL="en_US.UTF-8";
755
756 ${lib.concatStringsSep "\n" (lib.flatten (map mkSubstitute binaryReplacements))}
757 ${lib.concatMapStringsSep "\n" mkEnsureSubstituted binaryReplacements}
758
759 substituteInPlace src/libsystemd/sd-journal/catalog.c \
760 --replace /usr/lib/systemd/catalog/ $out/lib/systemd/catalog/
761
762 substituteInPlace src/import/pull-tar.c \
763 --replace 'wait_for_terminate_and_check("tar"' 'wait_for_terminate_and_check("${gnutar}/bin/tar"'
764 '';
765
766 # These defines are overridden by CFLAGS and would trigger annoying
767 # warning messages
768 postConfigure = ''
769 substituteInPlace config.h \
770 --replace "POLKIT_AGENT_BINARY_PATH" "_POLKIT_AGENT_BINARY_PATH" \
771 --replace "SYSTEMD_BINARY_PATH" "_SYSTEMD_BINARY_PATH" \
772 --replace "SYSTEMD_CGROUP_AGENTS_PATH" "_SYSTEMD_CGROUP_AGENT_PATH"
773 '';
774
775 env.NIX_CFLAGS_COMPILE = toString (
776 [
777 # Can't say ${polkit.bin}/bin/pkttyagent here because that would
778 # lead to a cyclic dependency.
779 "-UPOLKIT_AGENT_BINARY_PATH"
780 "-DPOLKIT_AGENT_BINARY_PATH=\"/run/current-system/sw/bin/pkttyagent\""
781
782 # Set the release_agent on /sys/fs/cgroup/systemd to the
783 # currently running systemd (/run/current-system/systemd) so
784 # that we don't use an obsolete/garbage-collected release agent.
785 "-USYSTEMD_CGROUP_AGENTS_PATH"
786 "-DSYSTEMD_CGROUP_AGENTS_PATH=\"/run/current-system/systemd/lib/systemd/systemd-cgroups-agent\""
787
788 "-USYSTEMD_BINARY_PATH"
789 "-DSYSTEMD_BINARY_PATH=\"/run/current-system/systemd/lib/systemd/systemd\""
790
791 ]
792 ++ lib.optionals stdenv.hostPlatform.isMusl [
793 "-D__UAPI_DEF_ETHHDR=0"
794 ]
795 );
796
797 doCheck = true;
798
799 # trigger the test -n "$DESTDIR" || mutate in upstreams build system
800 preInstall = ''
801 export DESTDIR=/
802 '';
803
804 mesonInstallTags = lib.optionals buildLibsOnly [
805 "devel"
806 "libudev"
807 "libsystemd"
808 ];
809
810 postInstall =
811 lib.optionalString (!buildLibsOnly) ''
812 mkdir -p $out/example/systemd
813 mv $out/lib/{binfmt.d,sysctl.d,tmpfiles.d} $out/example
814 mv $out/lib/systemd/{system,user} $out/example/systemd
815
816 rm -rf $out/etc/systemd/system
817
818 # Fix reference to /bin/false in the D-Bus services.
819 for i in $out/share/dbus-1/system-services/*.service; do
820 substituteInPlace $i --replace /bin/false ${coreutils}/bin/false
821 done
822
823 # For compatibility with dependents that use sbin instead of bin.
824 ln -s bin "$out/sbin"
825
826 rm -rf $out/etc/rpm
827 ''
828 + lib.optionalString (!withKernelInstall) ''
829 # "kernel-install" shouldn't be used on NixOS.
830 find $out -name "*kernel-install*" -exec rm {} \;
831 ''
832 + lib.optionalString (!withDocumentation) ''
833 rm -rf $out/share/doc
834 ''
835 + lib.optionalString (withKmod && !buildLibsOnly) ''
836 mv $out/lib/modules-load.d $out/example
837 ''
838 + lib.optionalString withSysusers ''
839 mv $out/lib/sysusers.d $out/example
840 '';
841
842 doInstallCheck = true;
843
844 # check udev rules exposed by systemd
845 # can't use `udevCheckHook` here as that would introduce infinite recursion
846 installCheckPhase = ''
847 runHook preInstallCheck
848
849 ${lib.optionalString (
850 !buildLibsOnly
851 ) "$out/bin/udevadm verify --resolve-names=never --no-style $out/lib/udev/rules.d"}
852
853 runHook postInstallCheck
854 '';
855
856 # Avoid *.EFI binary stripping.
857 # At least on aarch64-linux strip removes too much from PE32+ files:
858 # https://github.com/NixOS/nixpkgs/issues/169693
859 # The hack is to move EFI file out of lib/ before doStrip run and return it
860 # after doStrip run.
861 preFixup = lib.optionalString withBootloader ''
862 mv $out/lib/systemd/boot/efi $out/dont-strip-me
863 '';
864
865 # Wrap in the correct path for LUKS2 tokens.
866 postFixup =
867 lib.optionalString withCryptsetup ''
868 for f in bin/systemd-cryptsetup bin/systemd-cryptenroll; do
869 # This needs to be in LD_LIBRARY_PATH because rpath on a binary is not propagated to libraries using dlopen, in this case `libcryptsetup.so`
870 wrapProgram $out/$f --prefix LD_LIBRARY_PATH : ${placeholder "out"}/lib/cryptsetup
871 done
872 ''
873 + lib.optionalString withBootloader ''
874 mv $out/dont-strip-me $out/lib/systemd/boot/efi
875 ''
876 + lib.optionalString withUkify ''
877 # To cross compile a derivation that builds a UKI with ukify, we need to wrap
878 # ukify with the correct binutils. When wrapping, no splicing happens so we
879 # have to explicitly pull binutils from targetPackages.
880 wrapProgram $out/bin/ukify --prefix PATH : ${
881 lib.makeBinPath [ targetPackages.stdenv.cc.bintools ]
882 }:${placeholder "out"}/lib/systemd
883 '';
884
885 disallowedReferences =
886 lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform)
887 # 'or p' is for manually specified buildPackages as they dont have __spliced
888 (
889 builtins.filter (p: p != null) (
890 builtins.map (p: p.__spliced.buildHost or p) finalAttrs.nativeBuildInputs
891 )
892 );
893
894 passthru = {
895 # The `interfaceVersion` attribute below points out the incompatibilities
896 # between systemd versions. When the new systemd build is
897 # backwards-compatible with the previous one, then they can be switched at
898 # runtime (the reboot being optional in this case); otherwise, a reboot is
899 # needed - and therefore `interfaceVersion` should be incremented.
900 interfaceVersion = 2;
901
902 inherit
903 withBootloader
904 withCryptsetup
905 withEfi
906 withFido2
907 withHostnamed
908 withImportd
909 withKmod
910 withLocaled
911 withMachined
912 withNetworkd
913 withPortabled
914 withTimedated
915 withTpm2Tss
916 withUtmp
917 util-linux
918 kmod
919 kbd
920 ;
921
922 # Many TPM2-related units are only installed if this trio of features are
923 # enabled. See https://github.com/systemd/systemd/blob/876ee10e0eb4bbb0920bdab7817a9f06cc34910f/units/meson.build#L521
924 withTpm2Units = withTpm2Tss && withBootloader && withOpenSSL;
925
926 tests =
927 let
928 # Some entries in the `nixosTests.systemd-*` set of attributes are collections of tests,
929 # not individual tests themselves. Let's gather them into one set.
930 gatherNixosTestsFromCollection =
931 prefix: collection:
932 lib.mapAttrs' (name: value: {
933 name = "${prefix}-${name}";
934 inherit value;
935 }) collection;
936
937 # Here's all the nixosTests that are collections of tests, rather than individual tests.
938 collectedNixosTests = lib.mergeAttrsList (
939 lib.mapAttrsToList gatherNixosTestsFromCollection {
940 inherit (nixosTests)
941 systemd-binfmt
942 systemd-boot
943 systemd-initrd-networkd
944 systemd-repart
945 installer-systemd-stage-1
946 ;
947 }
948 );
949
950 # ... and here's all the individual tests.
951 individualNixosTests = {
952 inherit (nixosTests)
953 fsck-systemd-stage-1
954 hibernate-systemd-stage-1
955 switchTest
956 systemd
957 systemd-analyze
958 systemd-bpf
959 systemd-confinement
960 systemd-coredump
961 systemd-cryptenroll
962 systemd-credentials-tpm2
963 systemd-escaping
964 systemd-initrd-btrfs-raid
965 systemd-initrd-luks-fido2
966 systemd-initrd-luks-keyfile
967 systemd-initrd-luks-empty-passphrase
968 systemd-initrd-luks-password
969 systemd-initrd-luks-tpm2
970 systemd-initrd-luks-unl0kr
971 systemd-initrd-modprobe
972 systemd-initrd-shutdown
973 systemd-initrd-simple
974 systemd-initrd-swraid
975 systemd-initrd-vconsole
976 systemd-initrd-networkd-ssh
977 systemd-initrd-networkd-openvpn
978 systemd-initrd-vlan
979 systemd-journal
980 systemd-journal-gateway
981 systemd-journal-upload
982 systemd-lock-handler
983 systemd-machinectl
984 systemd-networkd
985 systemd-networkd-bridge
986 systemd-networkd-dhcpserver
987 systemd-networkd-dhcpserver-static-leases
988 systemd-networkd-ipv6-prefix-delegation
989 systemd-networkd-vrf
990 systemd-no-tainted
991 systemd-nspawn
992 systemd-nspawn-configfile
993 systemd-oomd
994 systemd-portabled
995 systemd-resolved
996 systemd-shutdown
997 systemd-sysupdate
998 systemd-sysusers-mutable
999 systemd-sysusers-immutable
1000 systemd-sysusers-password-option-override-ordering
1001 systemd-timesyncd
1002 systemd-timesyncd-nscd-dnssec
1003 systemd-user-linger
1004 systemd-user-tmpfiles-rules
1005 systemd-misc
1006 systemd-userdbd
1007 systemd-homed
1008 ;
1009 };
1010
1011 # Finally, make an attrset we're fairly sure is just tests.
1012 relevantNixosTests = lib.mapAttrs (
1013 name: value:
1014 assert lib.assertMsg (lib.isDerivation value) "${name} is not a derivation";
1015 value
1016 ) (individualNixosTests // collectedNixosTests);
1017 in
1018 relevantNixosTests
1019 // {
1020 cross =
1021 let
1022 systemString = if stdenv.buildPlatform.isAarch64 then "gnu64" else "aarch64-multiplatform";
1023 in
1024 pkgsCross.${systemString}.systemd;
1025
1026 pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
1027 };
1028 };
1029
1030 meta = {
1031 homepage = "https://www.freedesktop.org/wiki/Software/systemd/";
1032 description = "System and service manager for Linux";
1033 longDescription = ''
1034 systemd is a suite of basic building blocks for a Linux system. It
1035 provides a system and service manager that runs as PID 1 and starts the
1036 rest of the system. systemd provides aggressive parallelization
1037 capabilities, uses socket and D-Bus activation for starting services,
1038 offers on-demand starting of daemons, keeps track of processes using Linux
1039 control groups, maintains mount and automount points, and implements an
1040 elaborate transactional dependency-based service control logic. systemd
1041 supports SysV and LSB init scripts and works as a replacement for
1042 sysvinit. Other parts include a logging daemon, utilities to control basic
1043 system configuration like the hostname, date, locale, maintain a list of
1044 logged-in users and running containers and virtual machines, system
1045 accounts, runtime directories and settings, and daemons to manage simple
1046 network configuration, network time synchronization, log forwarding, and
1047 name resolution.
1048 '';
1049 license = with lib.licenses; [
1050 # Taken from https://raw.githubusercontent.com/systemd/systemd-stable/${finalAttrs.src.rev}/LICENSES/README.md
1051 bsd2
1052 bsd3
1053 cc0
1054 lgpl21Plus
1055 lgpl2Plus
1056 mit
1057 mit0
1058 ofl
1059 publicDomain
1060 ];
1061 teams = [ lib.teams.systemd ];
1062 pkgConfigModules = [
1063 "libsystemd"
1064 "libudev"
1065 "systemd"
1066 "udev"
1067 ];
1068 # See src/basic/missing_syscall_def.h
1069 platforms =
1070 with lib.platforms;
1071 lib.intersectLists linux (aarch ++ x86 ++ loongarch64 ++ m68k ++ mips ++ power ++ riscv ++ s390);
1072 priority = 10;
1073 badPlatforms = [
1074 # https://github.com/systemd/systemd/issues/20600#issuecomment-912338965
1075 lib.systems.inspect.platformPatterns.isStatic
1076 ];
1077 };
1078})