1{
2 lib,
3 stdenv,
4 buildPackages,
5 fetchurl,
6 updateAutotoolsGnuConfigScriptsHook,
7 bison,
8 util-linux,
9
10 interactive ? true,
11 readline,
12 withDocs ? null,
13 forFHSEnv ? false,
14
15 pkgsStatic,
16}:
17
18let
19 upstreamPatches = import ./bash-5.3-patches.nix (
20 nr: sha256:
21 fetchurl {
22 url = "mirror://gnu/bash/bash-5.3-patches/bash53-${nr}";
23 inherit sha256;
24 }
25 );
26in
27lib.warnIf (withDocs != null)
28 ''
29 bash: `.override { withDocs = true; }` is deprecated, the docs are always included.
30 ''
31 stdenv.mkDerivation
32 rec {
33 pname = "bash${lib.optionalString interactive "-interactive"}";
34 version = "5.3${patch_suffix}";
35 patch_suffix = "p${toString (builtins.length upstreamPatches)}";
36
37 src = fetchurl {
38 url = "mirror://gnu/bash/bash-${lib.removeSuffix patch_suffix version}.tar.gz";
39 hash = "sha256-DVzYaWX4aaJs9k9Lcb57lvkKO6iz104n6OnZ1VUPMbo=";
40 };
41
42 hardeningDisable = [
43 "format"
44 ]
45 # bionic libc is super weird and has issues with fortify outside of its own libc, check this comment:
46 # https://github.com/NixOS/nixpkgs/pull/192630#discussion_r978985593
47 # or you can check libc/include/sys/cdefs.h in bionic source code
48 ++ lib.optional (stdenv.hostPlatform.libc == "bionic") "fortify";
49
50 outputs = [
51 "out"
52 "dev"
53 "man"
54 "doc"
55 "info"
56 ];
57
58 separateDebugInfo = true;
59
60 env.NIX_CFLAGS_COMPILE = ''
61 -DSYS_BASHRC="/etc/bashrc"
62 -DSYS_BASH_LOGOUT="/etc/bash_logout"
63 ''
64 + lib.optionalString (!forFHSEnv) ''
65 -DDEFAULT_PATH_VALUE="/no-such-path"
66 -DSTANDARD_UTILS_PATH="/no-such-path"
67 -DDEFAULT_LOADABLE_BUILTINS_PATH="${placeholder "out"}/lib/bash:."
68 ''
69 + ''
70 -DNON_INTERACTIVE_LOGIN_SHELLS
71 -DSSH_SOURCE_BASHRC
72 '';
73
74 patchFlags = [ "-p0" ];
75
76 patches = upstreamPatches ++ [
77 # Enable PGRP_PIPE independently of the kernel of the build machine.
78 # This doesn't seem to be upstreamed despite such a mention of in https://github.com/NixOS/nixpkgs/pull/77196,
79 # which originally introduced the patch
80 # Some related discussion can be found in
81 # https://lists.gnu.org/archive/html/bug-bash/2015-05/msg00071.html
82 ./pgrp-pipe-5.patch
83 ];
84
85 configureFlags = [
86 # At least on Linux bash memory allocator has pathological performance
87 # in scenarios involving use of larger memory:
88 # https://lists.gnu.org/archive/html/bug-bash/2023-08/msg00052.html
89 # Various distributions default to system allocator. Let's nixpkgs
90 # do the same.
91 "--without-bash-malloc"
92 (if interactive then "--with-installed-readline" else "--disable-readline")
93 ]
94 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
95 "bash_cv_job_control_missing=nomissing"
96 "bash_cv_sys_named_pipes=nomissing"
97 "bash_cv_getcwd_malloc=yes"
98 # This check cannot be performed when cross compiling. The "yes"
99 # default is fine for static linking on Linux (weak symbols?) but
100 # not with BSDs, when it does clash with the regular `getenv`.
101 "bash_cv_getenv_redef=${
102 if !(with stdenv.hostPlatform; isStatic && (isOpenBSD || isFreeBSD)) then "yes" else "no"
103 }"
104 ]
105 ++ lib.optionals stdenv.hostPlatform.isCygwin [
106 "--without-libintl-prefix"
107 "--without-libiconv-prefix"
108 "--with-installed-readline"
109 "bash_cv_dev_stdin=present"
110 "bash_cv_dev_fd=standard"
111 "bash_cv_termcap_lib=libncurses"
112 ]
113 ++ lib.optionals (stdenv.hostPlatform.libc == "musl") [
114 "--disable-nls"
115 ]
116 ++ lib.optionals stdenv.hostPlatform.isFreeBSD [
117 # /dev/fd is optional on FreeBSD. we need it to work when built on a system
118 # with it and transferred to a system without it! This includes linux cross.
119 "bash_cv_dev_fd=absent"
120 ];
121
122 strictDeps = true;
123 # Note: Bison is needed because the patches above modify parse.y.
124 depsBuildBuild = [ buildPackages.stdenv.cc ];
125 nativeBuildInputs = [
126 updateAutotoolsGnuConfigScriptsHook
127 bison
128 ]
129 ++ lib.optional stdenv.hostPlatform.isDarwin stdenv.cc.bintools;
130
131 buildInputs = lib.optional interactive readline;
132
133 enableParallelBuilding = true;
134
135 makeFlags = lib.optionals stdenv.hostPlatform.isCygwin [
136 "LOCAL_LDFLAGS=-Wl,--export-all,--out-implib,libbash.dll.a"
137 "SHOBJ_LIBS=-lbash"
138 ];
139
140 nativeCheckInputs = [ util-linux ];
141 doCheck = false; # dependency cycle, needs to be interactive
142
143 postInstall = ''
144 ln -s bash "$out/bin/sh"
145 rm -f $out/lib/bash/Makefile.inc
146 '';
147
148 postFixup =
149 if interactive then
150 ''
151 substituteInPlace "$out/bin/bashbug" \
152 --replace '#!/bin/sh' "#!$out/bin/bash"
153 ''
154 # most space is taken by locale data
155 else
156 ''
157 rm -rf "$out/share" "$out/bin/bashbug"
158 '';
159
160 passthru = {
161 shellPath = "/bin/bash";
162 tests.static = pkgsStatic.bash;
163 };
164
165 meta = with lib; {
166 homepage = "https://www.gnu.org/software/bash/";
167 description =
168 "GNU Bourne-Again Shell, the de facto standard shell on Linux"
169 + lib.optionalString interactive " (for interactive use)";
170 longDescription = ''
171 Bash is the shell, or command language interpreter, that will
172 appear in the GNU operating system. Bash is an sh-compatible
173 shell that incorporates useful features from the Korn shell
174 (ksh) and C shell (csh). It is intended to conform to the IEEE
175 POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers
176 functional improvements over sh for both programming and
177 interactive use. In addition, most sh scripts can be run by
178 Bash without modification.
179 '';
180 license = licenses.gpl3Plus;
181 platforms = platforms.all;
182 # https://github.com/NixOS/nixpkgs/issues/333338
183 badPlatforms = [ lib.systems.inspect.patterns.isMinGW ];
184 maintainers = [ ];
185 mainProgram = "bash";
186 identifiers.cpeParts =
187 let
188 versionSplit = lib.split "p" version;
189 in
190 {
191 vendor = "gnu";
192 product = "bash";
193 version = lib.elemAt versionSplit 0;
194 update = lib.elemAt versionSplit 2;
195 };
196 };
197 }