1{
2 lib,
3 stdenv,
4 fetchurl,
5 pkg-config,
6 autoconf,
7 automake116x,
8 zlib,
9 shadow,
10 capabilitiesSupport ? stdenv.hostPlatform.isLinux,
11 libcap_ng,
12 libxcrypt,
13 # Disable this by default because `mount` is setuid. However, we also support
14 # "dlopen" as a value here. Note that the nixpkgs setuid wrapper and ld-linux.so will filter out LD_LIBRARY_PATH
15 # if you set this to dlopen, so ensure you're accessing it without the wrapper if you depend on that.
16 cryptsetupSupport ? false,
17 cryptsetup,
18 ncursesSupport ? true,
19 ncurses,
20 pamSupport ? true,
21 pam,
22 systemdSupport ? lib.meta.availableOn stdenv.hostPlatform systemd,
23 systemd,
24 sqlite,
25 nlsSupport ? true,
26 translateManpages ? true,
27 po4a,
28 installShellFiles,
29 writeSupport ? stdenv.hostPlatform.isLinux,
30 shadowSupport ? stdenv.hostPlatform.isLinux,
31 gitUpdater,
32}:
33
34let
35 isMinimal = cryptsetupSupport == false && !nlsSupport && !ncursesSupport && !systemdSupport;
36in
37stdenv.mkDerivation (finalPackage: rec {
38 pname = "util-linux" + lib.optionalString isMinimal "-minimal";
39 version = "2.41.1";
40
41 src = fetchurl {
42 url = "mirror://kernel/linux/utils/util-linux/v${lib.versions.majorMinor version}/util-linux-${version}.tar.xz";
43 hash = "sha256-vprZonb0MFq33S9SJci+H/VDUvVl/03t6WKMGqp97Fc=";
44 };
45
46 patches = [
47 ./rtcwake-search-PATH-for-shutdown.patch
48 (fetchurl {
49 name = "bits-only-build-when-cpu_set_t-is-available.patch";
50 url = "https://lore.kernel.org/util-linux/20250501075806.88759-1-hi@alyssa.is/raw";
51 hash = "sha256-G7Cdv8636wJEjgt9am7PaDI8bpSF8sO9bFWEIiAL25A=";
52 })
53 ];
54
55 # We separate some of the utilities into their own outputs. This
56 # allows putting together smaller systems depending on only part of
57 # the greater util-linux toolset.
58 # Compatibility is maintained by symlinking the binaries from the
59 # smaller outputs in the bin output.
60 outputs = [
61 "bin"
62 "dev"
63 "out"
64 "lib"
65 "man"
66 ]
67 ++ lib.optionals stdenv.hostPlatform.isLinux [ "mount" ]
68 ++ [ "login" ]
69 ++ lib.optionals stdenv.hostPlatform.isLinux [ "swap" ];
70 separateDebugInfo = true;
71
72 postPatch = ''
73 patchShebangs tests/run.sh tools/all_syscalls tools/all_errnos
74
75 substituteInPlace sys-utils/eject.c \
76 --replace "/bin/umount" "$bin/bin/umount"
77 ''
78 + lib.optionalString shadowSupport ''
79 substituteInPlace include/pathnames.h \
80 --replace "/bin/login" "${shadow}/bin/login"
81 ''
82 + lib.optionalString stdenv.hostPlatform.isFreeBSD ''
83 substituteInPlace lib/c_strtod.c --replace-fail __APPLE__ __FreeBSD__
84 sed -E -i -e '/_POSIX_C_SOURCE/d' -e '/_XOPEN_SOURCE/d' misc-utils/hardlink.c
85 '';
86
87 # !!! It would be better to obtain the path to the mount helpers
88 # (/sbin/mount.*) through an environment variable, but that's
89 # somewhat risky because we have to consider that mount can setuid
90 # root...
91 configureFlags = [
92 "--localstatedir=/var"
93 "--disable-use-tty-group"
94 "--enable-fs-paths-default=/run/wrappers/bin:/run/current-system/sw/bin:/sbin"
95 "--disable-makeinstall-setuid"
96 "--disable-makeinstall-chown"
97 "--disable-su" # provided by shadow
98 (lib.enableFeature writeSupport "write")
99 (lib.enableFeature nlsSupport "nls")
100 (lib.withFeatureAs (cryptsetupSupport != false) "cryptsetup" (
101 if cryptsetupSupport == true then
102 "yes"
103 else if cryptsetupSupport == "dlopen" then
104 "dlopen"
105 else
106 throw "invalid cryptsetupSupport value: ${toString cryptsetupSupport}"
107 ))
108 (lib.withFeature ncursesSupport "ncursesw")
109 (lib.withFeature systemdSupport "systemd")
110 (lib.withFeatureAs systemdSupport "systemdsystemunitdir" "${placeholder "bin"}/lib/systemd/system/")
111 (lib.withFeatureAs systemdSupport "tmpfilesdir" "${placeholder "out"}/lib/tmpfiles.d")
112 (lib.withFeatureAs systemdSupport "sysusersdir" "${placeholder "out"}/lib/sysusers.d")
113 (lib.enableFeature translateManpages "poman")
114 "SYSCONFSTATICDIR=${placeholder "lib"}/lib"
115 ]
116 ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "scanf_cv_type_modifier=ms"
117 ++ lib.optionals stdenv.hostPlatform.isFreeBSD [
118 # These features are all disabled in the freebsd-ports distribution
119 "--disable-nls"
120 "--disable-ipcrm"
121 "--disable-ipcs"
122 ]
123 ++ lib.optionals stdenv.hostPlatform.isDarwin [
124 # Doesn't build on Darwin, also doesn't really make sense on Darwin
125 "--disable-liblastlog2"
126 ]
127 ++ lib.optionals stdenv.hostPlatform.isStatic [
128 # Mandatory shared library.
129 "--disable-pam-lastlog2"
130 ];
131
132 makeFlags = [
133 "usrbin_execdir=${placeholder "bin"}/bin"
134 "usrlib_execdir=${placeholder "lib"}/lib"
135 "usrsbin_execdir=${placeholder "bin"}/sbin"
136 ];
137
138 nativeBuildInputs = [
139 autoconf
140 automake116x
141 installShellFiles
142 pkg-config
143 ]
144 ++ lib.optionals translateManpages [ po4a ]
145 ++ lib.optionals (cryptsetupSupport == "dlopen") [ cryptsetup ];
146
147 buildInputs = [
148 zlib
149 libxcrypt
150 sqlite
151 ]
152 ++ lib.optionals (cryptsetupSupport == true) [ cryptsetup ]
153 ++ lib.optionals pamSupport [ pam ]
154 ++ lib.optionals capabilitiesSupport [ libcap_ng ]
155 ++ lib.optionals ncursesSupport [ ncurses ]
156 ++ lib.optionals systemdSupport [ systemd ];
157
158 doCheck = false; # "For development purpose only. Don't execute on production system!"
159
160 enableParallelBuilding = true;
161
162 postInstall =
163 lib.optionalString stdenv.hostPlatform.isLinux ''
164 moveToOutput bin/mount "$mount"
165 moveToOutput bin/umount "$mount"
166 ln -svf "$mount/bin/"* $bin/bin/
167 ''
168 + ''
169
170 moveToOutput sbin/nologin "$login"
171 moveToOutput sbin/sulogin "$login"
172 prefix=$login _moveSbin
173 ln -svf "$login/bin/"* $bin/bin/
174 ''
175 + lib.optionalString stdenv.hostPlatform.isLinux ''
176
177 moveToOutput sbin/swapon "$swap"
178 moveToOutput sbin/swapoff "$swap"
179 prefix=$swap _moveSbin
180 ln -svf "$swap/bin/"* $bin/bin/
181 ''
182 + ''
183
184 ln -svf "$bin/bin/hexdump" "$bin/bin/hd"
185 ln -svf "$man/share/man/man1/hexdump.1" "$man/share/man/man1/hd.1"
186
187 installShellCompletion --bash bash-completion/*
188 '';
189
190 passthru = {
191 updateScript = gitUpdater {
192 # No nicer place to find latest release.
193 url = "https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git";
194 rev-prefix = "v";
195 ignoredVersions = "(-rc).*";
196 };
197
198 # encode upstream assumption to be used in man-db
199 # https://github.com/util-linux/util-linux/commit/8886d84e25a457702b45194d69a47313f76dc6bc
200 hasCol = stdenv.hostPlatform.libc == "glibc";
201 };
202
203 meta = {
204 homepage = "https://www.kernel.org/pub/linux/utils/util-linux/";
205 description = "Set of system utilities for Linux";
206 changelog = "https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v${lib.versions.majorMinor version}/v${version}-ReleaseNotes";
207 # https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/README.licensing
208 license = with lib.licenses; [
209 gpl2Only
210 gpl2Plus
211 gpl3Plus
212 lgpl21Plus
213 bsd3
214 bsdOriginalUC
215 publicDomain
216 ];
217 maintainers = with lib.maintainers; [ numinit ];
218 platforms = lib.platforms.unix;
219 pkgConfigModules = [
220 "blkid"
221 "fdisk"
222 "mount"
223 "smartcols"
224 "uuid"
225 ];
226 priority = 6; # lower priority than coreutils ("kill") and shadow ("login" etc.) packages
227 };
228})