darwin.stdenv: allow patchShebangs during the bootstrap

This fixes pyicu (and any other package that uses `icu-config` instead
of the CMake or some other module to get the build flags).

What happened here is the bootstrap disables `patchShebangs` to avoid
propagating the bootstrap tools to the final stdenv (due to `sh` and
`bash` being on the `PATH` from the bootstrap tools). Because of that,
the `#!/bin/sh` line in `icu-config` was not updated, causing it to
invoke the system bash on Darwin. While that is undesirable in its own
right, when the system bash is invoked as `sh`, `echo -n` will print
`-n`, resulting in the breakage see in https://github.com/NixOS/nixpkgs/pull/241951#issuecomment-1627604354.

The fix is to build bash earlier in the bootstrap while making sure it
is picked up over the one in the bootstrap tools. That allows
`patchShebangs` to be enabled during the bootstrap. Any package with
scripts that is included in the final stdenv should now have its
scripts’ shebang lines properly patched.
This commit is contained in:
Randy Eckenrode 2023-07-09 11:00:13 -06:00
parent a61c7c58e4
commit 856ebe6fec
No known key found for this signature in database
GPG Key ID: 64C1CD4EC2A600D9

View File

@ -148,6 +148,8 @@ let
stdenvNoCC = prevStage.ccWrapperStdenv; stdenvNoCC = prevStage.ccWrapperStdenv;
}; };
bash = prevStage.bash or bootstrapTools;
thisStdenv = import ../generic { thisStdenv = import ../generic {
name = "${name}-stdenv-darwin"; name = "${name}-stdenv-darwin";
@ -159,18 +161,19 @@ let
extraBuildInputs = [ prevStage.darwin.CF ]; extraBuildInputs = [ prevStage.darwin.CF ];
preHook = '' preHook = lib.optionalString (!isBuiltByNixpkgsCompiler bash) ''
# Don't patch #!/interpreter because it leads to retained # Don't patch #!/interpreter because it leads to retained
# dependencies on the bootstrapTools in the final stdenv. # dependencies on the bootstrapTools in the final stdenv.
dontPatchShebangs=1 dontPatchShebangs=1
'' + ''
${commonPreHook prevStage} ${commonPreHook prevStage}
${extraPreHook} ${extraPreHook}
'' + lib.optionalString (prevStage.darwin ? locale) '' '' + lib.optionalString (prevStage.darwin ? locale) ''
export PATH_LOCALE=${prevStage.darwin.locale}/share/locale export PATH_LOCALE=${prevStage.darwin.locale}/share/locale
''; '';
shell = "${bootstrapTools}/bin/bash"; shell = bash + "/bin/bash";
initialPath = [ bootstrapTools ]; initialPath = [ bash bootstrapTools ];
fetchurlBoot = import ../../build-support/fetchurl { fetchurlBoot = import ../../build-support/fetchurl {
inherit lib; inherit lib;
@ -242,6 +245,8 @@ in
# stage should only access the stage that came before it. # stage should only access the stage that came before it.
ccWrapperStdenv = self.stdenv; ccWrapperStdenv = self.stdenv;
bash = bootstrapTools;
coreutils = bootstrapTools; coreutils = bootstrapTools;
gnugrep = bootstrapTools; gnugrep = bootstrapTools;
@ -445,7 +450,7 @@ in
# making sure both packages are present on x86_64-darwin and aarch64-darwin. # making sure both packages are present on x86_64-darwin and aarch64-darwin.
(prevStage: (prevStage:
# previous stage0 stdenv: # previous stage0 stdenv:
assert lib.all isFromBootstrapFiles (with prevStage; [ coreutils cpio gnugrep pbzx ]); assert lib.all isFromBootstrapFiles (with prevStage; [ bash coreutils cpio gnugrep pbzx ]);
assert lib.all isFromBootstrapFiles (with prevStage.darwin; [ assert lib.all isFromBootstrapFiles (with prevStage.darwin; [
binutils-unwrapped cctools print-reexports rewrite-tbd sigtool system_cmds binutils-unwrapped cctools print-reexports rewrite-tbd sigtool system_cmds
@ -727,7 +732,8 @@ in
''; '';
}) })
# This stage rebuilds Libsystem. # This stage rebuilds Libsystem. It also rebuilds bash, which will be needed in later stages
# to use in patched shebangs (e.g., to make sure `icu-config` uses bash from nixpkgs).
(prevStage: (prevStage:
# previous stage-xclang stdenv: # previous stage-xclang stdenv:
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [ assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
@ -764,13 +770,19 @@ in
overrides = self: super: { overrides = self: super: {
inherit (prevStage) ccWrapperStdenv inherit (prevStage) ccWrapperStdenv
autoconf automake bash binutils-unwrapped bison brotli cmake cmakeMinimal coreutils autoconf automake binutils-unwrapped bison brotli cmake cmakeMinimal coreutils
cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libffi cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libffi
libiconv libidn2 libkrb5 libssh2 libtool libunistring libxml2 m4 ncurses nghttp2 libiconv libidn2 libkrb5 libssh2 libtool libunistring libxml2 m4 ncurses nghttp2
ninja openbsm openldap openpam openssh openssl patchutils pbzx perl pkg-config ninja openbsm openldap openpam openssh openssl patchutils pbzx perl pkg-config
python3 python3Minimal scons serf sqlite subversion sysctl texinfo unzip which xz python3 python3Minimal scons serf sqlite subversion sysctl texinfo unzip which xz
zlib zstd; zlib zstd;
# Bash must be linked against the system CoreFoundation instead of the open-source one.
# Otherwise, there will be a dependency cycle: bash -> CF -> icu -> bash (for icu^dev).
bash = super.bash.overrideAttrs (super: {
buildInputs = super.buildInputs ++ [ self.darwin.apple_sdk.frameworks.CoreFoundation ];
});
darwin = super.darwin.overrideScope (selfDarwin: superDarwin: { darwin = super.darwin.overrideScope (selfDarwin: superDarwin: {
inherit (prevStage.darwin) inherit (prevStage.darwin)
CF binutils-unwrapped cctools configd darwin-stubs launchd libobjc libtapi locale CF binutils-unwrapped cctools configd darwin-stubs launchd libobjc libtapi locale
@ -822,13 +834,15 @@ in
(prevStage: (prevStage:
# previous stage2-Libsystem stdenv: # previous stage2-Libsystem stdenv:
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [ assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
autoconf automake bash binutils-unwrapped bison brotli cmake cmakeMinimal coreutils autoconf automake binutils-unwrapped bison brotli cmake cmakeMinimal coreutils
cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libidn2 cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libidn2
libkrb5 libssh2 libtool libunistring m4 nghttp2 ninja openbsm openldap openpam openssh libkrb5 libssh2 libtool libunistring m4 nghttp2 ninja openbsm openldap openpam openssh
openssl patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf openssl patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf
sqlite subversion sysctl.provider texinfo unzip which xz zstd sqlite subversion sysctl.provider texinfo unzip which xz zstd
]); ]);
assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [ bash ]);
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [ assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
libffi libiconv libxml2 ncurses zlib zstd libffi libiconv libxml2 ncurses zlib zstd
]); ]);
@ -946,14 +960,14 @@ in
(prevStage: (prevStage:
# previous stage2-CF stdenv: # previous stage2-CF stdenv:
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [ assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
autoconf automake bash bison brotli cmake cmakeMinimal coreutils cpio curl cyrus_sasl autoconf automake bison brotli cmake cmakeMinimal coreutils cpio curl cyrus_sasl
db ed expat flex gettext gmp gnugrep groff libedit libidn2 libkrb5 libssh2 libtool db ed expat flex gettext gmp gnugrep groff libedit libidn2 libkrb5 libssh2 libtool
libunistring m4 ncurses nghttp2 ninja openbsm openldap openpam openssh openssl libunistring m4 ncurses nghttp2 ninja openbsm openldap openpam openssh openssl
patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite
subversion sysctl.provider texinfo unzip which xz zstd subversion sysctl.provider texinfo unzip which xz zstd
]); ]);
assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [ assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [
binutils-unwrapped icu libffi libiconv libxml2 zlib bash binutils-unwrapped icu libffi libiconv libxml2 zlib
]); ]);
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage.darwin; [ assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage.darwin; [
@ -1025,7 +1039,7 @@ in
(prevStage: (prevStage:
# previous stage3 stdenv: # previous stage3 stdenv:
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [ assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
autoconf automake bash bison brotli cmake cmakeMinimal coreutils cpio curl cyrus_sasl autoconf automake bison brotli cmake cmakeMinimal coreutils cpio curl cyrus_sasl
db ed expat flex gettext gmp gnugrep groff libedit libidn2 libkrb5 libssh2 libtool db ed expat flex gettext gmp gnugrep groff libedit libidn2 libkrb5 libssh2 libtool
libunistring m4 nghttp2 ninja openbsm openldap openpam openssh openssl patchutils pbzx libunistring m4 nghttp2 ninja openbsm openldap openpam openssh openssl patchutils pbzx
perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite subversion perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite subversion
@ -1033,7 +1047,7 @@ in
]); ]);
assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [ assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [
binutils-unwrapped icu libffi libiconv libxml2 zlib bash binutils-unwrapped icu libffi libiconv libxml2 zlib
]); ]);
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage.darwin; [ assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage.darwin; [
@ -1060,7 +1074,7 @@ in
overrides = self: super: { overrides = self: super: {
inherit (prevStage) ccWrapperStdenv inherit (prevStage) ccWrapperStdenv
autoconf automake bison cmake cmakeMinimal cpio cyrus_sasl db expat flex groff autoconf automake bash bison cmake cmakeMinimal cpio cyrus_sasl db expat flex groff
libedit libtool m4 ninja openldap openssh patchutils pbzx perl pkg-config python3 libedit libtool m4 ninja openldap openssh patchutils pbzx perl pkg-config python3
python3Minimal scons serf sqlite subversion sysctl texinfo unzip which python3Minimal scons serf sqlite subversion sysctl texinfo unzip which