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