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.8";
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-XQ+IyRar74qQij96CKClHXW0kkPnGeKUgA8ULiWh5YY=";
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 (
895 builtins.filter (p: p != null) (
896 builtins.map (p: p.__spliced.buildHost or p) finalAttrs.nativeBuildInputs
897 )
898 );
899
900 disallowedRequisites = lib.optionals (!withUkify) [
901 bash
902 bashNonInteractive
903 ];
904
905 passthru = {
906 # The `interfaceVersion` attribute below points out the incompatibilities
907 # between systemd versions. When the new systemd build is
908 # backwards-compatible with the previous one, then they can be switched at
909 # runtime (the reboot being optional in this case); otherwise, a reboot is
910 # needed - and therefore `interfaceVersion` should be incremented.
911 interfaceVersion = 2;
912
913 inherit
914 withBootloader
915 withCryptsetup
916 withEfi
917 withFido2
918 withHostnamed
919 withImportd
920 withKmod
921 withLocaled
922 withMachined
923 withNetworkd
924 withPortabled
925 withSysupdate
926 withTimedated
927 withTpm2Tss
928 withUtmp
929 util-linux
930 kmod
931 ;
932
933 kbd = kbd';
934
935 # Many TPM2-related units are only installed if this trio of features are
936 # enabled. See https://github.com/systemd/systemd/blob/876ee10e0eb4bbb0920bdab7817a9f06cc34910f/units/meson.build#L521
937 withTpm2Units = withTpm2Tss && withBootloader && withOpenSSL;
938
939 tests =
940 let
941 # Some entries in the `nixosTests.systemd-*` set of attributes are collections of tests,
942 # not individual tests themselves. Let's gather them into one set.
943 gatherNixosTestsFromCollection =
944 prefix: collection:
945 lib.mapAttrs' (name: value: {
946 name = "${prefix}-${name}";
947 inherit value;
948 }) collection;
949
950 # Here's all the nixosTests that are collections of tests, rather than individual tests.
951 collectedNixosTests = lib.mergeAttrsList (
952 lib.mapAttrsToList gatherNixosTestsFromCollection {
953 inherit (nixosTests)
954 systemd-binfmt
955 systemd-boot
956 systemd-initrd-networkd
957 systemd-repart
958 installer-systemd-stage-1
959 ;
960 }
961 );
962
963 # ... and here's all the individual tests.
964 individualNixosTests = {
965 inherit (nixosTests)
966 fsck-systemd-stage-1
967 hibernate-systemd-stage-1
968 switchTest
969 systemd
970 systemd-analyze
971 systemd-bpf
972 systemd-confinement
973 systemd-coredump
974 systemd-cryptenroll
975 systemd-credentials-tpm2
976 systemd-escaping
977 systemd-initrd-btrfs-raid
978 systemd-initrd-luks-fido2
979 systemd-initrd-luks-keyfile
980 systemd-initrd-luks-empty-passphrase
981 systemd-initrd-luks-password
982 systemd-initrd-luks-tpm2
983 systemd-initrd-luks-unl0kr
984 systemd-initrd-modprobe
985 systemd-initrd-shutdown
986 systemd-initrd-simple
987 systemd-initrd-swraid
988 systemd-initrd-vconsole
989 systemd-initrd-networkd-ssh
990 systemd-initrd-networkd-openvpn
991 systemd-initrd-vlan
992 systemd-journal
993 systemd-journal-gateway
994 systemd-journal-upload
995 systemd-lock-handler
996 systemd-machinectl
997 systemd-networkd
998 systemd-networkd-bridge
999 systemd-networkd-dhcpserver
1000 systemd-networkd-dhcpserver-static-leases
1001 systemd-networkd-ipv6-prefix-delegation
1002 systemd-networkd-vrf
1003 systemd-no-tainted
1004 systemd-nspawn
1005 systemd-nspawn-configfile
1006 systemd-oomd
1007 systemd-portabled
1008 systemd-resolved
1009 systemd-shutdown
1010 systemd-sysupdate
1011 systemd-sysusers-mutable
1012 systemd-sysusers-immutable
1013 systemd-sysusers-password-option-override-ordering
1014 systemd-timesyncd
1015 systemd-timesyncd-nscd-dnssec
1016 systemd-user-linger
1017 systemd-user-tmpfiles-rules
1018 systemd-misc
1019 systemd-userdbd
1020 systemd-homed
1021 ;
1022 };
1023
1024 # Finally, make an attrset we're fairly sure is just tests.
1025 relevantNixosTests = lib.mapAttrs (
1026 name: value:
1027 assert lib.assertMsg (lib.isDerivation value) "${name} is not a derivation";
1028 value
1029 ) (individualNixosTests // collectedNixosTests);
1030 in
1031 relevantNixosTests
1032 // {
1033 cross =
1034 let
1035 systemString = if stdenv.buildPlatform.isAarch64 then "gnu64" else "aarch64-multiplatform";
1036 in
1037 pkgsCross.${systemString}.systemd;
1038
1039 pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
1040 };
1041 };
1042
1043 meta = {
1044 homepage = "https://www.freedesktop.org/wiki/Software/systemd/";
1045 description = "System and service manager for Linux";
1046 longDescription = ''
1047 systemd is a suite of basic building blocks for a Linux system. It
1048 provides a system and service manager that runs as PID 1 and starts the
1049 rest of the system. systemd provides aggressive parallelization
1050 capabilities, uses socket and D-Bus activation for starting services,
1051 offers on-demand starting of daemons, keeps track of processes using Linux
1052 control groups, maintains mount and automount points, and implements an
1053 elaborate transactional dependency-based service control logic. systemd
1054 supports SysV and LSB init scripts and works as a replacement for
1055 sysvinit. Other parts include a logging daemon, utilities to control basic
1056 system configuration like the hostname, date, locale, maintain a list of
1057 logged-in users and running containers and virtual machines, system
1058 accounts, runtime directories and settings, and daemons to manage simple
1059 network configuration, network time synchronization, log forwarding, and
1060 name resolution.
1061 '';
1062 license = with lib.licenses; [
1063 # Taken from https://raw.githubusercontent.com/systemd/systemd-stable/${finalAttrs.src.rev}/LICENSES/README.md
1064 bsd2
1065 bsd3
1066 cc0
1067 lgpl21Plus
1068 lgpl2Plus
1069 mit
1070 mit0
1071 ofl
1072 publicDomain
1073 ];
1074 teams = [ lib.teams.systemd ];
1075 pkgConfigModules = [
1076 "libsystemd"
1077 "libudev"
1078 "systemd"
1079 "udev"
1080 ];
1081 # See src/basic/missing_syscall_def.h
1082 platforms =
1083 with lib.platforms;
1084 lib.intersectLists linux (aarch ++ x86 ++ loongarch64 ++ m68k ++ mips ++ power ++ riscv ++ s390);
1085 priority = 10;
1086 badPlatforms = [
1087 # https://github.com/systemd/systemd/issues/20600#issuecomment-912338965
1088 lib.systems.inspect.platformPatterns.isStatic
1089 ];
1090 };
1091})