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