1{
2 lib,
3 stdenv,
4 fetchurl,
5 autoreconfHook,
6 buildPackages,
7 libiconv,
8 perl,
9 texinfo,
10 xz,
11 binlore,
12 coreutils,
13 gmpSupport ? true,
14 gmp,
15 aclSupport ? lib.meta.availableOn stdenv.hostPlatform acl,
16 acl,
17 attrSupport ? lib.meta.availableOn stdenv.hostPlatform attr,
18 attr,
19 selinuxSupport ? false,
20 libselinux,
21 libsepol,
22 # No openssl in default version, so openssl-induced rebuilds aren't too big.
23 # It makes *sum functions significantly faster.
24 minimal ? true,
25 withOpenssl ? !minimal,
26 openssl,
27 withPrefix ? false,
28 singleBinary ? "symlinks", # you can also pass "shebangs" or false
29}:
30
31# Note: this package is used for bootstrapping fetchurl, and thus cannot use
32# fetchpatch! All mutable patches (generated by GitHub or cgit) that are needed
33# here should be included directly in Nixpkgs as files.
34
35assert aclSupport -> acl != null;
36assert selinuxSupport -> libselinux != null && libsepol != null;
37
38let
39 inherit (lib)
40 concatStringsSep
41 isString
42 optional
43 optionalAttrs
44 optionals
45 optionalString
46 ;
47 isCross = (stdenv.hostPlatform != stdenv.buildPlatform);
48in
49stdenv.mkDerivation rec {
50 pname = "coreutils" + (optionalString (!minimal) "-full");
51 version = "9.7";
52
53 src = fetchurl {
54 url = "mirror://gnu/coreutils/coreutils-${version}.tar.xz";
55 hash = "sha256-6LsmrQKT+bWh/EP7QrqXDjEsZs6SwbCxZxPXUA2yUb8=";
56 };
57
58 postPatch =
59 ''
60 # The test tends to fail on btrfs, f2fs and maybe other unusual filesystems.
61 sed '2i echo Skipping dd sparse test && exit 77' -i ./tests/dd/sparse.sh
62 sed '2i echo Skipping du threshold test && exit 77' -i ./tests/du/threshold.sh
63 sed '2i echo Skipping cp reflink-auto test && exit 77' -i ./tests/cp/reflink-auto.sh
64 sed '2i echo Skipping cp sparse test && exit 77' -i ./tests/cp/sparse.sh
65 sed '2i echo Skipping env test && exit 77' -i ./tests/env/env.sh
66 sed '2i echo Skipping rm deep-2 test && exit 77' -i ./tests/rm/deep-2.sh
67 sed '2i echo Skipping du long-from-unreadable test && exit 77' -i ./tests/du/long-from-unreadable.sh
68
69 # The test tends to fail on cephfs
70 sed '2i echo Skipping df total-verify test && exit 77' -i ./tests/df/total-verify.sh
71
72 # Some target platforms, especially when building inside a container have
73 # issues with the inotify test.
74 sed '2i echo Skipping tail inotify dir recreate test && exit 77' -i ./tests/tail/inotify-dir-recreate.sh
75
76 # sandbox does not allow setgid
77 sed '2i echo Skipping chmod setgid test && exit 77' -i ./tests/chmod/setgid.sh
78 substituteInPlace ./tests/install/install-C.sh \
79 --replace 'mode3=2755' 'mode3=1755'
80
81 # Fails on systems with a rootfs. Looks like a bug in the test, see
82 # https://lists.gnu.org/archive/html/bug-coreutils/2019-12/msg00000.html
83 sed '2i print "Skipping df skip-rootfs test"; exit 77' -i ./tests/df/skip-rootfs.sh
84
85 # these tests fail in the unprivileged nix sandbox (without nix-daemon) as we break posix assumptions
86 for f in ./tests/chgrp/{basic.sh,recurse.sh,default-no-deref.sh,no-x.sh,posix-H.sh}; do
87 sed '2i echo Skipping chgrp && exit 77' -i "$f"
88 done
89 for f in gnulib-tests/{test-chown.c,test-fchownat.c,test-lchown.c}; do
90 echo "int main() { return 77; }" > "$f"
91 done
92
93 # We don't have localtime in the sandbox
94 for f in gnulib-tests/{test-localtime_r.c,test-localtime_r-mt.c}; do
95 echo "int main() { return 77; }" > "$f"
96 done
97
98 # intermittent failures on builders, unknown reason
99 sed '2i echo Skipping du basic test && exit 77' -i ./tests/du/basic.sh
100
101 # fails when syscalls related to acl not being available, e.g. in sandboxed environment
102 sed '2i echo Skipping ls -al with acl test && exit 77' -i ./tests/ls/acl.sh
103 ''
104 + (optionalString (stdenv.hostPlatform.libc == "musl") (
105 concatStringsSep "\n" [
106 ''
107 echo "int main() { return 77; }" > gnulib-tests/test-parse-datetime.c
108 echo "int main() { return 77; }" > gnulib-tests/test-getlogin.c
109 ''
110 ]
111 ))
112 + (optionalString stdenv.hostPlatform.isAarch64 ''
113 # Sometimes fails: https://github.com/NixOS/nixpkgs/pull/143097#issuecomment-954462584
114 sed '2i echo Skipping cut huge range test && exit 77' -i ./tests/cut/cut-huge-range.sh
115 '');
116
117 outputs = [
118 "out"
119 "info"
120 ];
121 separateDebugInfo = true;
122
123 nativeBuildInputs =
124 [
125 perl
126 xz.bin
127 ]
128 ++ optionals stdenv.hostPlatform.isCygwin [
129 # due to patch
130 autoreconfHook
131 texinfo
132 ];
133
134 buildInputs =
135 [ ]
136 ++ optional aclSupport acl
137 ++ optional attrSupport attr
138 ++ optional gmpSupport gmp
139 ++ optional withOpenssl openssl
140 ++ optionals selinuxSupport [
141 libselinux
142 libsepol
143 ]
144 # TODO(@Ericson2314): Investigate whether Darwin could benefit too
145 ++ optional (isCross && stdenv.hostPlatform.libc != "glibc") libiconv;
146
147 hardeningDisable = [ "trivialautovarinit" ];
148
149 configureFlags =
150 [ "--with-packager=https://nixos.org" ]
151 ++ optional (singleBinary != false) (
152 "--enable-single-binary" + optionalString (isString singleBinary) "=${singleBinary}"
153 )
154 ++ optional withOpenssl "--with-openssl"
155 ++ optional stdenv.hostPlatform.isSunOS "ac_cv_func_inotify_init=no"
156 ++ optional withPrefix "--program-prefix=g"
157 # the shipped configure script doesn't enable nls, but using autoreconfHook
158 # does so which breaks the build
159 ++ optional stdenv.hostPlatform.isDarwin "--disable-nls"
160 # The VMULL-based CRC implementation produces incorrect results on musl.
161 # https://lists.gnu.org/archive/html/bug-coreutils/2025-02/msg00046.html
162 ++ optional (
163 stdenv.hostPlatform.config == "aarch64-unknown-linux-musl"
164 ) "utils_cv_vmull_intrinsic_exists=no"
165 ++ optionals (isCross && stdenv.hostPlatform.libc == "glibc") [
166 # TODO(19b98110126fde7cbb1127af7e3fe1568eacad3d): Needed for fstatfs() I
167 # don't know why it is not properly detected cross building with glibc.
168 "fu_cv_sys_stat_statfs2_bsize=yes"
169 ]
170 # /proc/uptime is available on Linux and produces accurate results even if
171 # the boot time is set to the epoch because the system has no RTC. We
172 # explicitly enable it for cases where it can't be detected automatically,
173 # such as when cross-compiling.
174 ++ optional stdenv.hostPlatform.isLinux "gl_cv_have_proc_uptime=yes";
175
176 # The tests are known broken on Cygwin
177 # (http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/19025),
178 # Darwin (http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/19351),
179 # and {Open,Free}BSD.
180 # With non-standard storeDir: https://github.com/NixOS/nix/issues/512
181 doCheck =
182 (!isCross)
183 && (stdenv.hostPlatform.libc == "glibc" || stdenv.hostPlatform.libc == "musl")
184 && !stdenv.hostPlatform.isAarch32;
185
186 # Prevents attempts of running 'help2man' on cross-built binaries.
187 PERL = if isCross then "missing" else null;
188
189 enableParallelBuilding = true;
190
191 NIX_LDFLAGS = optionalString selinuxSupport "-lsepol";
192 FORCE_UNSAFE_CONFIGURE = optionalString stdenv.hostPlatform.isSunOS "1";
193 env.NIX_CFLAGS_COMPILE = toString (
194 [ ]
195 # Work around a bogus warning in conjunction with musl.
196 ++ optional stdenv.hostPlatform.isMusl "-Wno-error"
197 ++ optional stdenv.hostPlatform.isAndroid "-D__USE_FORTIFY_LEVEL=0"
198 );
199
200 # Works around a bug with 8.26:
201 # Makefile:3440: *** Recursive variable 'INSTALL' references itself (eventually). Stop.
202 preInstall = optionalString isCross ''
203 sed -i Makefile -e 's|^INSTALL =.*|INSTALL = ${buildPackages.coreutils}/bin/install -c|'
204 '';
205
206 postInstall =
207 optionalString (isCross && !minimal) ''
208 rm $out/share/man/man1/*
209 cp ${buildPackages.coreutils-full}/share/man/man1/* $out/share/man/man1
210 ''
211 # du: 8.7 M locale + 0.4 M man pages
212 + optionalString minimal ''
213 rm -r "$out/share"
214 '';
215
216 passthru =
217 { }
218 // optionalAttrs (singleBinary != false) {
219 # everything in the single binary gets the same verdict, so we
220 # override _that case_ with verdicts from separate binaries.
221 #
222 # binlore only spots exec in runcon on some platforms (i.e., not
223 # darwin; see comment on inverse case below)
224 binlore.out = binlore.synthesize coreutils ''
225 execer can bin/{chroot,env,install,nice,nohup,runcon,sort,split,stdbuf,timeout}
226 execer cannot bin/{[,b2sum,base32,base64,basename,basenc,cat,chcon,chgrp,chmod,chown,cksum,comm,cp,csplit,cut,date,dd,df,dir,dircolors,dirname,du,echo,expand,expr,factor,false,fmt,fold,groups,head,hostid,id,join,kill,link,ln,logname,ls,md5sum,mkdir,mkfifo,mknod,mktemp,mv,nl,nproc,numfmt,od,paste,pathchk,pinky,pr,printenv,printf,ptx,pwd,readlink,realpath,rm,rmdir,seq,sha1sum,sha224sum,sha256sum,sha384sum,sha512sum,shred,shuf,sleep,stat,stty,sum,sync,tac,tail,tee,test,touch,tr,true,truncate,tsort,tty,uname,unexpand,uniq,unlink,uptime,users,vdir,wc,who,whoami,yes}
227 '';
228 }
229 // optionalAttrs (singleBinary == false) {
230 # binlore only spots exec in runcon on some platforms (i.e., not
231 # darwin; I have a note that the behavior may need selinux?).
232 # hard-set it so people working on macOS don't miss cases of
233 # runcon until ofBorg fails.
234 binlore.out = binlore.synthesize coreutils ''
235 execer can bin/runcon
236 '';
237 };
238
239 meta = with lib; {
240 homepage = "https://www.gnu.org/software/coreutils/";
241 description = "GNU Core Utilities";
242 longDescription = ''
243 The GNU Core Utilities are the basic file, shell and text manipulation
244 utilities of the GNU operating system. These are the core utilities which
245 are expected to exist on every operating system.
246 '';
247 license = licenses.gpl3Plus;
248 maintainers = with maintainers; [ das_j ];
249 platforms = with platforms; unix ++ windows;
250 priority = 10;
251 };
252}