base16-schemes: unstable-2024-06-21 -> unstable-2024-11-12 (#356361)
[NixPkgs.git] / pkgs / top-level / unixtools.nix
blob93bb34bba20d3fe2017cb2cd2fe45d4e08cf9a1e
1 { pkgs, buildEnv, runCommand, lib, stdenv, freebsd, binlore }:
3 # These are some unix tools that are commonly included in the /usr/bin
4 # and /usr/sbin directory under more normal distributions. Along with
5 # coreutils, these are commonly assumed to be available by build
6 # systems, but we can't assume they are available. In Nix, we list
7 # each program by name directly through this unixtools attribute.
9 # You should always try to use single binaries when available. For
10 # instance, if your program needs to use "ps", just list it as a build
11 # input, not "procps" which requires Linux.
13 let
14   inherit (lib)
15     getBin
16     getOutput
17     mapAttrs
18     platforms
19     ;
21   version = "1003.1-2008";
23   singleBinary = cmd: providers: let
24       provider = providers.${stdenv.hostPlatform.parsed.kernel.name} or providers.linux;
25       bin = "${getBin provider}/bin/${cmd}";
26       manpage = "${getOutput "man" provider}/share/man/man1/${cmd}.1.gz";
27     in runCommand "${cmd}-${provider.name}" {
28       meta = {
29         mainProgram = cmd;
30         priority = 10;
31         platforms = platforms.${stdenv.hostPlatform.parsed.kernel.name} or platforms.all;
32       };
33       passthru = { inherit provider; } // lib.optionalAttrs (builtins.hasAttr "binlore" providers) {
34         binlore.out = (binlore.synthesize (getBin bins.${cmd}) providers.binlore);
35       };
36       preferLocalBuild = true;
37     } ''
38       if ! [ -x ${bin} ]; then
39         echo Cannot find command ${cmd}
40         exit 1
41       fi
43       mkdir -p $out/bin
44       ln -s ${bin} $out/bin/${cmd}
46       if [ -f ${manpage} ]; then
47         mkdir -p $out/share/man/man1
48         ln -s ${manpage} $out/share/man/man1/${cmd}.1.gz
49       fi
50     '';
52   # more is unavailable in darwin
53   # so we just use less
54   more_compat = runCommand "more-${pkgs.less.name}" {} ''
55     mkdir -p $out/bin
56     ln -s ${pkgs.less}/bin/less $out/bin/more
57   '';
59   bins = mapAttrs singleBinary {
60     # singular binaries
61     arp = {
62       linux = pkgs.nettools;
63       darwin = pkgs.darwin.network_cmds;
64       freebsd = pkgs.freebsd.arp;
65     };
66     col = {
67       linux = pkgs.util-linux;
68       darwin = pkgs.darwin.text_cmds;
69     };
70     column = {
71       linux = pkgs.util-linux;
72       darwin = pkgs.darwin.text_cmds;
73     };
74     eject = {
75       linux = pkgs.util-linux;
76     };
77     getconf = {
78       linux = if stdenv.hostPlatform.libc == "glibc" then pkgs.stdenv.cc.libc
79               else pkgs.netbsd.getconf;
80       darwin = pkgs.darwin.system_cmds;
81       # I don't see any obvious arg exec in the doc/manpage
82       binlore = ''
83         execer cannot bin/getconf
84       '';
85     };
86     getent = {
87       linux = if stdenv.hostPlatform.libc == "glibc" then pkgs.stdenv.cc.libc.getent
88               else pkgs.netbsd.getent;
89       darwin = pkgs.netbsd.getent;
90       freebsd = pkgs.freebsd.getent;
91     };
92     getopt = {
93       linux = pkgs.util-linux;
94       darwin = pkgs.getopt;
95     };
96     fdisk = {
97       linux = pkgs.util-linux;
98       darwin = pkgs.darwin.diskdev_cmds;
99       freebsd = pkgs.freebsd.fdisk;
100     };
101     fsck = {
102       linux = pkgs.util-linux;
103       darwin = pkgs.darwin.diskdev_cmds;
104     };
105     hexdump = {
106       linux = pkgs.util-linux;
107       darwin = pkgs.darwin.shell_cmds;
108     };
109     hostname = {
110       linux = pkgs.nettools;
111       darwin = pkgs.darwin.shell_cmds;
112       freebsd = pkgs.freebsd.bin;
113     };
114     ifconfig = {
115       linux = pkgs.nettools;
116       darwin = pkgs.darwin.network_cmds;
117       freebsd = pkgs.freebsd.ifconfig;
118     };
119     killall = {
120       linux = pkgs.psmisc;
121       darwin = pkgs.darwin.shell_cmds;
122     };
123     locale = {
124       linux = pkgs.glibc;
125       darwin = pkgs.darwin.adv_cmds;
126       freebsd = pkgs.freebsd.locale;
127       # technically just targeting glibc version
128       # no obvious exec in manpage
129       binlore = ''
130         execer cannot bin/locale
131       '';
132     };
133     logger = {
134       linux = pkgs.util-linux;
135     };
136     more = {
137       linux = pkgs.util-linux;
138       darwin = more_compat;
139     };
140     mount = {
141       linux = pkgs.util-linux;
142       darwin = pkgs.darwin.diskdev_cmds;
143       freebsd = freebsd.mount;
144       # technically just targeting the darwin version; binlore already
145       # ids the util-linux copy as 'cannot'
146       # no obvious exec in manpage args; I think binlore flags 'can'
147       # on the code to run `mount_<filesystem>` variants
148       binlore = ''
149         execer cannot bin/mount
150       '';
151     };
152     netstat = {
153       linux = pkgs.nettools;
154       darwin = pkgs.darwin.network_cmds;
155       freebsd = pkgs.freebsd.netstat;
156     };
157     ping = {
158       linux = pkgs.iputils;
159       darwin = pkgs.darwin.network_cmds;
160       freebsd = freebsd.ping;
161     };
162     ps = {
163       linux = pkgs.procps;
164       darwin = pkgs.darwin.ps;
165       freebsd = pkgs.freebsd.bin;
166       # technically just targeting procps ps (which ids as can)
167       # but I don't see obvious exec in args; have yet to look
168       # for underlying cause in source
169       binlore = ''
170         execer cannot bin/ps
171       '';
172     };
173     quota = {
174       linux = pkgs.linuxquota;
175       darwin = pkgs.darwin.diskdev_cmds;
176     };
177     route = {
178       linux = pkgs.nettools;
179       darwin = pkgs.darwin.network_cmds;
180       freebsd = pkgs.freebsd.route;
181     };
182     script = {
183       linux = pkgs.util-linux;
184       darwin = pkgs.darwin.shell_cmds;
185     };
186     sysctl = {
187       linux = pkgs.procps;
188       darwin = pkgs.darwin.system_cmds;
189       freebsd = pkgs.freebsd.sysctl;
190     };
191     top = {
192       linux = pkgs.procps;
193       darwin = pkgs.darwin.top;
194       freebsd = pkgs.freebsd.top;
195       # technically just targeting procps top; haven't needed this in
196       # any scripts so far, but overriding it for consistency with ps
197       # override above and in procps. (procps also overrides 'free',
198       # but it isn't included here.)
199       binlore = ''
200         execer cannot bin/top
201       '';
202     };
203     umount = {
204       linux = pkgs.util-linux;
205       darwin = pkgs.darwin.diskdev_cmds;
206     };
207     whereis = {
208       linux = pkgs.util-linux;
209       darwin = pkgs.darwin.shell_cmds;
210     };
211     wall = {
212       linux = pkgs.util-linux;
213     };
214     watch = {
215       linux = pkgs.procps;
217       # watch is the only command from procps that builds currently on
218       # Darwin/FreeBSD. Unfortunately no other implementations exist currently!
219       darwin = pkgs.callPackage ../os-specific/linux/procps-ng {};
220       freebsd = pkgs.callPackage ../os-specific/linux/procps-ng {};
221     };
222     write = {
223       linux = pkgs.util-linux;
224       darwin = pkgs.darwin.basic_cmds;
225     };
226     xxd = {
227       linux = pkgs.tinyxxd;
228       darwin = pkgs.tinyxxd;
229       freebsd = pkgs.tinyxxd;
230     };
231   };
233   makeCompat = pname: paths:
234     buildEnv {
235       name = "${pname}-${version}";
236       inherit paths;
237     };
239   # Compatibility derivations
240   # Provided for old usage of these commands.
241   compat = with bins; mapAttrs makeCompat {
242     procps = [ ps sysctl top watch ];
243     util-linux = [ fsck fdisk getopt hexdump mount
244                   script umount whereis write col column ];
245     nettools = [ arp hostname ifconfig netstat route ];
246   };
247 in bins // compat