about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2024-01-20 12:31:50 +0100
committerAlyssa Ross <hi@alyssa.is>2024-01-20 12:32:25 +0100
commitb7baf40e099b4215181fe7b0c63083b12ef2c7fb (patch)
treea6efabd31d05b6d0a36624729e80377bbbfb0149 /nixpkgs/pkgs/build-support
parent710028664e26e85cb831a869b3da9f6993902255 (diff)
parent0799f514b1cd74878174939df79ac60ca5036673 (diff)
downloadnixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar
nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.gz
nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.bz2
nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.lz
nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.xz
nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.zst
nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.zip
Merge branch 'nixos-unstable-small' of https://github.com/NixOS/nixpkgs
Conflicts:
	nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
Diffstat (limited to 'nixpkgs/pkgs/build-support')
-rw-r--r--nixpkgs/pkgs/build-support/alternatives/blas/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/alternatives/lapack/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/bintools-wrapper/default.nix25
-rw-r--r--nixpkgs/pkgs/build-support/bintools-wrapper/setup-hook.sh2
-rw-r--r--nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/default.nix16
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh2
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/default.nix36
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh3
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh2
-rw-r--r--nixpkgs/pkgs/build-support/checkpoint-build.nix79
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix10
-rw-r--r--nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix2
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh4
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh2
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix44
-rw-r--r--nixpkgs/pkgs/build-support/emacs/melpa.nix4
-rw-r--r--nixpkgs/pkgs/build-support/emacs/melpa2nix.el26
-rw-r--r--nixpkgs/pkgs/build-support/emacs/package-build-dont-use-mtime.patch43
-rw-r--r--nixpkgs/pkgs/build-support/fetchgithub/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/fetchurl/mirrors.nix1
-rw-r--r--nixpkgs/pkgs/build-support/fetchzip/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock12
-rw-r--r--nixpkgs/pkgs/build-support/mkshell/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/oci-tools/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix2
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix3
-rw-r--r--nixpkgs/pkgs/build-support/rust/hooks/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh2
-rw-r--r--nixpkgs/pkgs/build-support/rust/lib/default.nix26
-rw-r--r--nixpkgs/pkgs/build-support/rust/rustc-wrapper/rustc-wrapper.sh15
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh31
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/default.nix541
33 files changed, 512 insertions, 449 deletions
diff --git a/nixpkgs/pkgs/build-support/alternatives/blas/default.nix b/nixpkgs/pkgs/build-support/alternatives/blas/default.nix
index fec2d0526bb3..91001bc85377 100644
--- a/nixpkgs/pkgs/build-support/alternatives/blas/default.nix
+++ b/nixpkgs/pkgs/build-support/alternatives/blas/default.nix
@@ -80,7 +80,7 @@ stdenv.mkDerivation {
   cp -L "$libblas" $out/lib/libblas${canonicalExtension}
   chmod +w $out/lib/libblas${canonicalExtension}
 
-'' + (if stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf" then ''
+'' + (if stdenv.hostPlatform.isElf then ''
   patchelf --set-soname libblas${canonicalExtension} $out/lib/libblas${canonicalExtension}
   patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libblas${canonicalExtension}):${lib.getLib blasProvider'}/lib" $out/lib/libblas${canonicalExtension}
 '' else lib.optionalString (stdenv.hostPlatform.isDarwin) ''
@@ -112,7 +112,7 @@ EOF
   cp -L "$libcblas" $out/lib/libcblas${canonicalExtension}
   chmod +w $out/lib/libcblas${canonicalExtension}
 
-'' + (if stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf" then ''
+'' + (if stdenv.hostPlatform.isElf then ''
   patchelf --set-soname libcblas${canonicalExtension} $out/lib/libcblas${canonicalExtension}
   patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libcblas${canonicalExtension}):${lib.getLib blasProvider'}/lib" $out/lib/libcblas${canonicalExtension}
 '' else lib.optionalString stdenv.hostPlatform.isDarwin ''
diff --git a/nixpkgs/pkgs/build-support/alternatives/lapack/default.nix b/nixpkgs/pkgs/build-support/alternatives/lapack/default.nix
index cbc7bf25c797..2d62855b258a 100644
--- a/nixpkgs/pkgs/build-support/alternatives/lapack/default.nix
+++ b/nixpkgs/pkgs/build-support/alternatives/lapack/default.nix
@@ -57,7 +57,7 @@ stdenv.mkDerivation {
   cp -L "$liblapack" $out/lib/liblapack${canonicalExtension}
   chmod +w $out/lib/liblapack${canonicalExtension}
 
-'' + (lib.optionalString (stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf") ''
+'' + (lib.optionalString stdenv.hostPlatform.isElf ''
   patchelf --set-soname liblapack${canonicalExtension} $out/lib/liblapack${canonicalExtension}
   patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapack${canonicalExtension}):${lapackProvider'}/lib" $out/lib/liblapack${canonicalExtension}
 '') + ''
@@ -86,7 +86,7 @@ EOF
   cp -L "$liblapacke" $out/lib/liblapacke${canonicalExtension}
   chmod +w $out/lib/liblapacke${canonicalExtension}
 
-'' + (lib.optionalString (stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf") ''
+'' + (lib.optionalString stdenv.hostPlatform.isElf ''
   patchelf --set-soname liblapacke${canonicalExtension} $out/lib/liblapacke${canonicalExtension}
   patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapacke${canonicalExtension}):${lib.getLib lapackProvider'}/lib" $out/lib/liblapacke${canonicalExtension}
 '') + ''
diff --git a/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix b/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
index 525b44fe0480..5b185b09a4c5 100644
--- a/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
@@ -33,6 +33,28 @@
 , useMacosReexportHack ? false
 , wrapGas ? false
 
+# Note: the hardening flags are part of the bintools-wrapper, rather than
+# the cc-wrapper, because a few of them are handled by the linker.
+, defaultHardeningFlags ? with stdenvNoCC; [
+    "bindnow"
+    "format"
+    "fortify"
+    "fortify3"
+    "pic"
+    "relro"
+    "stackprotector"
+    "strictoverflow"
+  ] ++ lib.optional (
+    # Musl-based platforms will keep "pie", other platforms will not.
+    # If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}`
+    # in the nixpkgs manual to inform users about the defaults.
+    targetPlatform.libc == "musl"
+    # Except when:
+    #    - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries.
+    #    - static armv7l, where compilation fails.
+    && !(targetPlatform.isAarch && targetPlatform.isStatic)
+  ) "pie"
+
 # Darwin code signing support utilities
 , postLinkSignHook ? null, signingUtils ? null
 }:
@@ -124,6 +146,8 @@ stdenv.mkDerivation {
             (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib64"))))
         '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
     '';
+
+    inherit defaultHardeningFlags;
   };
 
   dontBuild = true;
@@ -380,6 +404,7 @@ stdenv.mkDerivation {
     wrapperName = "BINTOOLS_WRAPPER";
     inherit dynamicLinker targetPrefix suffixSalt coreutils_bin;
     inherit bintools_bin libc_bin libc_dev libc_lib;
+    default_hardening_flags_str = builtins.toString defaultHardeningFlags;
   };
 
   meta =
diff --git a/nixpkgs/pkgs/build-support/bintools-wrapper/setup-hook.sh b/nixpkgs/pkgs/build-support/bintools-wrapper/setup-hook.sh
index 7e9547b96c25..c146cbea80e4 100644
--- a/nixpkgs/pkgs/build-support/bintools-wrapper/setup-hook.sh
+++ b/nixpkgs/pkgs/build-support/bintools-wrapper/setup-hook.sh
@@ -65,7 +65,7 @@ do
 done
 
 # If unset, assume the default hardening flags.
-: ${NIX_HARDENING_ENABLE="fortify stackprotector pic strictoverflow format relro bindnow"}
+: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"}
 export NIX_HARDENING_ENABLE
 
 # No local scope in sourced file
diff --git a/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/default.nix b/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/default.nix
index e13288371b5d..3292f4039a63 100644
--- a/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/default.nix
+++ b/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/default.nix
@@ -191,7 +191,21 @@ let
     # sddm places XAUTHORITY in /tmp
     if [[ "$XAUTHORITY" == /tmp/* ]]; then
       x11_args+=(--ro-bind-try "$XAUTHORITY" "$XAUTHORITY")
-    fi''}
+    fi
+
+    # dbus-run-session puts the socket in /tmp
+    IFS=";" read -ra addrs <<<"$DBUS_SESSION_BUS_ADDRESS"
+    for addr in "''${addrs[@]}"; do
+      [[ "$addr" == unix:* ]] || continue
+      IFS="," read -ra parts <<<"''${addr#unix:}"
+      for part in "''${parts[@]}"; do
+        printf -v part '%s' "''${part//\\/\\\\}"
+        printf -v part '%b' "''${part//%/\\x}"
+        [[ "$part" == path=/tmp/* ]] || continue
+        x11_args+=(--ro-bind-try "''${part#path=}" "''${part#path=}")
+      done
+    done
+    ''}
 
     cmd=(
       ${bubblewrap}/bin/bwrap
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh b/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh
index 8cd63e460951..2eae278da160 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh
@@ -32,7 +32,7 @@ if [[ -n "${hardeningEnableMap[fortify3]-}" ]]; then
 fi
 
 if (( "${NIX_DEBUG:-0}" >= 1 )); then
-  declare -a allHardeningFlags=(fortify stackprotector pie pic strictoverflow format)
+  declare -a allHardeningFlags=(fortify fortify3 stackprotector pie pic strictoverflow format)
   declare -A hardeningDisableMap=()
 
   # Determine which flags were effectively disabled so we can report below.
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/default.nix b/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
index 539c29a0a774..0b25d70b14a2 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
@@ -110,6 +110,9 @@ let
   gccForLibs_solib = getLib gccForLibs
     + optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}";
 
+  # Analogously to cc_solib and gccForLibs_solib
+  libcxx_solib = "${lib.getLib libcxx}/lib";
+
   # The following two functions, `isGccArchSupported` and
   # `isGccTuneSupported`, only handle those situations where a flag
   # (`-march` or `-mtune`) is accepted by one compiler but rejected
@@ -218,6 +221,8 @@ let
        then guess
        else null;
 
+  defaultHardeningFlags = bintools.defaultHardeningFlags or [];
+
   darwinPlatformForCC = optionalString stdenv.targetPlatform.isDarwin (
     if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx"
     else targetPlatform.darwinPlatform
@@ -259,6 +264,25 @@ stdenv.mkDerivation {
     inherit bintools;
     inherit cc libc libcxx nativeTools nativeLibc nativePrefix isGNU isClang;
 
+    # Expose the C++ standard library we're using. See the comments on "General
+    # libc++ support". This is also relevant when using older gcc than the
+    # stdenv's, as may be required e.g. by CUDAToolkit's nvcc.
+    cxxStdlib =
+      let
+        givenLibcxx = libcxx.isLLVM or false;
+        givenGccForLibs = useGccForLibs && gccForLibs.langCC or false;
+      in
+      if (!givenLibcxx) && givenGccForLibs then
+        { kind = "libstdc++"; package = gccForLibs; solib = gccForLibs_solib; }
+      else if givenLibcxx then
+        { kind = "libc++"; package = libcxx;  solib = libcxx_solib;}
+      else
+      # We're probably using the `libstdc++` that came with our `gcc`.
+      # TODO: this is maybe not always correct?
+      # TODO: what happens when `nativeTools = true`?
+        { kind = "libstdc++"; package = cc; solib = cc_solib; }
+    ;
+
     emacsBufferSetup = pkgs: ''
       ; We should handle propagation here too
       (mapc
@@ -271,6 +295,8 @@ stdenv.mkDerivation {
     inherit expand-response-params;
 
     inherit nixSupport;
+
+    inherit defaultHardeningFlags;
   };
 
   dontBuild = true;
@@ -436,6 +462,13 @@ stdenv.mkDerivation {
       echo "-L${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-ldflags
       echo "-L${gccForLibs_solib}/lib" >> $out/nix-support/cc-ldflags
     ''
+    # The above "fix" may be incorrect; gcc.cc.lib doesn't contain a
+    # `target-triple` dir but the correct fix may be to just remove the above?
+    #
+    # For clang it's not necessary (see `--gcc-toolchain` below) and for other
+    # situations adding in the above will bring in lots of other gcc libraries
+    # (i.e. sanitizer libraries, `libatomic`, `libquadmath`) besides just
+    # `libstdc++`; this may actually break clang.
 
     # TODO We would like to connect this to `useGccForLibs`, but we cannot yet
     # because `libcxxStdenv` on linux still needs this. Maybe someday we'll
@@ -560,7 +593,7 @@ stdenv.mkDerivation {
       echo "$ccLDFlags" >> $out/nix-support/cc-ldflags
       echo "$ccCFlags" >> $out/nix-support/cc-cflags
     '' + optionalString (targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false)) ''
-      echo " -L${lib.getLib libcxx}/lib" >> $out/nix-support/cc-ldflags
+      echo " -L${libcxx_solib}" >> $out/nix-support/cc-ldflags
     ''
 
     ##
@@ -706,6 +739,7 @@ stdenv.mkDerivation {
     inherit suffixSalt coreutils_bin bintools;
     inherit libc_bin libc_dev libc_lib;
     inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable;
+    default_hardening_flags_str = builtins.toString defaultHardeningFlags;
   };
 
   meta =
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh b/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh
index d72f314c01ce..02da7fd0dc34 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh
@@ -4,8 +4,7 @@ getTargetRoleWrapper
 export FC${role_post}=@named_fc@
 
 # If unset, assume the default hardening flags.
-# These are different for fortran.
-: ${NIX_HARDENING_ENABLE="stackprotector pic strictoverflow relro bindnow"}
+: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"}
 export NIX_HARDENING_ENABLE
 
 unset -v role_post
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh b/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh
index 9326d76e2a8f..33a2b62a49b0 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh
@@ -111,7 +111,7 @@ export CC${role_post}=@named_cc@
 export CXX${role_post}=@named_cxx@
 
 # If unset, assume the default hardening flags.
-: ${NIX_HARDENING_ENABLE="fortify fortify3 stackprotector pic strictoverflow format relro bindnow"}
+: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"}
 export NIX_HARDENING_ENABLE
 
 # No local scope in sourced file
diff --git a/nixpkgs/pkgs/build-support/checkpoint-build.nix b/nixpkgs/pkgs/build-support/checkpoint-build.nix
index e08dde353e89..c9bee45005a1 100644
--- a/nixpkgs/pkgs/build-support/checkpoint-build.nix
+++ b/nixpkgs/pkgs/build-support/checkpoint-build.nix
@@ -1,40 +1,53 @@
-{ pkgs }:
+{ lib
+, buildPackages
+}:
+
+let
+  # rudimentary support for cross-compiling
+  # see: https://github.com/NixOS/nixpkgs/pull/279487#discussion_r1444449726
+  inherit (buildPackages)
+    mktemp
+    rsync
+    ;
+in
+
 rec {
   /* Prepare a derivation for local builds.
     *
-    * This function prepares checkpoint builds by provinding,
-    * containing the build output and the sources for cross checking.
+    * This function prepares checkpoint builds by storing
+    * the build output and the sources for cross checking.
     * The build output can be used later to allow checkpoint builds
     * by passing the derivation output to the `mkCheckpointBuild` function.
     *
-    * To build a project with checkpoints follow these steps:
-    * - run prepareIncrementalBuild on the desired derivation
-    *   e.G `incrementalBuildArtifacts = (pkgs.checkpointBuildTools.prepareCheckpointBuild pkgs.virtualbox);`
-    * - change something you want in the sources of the package( e.G using source override)
-    *   changedVBox = pkgs.virtuabox.overrideAttrs (old: {
-    *      src = path/to/vbox/sources;
-    *   }
-    * - use `mkCheckpointedBuild changedVBox buildOutput`
+    * To build a project with checkpoints, follow these steps:
+    * - run `prepareCheckpointBuild` on the desired derivation, e.g.
+    *     checkpointArtifacts = prepareCheckpointBuild virtualbox;
+    * - change something you want in the sources of the package,
+    *   e.g. using source override:
+    *     changedVBox = pkgs.virtuabox.overrideAttrs (old: {
+    *       src = path/to/vbox/sources;
+    *     };
+    * - use `mkCheckpointBuild changedVBox checkpointArtifacts`
     * - enjoy shorter build times
   */
   prepareCheckpointBuild = drv: drv.overrideAttrs (old: {
     outputs = [ "out" ];
     name = drv.name + "-checkpointArtifacts";
     # To determine differences between the state of the build directory
-    # from an earlier build and  a later one we store the state of the build
+    # from an earlier build and a later one we store the state of the build
     # directory before build, but after patch phases.
     # This way, the same derivation can be used multiple times and only changes are detected.
-    # Additionally Removed files are handled correctly in later builds.
+    # Additionally, removed files are handled correctly in later builds.
     preBuild = (old.preBuild or "") + ''
       mkdir -p $out/sources
       cp -r ./* $out/sources/
     '';
 
-    # After the build the build directory is copied again
+    # After the build, the build directory is copied again
     # to get the output files.
-    # We copy the complete build folder, to take care for
-    # Build tools, building in the source directory, instead of
-    # having a build root directory, e.G the Linux kernel.
+    # We copy the complete build folder, to take care of
+    # build tools that build in the source directory, instead of
+    # having a separate build directory such as the Linux kernel.
     installPhase = ''
       runHook preCheckpointInstall
       mkdir -p $out/outputs
@@ -44,26 +57,34 @@ rec {
   });
 
   /* Build a derivation based on the checkpoint output generated by
-    * the `prepareCheckpointBuild function.
+    * the `prepareCheckpointBuild` function.
     *
     * Usage:
     * let
-    *   checkpointArtifacts = prepareCheckpointBuild drv
-    * in mkCheckpointedBuild drv checkpointArtifacts
+    *   checkpointArtifacts = prepareCheckpointBuild drv;
+    * in mkCheckpointBuild drv checkpointArtifacts
   */
-  mkCheckpointedBuild = drv: previousBuildArtifacts: drv.overrideAttrs (old: {
+  mkCheckpointBuild = drv: checkpointArtifacts: drv.overrideAttrs (old: {
     # The actual checkpoint build phase.
-    # We compare the changed sources from a previous build with the current and create a patch
-    # Afterwards we clean the build directory to copy the previous output files (Including the sources)
-    # The source difference patch is applied to get the latest changes again to allow short build times.
+    # We compare the changed sources from a previous build with the current and create a patch.
+    # Afterwards we clean the build directory and copy the previous output files (including the sources).
+    # The source difference patch is then applied to get the latest changes again to allow short build times.
     preBuild = (old.preBuild or "") + ''
       set +e
-      diff -ur ${previousBuildArtifacts}/sources ./ > sourceDifference.patch
+      sourceDifferencePatchFile=$(${mktemp}/bin/mktemp)
+      diff -ur ${checkpointArtifacts}/sources ./ > "$sourceDifferencePatchFile"
       set -e
-      shopt -s extglob dotglob
-      rm -r !("sourceDifference.patch")
-      ${pkgs.rsync}/bin/rsync -cutU --chown=$USER:$USER --chmod=+w -r ${previousBuildArtifacts}/outputs/* .
-      patch -p 1 -i sourceDifference.patch
+      shopt -s dotglob
+      rm -r *
+      ${rsync}/bin/rsync \
+        --checksum --times --atimes --chown=$USER:$USER --chmod=+w \
+        -r ${checkpointArtifacts}/outputs/ .
+      patch -p 1 -i "$sourceDifferencePatchFile"
+      rm "$sourceDifferencePatchFile"
     '';
   });
+
+  mkCheckpointedBuild = lib.warn
+    "`mkCheckpointedBuild` is deprecated, use `mkCheckpointBuild` instead!"
+    mkCheckpointBuild;
 }
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix b/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
index e8e6bd16b168..f9a49fec3a2d 100644
--- a/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
@@ -1,6 +1,7 @@
 { lib
 , stdenv
 , callPackage
+, runCommand
 , writeText
 , pub2nix
 , dartHooks
@@ -9,6 +10,7 @@
 , nodejs
 , darwin
 , jq
+, yq
 }:
 
 { src
@@ -44,7 +46,13 @@
 
 , runtimeDependencies ? [ ]
 , extraWrapProgramArgs ? ""
-, pubspecLock
+
+, autoPubspecLock ? null
+, pubspecLock ? if autoPubspecLock == null then
+    throw "The pubspecLock argument is required. If import-from-derivation is allowed (it isn't in Nixpkgs), you can set autoPubspecLock to the path to a pubspec.lock instead."
+  else
+    assert lib.assertMsg (builtins.pathExists autoPubspecLock) "The pubspec.lock file could not be found!";
+    lib.importJSON (runCommand "${lib.getName args}-pubspec-lock-json" { nativeBuildInputs = [ yq ]; } ''yq . '${autoPubspecLock}' > "$out"'')
 , ...
 }@args:
 
diff --git a/nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix b/nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix
index 309e51ec84a1..70abb0a76cef 100644
--- a/nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix
+++ b/nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix
@@ -41,7 +41,7 @@ in
     fi
 
     languageConstraint="$(yq -r .environment.sdk "''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml")"
-    if [[ "$languageConstraint" =~ ^[[:space:]]*(\^|>=|>|)[[:space:]]*([[:digit:]]+\.[[:digit:]]+)\.[[:digit:]]+.*$ ]]; then
+    if [[ "$languageConstraint" =~ ^[[:space:]]*(\^|>=|>)?[[:space:]]*([[:digit:]]+\.[[:digit:]]+)\.[[:digit:]]+.*$ ]]; then
       languageVersionJson="\"''${BASH_REMATCH[2]}\""
     elif [ "$languageConstraint" = 'any' ]; then
       languageVersionJson='null'
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
index 573b270ee408..af960fb1d617 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
@@ -37,7 +37,7 @@
 
   # The path to publish the project to. When unset, the directory "$out/lib/$pname" is used.
 , installPath ? null
-  # The binaries that should get installed to `$out/bin`, relative to `$out/lib/$pname/`. These get wrapped accordingly.
+  # The binaries that should get installed to `$out/bin`, relative to `$installPath/`. These get wrapped accordingly.
   # Unfortunately, dotnet has no method for doing this automatically.
   # If unset, all executables in the projects root will get installed. This may cause bloat!
 , executables ? null
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh
index 4fec939bed33..97dd15c17dcf 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh
@@ -32,7 +32,7 @@ dotnetFixupHook() {
 
     if [ "${executables-}" ]; then
         for executable in ${executables[@]}; do
-            path="$out/lib/$pname/$executable"
+            path="${installPath-$out/lib/$pname}/$executable"
 
             if test -x "$path"; then
                 wrapDotnetProgram "$path" "$out/bin/$(basename "$executable")"
@@ -45,7 +45,7 @@ dotnetFixupHook() {
     else
         while IFS= read -d '' executable; do
             wrapDotnetProgram "$executable" "$out/bin/$(basename "$executable")" \;
-        done < <(find "$out/lib/$pname" ! -name "*.dll" -executable -type f -print0)
+        done < <(find "${installPath-$out/lib/$pname}" ! -name "*.dll" -executable -type f -print0)
     fi
 
     echo "Finished dotnetFixupPhase"
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh
index 3f2a89c41404..d832eac28809 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh
@@ -30,7 +30,7 @@ dotnetInstallHook() {
         env dotnet publish ${project-} \
             -p:ContinuousIntegrationBuild=true \
             -p:Deterministic=true \
-            --output "$out/lib/${pname}" \
+            --output "${installPath-$out/lib/$pname}" \
             --configuration "@buildType@" \
             --no-build \
             ${runtimeIdFlags[@]} \
diff --git a/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix b/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
index 48de65e8a881..4cf9c1a7412a 100644
--- a/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
@@ -3,36 +3,26 @@
 { name
 , description ? ""
 , deps ? []
-}:
+, ...
+}@args:
 
-let
-  nuget-source = stdenvNoCC.mkDerivation {
-    inherit name;
+stdenvNoCC.mkDerivation (lib.recursiveUpdate {
+  inherit name;
 
-    nativeBuildInputs = [ python3 ];
+  nativeBuildInputs = [ python3 ];
 
-    buildCommand = ''
-      mkdir -p $out/{lib,share}
+  buildCommand = ''
+    mkdir -p $out/{lib,share}
 
-      # use -L to follow symbolic links. When `projectReferences` is used in
-      # buildDotnetModule, one of the deps will be a symlink farm.
-      find -L ${lib.concatStringsSep " " deps} -type f -name '*.nupkg' -exec \
-        ln -s '{}' -t $out/lib ';'
+    # use -L to follow symbolic links. When `projectReferences` is used in
+    # buildDotnetModule, one of the deps will be a symlink farm.
+    find -L ${lib.concatStringsSep " " deps} -type f -name '*.nupkg' -exec \
+      ln -s '{}' -t $out/lib ';'
 
-      # Generates a list of all licenses' spdx ids, if available.
-      # Note that this currently ignores any license provided in plain text (e.g. "LICENSE.txt")
-      python ${./extract-licenses-from-nupkgs.py} $out/lib > $out/share/licenses
-    '';
+    # Generates a list of all licenses' spdx ids, if available.
+    # Note that this currently ignores any license provided in plain text (e.g. "LICENSE.txt")
+    python ${./extract-licenses-from-nupkgs.py} $out/lib > $out/share/licenses
+  '';
 
-    meta.description = description;
-  } // { # We need data from `$out` for `meta`, so we have to use overrides as to not hit infinite recursion.
-    meta = nuget-source.meta // {
-      licenses = let
-        # TODO: avoid IFD
-        depLicenses = lib.splitString "\n" (builtins.readFile "${nuget-source}/share/licenses");
-      in lib.flatten (lib.forEach depLicenses (spdx:
-        lib.optionals (spdx != "") (lib.getLicenseFromSpdxId spdx)
-      ));
-    };
-  };
-in nuget-source
+  meta.description = description;
+} (removeAttrs args [ "name" "description" "deps" ]))
diff --git a/nixpkgs/pkgs/build-support/emacs/melpa.nix b/nixpkgs/pkgs/build-support/emacs/melpa.nix
index 178f532d0871..323c6e65d9d9 100644
--- a/nixpkgs/pkgs/build-support/emacs/melpa.nix
+++ b/nixpkgs/pkgs/build-support/emacs/melpa.nix
@@ -11,8 +11,8 @@ let
     src = fetchFromGitHub {
       owner = "melpa";
       repo = "package-build";
-      rev = "c3c535e93d9dc92acd21ebc4b15016b5c3b90e7d";
-      sha256 = "17z0wbqdd6fspbj43yq8biff6wfggk74xgnaf1xx6ynsp1i74is5";
+      rev = "c48aa078c01b4f07b804270c4583a0a58ffea1c0";
+      sha256 = "sha256-MzPj375upIiYXdQR+wWXv3A1zMqbSrZlH0taLuxx/1M=";
     };
 
     patches = [ ./package-build-dont-use-mtime.patch ];
diff --git a/nixpkgs/pkgs/build-support/emacs/melpa2nix.el b/nixpkgs/pkgs/build-support/emacs/melpa2nix.el
index 72667dea652c..3de77dbf5e5c 100644
--- a/nixpkgs/pkgs/build-support/emacs/melpa2nix.el
+++ b/nixpkgs/pkgs/build-support/emacs/melpa2nix.el
@@ -11,22 +11,22 @@
 ;; Allow installing package tarfiles larger than 10MB
 (setq large-file-warning-threshold nil)
 
-(defun melpa2nix-build-package-1 (rcp version commit)
-  (let ((source-dir (package-recipe--working-tree rcp)))
+(defun melpa2nix-build-package-1 (rcp)
+  (let* ((default-directory (package-recipe--working-tree rcp)))
     (unwind-protect
         (let ((files (package-build-expand-files-spec rcp t)))
-          (cond
-           ((= (length files) 1)
-            (package-build--build-single-file-package
-             rcp version commit files source-dir))
-           ((> (length files) 1)
-            (package-build--build-multi-file-package
-             rcp version commit files source-dir))
-           (t (error "Unable to find files matching recipe patterns")))))))
+          (unless files
+            (error "Unable to find files matching recipe patterns"))
+          (if (> (length files) 1)
+              (package-build--build-multi-file-package rcp files)
+            (package-build--build-single-file-package rcp files))))))
 
 (defun melpa2nix-build-package ()
-  (if (not noninteractive)
-      (error "`melpa2nix-build-package' is to be used only with -batch"))
+  (unless noninteractive
+    (error "`melpa2nix-build-package' is to be used only with -batch"))
   (pcase command-line-args-left
     (`(,package ,version ,commit)
-     (melpa2nix-build-package-1 (package-recipe-lookup package) version commit))))
+     (let ((recipe (package-recipe-lookup package)))
+       (setf (oref recipe commit) commit)
+       (setf (oref recipe version) version)
+       (melpa2nix-build-package-1 recipe)))))
diff --git a/nixpkgs/pkgs/build-support/emacs/package-build-dont-use-mtime.patch b/nixpkgs/pkgs/build-support/emacs/package-build-dont-use-mtime.patch
index fe94de57a300..1ace7771ea3a 100644
--- a/nixpkgs/pkgs/build-support/emacs/package-build-dont-use-mtime.patch
+++ b/nixpkgs/pkgs/build-support/emacs/package-build-dont-use-mtime.patch
@@ -1,40 +1,21 @@
 diff --git a/package-build.el b/package-build.el
-index e572045..9eb0f82 100644
+index 29cdb61..c19be1b 100644
 --- a/package-build.el
 +++ b/package-build.el
-@@ -415,7 +415,7 @@ (defun package-build--write-pkg-file (desc dir)
-       (princ ";; Local Variables:\n;; no-byte-compile: t\n;; End:\n"
-              (current-buffer)))))
- 
--(defun package-build--create-tar (name version directory mtime)
-+(defun package-build--create-tar (name version directory)
-   "Create a tar file containing the contents of VERSION of package NAME.
- DIRECTORY is a temporary directory that contains the directory
- that is put in the tarball.  MTIME is used as the modification
-@@ -434,7 +434,7 @@ (defun package-build--create-tar (name version directory mtime)
-        ;; prevent a reproducable tarball as described at
+@@ -923,7 +923,6 @@ DIRECTORY is a temporary directory that contains the directory
+ that is put in the tarball."
+   (let* ((name (oref rcp name))
+          (version (oref rcp version))
+-         (time (oref rcp time))
+          (tar (expand-file-name (concat name "-" version ".tar")
+                                 package-build-archive-dir))
+          (dir (concat name "-" version)))
+@@ -939,7 +938,7 @@ that is put in the tarball."
+        ;; prevent a reproducible tarball as described at
         ;; https://reproducible-builds.org/docs/archives.
         "--sort=name"
--       (format "--mtime=@%d" mtime)
+-       (format "--mtime=@%d" time)
 +       "--mtime=@0"
         "--owner=0" "--group=0" "--numeric-owner"
         "--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime"))
      (when (and package-build-verbose noninteractive)
-@@ -848,12 +848,11 @@ (defun package-build--build-multi-file-package (rcp version commit files source-
-                            (package-build--desc-from-library
-                             name version commit files 'tar)
-                            (error "%s[-pkg].el matching package name is missing"
--                                  name))))
--               (mtime (package-build--get-commit-time rcp commit)))
-+                                  name)))))
-           (package-build--copy-package-files files source-dir target)
-           (package-build--write-pkg-file desc target)
-           (package-build--generate-info-files files source-dir target)
--          (package-build--create-tar name version tmp-dir mtime)
-+          (package-build--create-tar name version tmp-dir)
-           (package-build--write-pkg-readme name files source-dir)
-           (package-build--write-archive-entry desc))
-       (delete-directory tmp-dir t nil))))
--- 
-2.37.2
-
diff --git a/nixpkgs/pkgs/build-support/fetchgithub/default.nix b/nixpkgs/pkgs/build-support/fetchgithub/default.nix
index a2498700b545..37f7dcfa3006 100644
--- a/nixpkgs/pkgs/build-support/fetchgithub/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchgithub/default.nix
@@ -19,7 +19,7 @@ let
   baseUrl = "https://${githubBase}/${owner}/${repo}";
   newMeta = meta // {
     homepage = meta.homepage or baseUrl;
-
+  } // lib.optionalAttrs (position != null) {
     # to indicate where derivation originates, similar to make-derivation.nix's mkDerivation
     position = "${position.file}:${toString position.line}";
   };
@@ -28,7 +28,7 @@ let
   useFetchGit = fetchSubmodules || (leaveDotGit == true) || deepClone || forceFetchGit || (sparseCheckout != []);
   # We prefer fetchzip in cases we don't need submodules as the hash
   # is more stable in that case.
-  fetcher = if useFetchGit then fetchgit else fetchzip;
+  fetcher = if useFetchGit then fetchgit else fetchzip.override { withUnzip = false; };
   privateAttrs = lib.optionalAttrs private {
     netrcPhase = ''
       if [ -z "''$${varBase}USERNAME" -o -z "''$${varBase}PASSWORD" ]; then
diff --git a/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix b/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
index 2546b8e6dc99..af0468b3e494 100644
--- a/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
+++ b/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
@@ -125,6 +125,7 @@
 
   # Mirrors from https://download.kde.org/ls-lR.mirrorlist
   kde = [
+    "https://cdn.download.kde.org/"
     "https://download.kde.org/download.php?url="
     "https://ftp.gwdg.de/pub/linux/kde/"
     "https://mirrors.ocf.berkeley.edu/kde/"
diff --git a/nixpkgs/pkgs/build-support/fetchzip/default.nix b/nixpkgs/pkgs/build-support/fetchzip/default.nix
index 6e6c5270a750..dd04ccb6e093 100644
--- a/nixpkgs/pkgs/build-support/fetchzip/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchzip/default.nix
@@ -5,7 +5,7 @@
 # (e.g. due to minor changes in the compression algorithm, or changes
 # in timestamps).
 
-{ lib, fetchurl, unzip, glibcLocalesUtf8 }:
+{ lib, fetchurl, withUnzip ? true, unzip, glibcLocalesUtf8 }:
 
 { name ? "source"
 , url ? ""
@@ -42,7 +42,7 @@ fetchurl ({
   # Have to pull in glibcLocalesUtf8 for unzip in setup-hook.sh to handle
   # UTF-8 aware locale:
   #   https://github.com/NixOS/nixpkgs/issues/176225#issuecomment-1146617263
-  nativeBuildInputs = [ unzip glibcLocalesUtf8 ] ++ nativeBuildInputs;
+  nativeBuildInputs = lib.optionals withUnzip [ unzip glibcLocalesUtf8 ] ++ nativeBuildInputs;
 
   postFetch =
     ''
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock
index 1546456a3a85..961c5a3c1ab6 100644
--- a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock
@@ -57,18 +57,18 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.73"
+version = "1.0.76"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1"
+checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.34"
+version = "1.0.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
 dependencies = [
  "proc-macro2",
 ]
@@ -95,9 +95,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.44"
+version = "2.0.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d27c2c202598d05175a6dd3af46824b7f747f8d8e9b14c623f19fa5069735d"
+checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/nixpkgs/pkgs/build-support/mkshell/default.nix b/nixpkgs/pkgs/build-support/mkshell/default.nix
index 3517e949f67a..5369301ea105 100644
--- a/nixpkgs/pkgs/build-support/mkshell/default.nix
+++ b/nixpkgs/pkgs/build-support/mkshell/default.nix
@@ -16,6 +16,10 @@
 let
   mergeInputs = name:
     (attrs.${name} or [ ]) ++
+    # 1. get all `{build,nativeBuild,...}Inputs` from the elements of `inputsFrom`
+    # 2. since that is a list of lists, `flatten` that into a regular list
+    # 3. filter out of the result everything that's in `inputsFrom` itself
+    # this leaves actual dependencies of the derivations in `inputsFrom`, but never the derivations themselves
     (lib.subtractLists inputsFrom (lib.flatten (lib.catAttrs name inputsFrom)));
 
   rest = builtins.removeAttrs attrs [
diff --git a/nixpkgs/pkgs/build-support/oci-tools/default.nix b/nixpkgs/pkgs/build-support/oci-tools/default.nix
index 18b238033ffd..67e081522d64 100644
--- a/nixpkgs/pkgs/build-support/oci-tools/default.nix
+++ b/nixpkgs/pkgs/build-support/oci-tools/default.nix
@@ -42,7 +42,7 @@
       "/sys/fs/cgroup" = {
         type = "cgroup";
         source = "cgroup";
-        options = [ "nosuid" "noexec" "nodev" "realatime" "ro" ];
+        options = [ "nosuid" "noexec" "nodev" "relatime" "ro" ];
       };
     };
     config = writeText "config.json" (builtins.toJSON {
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
index e842b6a3f501..bbb26606a6a4 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
@@ -51,7 +51,7 @@
     # configure & source common build functions
     LIB_RUSTC_OPTS="${libRustcOpts}"
     BIN_RUSTC_OPTS="${binRustcOpts}"
-    LIB_EXT="${stdenv.hostPlatform.extensions.sharedLibrary}"
+    LIB_EXT="${stdenv.hostPlatform.extensions.sharedLibrary or ""}"
     LIB_PATH="${libPath}"
     LIB_NAME="${libName}"
 
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
index 8707ce084705..bac77b2d893f 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
@@ -46,7 +46,8 @@ let
     , buildFeatures ? [ ]
     , checkFeatures ? buildFeatures
     , useNextest ? false
-    , auditable ? !cargo-auditable.meta.broken
+    # Enable except on aarch64 pkgsStatic, where we use lld for reasons
+    , auditable ? !cargo-auditable.meta.broken && !(stdenv.hostPlatform.isStatic && stdenv.hostPlatform.isAarch64 && !stdenv.hostPlatform.isDarwin)
 
     , depsExtraArgs ? {}
 
diff --git a/nixpkgs/pkgs/build-support/rust/hooks/default.nix b/nixpkgs/pkgs/build-support/rust/hooks/default.nix
index 7703ff4abad4..874f23fe7ed3 100644
--- a/nixpkgs/pkgs/build-support/rust/hooks/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/hooks/default.nix
@@ -66,10 +66,10 @@
 
         cargoConfig = ''
           [target."${stdenv.buildPlatform.rust.rustcTarget}"]
-          "linker" = "${rust.envVars.ccForBuild}"
+          "linker" = "${rust.envVars.linkerForBuild}"
           ${lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) ''
             [target."${stdenv.hostPlatform.rust.rustcTarget}"]
-            "linker" = "${rust.envVars.ccForHost}"
+            "linker" = "${rust.envVars.linkerForHost}"
           ''}
           "rustflags" = [ "-C", "target-feature=${if stdenv.hostPlatform.isStatic then "+" else "-"}crt-static" ]
         '';
diff --git a/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh b/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh
index d5ff069290ba..028441d18160 100644
--- a/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh
+++ b/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh
@@ -25,7 +25,7 @@ maturinBuildHook() {
 
     # Move the wheel to dist/ so that regular Python tooling can find it.
     mkdir -p dist
-    mv target/wheels/*.whl dist/
+    mv ${cargoRoot:+$cargoRoot/}target/wheels/*.whl dist/
 
     # These are python build hooks and may depend on ./dist
     runHook postBuild
diff --git a/nixpkgs/pkgs/build-support/rust/lib/default.nix b/nixpkgs/pkgs/build-support/rust/lib/default.nix
index dad8ab528235..e70b8229d356 100644
--- a/nixpkgs/pkgs/build-support/rust/lib/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/lib/default.nix
@@ -12,10 +12,20 @@ rec {
   # hostPlatform-targeted compiler -- for example, `-m64` being
   # passed on a build=x86_64/host=aarch64 compilation.
   envVars = let
+
+    # As a workaround for https://github.com/rust-lang/rust/issues/89626 use lld on pkgsStatic aarch64
+    shouldUseLLD = platform: platform.isAarch64 && platform.isStatic && !stdenv.isDarwin;
+
     ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
     cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
+    linkerForBuild = ccForBuild;
+
     ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
     cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
+    linkerForHost = if shouldUseLLD stdenv.targetPlatform
+      && !stdenv.cc.bintools.isLLVM
+      then "${buildPackages.lld}/bin/ld.lld"
+      else ccForHost;
 
     # Unfortunately we must use the dangerous `targetPackages` here
     # because hooks are artificially phase-shifted one slot earlier
@@ -23,6 +33,10 @@ rec {
     # a targetPlatform to them).
     ccForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}cc";
     cxxForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}c++";
+    linkerForTarget = if shouldUseLLD targetPackages.stdenv.targetPlatform
+      && !targetPackages.stdenv.cc.bintools.isLLVM # whether stdenv's linker is lld already
+      then "${buildPackages.lld}/bin/ld.lld"
+      else ccForTarget;
 
     rustBuildPlatform = stdenv.buildPlatform.rust.rustcTarget;
     rustBuildPlatformSpec = stdenv.buildPlatform.rust.rustcTargetSpec;
@@ -32,9 +46,9 @@ rec {
     rustTargetPlatformSpec = stdenv.targetPlatform.rust.rustcTargetSpec;
   in {
     inherit
-      ccForBuild  cxxForBuild  rustBuildPlatform   rustBuildPlatformSpec
-      ccForHost   cxxForHost   rustHostPlatform    rustHostPlatformSpec
-      ccForTarget cxxForTarget rustTargetPlatform  rustTargetPlatformSpec;
+      ccForBuild  cxxForBuild  linkerForBuild  rustBuildPlatform   rustBuildPlatformSpec
+      ccForHost   cxxForHost   linkerForHost   rustHostPlatform    rustHostPlatformSpec
+      ccForTarget cxxForTarget linkerForTarget rustTargetPlatform  rustTargetPlatformSpec;
 
     # Prefix this onto a command invocation in order to set the
     # variables needed by cargo.
@@ -50,15 +64,15 @@ rec {
     + lib.optionalString (rustTargetPlatform != rustHostPlatform) ''
       "CC_${stdenv.targetPlatform.rust.cargoEnvVarTarget}=${ccForTarget}" \
       "CXX_${stdenv.targetPlatform.rust.cargoEnvVarTarget}=${cxxForTarget}" \
-      "CARGO_TARGET_${stdenv.targetPlatform.rust.cargoEnvVarTarget}_LINKER=${ccForTarget}" \
+      "CARGO_TARGET_${stdenv.targetPlatform.rust.cargoEnvVarTarget}_LINKER=${linkerForTarget}" \
     '' + ''
       "CC_${stdenv.hostPlatform.rust.cargoEnvVarTarget}=${ccForHost}" \
       "CXX_${stdenv.hostPlatform.rust.cargoEnvVarTarget}=${cxxForHost}" \
-      "CARGO_TARGET_${stdenv.hostPlatform.rust.cargoEnvVarTarget}_LINKER=${ccForHost}" \
+      "CARGO_TARGET_${stdenv.hostPlatform.rust.cargoEnvVarTarget}_LINKER=${linkerForHost}" \
     '' + ''
       "CC_${stdenv.buildPlatform.rust.cargoEnvVarTarget}=${ccForBuild}" \
       "CXX_${stdenv.buildPlatform.rust.cargoEnvVarTarget}=${cxxForBuild}" \
-      "CARGO_TARGET_${stdenv.buildPlatform.rust.cargoEnvVarTarget}_LINKER=${ccForBuild}" \
+      "CARGO_TARGET_${stdenv.buildPlatform.rust.cargoEnvVarTarget}_LINKER=${linkerForBuild}" \
       "CARGO_BUILD_TARGET=${rustBuildPlatform}" \
       "HOST_CC=${buildPackages.stdenv.cc}/bin/cc" \
       "HOST_CXX=${buildPackages.stdenv.cc}/bin/c++" \
diff --git a/nixpkgs/pkgs/build-support/rust/rustc-wrapper/rustc-wrapper.sh b/nixpkgs/pkgs/build-support/rust/rustc-wrapper/rustc-wrapper.sh
index a62e35b8736f..2082f3126a53 100644
--- a/nixpkgs/pkgs/build-support/rust/rustc-wrapper/rustc-wrapper.sh
+++ b/nixpkgs/pkgs/build-support/rust/rustc-wrapper/rustc-wrapper.sh
@@ -1,6 +1,19 @@
 #!@shell@
 
-extraBefore=(@sysroot@)
+defaultSysroot=(@sysroot@)
+
+for arg; do
+    case "$arg" in
+        --sysroot)
+            defaultSysroot=()
+            ;;
+        --)
+            break
+            ;;
+    esac
+done
+
+extraBefore=("${defaultSysroot[@]}")
 extraAfter=($NIX_RUSTFLAGS)
 
 # Optionally print debug info.
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh b/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh
index 371389df427b..9f6366b3feae 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh
@@ -53,17 +53,30 @@ autoPatchelf() {
         esac
     done
 
-    readarray -td' ' ignoreMissingDepsArray < <(echo -n "$autoPatchelfIgnoreMissingDeps")
-    if [ "$autoPatchelfIgnoreMissingDeps" == "1" ]; then
-        echo "autoPatchelf: WARNING: setting 'autoPatchelfIgnoreMissingDeps" \
-             "= true;' is deprecated and will be removed in a future release." \
-             "Use 'autoPatchelfIgnoreMissingDeps = [ \"*\" ];' instead." >&2
-        ignoreMissingDepsArray=( "*" )
+    if [ -n "$__structuredAttrs" ]; then
+        local ignoreMissingDepsArray=( "${autoPatchelfIgnoreMissingDeps[@]}" )
+        local appendRunpathsArray=( "${appendRunpaths[@]}" )
+        local runtimeDependenciesArray=( "${runtimeDependencies[@]}" )
+        local patchelfFlagsArray=( "${patchelfFlags[@]}" )
+    else
+        readarray -td' ' ignoreMissingDepsArray < <(echo -n "$autoPatchelfIgnoreMissingDeps")
+        local appendRunpathsArray=($appendRunpaths)
+        local runtimeDependenciesArray=($runtimeDependencies)
+        local patchelfFlagsArray=($patchelfFlags)
     fi
 
-    local appendRunpathsArray=($appendRunpaths)
-    local runtimeDependenciesArray=($runtimeDependencies)
-    local patchelfFlagsArray=($patchelfFlags)
+    # Check if ignoreMissingDepsArray contains "1" and if so, replace it with
+    # "*", printing a deprecation warning.
+    for dep in "${ignoreMissingDepsArray[@]}"; do
+        if [ "$dep" == "1" ]; then
+            echo "autoPatchelf: WARNING: setting 'autoPatchelfIgnoreMissingDeps" \
+                 "= true;' is deprecated and will be removed in a future release." \
+                 "Use 'autoPatchelfIgnoreMissingDeps = [ \"*\" ];' instead." >&2
+            ignoreMissingDepsArray=( "*" )
+            break
+        fi
+    done
+
     @pythonInterpreter@ @autoPatchelfScript@                            \
         ${norecurse:+--no-recurse}                                      \
         --ignore-missing "${ignoreMissingDepsArray[@]}"                 \
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/default.nix b/nixpkgs/pkgs/build-support/trivial-builders/default.nix
index 0b9f696d1cb8..9643c9ba048e 100644
--- a/nixpkgs/pkgs/build-support/trivial-builders/default.nix
+++ b/nixpkgs/pkgs/build-support/trivial-builders/default.nix
@@ -9,31 +9,41 @@ in
 
 rec {
 
-  /* Run the shell command `buildCommand' to produce a store path named
-   `name'.  The attributes in `env' are added to the environment
-   prior to running the command. By default `runCommand` runs in a
-   stdenv with no compiler environment. `runCommandCC` uses the default
-   stdenv, `pkgs.stdenv`.
+  /*
+    Run the shell command `buildCommand` to produce a store path named `name`.
+
+    The attributes in `env` are added to the environment prior to running the command.
+    Environment variables set by `stdenv.mkDerivation` take precedence.
 
-   Example:
+    By default `runCommand` runs in a stdenv with no compiler environment.
+    `runCommandCC` uses the default stdenv, `pkgs.stdenv`.
 
+    Example:
 
-   runCommand "name" {envVariable = true;} ''echo hello > $out''
-   runCommandCC "name" {} ''gcc -o myfile myfile.c; cp myfile $out'';
+    ```nix
+    runCommand "name" {envVariable = true;} ''echo hello > $out'';
+    ```
 
+    ```nix
+    runCommandCC "name" {} ''gcc -o myfile myfile.c; cp myfile $out'';
+    ```
 
-   The `*Local` variants force a derivation to be built locally,
-   it is not substituted.
+    The `*Local` variants force a derivation to be built locally,
+    it is not substituted.
 
-   This is intended for very cheap commands (<1s execution time).
-   It saves on the network roundrip and can speed up a build.
+    This is intended for very cheap commands (<1s execution time).
+    It saves on the network roundrip and can speed up a build.
 
-   It is the same as adding the special fields
+    It is the same as adding the special fields
 
-   `preferLocalBuild = true;`
-   `allowSubstitutes = false;`
+    ```nix
+    {
+      preferLocalBuild = true;
+      allowSubstitutes = false;
+    }
+    ```
 
-   to a derivation’s attributes.
+    to a derivation’s attributes.
   */
   runCommand = name: env: runCommandWith {
     stdenv = stdenvNoCC;
@@ -57,7 +67,8 @@ rec {
   # `runCommandCCLocal` left out on purpose.
   # We shouldn’t force the user to have a cc in scope.
 
-  /* Generalized version of the `runCommand`-variants
+  /*
+    Generalized version of the `runCommand`-variants
     which does customized behavior via a single
     attribute set passed as the first argument
     instead of having a lot of variants like
@@ -72,36 +83,37 @@ rec {
       defaultStdenv = stdenv;
     in
     {
-    # which stdenv to use, defaults to a stdenv with a C compiler, pkgs.stdenv
+      # which stdenv to use, defaults to a stdenv with a C compiler, pkgs.stdenv
       stdenv ? defaultStdenv
-    # whether to build this derivation locally instead of substituting
+      # whether to build this derivation locally instead of substituting
     , runLocal ? false
-    # extra arguments to pass to stdenv.mkDerivation
-    , derivationArgs ? {}
-    # name of the resulting derivation
+      # extra arguments to pass to stdenv.mkDerivation
+    , derivationArgs ? { }
+      # name of the resulting derivation
     , name
-    # TODO(@Artturin): enable strictDeps always
+      # TODO(@Artturin): enable strictDeps always
     }: buildCommand:
-    stdenv.mkDerivation ({
-      enableParallelBuilding = true;
-      inherit buildCommand name;
-      passAsFile = [ "buildCommand" ]
-        ++ (derivationArgs.passAsFile or []);
-    }
-    // lib.optionalAttrs (! derivationArgs?meta) {
-      pos = let args = builtins.attrNames derivationArgs; in
-        if builtins.length args > 0
-        then builtins.unsafeGetAttrPos (builtins.head args) derivationArgs
-        else null;
-    }
-    // (lib.optionalAttrs runLocal {
-          preferLocalBuild = true;
-          allowSubstitutes = false;
-       })
-    // builtins.removeAttrs derivationArgs [ "passAsFile" ]);
+      stdenv.mkDerivation ({
+        enableParallelBuilding = true;
+        inherit buildCommand name;
+        passAsFile = [ "buildCommand" ]
+          ++ (derivationArgs.passAsFile or [ ]);
+      }
+      // lib.optionalAttrs (! derivationArgs?meta) {
+        pos = let args = builtins.attrNames derivationArgs; in
+          if builtins.length args > 0
+          then builtins.unsafeGetAttrPos (builtins.head args) derivationArgs
+          else null;
+      }
+      // (lib.optionalAttrs runLocal {
+        preferLocalBuild = true;
+        allowSubstitutes = false;
+      })
+      // builtins.removeAttrs derivationArgs [ "passAsFile" ]);
 
 
-  /* Writes a text file to the nix store.
+  /*
+    Writes a text file to the nix store.
     The contents of text is added to the file in the store.
 
     Example:
@@ -145,11 +157,13 @@ rec {
       matches = builtins.match "/bin/([^/]+)" destination;
     in
     runCommand name
-      { inherit text executable checkPhase allowSubstitutes preferLocalBuild;
+      {
+        inherit text executable checkPhase allowSubstitutes preferLocalBuild;
         passAsFile = [ "text" ];
-        meta = lib.optionalAttrs (executable && matches != null) {
-          mainProgram = lib.head matches;
-        } // meta;
+        meta = lib.optionalAttrs (executable && matches != null)
+          {
+            mainProgram = lib.head matches;
+          } // meta;
       }
       ''
         target=$out${lib.escapeShellArg destination}
@@ -168,101 +182,32 @@ rec {
         eval "$checkPhase"
       '';
 
-  /*
-   Writes a text file to nix store with no optional parameters available.
-
-   Example:
-
-
-   # Writes contents of file to /nix/store/<store path>
-   writeText "my-file"
-     ''
-     Contents of File
-     '';
-
-
-  */
-  writeText = name: text: writeTextFile {inherit name text;};
-
-  /*
-    Writes a text file to nix store in a specific directory with no
-    optional parameters available.
+  # See doc/build-helpers/trivial-build-helpers.chapter.md
+  # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing
+  writeText = name: text: writeTextFile { inherit name text; };
 
-    Example:
-
-
-    # Writes contents of file to /nix/store/<store path>/share/my-file
-    writeTextDir "share/my-file"
-     ''
-     Contents of File
-     '';
-
-
-  */
+  # See doc/build-helpers/trivial-build-helpers.chapter.md
+  # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing
   writeTextDir = path: text: writeTextFile {
     inherit text;
     name = builtins.baseNameOf path;
     destination = "/${path}";
   };
 
-  /*
-    Writes a text file to /nix/store/<store path> and marks the file as
-    executable.
-
-    If passed as a build input, will be used as a setup hook. This makes setup
-    hooks more efficient to create: you don't need a derivation that copies
-    them to $out/nix-support/setup-hook, instead you can use the file as is.
-
-    Example:
-
-
-    # Writes my-file to /nix/store/<store path> and makes executable
-    writeScript "my-file"
-      ''
-      Contents of File
-      '';
-
-
-  */
-  writeScript = name: text: writeTextFile {inherit name text; executable = true;};
-
-  /*
-    Writes a text file to /nix/store/<store path>/bin/<name> and
-    marks the file as executable.
-
-    Example:
-
+  # See doc/build-helpers/trivial-build-helpers.chapter.md
+  # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing
+  writeScript = name: text: writeTextFile { inherit name text; executable = true; };
 
-
-    # Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
-    writeScriptBin "my-file"
-      ''
-      Contents of File
-      '';
-
-
-  */
+  # See doc/build-helpers/trivial-build-helpers.chapter.md
+  # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing
   writeScriptBin = name: text: writeTextFile {
     inherit name text;
     executable = true;
     destination = "/bin/${name}";
   };
 
-  /*
-    Similar to writeScript. Writes a Shell script and checks its syntax.
-    Automatically includes interpreter above the contents passed.
-
-    Example:
-
-
-    # Writes my-file to /nix/store/<store path> and makes executable.
-    writeShellScript "my-file"
-      ''
-      Contents of File
-      '';
-
-
-  */
+  # See doc/build-helpers/trivial-build-helpers.chapter.md
+  # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing
   writeShellScript = name: text:
     writeTextFile {
       inherit name;
@@ -270,29 +215,15 @@ rec {
       text = ''
         #!${runtimeShell}
         ${text}
-        '';
+      '';
       checkPhase = ''
         ${stdenv.shellDryRun} "$target"
       '';
     };
 
-  /*
-    Similar to writeShellScript and writeScriptBin.
-    Writes an executable Shell script to /nix/store/<store path>/bin/<name> and checks its syntax.
-    Automatically includes interpreter above the contents passed.
-
-    Example:
-
-
-    # Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
-    writeShellScriptBin "my-file"
-      ''
-      Contents of File
-      '';
-
-
-  */
-  writeShellScriptBin = name : text :
+  # See doc/build-helpers/trivial-build-helpers.chapter.md
+  # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing
+  writeShellScriptBin = name: text:
     writeTextFile {
       inherit name;
       executable = true;
@@ -300,7 +231,7 @@ rec {
       text = ''
         #!${runtimeShell}
         ${text}
-        '';
+      '';
       checkPhase = ''
         ${stdenv.shellDryRun} "$target"
       '';
@@ -340,7 +271,7 @@ rec {
     , runtimeInputs ? [ ]
     , meta ? { }
     , checkPhase ? null
-    , excludeShellChecks ? [  ]
+    , excludeShellChecks ? [ ]
     }:
     writeTextFile {
       inherit name meta;
@@ -366,7 +297,7 @@ rec {
         # but we still want to use writeShellApplication on those platforms
         let
           shellcheckSupported = lib.meta.availableOn stdenv.buildPlatform shellcheck-minimal.compiler;
-          excludeOption = lib.optionalString (excludeShellChecks != [  ]) "--exclude '${lib.concatStringsSep "," excludeShellChecks}'";
+          excludeOption = lib.optionalString (excludeShellChecks != [ ]) "--exclude '${lib.concatStringsSep "," excludeShellChecks}'";
           shellcheckCommand = lib.optionalString shellcheckSupported ''
             # use shellcheck which does not include docs
             # pandoc takes long to build and documentation isn't needed for just running the cli
@@ -385,23 +316,23 @@ rec {
   # Create a C binary
   writeCBin = pname: code:
     runCommandCC pname
-    {
-      inherit pname code;
-      executable = true;
-      passAsFile = ["code"];
-      # Pointless to do this on a remote machine.
-      preferLocalBuild = true;
-      allowSubstitutes = false;
-      meta = {
-        mainProgram = pname;
-      };
-    }
-    ''
-      n=$out/bin/${pname}
-      mkdir -p "$(dirname "$n")"
-      mv "$codePath" code.c
-      $CC -x c code.c -o "$n"
-    '';
+      {
+        inherit pname code;
+        executable = true;
+        passAsFile = [ "code" ];
+        # Pointless to do this on a remote machine.
+        preferLocalBuild = true;
+        allowSubstitutes = false;
+        meta = {
+          mainProgram = pname;
+        };
+      }
+      ''
+        n=$out/bin/${pname}
+        mkdir -p "$(dirname "$n")"
+        mv "$codePath" code.c
+        $CC -x c code.c -o "$n"
+      '';
 
 
   /* concat a list of files to the nix store.
@@ -478,7 +409,7 @@ rec {
 
 
   /*
-    Create a forest of symlinks to the files in `paths'.
+    Create a forest of symlinks to the files in `paths`.
 
     This creates a single derivation that replicates the directory structure
     of all the input paths.
@@ -532,19 +463,20 @@ rec {
    */
   symlinkJoin =
     args_@{ name
-         , paths
-         , preferLocalBuild ? true
-         , allowSubstitutes ? false
-         , postBuild ? ""
-         , ...
-         }:
+    , paths
+    , preferLocalBuild ? true
+    , allowSubstitutes ? false
+    , postBuild ? ""
+    , ...
+    }:
     let
       args = removeAttrs args_ [ "name" "postBuild" ]
         // {
-          inherit preferLocalBuild allowSubstitutes;
-          passAsFile = [ "paths" ];
-        }; # pass the defaults
-    in runCommand name args
+        inherit preferLocalBuild allowSubstitutes;
+        passAsFile = [ "paths" ];
+      }; # pass the defaults
+    in
+    runCommand name args
       ''
         mkdir -p $out
         for i in $(cat $pathsPath); do
@@ -584,27 +516,30 @@ rec {
     See the note on symlinkJoin for the difference between linkFarm and symlinkJoin.
    */
   linkFarm = name: entries:
-  let
-    entries' =
-      if (lib.isAttrs entries) then entries
-      # We do this foldl to have last-wins semantics in case of repeated entries
-      else if (lib.isList entries) then lib.foldl (a: b: a // { "${b.name}" = b.path; }) { } entries
-      else throw "linkFarm entries must be either attrs or a list!";
-
-    linkCommands = lib.mapAttrsToList (name: path: ''
-      mkdir -p "$(dirname ${lib.escapeShellArg "${name}"})"
-      ln -s ${lib.escapeShellArg "${path}"} ${lib.escapeShellArg "${name}"}
-    '') entries';
-  in
-  runCommand name {
-    preferLocalBuild = true;
-    allowSubstitutes = false;
-    passthru.entries = entries';
-   } ''
-    mkdir -p $out
-    cd $out
-    ${lib.concatStrings linkCommands}
-  '';
+    let
+      entries' =
+        if (lib.isAttrs entries) then entries
+        # We do this foldl to have last-wins semantics in case of repeated entries
+        else if (lib.isList entries) then lib.foldl (a: b: a // { "${b.name}" = b.path; }) { } entries
+        else throw "linkFarm entries must be either attrs or a list!";
+
+      linkCommands = lib.mapAttrsToList
+        (name: path: ''
+          mkdir -p "$(dirname ${lib.escapeShellArg "${name}"})"
+          ln -s ${lib.escapeShellArg "${path}"} ${lib.escapeShellArg "${name}"}
+        '')
+        entries';
+    in
+    runCommand name
+      {
+        preferLocalBuild = true;
+        allowSubstitutes = false;
+        passthru.entries = entries';
+      } ''
+      mkdir -p $out
+      cd $out
+      ${lib.concatStrings linkCommands}
+    '';
 
   /*
     Easily create a linkFarm from a set of derivations.
@@ -639,7 +574,7 @@ rec {
     bin output and other contents of the package's output (e.g. setup
     hooks) cause trouble when used in your environment.
   */
-  onlyBin = drv: runCommand "${drv.name}-only-bin" {} ''
+  onlyBin = drv: runCommand "${drv.name}-only-bin" { } ''
     mkdir -p $out
     ln -s ${lib.getBin drv}/bin $out/bin
   '';
@@ -675,23 +610,23 @@ rec {
         # TODO 2023-01, no backport: simplify to inherit passthru;
         passthru = passthru
           // optionalAttrs (substitutions?passthru)
-            (warn "makeSetupHook (name = ${lib.strings.escapeNixString name}): `substitutions.passthru` is deprecated. Please set `passthru` directly."
-              substitutions.passthru);
+          (warn "makeSetupHook (name = ${lib.strings.escapeNixString name}): `substitutions.passthru` is deprecated. Please set `passthru` directly."
+            substitutions.passthru);
       })
       (''
         mkdir -p $out/nix-support
         cp ${script} $out/nix-support/setup-hook
         recordPropagatedDependencies
-      '' + lib.optionalString (substitutions != {}) ''
+      '' + lib.optionalString (substitutions != { }) ''
         substituteAll ${script} $out/nix-support/setup-hook
       '');
 
 
-  # Write the references (i.e. the runtime dependencies in the Nix store) of `path' to a file.
+  # Write the references (i.e. the runtime dependencies in the Nix store) of `path` to a file.
 
   writeReferencesToFile = path: runCommand "runtime-deps"
     {
-      exportReferencesGraph = ["graph" path];
+      exportReferencesGraph = [ "graph" path ];
     }
     ''
       touch $out
@@ -710,7 +645,7 @@ rec {
    */
   writeDirectReferencesToFile = path: runCommand "runtime-references"
     {
-      exportReferencesGraph = ["graph" path];
+      exportReferencesGraph = [ "graph" path ];
       inherit path;
     }
     ''
@@ -744,17 +679,17 @@ rec {
    */
   writeStringReferencesToFile = string:
     /*
-     The basic operation this performs is to copy the string context
-     from `string' to a second string and wrap that string in a
-     derivation. However, that alone is not enough, since nothing in the
-     string refers to the output paths of the derivations/paths in its
-     context, meaning they'll be considered build-time dependencies and
-     removed from the wrapper derivation's closure. Putting the
-     necessary output paths in the new string is however not very
-     straightforward - the attrset returned by `getContext' contains
-     only references to derivations' .drv-paths, not their output
-     paths. In order to "convert" them, we try to extract the
-     corresponding paths from the original string using regex.
+       The basic operation this performs is to copy the string context
+       from `string` to a second string and wrap that string in a
+       derivation. However, that alone is not enough, since nothing in the
+       string refers to the output paths of the derivations/paths in its
+       context, meaning they'll be considered build-time dependencies and
+       removed from the wrapper derivation's closure. Putting the
+       necessary output paths in the new string is however not very
+       straightforward - the attrset returned by `getContext` contains
+       only references to derivations' .drv-paths, not their output
+       paths. In order to "convert" them, we try to extract the
+       corresponding paths from the original string using regex.
     */
     let
       # Taken from https://github.com/NixOS/nix/blob/130284b8508dad3c70e8160b15f3d62042fc730a/src/libutil/hash.cc#L84
@@ -798,21 +733,21 @@ rec {
               if lib.elem "out" value.outputs then
                 lib.filter
                   (x: lib.isList x &&
-                      # If the matched path is in `namedOutputPaths`,
-                      # it's a partial match of an output path where
-                      # the output name isn't `out`
-                      lib.all (o: !lib.hasPrefix (lib.head x) o) namedOutputPaths)
+                    # If the matched path is in `namedOutputPaths`,
+                    # it's a partial match of an output path where
+                    # the output name isn't `out`
+                    lib.all (o: !lib.hasPrefix (lib.head x) o) namedOutputPaths)
                   (builtins.split "(${builtins.storeDir}/[${nixHashChars}]+-${name})" string)
               else
-                [])
+                [ ])
             packages);
       allPaths = lib.concatStringsSep "\n" (lib.unique (sources ++ namedOutputPaths ++ outputPaths));
       allPathsWithContext = builtins.appendContext allPaths context;
     in
-      if builtins ? getContext then
-        writeText "string-references" allPathsWithContext
-      else
-        writeDirectReferencesToFile (writeText "string-file" string);
+    if builtins ? getContext then
+      writeText "string-references" allPathsWithContext
+    else
+      writeDirectReferencesToFile (writeText "string-file" string);
 
 
   /* Print an error message if the file with the specified name and
@@ -830,55 +765,59 @@ rec {
     }
 
    */
-  requireFile = { name ? null
-                , sha256 ? null
-                , sha1 ? null
-                , hash ? null
-                , url ? null
-                , message ? null
-                , hashMode ? "flat"
-                } :
-    assert (message != null) || (url != null);
-    assert (sha256 != null) || (sha1 != null) || (hash != null);
-    assert (name != null) || (url != null);
-    let msg =
-      if message != null then message
-      else ''
-        Unfortunately, we cannot download file ${name_} automatically.
-        Please go to ${url} to download it yourself, and add it to the Nix store
-        using either
-          nix-store --add-fixed ${hashAlgo} ${name_}
-        or
-          nix-prefetch-url --type ${hashAlgo} file:///path/to/${name_}
-      '';
-      hashAlgo = if hash != null then (builtins.head (lib.strings.splitString "-" hash))
-            else if sha256 != null then "sha256"
-            else "sha1";
-      hashAlgo_ = if hash != null then "" else hashAlgo;
-      hash_ = if hash != null then hash
-         else if sha256 != null then sha256
-         else sha1;
-      name_ = if name == null then baseNameOf (toString url) else name;
-    in
-    stdenvNoCC.mkDerivation {
-      name = name_;
-      outputHashMode = hashMode;
-      outputHashAlgo = hashAlgo_;
-      outputHash = hash_;
-      preferLocalBuild = true;
-      allowSubstitutes = false;
-      builder = writeScript "restrict-message" ''
-        source ${stdenvNoCC}/setup
-        cat <<_EOF_
-
-        ***
-        ${msg}
-        ***
-
-        _EOF_
-        exit 1
-      '';
-    };
+  requireFile =
+    { name ? null
+    , sha256 ? null
+    , sha1 ? null
+    , hash ? null
+    , url ? null
+    , message ? null
+    , hashMode ? "flat"
+    }:
+      assert (message != null) || (url != null);
+      assert (sha256 != null) || (sha1 != null) || (hash != null);
+      assert (name != null) || (url != null);
+      let
+        msg =
+          if message != null then message
+          else ''
+            Unfortunately, we cannot download file ${name_} automatically.
+            Please go to ${url} to download it yourself, and add it to the Nix store
+            using either
+              nix-store --add-fixed ${hashAlgo} ${name_}
+            or
+              nix-prefetch-url --type ${hashAlgo} file:///path/to/${name_}
+          '';
+        hashAlgo =
+          if hash != null then (builtins.head (lib.strings.splitString "-" hash))
+          else if sha256 != null then "sha256"
+          else "sha1";
+        hashAlgo_ = if hash != null then "" else hashAlgo;
+        hash_ =
+          if hash != null then hash
+          else if sha256 != null then sha256
+          else sha1;
+        name_ = if name == null then baseNameOf (toString url) else name;
+      in
+      stdenvNoCC.mkDerivation {
+        name = name_;
+        outputHashMode = hashMode;
+        outputHashAlgo = hashAlgo_;
+        outputHash = hash_;
+        preferLocalBuild = true;
+        allowSubstitutes = false;
+        builder = writeScript "restrict-message" ''
+          source ${stdenvNoCC}/setup
+          cat <<_EOF_
+
+          ***
+          ${msg}
+          ***
+
+          _EOF_
+          exit 1
+        '';
+      };
 
 
   /*
@@ -915,39 +854,45 @@ rec {
   applyPatches =
     { src
     , name ? (if builtins.typeOf src == "path"
-              then builtins.baseNameOf src
-              else
-                if builtins.isAttrs src && builtins.hasAttr "name" src
-                then src.name
-                else throw "applyPatches: please supply a `name` argument because a default name can only be computed when the `src` is a path or is an attribute set with a `name` attribute."
-             ) + "-patched"
-    , patches   ? []
+      then builtins.baseNameOf src
+      else
+        if builtins.isAttrs src && builtins.hasAttr "name" src
+        then src.name
+        else throw "applyPatches: please supply a `name` argument because a default name can only be computed when the `src` is a path or is an attribute set with a `name` attribute."
+      ) + "-patched"
+    , patches ? [ ]
     , postPatch ? ""
     , ...
-    }@args: stdenvNoCC.mkDerivation {
-      inherit name src patches postPatch;
-      preferLocalBuild = true;
-      allowSubstitutes = false;
-      phases = "unpackPhase patchPhase installPhase";
-      installPhase = "cp -R ./ $out";
-    }
+    }@args:
+    if patches == [ ] && postPatch == ""
+    then src # nothing to do, so use original src to avoid additional drv
+    else stdenvNoCC.mkDerivation
+      {
+        inherit name src patches postPatch;
+        preferLocalBuild = true;
+        allowSubstitutes = false;
+        phases = "unpackPhase patchPhase installPhase";
+        installPhase = "cp -R ./ $out";
+      }
     # Carry `meta` information from the underlying `src` if present.
     // (optionalAttrs (src?meta) { inherit (src) meta; })
     // (removeAttrs args [ "src" "name" "patches" "postPatch" ]);
 
   /* An immutable file in the store with a length of 0 bytes. */
-  emptyFile = runCommand "empty-file" {
-    outputHashAlgo = "sha256";
-    outputHashMode = "recursive";
-    outputHash = "0ip26j2h11n1kgkz36rl4akv694yz65hr72q4kv4b3lxcbi65b3p";
-    preferLocalBuild = true;
-  } "touch $out";
+  emptyFile = runCommand "empty-file"
+    {
+      outputHashAlgo = "sha256";
+      outputHashMode = "recursive";
+      outputHash = "0ip26j2h11n1kgkz36rl4akv694yz65hr72q4kv4b3lxcbi65b3p";
+      preferLocalBuild = true;
+    } "touch $out";
 
   /* An immutable empty directory in the store. */
-  emptyDirectory = runCommand "empty-directory" {
-    outputHashAlgo = "sha256";
-    outputHashMode = "recursive";
-    outputHash = "0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5";
-    preferLocalBuild = true;
-  } "mkdir $out";
+  emptyDirectory = runCommand "empty-directory"
+    {
+      outputHashAlgo = "sha256";
+      outputHashMode = "recursive";
+      outputHash = "0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5";
+      preferLocalBuild = true;
+    } "mkdir $out";
 }