about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2022-12-06 19:57:55 +0000
committerAlyssa Ross <hi@alyssa.is>2023-02-08 13:48:30 +0000
commitbf3aadfdd39aa197e18bade671fab6726349ffa4 (patch)
tree698567af766ed441d757b57a7b21e68d4a342a2b /nixpkgs/pkgs/build-support
parentf4afc5a01d9539ce09e47494e679c51f80723d07 (diff)
parent99665eb45f58d959d2cb9e49ddb960c79d596f33 (diff)
downloadnixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar
nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.gz
nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.bz2
nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.lz
nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.xz
nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.zst
nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.zip
Merge commit '99665eb45f58d959d2cb9e49ddb960c79d596f33'
Diffstat (limited to 'nixpkgs/pkgs/build-support')
-rw-r--r--nixpkgs/pkgs/build-support/appimage/default.nix15
-rw-r--r--nixpkgs/pkgs/build-support/bintools-wrapper/default.nix46
-rw-r--r--nixpkgs/pkgs/build-support/bintools-wrapper/ld-wrapper.sh10
-rw-r--r--nixpkgs/pkgs/build-support/build-bazel-package/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix13
-rw-r--r--nixpkgs/pkgs/build-support/build-graalvm-native-image/default.nix18
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/add-clang-cc-cflags-before.sh11
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/cc-wrapper.sh87
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/default.nix41
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh2
-rw-r--r--nixpkgs/pkgs/build-support/coq/default.nix40
-rw-r--r--nixpkgs/pkgs/build-support/docker/default.nix88
-rw-r--r--nixpkgs/pkgs/build-support/docker/examples.nix150
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix67
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix9
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh14
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh5
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh10
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh15
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh19
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix11
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix44
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/default.nix34
-rwxr-xr-xnixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh23
-rw-r--r--nixpkgs/pkgs/build-support/emacs/melpa.nix4
-rw-r--r--nixpkgs/pkgs/build-support/emacs/melpa2nix.el18
-rw-r--r--nixpkgs/pkgs/build-support/emacs/wrapper.nix1
-rw-r--r--nixpkgs/pkgs/build-support/expand-response-params/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/fake-nss/default.nix24
-rwxr-xr-xnixpkgs/pkgs/build-support/fetchcvs/nix-prefetch-cvs6
-rw-r--r--nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/fetchfirefoxaddon/tests.nix6
-rw-r--r--nixpkgs/pkgs/build-support/fetchgit/builder.sh1
-rw-r--r--nixpkgs/pkgs/build-support/fetchgit/default.nix13
-rwxr-xr-xnixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git4
-rw-r--r--nixpkgs/pkgs/build-support/fetchgit/tests.nix18
-rw-r--r--nixpkgs/pkgs/build-support/fetchgithub/default.nix13
-rw-r--r--nixpkgs/pkgs/build-support/fetchgitlab/default.nix8
-rw-r--r--nixpkgs/pkgs/build-support/fetchnextcloudapp/default.nix9
-rw-r--r--nixpkgs/pkgs/build-support/fetchpatch/tests.nix8
-rw-r--r--nixpkgs/pkgs/build-support/fetchsourcehut/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/fetchurl/builder.sh2
-rw-r--r--nixpkgs/pkgs/build-support/fetchurl/default.nix17
-rw-r--r--nixpkgs/pkgs/build-support/fetchurl/mirrors.nix7
-rw-r--r--nixpkgs/pkgs/build-support/fetchurl/tests.nix13
-rw-r--r--nixpkgs/pkgs/build-support/fetchzip/default.nix15
-rw-r--r--nixpkgs/pkgs/build-support/fetchzip/tests.nix17
-rw-r--r--nixpkgs/pkgs/build-support/go/garble.nix35
-rw-r--r--nixpkgs/pkgs/build-support/go/module.nix317
-rw-r--r--nixpkgs/pkgs/build-support/go/package.nix286
-rw-r--r--nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix16
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng-tool.nix17
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix97
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock97
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.toml10
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng/README.md79
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng/src/main.rs233
-rwxr-xr-xnixpkgs/pkgs/build-support/kernel/make-initrd-ng/update.sh4
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd.nix4
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd.sh2
-rw-r--r--nixpkgs/pkgs/build-support/kernel/modules-closure.sh8
-rw-r--r--nixpkgs/pkgs/build-support/libredirect/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/make-darwin-bundle/default.nix8
-rw-r--r--nixpkgs/pkgs/build-support/make-desktopitem/default.nix15
-rw-r--r--nixpkgs/pkgs/build-support/make-pkgconfigitem/default.nix69
-rwxr-xr-xnixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js8
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix8
-rw-r--r--nixpkgs/pkgs/build-support/nuke-references/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/ocaml/dune.nix4
-rw-r--r--nixpkgs/pkgs/build-support/ocaml/oasis.nix2
-rw-r--r--nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix5
-rw-r--r--nixpkgs/pkgs/build-support/prefer-remote-fetch/default.nix10
-rw-r--r--nixpkgs/pkgs/build-support/replace-dependency.nix2
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix13
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix3
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix39
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/lib.sh2
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/test/default.nix14
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix3496
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix9
-rw-r--r--nixpkgs/pkgs/build-support/rust/default-crate-overrides.nix9
-rw-r--r--nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix5
-rw-r--r--nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh3
-rw-r--r--nixpkgs/pkgs/build-support/rust/lib/default.nix8
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.py40
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh10
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/copy-desktop-items.sh9
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/copy-pkgconfig-items.sh46
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh32
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix27
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh (renamed from nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper.sh)83
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh48
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix9
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh79
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix27
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh1
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/strip.sh42
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix16
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/tests/lib.nix13
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/wrap-gapps-hook.sh4
-rw-r--r--nixpkgs/pkgs/build-support/skaware/build-skaware-package.nix2
-rw-r--r--nixpkgs/pkgs/build-support/src-only/default.nix30
-rw-r--r--nixpkgs/pkgs/build-support/templaterpm/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/testers/default.nix72
-rw-r--r--nixpkgs/pkgs/build-support/testers/test-equal-derivation.nix (renamed from nixpkgs/pkgs/build-support/test-equal-derivation.nix)19
-rw-r--r--nixpkgs/pkgs/build-support/testers/test/README.md8
-rw-r--r--nixpkgs/pkgs/build-support/testers/test/default.nix27
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders.nix62
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/test/references.nix4
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix34
-rw-r--r--nixpkgs/pkgs/build-support/vm/default.nix8
-rw-r--r--nixpkgs/pkgs/build-support/writers/default.nix15
113 files changed, 6084 insertions, 614 deletions
diff --git a/nixpkgs/pkgs/build-support/appimage/default.nix b/nixpkgs/pkgs/build-support/appimage/default.nix
index 0bee6ce065ad..17d5bca65669 100644
--- a/nixpkgs/pkgs/build-support/appimage/default.nix
+++ b/nixpkgs/pkgs/build-support/appimage/default.nix
@@ -37,7 +37,13 @@ rec {
   extractType2 = extract;
   wrapType1 = wrapType2;
 
-  wrapAppImage = args@{ name ? "${args.pname}-${args.version}", src, extraPkgs, ... }: buildFHSUserEnv
+  wrapAppImage = args@{
+    name ? "${args.pname}-${args.version}",
+    src,
+    extraPkgs,
+    meta ? {},
+    ...
+  }: buildFHSUserEnv
     (defaultFhsEnvArgs // {
       inherit name;
 
@@ -45,6 +51,10 @@ rec {
         ++ defaultFhsEnvArgs.targetPkgs pkgs ++ extraPkgs pkgs;
 
       runScript = "appimage-exec.sh -w ${src} --";
+
+      meta = {
+        sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
+      } // meta;
     } // (removeAttrs args ([ "pname" "version" ] ++ (builtins.attrNames (builtins.functionArgs wrapAppImage)))));
 
   wrapType2 = args@{ name ? "${args.pname}-${args.version}", src, extraPkgs ? pkgs: [ ], ... }: wrapAppImage
@@ -106,9 +116,8 @@ rec {
       xorg.libXi
       xorg.libSM
       xorg.libICE
-      gnome2.GConf
       freetype
-      (curl.override { gnutlsSupport = true; opensslSupport = false; })
+      curlWithGnuTls
       nspr
       nss
       fontconfig
diff --git a/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix b/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
index c2d67169c9ca..cdd07d6b2efe 100644
--- a/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
@@ -70,6 +70,7 @@ let
   dynamicLinker =
     /**/ if sharedLibraryLoader == null then null
     else if targetPlatform.libc == "musl"             then "${sharedLibraryLoader}/lib/ld-musl-*"
+    else if targetPlatform.libc == "uclibc"           then "${sharedLibraryLoader}/lib/ld*-uClibc.so.1"
     else if (targetPlatform.libc == "bionic" && targetPlatform.is32bit) then "/system/bin/linker"
     else if (targetPlatform.libc == "bionic" && targetPlatform.is64bit) then "/system/bin/linker64"
     else if targetPlatform.libc == "nblibc"           then "${sharedLibraryLoader}/libexec/ld.elf_so"
@@ -128,6 +129,8 @@ stdenv.mkDerivation {
   dontBuild = true;
   dontConfigure = true;
 
+  enableParallelBuilding = true;
+
   unpackPhase = ''
     src=$PWD
   '';
@@ -162,11 +165,13 @@ stdenv.mkDerivation {
       wrap ld-solaris ${./ld-solaris-wrapper.sh}
     '')
 
-    # Create a symlink to as (the assembler).
+    # Create symlinks for rest of the binaries.
     + ''
-      if [ -e $ldPath/${targetPrefix}as ]; then
-        ln -s $ldPath/${targetPrefix}as $out/bin/${targetPrefix}as
-      fi
+      for binary in objdump objcopy size strings as ar nm gprof dwp c++filt addr2line ranlib readelf elfedit; do
+        if [ -e $ldPath/${targetPrefix}''${binary} ]; then
+          ln -s $ldPath/${targetPrefix}''${binary} $out/bin/${targetPrefix}''${binary}
+        fi
+      done
 
     '' + (if !useMacosReexportHack then ''
       wrap ${targetPrefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${targetPrefix}ld}
@@ -184,39 +189,6 @@ stdenv.mkDerivation {
       done
     '';
 
-  emulation = let
-    fmt =
-      /**/ if targetPlatform.isDarwin  then "mach-o"
-      else if targetPlatform.isWindows then "pe"
-      else "elf" + toString targetPlatform.parsed.cpu.bits;
-    endianPrefix = if targetPlatform.isBigEndian then "big" else "little";
-    sep = optionalString (!targetPlatform.isMips && !targetPlatform.isPower && !targetPlatform.isRiscV) "-";
-    arch =
-      /**/ if targetPlatform.isAarch64 then endianPrefix + "aarch64"
-      else if targetPlatform.isAarch32     then endianPrefix + "arm"
-      else if targetPlatform.isx86_64  then "x86-64"
-      else if targetPlatform.isx86_32  then "i386"
-      else if targetPlatform.isMips    then {
-          mips     = "btsmipn32"; # n32 variant
-          mipsel   = "ltsmipn32"; # n32 variant
-          mips64   = "btsmip";
-          mips64el = "ltsmip";
-        }.${targetPlatform.parsed.cpu.name}
-      else if targetPlatform.isMmix then "mmix"
-      else if targetPlatform.isPower then if targetPlatform.isBigEndian then "ppc" else "lppc"
-      else if targetPlatform.isSparc then "sparc"
-      else if targetPlatform.isMsp430 then "msp430"
-      else if targetPlatform.isAvr then "avr"
-      else if targetPlatform.isAlpha then "alpha"
-      else if targetPlatform.isVc4 then "vc4"
-      else if targetPlatform.isOr1k then "or1k"
-      else if targetPlatform.isM68k then "m68k"
-      else if targetPlatform.isS390 then "s390"
-      else if targetPlatform.isRiscV then "lriscv"
-      else throw "unknown emulation for platform: ${targetPlatform.config}";
-    in if targetPlatform.useLLVM or false then ""
-       else targetPlatform.bfdEmulation or (fmt + sep + arch);
-
   strictDeps = true;
   depsTargetTargetPropagated = extraPackages;
 
diff --git a/nixpkgs/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/nixpkgs/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
index fb01c5096d5b..86a741602201 100644
--- a/nixpkgs/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
+++ b/nixpkgs/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
@@ -50,6 +50,11 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}"
             n+=1; skip "$p2"
         elif [ "$p" = -dynamic-linker ] && badPath "$p2"; then
             n+=1; skip "$p2"
+        elif [ "$p" = -syslibroot ] && [ $p2 == // ]; then
+            # When gcc is built on darwin --with-build-sysroot=/
+            # produces '-syslibroot //' linker flag. It's a no-op,
+            # which does not introduce impurities.
+            n+=1; skip "$p2"
         elif [ "${p:0:1}" = / ] && badPath "$p"; then
             # We cannot skip this; barf.
             echo "impure path \`$p' used in link" >&2
@@ -93,11 +98,6 @@ if [ -e @out@/nix-support/add-local-ldflags-before.sh ]; then
 fi
 
 
-# Specify the target emulation if nothing is passed in ("-m" overrides this
-# environment variable). Ensures we never blindly fallback on targeting the host
-# platform.
-: ${LDEMULATION:=@emulation@}
-
 # Three tasks:
 #
 #   1. Find all -L... switches for rpath
diff --git a/nixpkgs/pkgs/build-support/build-bazel-package/default.nix b/nixpkgs/pkgs/build-support/build-bazel-package/default.nix
index 74486e2e1003..f379334786b6 100644
--- a/nixpkgs/pkgs/build-support/build-bazel-package/default.nix
+++ b/nixpkgs/pkgs/build-support/build-bazel-package/default.nix
@@ -58,7 +58,7 @@ in stdenv.mkDerivation (fBuildAttrs // {
     name = "${name}-deps.tar.gz";
     inherit bazelFlags bazelBuildFlags bazelFetchFlags bazelTarget;
 
-    impureEnvVars = lib.fetchers.proxyImpureEnvVars;
+    impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ fFetchAttrs.impureEnvVars or [];
 
     nativeBuildInputs = fFetchAttrs.nativeBuildInputs or [] ++ [ bazel ];
 
diff --git a/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix b/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix
index e44519a04046..f66ad38f7b86 100644
--- a/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix
+++ b/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix
@@ -88,6 +88,8 @@ let
     /lib32
     /usr/lib/i386-linux-gnu
     /usr/lib32
+    /run/opengl-driver/lib
+    /run/opengl-driver-32/lib
     EOF
     ldconfig &> /dev/null
   '';
diff --git a/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix b/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix
index a36008d752bd..7ebcba73708c 100644
--- a/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix
+++ b/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix
@@ -22,8 +22,10 @@
 # /lib will link to /lib32
 
 let
-  is64Bit = stdenv.hostPlatform.parsed.cpu.bits == 64;
-  isMultiBuild  = multiPkgs != null && is64Bit;
+  inherit (stdenv) is64bit;
+
+  # use of glibc_multi is only supported on x86_64-linux
+  isMultiBuild  = multiPkgs != null && stdenv.isx86_64 && stdenv.isLinux;
   isTargetBuild = !isMultiBuild;
 
   # list of packages (usually programs) which are only be installed for the
@@ -50,7 +52,8 @@ let
     ];
 
   ldconfig = writeShellScriptBin "ldconfig" ''
-    exec ${pkgs.glibc.bin}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@"
+    # due to a glibc bug, 64-bit ldconfig complains about patchelf'd 32-bit libraries, so we're using 32-bit ldconfig
+    exec ${pkgsi686Linux.glibc.bin}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@"
   '';
   etcProfile = writeText "profile" ''
     export PS1='${name}-chrootenv:\u@\h:\w\$ '
@@ -138,7 +141,7 @@ let
   setupLibDirsTarget = ''
     # link content of targetPaths
     cp -rsHf ${staticUsrProfileTarget}/lib lib
-    ln -s lib lib${if is64Bit then "64" else "32"}
+    ln -s lib lib${if is64bit then "64" else "32"}
   '';
 
   # setup /lib, /lib32 and /lib64
@@ -178,7 +181,7 @@ let
         chmod -R 755 share
         cp -rLTf ${staticUsrProfileTarget}/share share
       else
-        cp -rLf ${staticUsrProfileTarget}/share share
+        cp -rsHf ${staticUsrProfileTarget}/share share
       fi
     fi
     for i in bin sbin include; do
diff --git a/nixpkgs/pkgs/build-support/build-graalvm-native-image/default.nix b/nixpkgs/pkgs/build-support/build-graalvm-native-image/default.nix
index 3aedd61ea6ce..f223009cba5c 100644
--- a/nixpkgs/pkgs/build-support/build-graalvm-native-image/default.nix
+++ b/nixpkgs/pkgs/build-support/build-graalvm-native-image/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, graalvmCEPackages, glibcLocales }:
+{ lib, stdenv, graalvm, glibcLocales }:
 
 { name ? "${args.pname}-${args.version}"
   # Final executable name
@@ -19,22 +19,22 @@
 , extraNativeImageBuildArgs ? [ ]
   # XMX size of GraalVM during build
 , graalvmXmx ? "-J-Xmx6g"
-  # The GraalVM to use
-, graalvm ? graalvmCEPackages.graalvm11-ce
+  # The GraalVM derivation to use
+, graalvmDrv ? graalvm
+  # Locale to be used by GraalVM compiler
+, LC_ALL ? "en_US.UTF-8"
 , meta ? { }
 , ...
 } @ args:
 
 stdenv.mkDerivation (args // {
-  inherit dontUnpack;
+  inherit dontUnpack LC_ALL;
 
-  nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [ graalvm glibcLocales ];
+  nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [ graalvmDrv glibcLocales ];
 
   nativeImageBuildArgs = nativeImageBuildArgs ++ extraNativeImageBuildArgs ++ [ graalvmXmx ];
 
   buildPhase = args.buildPhase or ''
-    export LC_ALL="en_US.UTF-8"
-
     runHook preBuild
 
     native-image ''${nativeImageBuildArgs[@]}
@@ -52,8 +52,10 @@ stdenv.mkDerivation (args // {
 
   meta = {
     # default to graalvm's platforms
-    platforms = graalvm.meta.platforms;
+    platforms = graalvmDrv.meta.platforms;
     # default to executable name
     mainProgram = executable;
+    # need to have native-image-installable-svm available
+    broken = !(builtins.elem "native-image-installable-svm" graalvmDrv.products);
   } // meta;
 })
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/add-clang-cc-cflags-before.sh b/nixpkgs/pkgs/build-support/cc-wrapper/add-clang-cc-cflags-before.sh
new file mode 100644
index 000000000000..f943b8504683
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/add-clang-cc-cflags-before.sh
@@ -0,0 +1,11 @@
+needsTarget=true
+
+for p in "${params[@]}"; do
+    case "$p" in
+    -target | --target=*) needsTarget=false ;;
+    esac
+done
+
+if $needsTarget; then
+    extraBefore+=(-target @defaultTarget@)
+fi
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/nixpkgs/pkgs/build-support/cc-wrapper/cc-wrapper.sh
index 1220841162c3..83b6817798f2 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/cc-wrapper.sh
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/cc-wrapper.sh
@@ -38,36 +38,23 @@ nParams=${#params[@]}
 while (( "$n" < "$nParams" )); do
     p=${params[n]}
     p2=${params[n+1]:-} # handle `p` being last one
-    if [ "$p" = -c ]; then
-        dontLink=1
-    elif [ "$p" = -S ]; then
-        dontLink=1
-    elif [ "$p" = -E ]; then
-        dontLink=1
-    elif [ "$p" = -E ]; then
-        dontLink=1
-    elif [ "$p" = -M ]; then
-        dontLink=1
-    elif [ "$p" = -MM ]; then
-        dontLink=1
-    elif [[ "$p" = -x && "$p2" = *-header ]]; then
-        dontLink=1
-    elif [[ "$p" = -x && "$p2" = c++* && "$isCxx" = 0 ]]; then
-        isCxx=1
-    elif [ "$p" = -nostdlib ]; then
-        cxxLibrary=0
-    elif [ "$p" = -nostdinc ]; then
-        cInclude=0
-        cxxInclude=0
-    elif [ "$p" = -nostdinc++ ]; then
-        cxxInclude=0
-    elif [[ "$p" != -?* ]]; then
-        # A dash alone signifies standard input; it is not a flag
-        nonFlagArgs=1
-    elif [ "$p" = -cc1 ]; then
-        cc1=1
-    fi
     n+=1
+
+    case "$p" in
+        -[cSEM] | -MM) dontLink=1 ;;
+        -cc1) cc1=1 ;;
+        -nostdinc) cInclude=0 cxxInclude=0 ;;
+        -nostdinc++) cxxInclude=0 ;;
+        -nostdlib) cxxLibrary=0 ;;
+        -x)
+            case "$p2" in
+                *-header) dontLink=1 ;;
+                c++*) isCxx=1 ;;
+            esac
+            ;;
+        -?*) ;;
+        *) nonFlagArgs=1 ;; # Includes a solitary dash (`-`) which signifies standard input; it is not a flag
+    esac
 done
 
 # If we pass a flag like -Wl, then gcc will call the linker unless it
@@ -81,29 +68,31 @@ fi
 
 # Optionally filter out paths not refering to the store.
 if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then
-    rest=()
+    kept=()
     nParams=${#params[@]}
     declare -i n=0
     while (( "$n" < "$nParams" )); do
         p=${params[n]}
         p2=${params[n+1]:-} # handle `p` being last one
-        if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then
-            skip "${p:2}"
-        elif [ "$p" = -L ] && badPath "$p2"; then
-            n+=1; skip "$p2"
-        elif [ "${p:0:3}" = -I/ ] && badPath "${p:2}"; then
-            skip "${p:2}"
-        elif [ "$p" = -I ] && badPath "$p2"; then
-            n+=1; skip "$p2"
-        elif [ "$p" = -isystem ] && badPath "$p2"; then
-            n+=1; skip "$p2"
-        else
-            rest+=("$p")
-        fi
         n+=1
+
+        skipNext=false
+        path=""
+        case "$p" in
+            -[IL]/*) path=${p:2} ;;
+            -[IL] | -isystem) path=$p2 skipNext=true ;;
+        esac
+
+        if [[ -n $path ]] && badPath "$path"; then
+            skip "$path"
+            $skipNext && n+=1
+            continue
+        fi
+
+        kept+=("$p")
     done
     # Old bash empty array hack
-    params=(${rest+"${rest[@]}"})
+    params=(${kept+"${kept[@]}"})
 fi
 
 # Flirting with a layer violation here.
@@ -118,17 +107,17 @@ fi
 
 # Clear march/mtune=native -- they bring impurity.
 if [ "$NIX_ENFORCE_NO_NATIVE_@suffixSalt@" = 1 ]; then
-    rest=()
+    kept=()
     # Old bash empty array hack
     for p in ${params+"${params[@]}"}; do
         if [[ "$p" = -m*=native ]]; then
             skip "$p"
         else
-            rest+=("$p")
+            kept+=("$p")
         fi
     done
     # Old bash empty array hack
-    params=(${rest+"${rest[@]}"})
+    params=(${kept+"${kept[@]}"})
 fi
 
 if [[ "$isCxx" = 1 ]]; then
@@ -170,6 +159,10 @@ if [ "$dontLink" != 1 ]; then
     export NIX_LINK_TYPE_@suffixSalt@=$linkType
 fi
 
+if [[ -e @out@/nix-support/add-local-cc-cflags-before.sh ]]; then
+    source @out@/nix-support/add-local-cc-cflags-before.sh
+fi
+
 # As a very special hack, if the arguments are just `-v', then don't
 # add anything.  This is to prevent `gcc -v' (which normally prints
 # out the version number and returns exit code 0) from printing out
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/default.nix b/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
index 3738f628b187..047cdf6a4911 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
@@ -14,6 +14,7 @@
 , nativeTools, noLibc ? false, nativeLibc, nativePrefix ? ""
 , propagateDoc ? cc != null && cc ? man
 , extraTools ? [], extraPackages ? [], extraBuildCommands ? ""
+, nixSupport ? {}
 , isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null
 , buildPackages ? {}
 , libcxx ? null
@@ -155,10 +156,13 @@ stdenv.mkDerivation {
             (setenv "NIX_CFLAGS_COMPILE_${suffixSalt}" (concat (getenv "NIX_CFLAGS_COMPILE_${suffixSalt}") " -isystem " arg "/include"))))
         '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
     '';
+
+    inherit nixSupport;
   };
 
   dontBuild = true;
   dontConfigure = true;
+  enableParallelBuilding = true;
 
   unpackPhase = ''
     src=$PWD
@@ -245,12 +249,19 @@ stdenv.mkDerivation {
       wrap ${targetPrefix}gdc $wrapper $ccPath/${targetPrefix}gdc
     ''
 
-    + optionalString cc.langFortran or false ''
+    + optionalString cc.langFortran or false (''
       wrap ${targetPrefix}gfortran $wrapper $ccPath/${targetPrefix}gfortran
       ln -sv ${targetPrefix}gfortran $out/bin/${targetPrefix}g77
       ln -sv ${targetPrefix}gfortran $out/bin/${targetPrefix}f77
       export named_fc=${targetPrefix}gfortran
     ''
+    # Darwin aarch64 fortran compilations seem to fail otherwise, see:
+    # https://github.com/NixOS/nixpkgs/issues/140041
+    + (if (stdenvNoCC.isDarwin && stdenvNoCC.isAarch64) then ''
+      export fortran_hardening="pic strictoverflow relro bindnow"
+    '' else ''
+      export fortran_hardening="pic strictoverflow relro bindnow stackprotector"
+    ''))
 
     + optionalString cc.langJava or false ''
       wrap ${targetPrefix}gcj $wrapper $ccPath/${targetPrefix}gcj
@@ -294,14 +305,6 @@ stdenv.mkDerivation {
     ''
 
     ##
-    ## General Clang support
-    ##
-    + optionalString isClang ''
-
-      echo "-target ${targetPlatform.config}" >> $out/nix-support/cc-cflags
-    ''
-
-    ##
     ## GCC libs for non-GCC support
     ##
     + optionalString useGccForLibs ''
@@ -378,7 +381,6 @@ stdenv.mkDerivation {
     + optionalString (libcxx.isLLVM or false) (''
       echo "-isystem ${lib.getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
       echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags
-    '' + lib.optionalString stdenv.targetPlatform.isLinux ''
       echo "-lc++abi" >> $out/nix-support/libcxx-ldflags
     '')
 
@@ -478,7 +480,7 @@ stdenv.mkDerivation {
       hardening_unsupported_flags+=" stackprotector fortify"
     '' + optionalString targetPlatform.isAvr ''
       hardening_unsupported_flags+=" stackprotector pic"
-    '' + optionalString (targetPlatform.libc == "newlib") ''
+    '' + optionalString (targetPlatform.libc == "newlib" || targetPlatform.libc == "newlib-nano") ''
       hardening_unsupported_flags+=" stackprotector fortify pie pic"
     '' + optionalString (targetPlatform.libc == "musl" && targetPlatform.isx86_32) ''
       hardening_unsupported_flags+=" stackprotector"
@@ -488,6 +490,8 @@ stdenv.mkDerivation {
       hardening_unsupported_flags+=" format stackprotector strictoverflow"
     '' + optionalString cc.langD or false ''
       hardening_unsupported_flags+=" format"
+    '' + optionalString cc.langFortran or false ''
+      hardening_unsupported_flags+=" format"
     '' + optionalString targetPlatform.isWasm ''
       hardening_unsupported_flags+=" stackprotector fortify pie pic"
     ''
@@ -519,9 +523,22 @@ stdenv.mkDerivation {
     ''
 
     ##
+    ## General Clang support
+    ## Needs to go after ^ because the for loop eats \n and makes this file an invalid script
+    ##
+    + optionalString isClang ''
+      export defaultTarget=${targetPlatform.config}
+      substituteAll ${./add-clang-cc-cflags-before.sh} $out/nix-support/add-local-cc-cflags-before.sh
+    ''
+
+    ##
     ## Extra custom steps
     ##
-    + extraBuildCommands;
+    + extraBuildCommands
+    + lib.strings.concatStringsSep "; "
+      (lib.attrsets.mapAttrsToList
+        (name: value: "echo ${toString value} >> $out/nix-support/${name}")
+        nixSupport);
 
   inherit expand-response-params;
 
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh b/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh
index d72f314c01ce..59e493e1836d 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/fortran-hook.sh
@@ -5,7 +5,7 @@ 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="@fortran_hardening@"}
 export NIX_HARDENING_ENABLE
 
 unset -v role_post
diff --git a/nixpkgs/pkgs/build-support/coq/default.nix b/nixpkgs/pkgs/build-support/coq/default.nix
index a681bbda5575..0dc5c999ea35 100644
--- a/nixpkgs/pkgs/build-support/coq/default.nix
+++ b/nixpkgs/pkgs/build-support/coq/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, coqPackages, coq, fetchzip }@args:
+{ lib, stdenv, coqPackages, coq, which, fetchzip }@args:
 let lib = import ./extra-lib.nix {inherit (args) lib;}; in
 with builtins; with lib;
 let
@@ -15,8 +15,12 @@ in
   releaseRev ? (v: v),
   displayVersion ? {},
   release ? {},
+  buildInputs ? [],
+  nativeBuildInputs ? [],
   extraBuildInputs ? [],
   extraNativeBuildInputs ? [],
+  overrideBuildInputs ? [],
+  overrideNativeBuildInputs ? [],
   namePrefix ? [ "coq" ],
   enableParallelBuilding ? true,
   extraInstallFlags ? [],
@@ -35,7 +39,11 @@ let
   args-to-remove = foldl (flip remove) ([
     "version" "fetcher" "repo" "owner" "domain" "releaseRev"
     "displayVersion" "defaultVersion" "useMelquiondRemake"
-    "release" "extraBuildInputs" "extraNativeBuildInputs" "extraPropagatedBuildInputs" "namePrefix"
+    "release"
+    "buildInputs" "nativeBuildInputs"
+    "extraBuildInputs" "extraNativeBuildInputs"
+    "overrideBuildInputs" "overrideNativeBuildInputs"
+    "namePrefix"
     "meta" "useDune2ifVersion" "useDune2" "opam-name"
     "extraInstallFlags" "setCOQBIN" "mlPlugin"
     "dropAttrs" "dropDerivationAttrs" "keepAttrs" ] ++ dropAttrs) keepAttrs;
@@ -57,9 +65,16 @@ let
     ] "") + optionalString (v == null) "-broken";
   append-version = p: n: p + display-pkg n "" coqPackages.${n}.version + "-";
   prefix-name = foldl append-version "" namePrefix;
-  var-coqlib-install =
-    (optionalString (versions.isGe "8.7" coq.coq-version || coq.coq-version == "dev") "COQMF_") + "COQLIB";
   useDune2 = args.useDune2 or (useDune2ifVersion fetched.version);
+  coqlib-flags = switch coq.coq-version [
+    { case = v: versions.isLe "8.6" v && v != "dev" ;
+      out = [ "COQLIB=$(out)/lib/coq/${coq.coq-version}/" ]; }
+  ] [ "COQLIBINSTALL=$(out)/lib/coq/${coq.coq-version}/user-contrib"
+      "COQPLUGININSTALL=$(OCAMLFIND_DESTDIR)" ];
+  docdir-flags = switch coq.coq-version [
+    { case = v: versions.isLe "8.6" v && v != "dev";
+      out = [ "DOCDIR=$(out)/share/coq/${coq.coq-version}/" ]; }
+  ] [ "COQDOCINSTALL=$(out)/share/coq/${coq.coq-version}/user-contrib" ];
 in
 
 stdenv.mkDerivation (removeAttrs ({
@@ -68,12 +83,13 @@ stdenv.mkDerivation (removeAttrs ({
 
   inherit (fetched) version src;
 
-  nativeBuildInputs = [ coq ]
-    ++ optionals useDune2 [coq.ocaml coq.ocamlPackages.dune_2]
-    ++ optionals mlPlugin coq.ocamlNativeBuildInputs
-    ++ extraNativeBuildInputs;
-  buildInputs = optionals mlPlugin coq.ocamlBuildInputs
-    ++ extraBuildInputs;
+  nativeBuildInputs = args.overrideNativeBuildInputs
+    or ([ which coq.ocamlPackages.findlib ]
+        ++ optional useDune2 coq.ocamlPackages.dune_2
+        ++ optional (useDune2 || mlPlugin) coq.ocamlPackages.ocaml
+        ++ (args.nativeBuildInputs or []) ++ extraNativeBuildInputs);
+  buildInputs = args.overrideBuildInputs
+    or ([ coq ] ++ (args.buildInputs or []) ++ extraBuildInputs);
   inherit enableParallelBuilding;
 
   meta = ({ platforms = coq.meta.platforms; } //
@@ -88,9 +104,7 @@ stdenv.mkDerivation (removeAttrs ({
 // (optionalAttrs setCOQBIN { COQBIN = "${coq}/bin/"; })
 // (optionalAttrs (!args?installPhase && !args?useMelquiondRemake) {
   installFlags =
-    [ "${var-coqlib-install}=$(out)/lib/coq/${coq.coq-version}/" ] ++
-    optional (match ".*doc$" (args.installTargets or "") != null)
-      "DOCDIR=$(out)/share/coq/${coq.coq-version}/" ++
+    coqlib-flags ++ docdir-flags ++
     extraInstallFlags;
 })
 // (optionalAttrs useDune2 {
diff --git a/nixpkgs/pkgs/build-support/docker/default.nix b/nixpkgs/pkgs/build-support/docker/default.nix
index 5718cadd4ffa..7468f056005a 100644
--- a/nixpkgs/pkgs/build-support/docker/default.nix
+++ b/nixpkgs/pkgs/build-support/docker/default.nix
@@ -6,8 +6,8 @@
 , coreutils
 , e2fsprogs
 , fakechroot
+, fakeNss
 , fakeroot
-, findutils
 , go
 , jq
 , jshon
@@ -15,8 +15,8 @@
 , makeWrapper
 , moreutils
 , nix
+, nixosTests
 , pigz
-, pkgs
 , rsync
 , runCommand
 , runtimeShell
@@ -25,6 +25,7 @@
 , storeDir ? builtins.storeDir
 , substituteAll
 , symlinkJoin
+, tarsum
 , util-linux
 , vmTools
 , writeReferencesToFile
@@ -80,6 +81,15 @@ rec {
     inherit buildImage buildLayeredImage fakeNss pullImage shadowSetup buildImageWithNixDb;
   };
 
+  tests = {
+    inherit (nixosTests)
+      docker-tools
+      docker-tools-overlay
+      # requires remote builder
+      # docker-tools-cross
+      ;
+  };
+
   pullImage =
     let
       fixName = name: builtins.replaceStrings [ "/" ":" ] [ "-" "-" ] name;
@@ -112,7 +122,7 @@ rec {
         outputHashAlgo = "sha256";
         outputHash = sha256;
 
-        nativeBuildInputs = lib.singleton skopeo;
+        nativeBuildInputs = [ skopeo ];
         SSL_CERT_FILE = "${cacert.out}/etc/ssl/certs/ca-bundle.crt";
 
         sourceURL = "docker://${imageName}@${imageDigest}";
@@ -131,7 +141,7 @@ rec {
 
   # We need to sum layer.tar, not a directory, hence tarsum instead of nix-hash.
   # And we cannot untar it, because then we cannot preserve permissions etc.
-  tarsum = pkgs.tarsum;
+  inherit tarsum; # pkgs.dockerTools.tarsum
 
   # buildEnv creates symlinks to dirs, which is hard to edit inside the overlay VM
   mergeDrvs =
@@ -195,6 +205,7 @@ rec {
     , fromImageName ? null
     , fromImageTag ? null
     , diskSize ? 1024
+    , buildVMMemorySize ? 512
     , preMount ? ""
     , postMount ? ""
     , postUmount ? ""
@@ -208,6 +219,7 @@ rec {
               destination = "./image";
             };
             inherit fromImage fromImageName fromImageTag;
+            memSize = buildVMMemorySize;
 
             nativeBuildInputs = [ util-linux e2fsprogs jshon rsync jq ];
           } ''
@@ -322,7 +334,7 @@ rec {
     , # JSON containing configuration and metadata for this layer.
       baseJson
     , # Files to add to the layer.
-      contents ? null
+      copyToRoot ? null
     , # When copying the contents into the image, preserve symlinks to
       # directories (see `rsync -K`).  Otherwise, transform those symlinks
       # into directories.
@@ -334,7 +346,8 @@ rec {
     }:
     runCommand "docker-layer-${name}"
       {
-        inherit baseJson contents extraCommands;
+        inherit baseJson extraCommands;
+        contents = copyToRoot;
         nativeBuildInputs = [ jshon rsync tarsum ];
       }
       ''
@@ -380,7 +393,8 @@ rec {
     , # Script to run as root. Bash.
       runAsRoot
     , # Files to add to the layer. If null, an empty layer will be created.
-      contents ? null
+      # To add packages to /bin, use `buildEnv` or similar.
+      copyToRoot ? null
     , # When copying the contents into the image, preserve symlinks to
       # directories (see `rsync -K`).  Otherwise, transform those symlinks
       # into directories.
@@ -395,6 +409,8 @@ rec {
       fromImageTag ? null
     , # How much disk to allocate for the temporary virtual machine.
       diskSize ? 1024
+    , # How much memory to allocate for the temporary virtual machine.
+      buildVMMemorySize ? 512
     , # Commands (bash) to run on the layer; these do not require sudo.
       extraCommands ? ""
     }:
@@ -406,11 +422,11 @@ rec {
     runWithOverlay {
       name = "docker-layer-${name}";
 
-      inherit fromImage fromImageName fromImageTag diskSize;
+      inherit fromImage fromImageName fromImageTag diskSize buildVMMemorySize;
 
-      preMount = lib.optionalString (contents != null && contents != [ ]) ''
+      preMount = lib.optionalString (copyToRoot != null && copyToRoot != [ ]) ''
         echo "Adding contents..."
-        for item in ${escapeShellArgs (map (c: "${c}") (toList contents))}; do
+        for item in ${escapeShellArgs (map (c: "${c}") (toList copyToRoot))}; do
           echo "Adding $item..."
           rsync -a${if keepContentsDirlinks then "K" else "k"} --chown=0:0 $item/ layer/
         done
@@ -490,7 +506,7 @@ rec {
     , # Tag of the parent image; will be read from the image otherwise.
       fromImageTag ? null
     , # Files to put on the image (a nix store path or list of paths).
-      contents ? null
+      copyToRoot ? null
     , # When copying the contents into the image, preserve symlinks to
       # directories (see `rsync -K`).  Otherwise, transform those symlinks
       # into directories.
@@ -505,12 +521,24 @@ rec {
       runAsRoot ? null
     , # Size of the virtual machine disk to provision when building the image.
       diskSize ? 1024
+    , # Size of the virtual machine memory to provision when building the image.
+      buildVMMemorySize ? 512
     , # Time of creation of the image.
       created ? "1970-01-01T00:00:01Z"
+    , # Deprecated.
+      contents ? null
     ,
     }:
 
     let
+      checked =
+        lib.warnIf (contents != null)
+          "in docker image ${name}: The contents parameter is deprecated. Change to copyToRoot if the contents are designed to be copied to the root filesystem, such as when you use `buildEnv` or similar between contents and your packages. Use copyToRoot = buildEnv { ... }; or similar if you intend to add packages to /bin."
+        lib.throwIf (contents != null && copyToRoot != null) "in docker image ${name}: You can not specify both contents and copyToRoot."
+        ;
+
+      rootContents = if copyToRoot == null then contents else copyToRoot;
+
       baseName = baseNameOf name;
 
       # Create a JSON blob of the configuration. Set the date to unix zero.
@@ -535,17 +563,19 @@ rec {
           mkPureLayer
             {
               name = baseName;
-              inherit baseJson contents keepContentsDirlinks extraCommands uid gid;
+              inherit baseJson keepContentsDirlinks extraCommands uid gid;
+              copyToRoot = rootContents;
             } else
           mkRootLayer {
             name = baseName;
             inherit baseJson fromImage fromImageName fromImageTag
-              contents keepContentsDirlinks runAsRoot diskSize
+              keepContentsDirlinks runAsRoot diskSize buildVMMemorySize
               extraCommands;
+            copyToRoot = rootContents;
           };
       result = runCommand "docker-image-${baseName}.tar.gz"
         {
-          nativeBuildInputs = [ jshon pigz coreutils findutils jq moreutils ];
+          nativeBuildInputs = [ jshon pigz jq moreutils ];
           # Image name must be lowercase
           imageName = lib.toLower name;
           imageTag = if tag == null then "" else tag;
@@ -705,7 +735,7 @@ rec {
       '';
 
     in
-    result;
+    checked result;
 
   # Merge the tarballs of images built with buildImage into a single
   # tarball that contains all images. Running `docker load` on the resulting
@@ -747,31 +777,13 @@ rec {
   # Useful when packaging binaries that insist on using nss to look up
   # username/groups (like nginx).
   # /bin/sh is fine to not exist, and provided by another shim.
-  fakeNss = symlinkJoin {
-    name = "fake-nss";
-    paths = [
-      (writeTextDir "etc/passwd" ''
-        root:x:0:0:root user:/var/empty:/bin/sh
-        nobody:x:65534:65534:nobody:/var/empty:/bin/sh
-      '')
-      (writeTextDir "etc/group" ''
-        root:x:0:
-        nobody:x:65534:
-      '')
-      (writeTextDir "etc/nsswitch.conf" ''
-        hosts: files dns
-      '')
-      (runCommand "var-empty" { } ''
-        mkdir -p $out/var/empty
-      '')
-    ];
-  };
+  inherit fakeNss; # alias
 
   # This provides a /usr/bin/env, for shell scripts using the
   # "#!/usr/bin/env executable" shebang.
   usrBinEnv = runCommand "usr-bin-env" { } ''
     mkdir -p $out/usr/bin
-    ln -s ${pkgs.coreutils}/bin/env $out/usr/bin
+    ln -s ${coreutils}/bin/env $out/usr/bin
   '';
 
   # This provides /bin/sh, pointing to bashInteractive.
@@ -784,12 +796,14 @@ rec {
   # contents. The main purpose is to be able to use nix commands in
   # the container.
   # Be careful since this doesn't work well with multilayer.
-  buildImageWithNixDb = args@{ contents ? null, extraCommands ? "", ... }: (
+  # TODO: add the dependencies of the config json.
+  buildImageWithNixDb = args@{ copyToRoot ? contents, contents ? null, extraCommands ? "", ... }: (
     buildImage (args // {
-      extraCommands = (mkDbExtraCommand contents) + extraCommands;
+      extraCommands = (mkDbExtraCommand copyToRoot) + extraCommands;
     })
   );
 
+  # TODO: add the dependencies of the config json.
   buildLayeredImageWithNixDb = args@{ contents ? null, extraCommands ? "", ... }: (
     buildLayeredImage (args // {
       extraCommands = (mkDbExtraCommand contents) + extraCommands;
diff --git a/nixpkgs/pkgs/build-support/docker/examples.nix b/nixpkgs/pkgs/build-support/docker/examples.nix
index 941ee048666d..ff3934941c7b 100644
--- a/nixpkgs/pkgs/build-support/docker/examples.nix
+++ b/nixpkgs/pkgs/build-support/docker/examples.nix
@@ -9,12 +9,26 @@
 
 { pkgs, buildImage, buildLayeredImage, fakeNss, pullImage, shadowSetup, buildImageWithNixDb, pkgsCross }:
 
+let
+  nixosLib = import ../../../nixos/lib {
+    # Experimental features need testing too, but there's no point in warning
+    # about it, so we enable the feature flag.
+    featureFlags.minimalModules = {};
+  };
+  evalMinimalConfig = module: nixosLib.evalModules { modules = [ module ]; };
+
+in
+
 rec {
   # 1. basic example
   bash = buildImage {
     name = "bash";
     tag = "latest";
-    contents = pkgs.bashInteractive;
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      paths = [ pkgs.bashInteractive ];
+      pathsToLink = [ "/bin" ];
+    };
   };
 
   # 2. service example, layered on another image
@@ -26,7 +40,12 @@ rec {
     fromImage = bash;
     # fromImage = debian;
 
-    contents = pkgs.redis;
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      paths = [ pkgs.redis ];
+      pathsToLink = [ "/bin" ];
+    };
+
     runAsRoot = ''
       mkdir -p /data
     '';
@@ -97,7 +116,7 @@ rec {
   };
   # Same example, but re-fetches every time the fetcher implementation changes.
   # NOTE: Only use this for testing, or you'd be wasting a lot of time, network and space.
-  testNixFromDockerHub = pkgs.invalidateFetcherByDrvHash pullImage {
+  testNixFromDockerHub = pkgs.testers.invalidateFetcherByDrvHash pullImage {
     imageName = "nixos/nix";
     imageDigest = "sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357";
     sha256 = "19fw0n3wmddahzr20mhdqv6jkjn1kanh6n2mrr08ai53dr8ph5n7";
@@ -108,13 +127,17 @@ rec {
   # 5. example of multiple contents, emacs and vi happily coexisting
   editors = buildImage {
     name = "editors";
-    contents = [
-      pkgs.coreutils
-      pkgs.bash
-      pkgs.emacs
-      pkgs.vim
-      pkgs.nano
-    ];
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [
+        pkgs.coreutils
+        pkgs.bash
+        pkgs.emacs
+        pkgs.vim
+        pkgs.nano
+      ];
+    };
   };
 
   # 6. nix example to play with the container nix store
@@ -122,13 +145,17 @@ rec {
   nix = buildImageWithNixDb {
     name = "nix";
     tag = "latest";
-    contents = [
-      # nix-store uses cat program to display results as specified by
-      # the image env variable NIX_PAGER.
-      pkgs.coreutils
-      pkgs.nix
-      pkgs.bash
-    ];
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [
+        # nix-store uses cat program to display results as specified by
+        # the image env variable NIX_PAGER.
+        pkgs.coreutils
+        pkgs.nix
+        pkgs.bash
+      ];
+    };
     config = {
       Env = [
         "NIX_PAGER=cat"
@@ -145,7 +172,11 @@ rec {
     name = "onTopOfPulledImage";
     tag = "latest";
     fromImage = nixFromDockerHub;
-    contents = [ pkgs.hello ];
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [ pkgs.hello ];
+    };
   };
 
   # 8. regression test for erroneous use of eval and string expansion.
@@ -153,7 +184,11 @@ rec {
   runAsRootExtraCommands = pkgs.dockerTools.buildImage {
     name = "runAsRootExtraCommands";
     tag = "latest";
-    contents = [ pkgs.coreutils ];
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [ pkgs.coreutils ];
+    };
     # The parens here are to create problematic bash to embed and eval. In case
     # this is *embedded* into the script (with nix expansion) the initial quotes
     # will close the string and the following parens are unexpected
@@ -166,7 +201,11 @@ rec {
   unstableDate = pkgs.dockerTools.buildImage {
     name = "unstable-date";
     tag = "latest";
-    contents = [ pkgs.coreutils ];
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [ pkgs.coreutils ];
+    };
     created = "now";
   };
 
@@ -255,7 +294,11 @@ rec {
     name = "l3";
     fromImage = l2;
     tag = "latest";
-    contents = [ pkgs.coreutils ];
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [ pkgs.coreutils ];
+    };
     extraCommands = ''
       mkdir -p tmp
       echo layer3 > tmp/layer3
@@ -280,7 +323,11 @@ rec {
     name = "child";
     fromImage = environmentVariablesParent;
     tag = "latest";
-    contents = [ pkgs.coreutils ];
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [ pkgs.coreutils ];
+    };
     config = {
       Env = [
         "FROM_CHILD=true"
@@ -414,7 +461,11 @@ rec {
         name = "layers-unpack-order-${layerName}";
         tag = "latest";
         fromImage = parent;
-        contents = [ pkgs.coreutils ];
+        copyToRoot = pkgs.buildEnv {
+          name = "image-root";
+          pathsToLink = [ "/bin" ];
+          paths = [ pkgs.coreutils ];
+        };
         runAsRoot = ''
           #!${pkgs.runtimeShell}
           echo -n "${layerName}" >> /layer-order
@@ -431,7 +482,8 @@ rec {
   # buildImage without explicit tag
   bashNoTag = pkgs.dockerTools.buildImage {
     name = "bash-no-tag";
-    contents = pkgs.bashInteractive;
+    # Not recommended. Use `buildEnv` between copy and packages to avoid file duplication.
+    copyToRoot = pkgs.bashInteractive;
   };
 
   # buildLayeredImage without explicit tag
@@ -486,12 +538,16 @@ rec {
   cross = let
     # Cross compile for x86_64 if on aarch64
     crossPkgs =
-      if pkgs.system == "aarch64-linux" then pkgsCross.gnu64
+      if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then pkgsCross.gnu64
       else pkgsCross.aarch64-multiplatform;
   in crossPkgs.dockerTools.buildImage {
     name = "hello-cross";
     tag = "latest";
-    contents = crossPkgs.hello;
+    copyToRoot = pkgs.buildEnv {
+      name = "image-root";
+      pathsToLink = [ "/bin" ];
+      paths = [ crossPkgs.hello ];
+    };
   };
 
   # layered image where a store path is itself a symlink
@@ -528,11 +584,11 @@ rec {
       pkgs.pkgsStatic.busybox
     ];
     fakeRootCommands = ''
-      mkdir -p ./home/jane
-      chown 1000 ./home/jane
+      mkdir -p ./home/alice
+      chown 1000 ./home/alice
       ln -s ${pkgs.hello.overrideAttrs (o: {
         # A unique `hello` to make sure that it isn't included via another mechanism by accident.
-        configureFlags = o.configureFlags or "" + " --program-prefix=layeredImageWithFakeRootCommands-";
+        configureFlags = o.configureFlags or [] ++ [ " --program-prefix=layeredImageWithFakeRootCommands-" ];
         doCheck = false;
       })} ./hello
     '';
@@ -551,7 +607,7 @@ rec {
   ];
 
   # tarball consisting of bash and layered image with different owner of the
-  # /home/jane directory
+  # /home/alice directory
   mergedBashFakeRoot = pkgs.dockerTools.mergeImages [
     bash
     layeredImageWithFakeRootCommands
@@ -582,6 +638,37 @@ rec {
     includeStorePaths = false;
   };
 
+  etc =
+    let
+      inherit (pkgs) lib;
+      nixosCore = (evalMinimalConfig ({ config, ... }: {
+        imports = [
+          pkgs.pkgsModule
+          ../../../nixos/modules/system/etc/etc.nix
+        ];
+        environment.etc."some-config-file" = {
+          text = ''
+            127.0.0.1 localhost
+            ::1 localhost
+          '';
+          # For executables:
+          # mode = "0755";
+        };
+      }));
+    in pkgs.dockerTools.streamLayeredImage {
+      name = "etc";
+      tag = "latest";
+      enableFakechroot = true;
+      fakeRootCommands = ''
+        mkdir -p /etc
+        ${nixosCore.config.system.build.etcActivationCommands}
+      '';
+      config.Cmd = pkgs.writeScript "etc-cmd" ''
+        #!${pkgs.busybox}/bin/sh
+        ${pkgs.busybox}/bin/cat /etc/some-config-file
+      '';
+    };
+
   # Example export of the bash image
   exportBash = pkgs.dockerTools.exportImage { fromImage = bash; };
 
@@ -602,7 +689,8 @@ rec {
   build-image-with-path = buildImage {
     name = "build-image-with-path";
     tag = "latest";
-    contents = [ pkgs.bashInteractive ./test-dummy ];
+    # Not recommended. Use `buildEnv` between copy and packages to avoid file duplication.
+    copyToRoot = [ pkgs.bashInteractive ./test-dummy ];
   };
 
   layered-image-with-path = pkgs.dockerTools.streamLayeredImage {
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 b5651d72a920..bc50f1bd090c 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenvNoCC, linkFarmFromDrvs, callPackage, nuget-to-nix, writeScript, makeWrapper, fetchurl, xml2, dotnetCorePackages, dotnetPackages, mkNugetSource, mkNugetDeps, cacert }:
+{ lib, stdenvNoCC, linkFarmFromDrvs, callPackage, nuget-to-nix, writeShellScript, makeWrapper, fetchurl, xml2, dotnetCorePackages, dotnetPackages, mkNugetSource, mkNugetDeps, cacert, srcOnly, symlinkJoin, coreutils }:
 
 { name ? "${args.pname}-${args.version}"
 , pname ? name
@@ -55,10 +55,12 @@
 
 # The type of build to perform. This is passed to `dotnet` with the `--configuration` flag. Possible values are `Release`, `Debug`, etc.
 , buildType ? "Release"
+# If set to true, builds the application as a self-contained - removing the runtime dependency on dotnet
+, selfContainedBuild ? false
 # The dotnet SDK to use.
-, dotnet-sdk ? dotnetCorePackages.sdk_5_0
+, dotnet-sdk ? dotnetCorePackages.sdk_6_0
 # The dotnet runtime to use.
-, dotnet-runtime ? dotnetCorePackages.runtime_5_0
+, dotnet-runtime ? dotnetCorePackages.runtime_6_0
 # The dotnet SDK to run tests against. This can differentiate from the SDK compiled against.
 , dotnet-test-sdk ? dotnet-sdk
 , ... } @ args:
@@ -74,15 +76,38 @@ let
     inherit dotnet-sdk dotnet-test-sdk disabledTests nuget-source dotnet-runtime runtimeDeps buildType;
   }) dotnetConfigureHook dotnetBuildHook dotnetCheckHook dotnetInstallHook dotnetFixupHook;
 
-  _nugetDeps = mkNugetDeps { name = "${name}-nuget-deps"; nugetDeps = import nugetDeps; };
-  _localDeps = linkFarmFromDrvs "${name}-local-nuget-deps" projectReferences;
+  localDeps = if (projectReferences != [])
+    then linkFarmFromDrvs "${name}-project-references" projectReferences
+    else null;
 
-  nuget-source = mkNugetSource {
-    name = "${args.pname}-nuget-source";
-    description = "A Nuget source with the dependencies for ${args.pname}";
-    deps = [ _nugetDeps _localDeps ];
+  _nugetDeps = if lib.isDerivation nugetDeps
+    then nugetDeps
+    else mkNugetDeps { inherit name; nugetDeps = import nugetDeps; };
+
+  # contains the actual package dependencies
+  _dependenciesSource = mkNugetSource {
+    name = "${name}-dependencies-source";
+    description = "A Nuget source with the dependencies for ${name}";
+    deps = [ _nugetDeps ] ++ lib.optional (localDeps != null) localDeps;
+  };
+
+  # this contains all the nuget packages that are implictly referenced by the dotnet
+  # build system. having them as separate deps allows us to avoid having to regenerate
+  # a packages dependencies when the dotnet-sdk version changes
+  _sdkDeps = mkNugetDeps {
+    name = "dotnet-sdk-${dotnet-sdk.version}-deps";
+    nugetDeps = dotnet-sdk.passthru.packages;
   };
 
+  _sdkSource = mkNugetSource {
+    name = "dotnet-sdk-${dotnet-sdk.version}-source";
+    deps = [ _sdkDeps ];
+  };
+
+  nuget-source = symlinkJoin {
+    name = "${name}-nuget-source";
+    paths = [ _dependenciesSource _sdkSource ];
+  };
 in stdenvNoCC.mkDerivation (args // {
   nativeBuildInputs = args.nativeBuildInputs or [] ++ [
     dotnetConfigureHook
@@ -91,9 +116,13 @@ in stdenvNoCC.mkDerivation (args // {
     dotnetInstallHook
     dotnetFixupHook
 
-    dotnet-sdk
     cacert
     makeWrapper
+    dotnet-sdk
+  ];
+
+  makeWrapperArgs = args.makeWrapperArgs or [ ] ++ [
+    "--prefix LD_LIBRARY_PATH : ${dotnet-sdk.icu}/lib"
   ];
 
   # Stripping breaks the executable
@@ -103,14 +132,20 @@ in stdenvNoCC.mkDerivation (args // {
   dontWrapGApps = args.dontWrapGApps or true;
 
   passthru = {
-    fetch-deps = writeScript "fetch-${pname}-deps" ''
+    inherit nuget-source;
+
+    fetch-deps = let
+      exclusions = dotnet-sdk.passthru.packages { fetchNuGet = attrs: attrs.pname; };
+    in writeShellScript "fetch-${pname}-deps" ''
       set -euo pipefail
+      export PATH="${lib.makeBinPath [ coreutils dotnet-sdk nuget-to-nix ]}"
+
       cd "$(dirname "''${BASH_SOURCE[0]}")"
 
       export HOME=$(mktemp -d)
-      deps_file="/tmp/${pname}-deps.nix"
+      deps_file="''${1:-/tmp/${pname}-deps.nix}"
 
-      store_src="${args.src}"
+      store_src="${srcOnly args}"
       src="$(mktemp -d /tmp/${pname}.XXX)"
       cp -rT "$store_src" "$src"
       chmod -R +w "$src"
@@ -124,7 +159,7 @@ in stdenvNoCC.mkDerivation (args // {
       mkdir -p "$HOME/nuget_pkgs"
 
       for project in "${lib.concatStringsSep "\" \"" ((lib.toList projectFile) ++ lib.optionals (testProjectFile != "") (lib.toList testProjectFile))}"; do
-        ${dotnet-sdk}/bin/dotnet restore "$project" \
+        dotnet restore "$project" \
           ${lib.optionalString (!enableParallelBuilding) "--disable-parallel"} \
           -p:ContinuousIntegrationBuild=true \
           -p:Deterministic=true \
@@ -133,8 +168,10 @@ in stdenvNoCC.mkDerivation (args // {
           ${lib.optionalString (dotnetFlags != []) (builtins.toString dotnetFlags)}
       done
 
+      echo "${lib.concatStringsSep "\n" exclusions}" > "$HOME/package_exclusions"
+
       echo "Writing lockfile..."
-      ${nuget-to-nix}/bin/nuget-to-nix "$HOME/nuget_pkgs" > "$deps_file"
+      nuget-to-nix "$HOME/nuget_pkgs" "$HOME/package_exclusions" > "$deps_file"
       echo "Succesfully wrote lockfile to: $deps_file"
     '';
   } // args.passthru or {};
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix
index 76f7eea5bfec..1cc88602ff4c 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix
@@ -11,6 +11,9 @@
 , buildType
 }:
 
+let
+  libraryPath = lib.makeLibraryPath runtimeDeps;
+in
 {
   dotnetConfigureHook = callPackage ({ }:
     makeSetupHook {
@@ -35,7 +38,7 @@
       name = "dotnet-check-hook";
       deps = [ dotnet-test-sdk ];
       substitutions = {
-        inherit buildType;
+        inherit buildType libraryPath;
         disabledTests = lib.optionalString (disabledTests != [])
           (lib.concatStringsSep "&FullyQualifiedName!=" disabledTests);
       };
@@ -53,10 +56,10 @@
   dotnetFixupHook = callPackage ({ }:
     makeSetupHook {
       name = "dotnet-fixup-hook";
-      deps = [ dotnet-runtime makeWrapper ];
+      deps = [ dotnet-runtime ];
       substitutions = {
         dotnetRuntime = dotnet-runtime;
-        runtimeDeps = lib.makeLibraryPath runtimeDeps;
+        runtimeDeps = libraryPath;
       };
     } ./dotnet-fixup-hook.sh) { };
 }
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh
index a1dc80a77fd7..c7a6d8c17aba 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh
@@ -1,4 +1,5 @@
-declare -a projectFile testProjectFile dotnetBuildFlags dotnetFlags
+# inherit arguments from derivation
+dotnetBuildFlags=( ${dotnetBuildFlags[@]-} )
 
 dotnetBuildHook() {
     echo "Executing dotnetBuildHook"
@@ -13,6 +14,12 @@ dotnetBuildHook() {
         parallelBuildFlag="false"
     fi
 
+    if [ "${selfContainedBuild-}" ]; then
+        dotnetBuildFlags+=("-p:SelfContained=true")
+    else
+        dotnetBuildFlags+=("-p:SelfContained=false")
+    fi
+
     if [ "${version-}" ]; then
         versionFlag="-p:Version=${version-}"
     fi
@@ -24,11 +31,12 @@ dotnetBuildHook() {
                 -p:BuildInParallel=$parallelBuildFlag \
                 -p:ContinuousIntegrationBuild=true \
                 -p:Deterministic=true \
+                -p:UseAppHost=true \
                 --configuration "@buildType@" \
                 --no-restore \
                 ${versionFlag-} \
-                "${dotnetBuildFlags[@]}"  \
-                "${dotnetFlags[@]}"
+                ${dotnetBuildFlags[@]}  \
+                ${dotnetFlags[@]}
     done
 
     runHook postBuild
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh
index e3098908fe27..bc7b1b5c3d82 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh
@@ -1,4 +1,5 @@
-declare -a testProjectFile dotnetTestFlags dotnetFlags
+# inherit arguments from derivation
+dotnetTestFlags=( ${dotnetTestFlags[@]-} )
 
 dotnetCheckHook() {
     echo "Executing dotnetCheckHook"
@@ -10,7 +11,7 @@ dotnetCheckHook() {
     fi
 
     for project in ${testProjectFile[@]}; do
-        env \
+        env "LD_LIBRARY_PATH=@libraryPath@" \
             dotnet test "$project" \
               -maxcpucount:$maxCpuFlag \
               -p:ContinuousIntegrationBuild=true \
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
index 59daacbac0ed..3e8c14189500 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
@@ -1,4 +1,8 @@
-declare -a projectFile testProjectFile dotnetRestoreFlags dotnetFlags
+declare -a projectFile testProjectFile
+
+# Inherit arguments from derivation
+dotnetFlags=( ${dotnetFlags[@]-} )
+dotnetRestoreFlags=( ${dotnetRestoreFlags[@]-} )
 
 dotnetConfigureHook() {
     echo "Executing dotnetConfigureHook"
@@ -16,8 +20,8 @@ dotnetConfigureHook() {
                 -p:Deterministic=true \
                 --source "@nugetSource@/lib" \
                 ${parallelFlag-} \
-                "${dotnetRestoreFlags[@]}" \
-                "${dotnetFlags[@]}"
+                ${dotnetRestoreFlags[@]} \
+                ${dotnetFlags[@]}
     done
 
     runHook postConfigure
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 f8bbb7b1805b..0a881fae9cfa 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
@@ -1,10 +1,15 @@
-declare -a makeWrapperArgs gappsWrapperArgs
+# Inherit arguments from the derivation
+makeWrapperArgs=( ${makeWrapperArgs-} )
 
 # First argument is the executable you want to wrap,
 # the second is the destination for the wrapper.
 wrapDotnetProgram() {
+    if [ ! "${selfContainedBuild-}" ]; then
+        dotnetRootFlag=("--set" "DOTNET_ROOT" "@dotnetRuntime@")
+    fi
+
     makeWrapper "$1" "$2" \
-        --set "DOTNET_ROOT" "@dotnetRuntime@" \
+        "${dotnetRootFlag[@]}" \
         --suffix "LD_LIBRARY_PATH" : "@runtimeDeps@" \
         "${gappsWrapperArgs[@]}" \
         "${makeWrapperArgs[@]}"
@@ -15,9 +20,9 @@ wrapDotnetProgram() {
 dotnetFixupHook() {
     echo "Executing dotnetFixupPhase"
 
-    if [ "${executables-}" ]; then
+    if [ "${executables}" ]; then
         for executable in ${executables[@]}; do
-            execPath="$out/lib/${pname-}/$executable"
+            execPath="$out/lib/${pname}/$executable"
 
             if [[ -f "$execPath" && -x "$execPath" ]]; then
                 wrapDotnetProgram "$execPath" "$out/bin/$(basename "$executable")"
@@ -27,7 +32,7 @@ dotnetFixupHook() {
             fi
         done
     else
-        for executable in $out/lib/${pname-}/*; do
+        for executable in $out/lib/${pname}/*; do
             if [[ -f "$executable" && -x "$executable" && "$executable" != *"dll"* ]]; then
                 wrapDotnetProgram "$executable" "$out/bin/$(basename "$executable")"
             fi
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 ed2c9160cd2c..fd88ea32ec04 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
@@ -1,21 +1,28 @@
-declare -a projectFile dotnetInstallFlags dotnetFlags
+# inherit arguments from derivation
+dotnetInstallFlags=( ${dotnetInstallFlags[@]-} )
 
 dotnetInstallHook() {
     echo "Executing dotnetInstallHook"
 
     runHook preInstall
 
+    if [ "${selfContainedBuild-}" ]; then
+        dotnetInstallFlags+=("--self-contained")
+    else
+        dotnetInstallFlags+=("--no-self-contained")
+    fi
+
     for project in ${projectFile[@]}; do
         env \
             dotnet publish "$project" \
                 -p:ContinuousIntegrationBuild=true \
                 -p:Deterministic=true \
+                -p:UseAppHost=true \
                 --output "$out/lib/${pname}" \
                 --configuration "@buildType@" \
                 --no-build \
-                --no-self-contained \
-                "${dotnetInstallFlags[@]}"  \
-                "${dotnetFlags[@]}"
+                ${dotnetInstallFlags[@]}  \
+                ${dotnetFlags[@]}
     done
 
     if [[ "${packNupkg-}" ]]; then
@@ -27,8 +34,8 @@ dotnetInstallHook() {
                     --output "$out/share" \
                     --configuration "@buildType@" \
                     --no-build \
-                    "${dotnetPackFlags[@]}"  \
-                    "${dotnetFlags[@]}"
+                    ${dotnetPackFlags[@]}  \
+                    ${dotnetFlags[@]}
         done
     fi
 
diff --git a/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix b/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix
index 75178d5b7797..edbea45c52a5 100644
--- a/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix
@@ -1,9 +1,10 @@
 { linkFarmFromDrvs, fetchurl }:
 { name, nugetDeps }:
-  linkFarmFromDrvs "${name}-nuget-deps" (nugetDeps {
-    fetchNuGet = { pname, version, sha256 }: fetchurl {
+linkFarmFromDrvs "${name}-nuget-deps" (nugetDeps {
+  fetchNuGet = { pname, version, sha256
+    , url ? "https://www.nuget.org/api/v2/package/${pname}/${version}" }:
+    fetchurl {
       name = "${pname}-${version}.nupkg";
-      url = "https://www.nuget.org/api/v2/package/${pname}/${version}";
-      inherit sha256;
+      inherit url sha256;
     };
-  })
+})
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 0690a05aa2bc..8dc77f3aac03 100644
--- a/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
@@ -1,30 +1,38 @@
 { dotnetPackages, lib, xml2, stdenvNoCC }:
-{ name, description ? "", deps ? [] }:
+
+{ name
+, description ? ""
+, deps ? []
+}:
+
 let
-  _nuget-source = stdenvNoCC.mkDerivation rec {
+  nuget-source = stdenvNoCC.mkDerivation rec {
     inherit name;
-    meta.description = description;
 
+    meta.description = description;
     nativeBuildInputs = [ dotnetPackages.Nuget xml2 ];
+
     buildCommand = ''
       export HOME=$(mktemp -d)
       mkdir -p $out/{lib,share}
 
-      nuget sources Add -Name nixos -Source "$out/lib"
-      ${ lib.concatMapStringsSep "\n" (dep:
-          ''nuget init "${dep}" "$out/lib"''
-        ) deps }
+      ${lib.concatMapStringsSep "\n" (dep: ''
+        nuget init "${dep}" "$out/lib"
+      '') deps}
 
-      # Generates a list of all unique licenses' spdx ids.
+      # 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")
       find "$out/lib" -name "*.nuspec" -exec sh -c \
-        "xml2 < {} | grep "license=" | cut -d'=' -f2" \; | sort -u > $out/share/licenses
+        "NUSPEC=\$(xml2 < {}) && echo "\$NUSPEC" | grep license/@type=expression | tr -s \  '\n' | grep "license=" | cut -d'=' -f2" \
+      \; | sort -u > $out/share/licenses
     '';
-} // { # This is done because we need data from `$out` for `meta`. We have to use overrides as to not hit infinite recursion.
-  meta.licence = let
-    depLicenses = lib.splitString "\n" (builtins.readFile "${_nuget-source}/share/licenses");
-    getLicence = spdx: lib.filter (license: license.spdxId or null == spdx) (builtins.attrValues lib.licenses);
-  in (lib.flatten (lib.forEach depLicenses (spdx:
-    if (getLicence spdx) != [] then (getLicence spdx) else [] ++ lib.optional (spdx != "") spdx
-  )));
-};
-in _nuget-source
+  } // { # We need data from `$out` for `meta`, so we have to use overrides as to not hit infinite recursion.
+    meta.licence = let
+      depLicenses = lib.splitString "\n" (builtins.readFile "${nuget-source}/share/licenses");
+    in (lib.flatten (lib.forEach depLicenses (spdx:
+      if (spdx != "")
+        then lib.getLicenseFromSpdxId spdx
+        else []
+    )));
+  };
+in nuget-source
diff --git a/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/default.nix b/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/default.nix
index a5fc4e209cd2..e3a3e45ac20c 100644
--- a/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/default.nix
@@ -1,5 +1,33 @@
-{ runCommand }:
+{ lib
+, runCommandLocal
+, runtimeShell
+, substituteAll
+, nix
+, coreutils
+, findutils
+, gnused
+, jq
+, curl
+, gnugrep
+}:
 
-runCommand "nuget-to-nix" { preferLocalBuild = true; } ''
-  install -D -m755 ${./nuget-to-nix.sh} $out/bin/nuget-to-nix
+runCommandLocal "nuget-to-nix" {
+  script = substituteAll {
+    src = ./nuget-to-nix.sh;
+    inherit runtimeShell;
+
+    binPath = lib.makeBinPath [
+      nix
+      coreutils
+      findutils
+      gnused
+      jq
+      curl
+      gnugrep
+    ];
+  };
+
+  meta.description = "Convert a nuget packages directory to a lockfile for buildDotnetModule";
+} ''
+  install -Dm755 $script $out/bin/nuget-to-nix
 ''
diff --git a/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh b/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh
index d2e7882caf6d..ca0a63b3cd20 100755
--- a/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh
@@ -1,25 +1,42 @@
-#!/usr/bin/env bash
+#!@runtimeShell@
 
 set -euo pipefail
 
+export PATH="@binPath@"
+
 if [ $# -eq 0 ]; then
-  >&2 echo "Usage: $0 [packages directory] > deps.nix"
+  >&2 echo "Usage: $0 <packages directory> [path to file with a list of excluded packages] > deps.nix"
   exit 1
 fi
 
 pkgs=$1
+exclusions="${2:-/dev/null}"
 tmpfile=$(mktemp /tmp/nuget-to-nix.XXXXXX)
 trap "rm -f ${tmpfile}" EXIT
 
+declare -A nuget_sources_cache
+
 echo "{ fetchNuGet }: ["
 
 while read pkg_spec; do
   { read pkg_name; read pkg_version; } < <(
     # Build version part should be ignored: `3.0.0-beta2.20059.3+77df2220` -> `3.0.0-beta2.20059.3`
     sed -nE 's/.*<id>([^<]*).*/\1/p; s/.*<version>([^<+]*).*/\1/p' "$pkg_spec")
+
+  if grep "$pkg_name" "$exclusions" > /dev/null; then
+    continue
+  fi
+
   pkg_sha256="$(nix-hash --type sha256 --flat --base32 "$(dirname "$pkg_spec")"/*.nupkg)"
 
-  echo "  (fetchNuGet { pname = \"$pkg_name\"; version = \"$pkg_version\"; sha256 = \"$pkg_sha256\"; })" >> ${tmpfile}
+  pkg_src="$(jq --raw-output '.source' "$(dirname "$pkg_spec")/.nupkg.metadata")"
+  if [[ $pkg_src != https://api.nuget.org/* ]] && [[ ! -d $pkg_src ]]; then
+    pkg_source_url="${nuget_sources_cache[$pkg_src]:=$(curl -n --fail "$pkg_src" | jq --raw-output '.resources[] | select(."@type" == "PackageBaseAddress/3.0.0")."@id"')}"
+    pkg_url="$pkg_source_url${pkg_name,,}/${pkg_version,,}/${pkg_name,,}.${pkg_version,,}.nupkg"
+    echo "  (fetchNuGet { pname = \"$pkg_name\"; version = \"$pkg_version\"; sha256 = \"$pkg_sha256\"; url = \"$pkg_url\"; })" >> ${tmpfile}
+  else
+    echo "  (fetchNuGet { pname = \"$pkg_name\"; version = \"$pkg_version\"; sha256 = \"$pkg_sha256\"; })" >> ${tmpfile}
+  fi
 done < <(find $1 -name '*.nuspec')
 
 LC_ALL=C sort --ignore-case ${tmpfile}
diff --git a/nixpkgs/pkgs/build-support/emacs/melpa.nix b/nixpkgs/pkgs/build-support/emacs/melpa.nix
index 408448f26a0e..924e6d95f14a 100644
--- a/nixpkgs/pkgs/build-support/emacs/melpa.nix
+++ b/nixpkgs/pkgs/build-support/emacs/melpa.nix
@@ -38,8 +38,8 @@ import ./generic.nix { inherit lib stdenv emacs texinfo writeText gcc; } ({
   packageBuild = fetchFromGitHub {
     owner = "melpa";
     repo = "package-build";
-    rev = "047801d301a73d4932f33f768d94a8ed26b8d524";
-    sha256 = "0ygzkpg7xc3mjjbxg1kcyz6fwbkb0prvca499f0ffmhfaiv28h59";
+    rev = "35017a2d87376c70c3239f48bdbac7efca85aa10";
+    sha256 = "07hdmam85452v4r2vaabj1qfyami1hgbh0jgj9dcwbkpr0y1gvqj";
   };
 
   elpa2nix = ./elpa2nix.el;
diff --git a/nixpkgs/pkgs/build-support/emacs/melpa2nix.el b/nixpkgs/pkgs/build-support/emacs/melpa2nix.el
index 383423af0818..72667dea652c 100644
--- a/nixpkgs/pkgs/build-support/emacs/melpa2nix.el
+++ b/nixpkgs/pkgs/build-support/emacs/melpa2nix.el
@@ -11,12 +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)))
+    (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")))))))
+
 (defun melpa2nix-build-package ()
   (if (not noninteractive)
       (error "`melpa2nix-build-package' is to be used only with -batch"))
   (pcase command-line-args-left
     (`(,package ,version ,commit)
-     ;; Monkey-patch package-build so it doesn't shell out to git/hg.
-     (defun package-build--get-commit (&rest _)
-       commit)
-     (package-build--package (package-recipe-lookup package) version))))
+     (melpa2nix-build-package-1 (package-recipe-lookup package) version commit))))
diff --git a/nixpkgs/pkgs/build-support/emacs/wrapper.nix b/nixpkgs/pkgs/build-support/emacs/wrapper.nix
index 2aa61d6d2f62..edbe3ed97173 100644
--- a/nixpkgs/pkgs/build-support/emacs/wrapper.nix
+++ b/nixpkgs/pkgs/build-support/emacs/wrapper.nix
@@ -215,6 +215,7 @@ runCommand
       substitute ${./wrapper.sh} $out/Applications/Emacs.app/Contents/MacOS/Emacs \
         --subst-var-by bash ${emacs.stdenv.shell} \
         --subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \
+        --subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp:" \
         --subst-var-by prog "$emacs/Applications/Emacs.app/Contents/MacOS/Emacs"
       chmod +x $out/Applications/Emacs.app/Contents/MacOS/Emacs
     fi
diff --git a/nixpkgs/pkgs/build-support/expand-response-params/default.nix b/nixpkgs/pkgs/build-support/expand-response-params/default.nix
index 402f0071a533..9371b7702362 100644
--- a/nixpkgs/pkgs/build-support/expand-response-params/default.nix
+++ b/nixpkgs/pkgs/build-support/expand-response-params/default.nix
@@ -3,6 +3,8 @@
 stdenv.mkDerivation {
   name = "expand-response-params";
   src = ./expand-response-params.c;
+  strictDeps = true;
+  enableParallelBuilding = true;
   # Work around "stdenv-darwin-boot-2 is not allowed to refer to path
   # /nix/store/...-expand-response-params.c"
   unpackPhase = ''
diff --git a/nixpkgs/pkgs/build-support/fake-nss/default.nix b/nixpkgs/pkgs/build-support/fake-nss/default.nix
new file mode 100644
index 000000000000..9e0b60133e00
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/fake-nss/default.nix
@@ -0,0 +1,24 @@
+# Provide a /etc/passwd and /etc/group that contain root and nobody.
+# Useful when packaging binaries that insist on using nss to look up
+# username/groups (like nginx).
+# /bin/sh is fine to not exist, and provided by another shim.
+{ symlinkJoin, writeTextDir, runCommand }:
+symlinkJoin {
+  name = "fake-nss";
+  paths = [
+    (writeTextDir "etc/passwd" ''
+      root:x:0:0:root user:/var/empty:/bin/sh
+      nobody:x:65534:65534:nobody:/var/empty:/bin/sh
+    '')
+    (writeTextDir "etc/group" ''
+      root:x:0:
+      nobody:x:65534:
+    '')
+    (writeTextDir "etc/nsswitch.conf" ''
+      hosts: files dns
+    '')
+    (runCommand "var-empty" { } ''
+      mkdir -p $out/var/empty
+    '')
+  ];
+}
diff --git a/nixpkgs/pkgs/build-support/fetchcvs/nix-prefetch-cvs b/nixpkgs/pkgs/build-support/fetchcvs/nix-prefetch-cvs
index f9ed8ffa066f..b6a169f8b531 100755
--- a/nixpkgs/pkgs/build-support/fetchcvs/nix-prefetch-cvs
+++ b/nixpkgs/pkgs/build-support/fetchcvs/nix-prefetch-cvs
@@ -21,13 +21,11 @@ fi
 
 mkTempDir() {
     tmpPath="$(mktemp -d "${TMPDIR:-/tmp}/nix-prefetch-cvs-XXXXXXXX")"
-    trap removeTempDir EXIT SIGINT SIGQUIT
+    trap removeTempDir EXIT
 }
 
 removeTempDir() {
-    if test -n "$tmpPath"; then
-        rm -rf "$tmpPath" || true
-    fi
+    rm -rf "$tmpPath"
 }
 
 
diff --git a/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix b/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix
index 79014fd23c48..0fa51e69840c 100644
--- a/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix
@@ -1,4 +1,4 @@
-{stdenv, lib, coreutils, unzip, jq, zip, fetchurl,writeScript,  ...}:
+{stdenv, unzip, jq, zip, fetchurl,writeScript,  ...}:
 
 {
   name
@@ -40,5 +40,5 @@ stdenv.mkDerivation {
     zip -r -q -FS "$out/$UUID.xpi" *
     rm -r "$out/$UUID"
   '';
-  nativeBuildInputs = [ coreutils unzip zip jq  ];
+  nativeBuildInputs = [ unzip zip jq  ];
 }
diff --git a/nixpkgs/pkgs/build-support/fetchfirefoxaddon/tests.nix b/nixpkgs/pkgs/build-support/fetchfirefoxaddon/tests.nix
index c407d0e74b82..fd70d0f82ac0 100644
--- a/nixpkgs/pkgs/build-support/fetchfirefoxaddon/tests.nix
+++ b/nixpkgs/pkgs/build-support/fetchfirefoxaddon/tests.nix
@@ -1,7 +1,7 @@
-{ invalidateFetcherByDrvHash, fetchFirefoxAddon, fetchurl, ... }:
+{ testers, fetchFirefoxAddon, fetchurl, ... }:
 
 {
-  simple = invalidateFetcherByDrvHash fetchFirefoxAddon {
+  simple = testers.invalidateFetcherByDrvHash fetchFirefoxAddon {
     name = "image-search-options";
     # Chosen because its only 147KB
     url = "https://addons.mozilla.org/firefox/downloads/file/3059971/image_search_options-3.0.12-fx.xpi";
@@ -14,7 +14,7 @@
         sha256 = "sha256-H73YWX/DKxvhEwKpWOo7orAQ7c/rQywpljeyxYxv0Gg=";
       };
     in
-    invalidateFetcherByDrvHash fetchFirefoxAddon {
+    testers.invalidateFetcherByDrvHash fetchFirefoxAddon {
       name = "image-search-options";
       src = image-search-options;
     };
diff --git a/nixpkgs/pkgs/build-support/fetchgit/builder.sh b/nixpkgs/pkgs/build-support/fetchgit/builder.sh
index c7c7d21709a1..66b6c168e41d 100644
--- a/nixpkgs/pkgs/build-support/fetchgit/builder.sh
+++ b/nixpkgs/pkgs/build-support/fetchgit/builder.sh
@@ -12,6 +12,7 @@ $SHELL $fetcher --builder --url "$url" --out "$out" --rev "$rev" \
   ${deepClone:+--deepClone} \
   ${fetchSubmodules:+--fetch-submodules} \
   ${sparseCheckout:+--sparse-checkout "$sparseCheckout"} \
+  ${nonConeMode:+--non-cone-mode} \
   ${branchName:+--branch-name "$branchName"}
 
 runHook postFetch
diff --git a/nixpkgs/pkgs/build-support/fetchgit/default.nix b/nixpkgs/pkgs/build-support/fetchgit/default.nix
index 1b59668ce4bc..f516c3d5a03b 100644
--- a/nixpkgs/pkgs/build-support/fetchgit/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchgit/default.nix
@@ -16,6 +16,7 @@ in
 , fetchSubmodules ? true, deepClone ? false
 , branchName ? null
 , sparseCheckout ? ""
+, nonConeMode ? false
 , name ? urlToName url rev
 , # Shell code executed after the file has been fetched
   # successfully. This can do things like check or transform the file.
@@ -27,6 +28,8 @@ in
 , # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes)
   # needed for netrcPhase
   netrcImpureEnvVars ? []
+, meta ? {}
+, allowedRequisites ? null
 }:
 
 /* NOTE:
@@ -52,6 +55,7 @@ in
 */
 
 assert deepClone -> leaveDotGit;
+assert nonConeMode -> (sparseCheckout != "");
 
 if md5 != "" then
   throw "fetchgit does not support md5 anymore, please use sha256"
@@ -75,7 +79,7 @@ stdenvNoCC.mkDerivation {
   else
     lib.fakeSha256;
 
-  inherit url rev leaveDotGit fetchLFS fetchSubmodules deepClone branchName sparseCheckout postFetch;
+  inherit url rev leaveDotGit fetchLFS fetchSubmodules deepClone branchName sparseCheckout nonConeMode postFetch;
 
   postHook = if netrcPhase == null then null else ''
     ${netrcPhase}
@@ -90,5 +94,10 @@ stdenvNoCC.mkDerivation {
     "GIT_PROXY_COMMAND" "NIX_GIT_SSL_CAINFO" "SOCKS_SERVER"
   ];
 
-  inherit preferLocalBuild;
+
+  inherit preferLocalBuild meta allowedRequisites;
+
+  passthru = {
+    gitRepoUrl = url;
+  };
 }
diff --git a/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git b/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git
index 4e6f25b8dd7d..9c2048066ce4 100755
--- a/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git
+++ b/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git
@@ -49,6 +49,7 @@ Options:
       --hash h        Expected hash.
       --branch-name   Branch name to check out into
       --sparse-checkout Only fetch and checkout part of the repository.
+      --non-cone-mode Use non-cone mode for sparse checkouts.
       --deepClone     Clone the entire repository.
       --no-deepClone  Make a shallow clone of just the required ref.
       --leave-dotGit  Keep the .git directories.
@@ -77,6 +78,7 @@ for arg; do
             --branch-name) argfun=set_branchName;;
             --deepClone) deepClone=true;;
             --sparse-checkout) argfun=set_sparseCheckout;;
+            --non-cone-mode) nonConeMode=true;;
             --quiet) QUIET=true;;
             --no-deepClone) deepClone=;;
             --leave-dotGit) leaveDotGit=true;;
@@ -116,7 +118,7 @@ init_remote(){
     clean_git remote add origin "$url"
     if [ -n "$sparseCheckout" ]; then
         git config remote.origin.partialclonefilter "blob:none"
-        echo "$sparseCheckout" | git sparse-checkout set --stdin
+        echo "$sparseCheckout" | git sparse-checkout set --stdin ${nonConeMode:+--no-cone}
     fi
     ( [ -n "$http_proxy" ] && clean_git config http.proxy "$http_proxy" ) || true
 }
diff --git a/nixpkgs/pkgs/build-support/fetchgit/tests.nix b/nixpkgs/pkgs/build-support/fetchgit/tests.nix
index c558fb6efa4d..62fe3f77bbdd 100644
--- a/nixpkgs/pkgs/build-support/fetchgit/tests.nix
+++ b/nixpkgs/pkgs/build-support/fetchgit/tests.nix
@@ -1,14 +1,14 @@
-{ invalidateFetcherByDrvHash, fetchgit, ... }:
+{ testers, fetchgit, ... }:
 
 {
-  simple = invalidateFetcherByDrvHash fetchgit {
+  simple = testers.invalidateFetcherByDrvHash fetchgit {
     name = "nix-source";
     url = "https://github.com/NixOS/nix";
     rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
     sha256 = "sha256-7DszvbCNTjpzGRmpIVAWXk20P0/XTrWZ79KSOGLrUWY=";
   };
 
-  sparseCheckout = invalidateFetcherByDrvHash fetchgit {
+  sparseCheckout = testers.invalidateFetcherByDrvHash fetchgit {
     name = "nix-source";
     url = "https://github.com/NixOS/nix";
     rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
@@ -16,6 +16,18 @@
       src
       tests
     '';
+    sha256 = "sha256-g1PHGTWgAcd/+sXHo1o6AjVWCvC6HiocOfMbMh873LQ=";
+  };
+
+  sparseCheckoutNonConeMode = testers.invalidateFetcherByDrvHash fetchgit {
+    name = "nix-source";
+    url = "https://github.com/NixOS/nix";
+    rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
+    sparseCheckout = ''
+      src
+      tests
+    '';
+    nonConeMode = true;
     sha256 = "sha256-FknO6C/PSnMPfhUqObD4vsW4PhkwdmPa9blNzcNvJQ4=";
   };
 }
diff --git a/nixpkgs/pkgs/build-support/fetchgithub/default.nix b/nixpkgs/pkgs/build-support/fetchgithub/default.nix
index 27cb8312ea0a..cfb6a6ca7cd8 100644
--- a/nixpkgs/pkgs/build-support/fetchgithub/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchgithub/default.nix
@@ -42,11 +42,20 @@ let
     '';
     netrcImpureEnvVars = [ "${varBase}USERNAME" "${varBase}PASSWORD" ];
   };
+
+  gitRepoUrl = "${baseUrl}.git";
+
   fetcherArgs = (if useFetchGit
     then {
-      inherit rev deepClone fetchSubmodules sparseCheckout; url = "${baseUrl}.git";
+      inherit rev deepClone fetchSubmodules sparseCheckout; url = gitRepoUrl;
     } // lib.optionalAttrs (leaveDotGit != null) { inherit leaveDotGit; }
-    else { url = "${baseUrl}/archive/${rev}.tar.gz"; }
+    else {
+      url = "${baseUrl}/archive/${rev}.tar.gz";
+
+      passthru = {
+        inherit gitRepoUrl;
+      };
+    }
   ) // privateAttrs // passthruAttrs // { inherit name; };
 in
 
diff --git a/nixpkgs/pkgs/build-support/fetchgitlab/default.nix b/nixpkgs/pkgs/build-support/fetchgitlab/default.nix
index 5c82a8f8587d..264bbcf3f761 100644
--- a/nixpkgs/pkgs/build-support/fetchgitlab/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchgitlab/default.nix
@@ -15,11 +15,17 @@ let
   useFetchGit = deepClone || fetchSubmodules || leaveDotGit;
   fetcher = if useFetchGit then fetchgit else fetchzip;
 
+  gitRepoUrl = "${protocol}://${domain}/${slug}.git";
+
   fetcherArgs = (if useFetchGit then {
     inherit rev deepClone fetchSubmodules leaveDotGit;
-    url = "${protocol}://${domain}/${slug}.git";
+    url = gitRepoUrl;
   } else {
     url = "${protocol}://${domain}/api/v4/projects/${escapedSlug}/repository/archive.tar.gz?sha=${escapedRev}";
+
+    passthru = {
+      inherit gitRepoUrl;
+    };
   }) // passthruAttrs // { inherit name; };
 in
 
diff --git a/nixpkgs/pkgs/build-support/fetchnextcloudapp/default.nix b/nixpkgs/pkgs/build-support/fetchnextcloudapp/default.nix
index 7fe5b35e2596..1997c80c8a15 100644
--- a/nixpkgs/pkgs/build-support/fetchnextcloudapp/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchnextcloudapp/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, gnutar, findutils, fetchurl, ... }:
+{ stdenv, fetchurl, ... }:
 { name
 , url
 , version
@@ -6,18 +6,13 @@
 , patches ? [ ]
 }:
 stdenv.mkDerivation {
-  name = "nc-app-${name}";
+  pname = "nc-app-${name}";
   inherit version patches;
 
   src = fetchurl {
     inherit url sha256;
   };
 
-  nativeBuildInputs = [
-    gnutar
-    findutils
-  ];
-
   unpackPhase = ''
     tar -xzpf $src
   '';
diff --git a/nixpkgs/pkgs/build-support/fetchpatch/tests.nix b/nixpkgs/pkgs/build-support/fetchpatch/tests.nix
index ff2b81bf3a1d..a42b7cd7d14b 100644
--- a/nixpkgs/pkgs/build-support/fetchpatch/tests.nix
+++ b/nixpkgs/pkgs/build-support/fetchpatch/tests.nix
@@ -1,18 +1,18 @@
-{ invalidateFetcherByDrvHash, fetchpatch, ... }:
+{ testers, fetchpatch, ... }:
 
 {
-  simple = invalidateFetcherByDrvHash fetchpatch {
+  simple = testers.invalidateFetcherByDrvHash fetchpatch {
     url = "https://github.com/facebook/zstd/pull/2724/commits/e1f85dbca3a0ed5ef06c8396912a0914db8dea6a.patch";
     sha256 = "sha256-PuYAqnJWAE+L9bsroOnnBGJhERW8LHrGSLtIEkKU9vg=";
   };
 
-  relative = invalidateFetcherByDrvHash fetchpatch {
+  relative = testers.invalidateFetcherByDrvHash fetchpatch {
     url = "https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch";
     relative = "include";
     sha256 = "sha256-KlmIbixcds6GyKYt1fx5BxDIrU7msrgDdYo9Va/KJR4=";
   };
 
-  full = invalidateFetcherByDrvHash fetchpatch {
+  full = testers.invalidateFetcherByDrvHash fetchpatch {
     url = "https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch";
     relative = "test";
     stripLen = 1;
diff --git a/nixpkgs/pkgs/build-support/fetchsourcehut/default.nix b/nixpkgs/pkgs/build-support/fetchsourcehut/default.nix
index 2b1feaa496e4..d111e96885c0 100644
--- a/nixpkgs/pkgs/build-support/fetchsourcehut/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchsourcehut/default.nix
@@ -38,7 +38,7 @@ let
       fetch = fetchzip;
       arguments = baseArgs // {
         url = "${baseUrl}/archive/${rev}.tar.gz";
-        extraPostFetch = optionalString (vc == "hg") ''
+        postFetch = optionalString (vc == "hg") ''
           rm -f "$out/.hg_archival.txt"
         ''; # impure file; see #12002
       };
diff --git a/nixpkgs/pkgs/build-support/fetchurl/builder.sh b/nixpkgs/pkgs/build-support/fetchurl/builder.sh
index 5b04a702aff4..5ca09b6fc77d 100644
--- a/nixpkgs/pkgs/build-support/fetchurl/builder.sh
+++ b/nixpkgs/pkgs/build-support/fetchurl/builder.sh
@@ -22,6 +22,8 @@ if ! [ -f "$SSL_CERT_FILE" ]; then
     curl+=(--insecure)
 fi
 
+eval "curl+=($curlOptsList)"
+
 curl+=(
     $curlOpts
     $NIX_CURL_FLAGS
diff --git a/nixpkgs/pkgs/build-support/fetchurl/default.nix b/nixpkgs/pkgs/build-support/fetchurl/default.nix
index dcab471fc839..7ec831c61ac7 100644
--- a/nixpkgs/pkgs/build-support/fetchurl/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchurl/default.nix
@@ -14,6 +14,7 @@ let
   mirrorsFile =
     buildPackages.stdenvNoCC.mkDerivation ({
       name = "mirrors-list";
+      strictDeps = true;
       builder = ./write-mirror-list.sh;
       preferLocalBuild = true;
     } // mirrors);
@@ -45,8 +46,13 @@ in
   urls ? []
 
 , # Additional curl options needed for the download to succeed.
+  # Warning: Each space (no matter the escaping) will start a new argument.
+  # If you wish to pass arguments with spaces, use `curlOptsList`
   curlOpts ? ""
 
+, # Additional curl options needed for the download to succeed.
+  curlOptsList ? []
+
 , # Name of the file.  If empty, use the basename of `url' (or of the
   # first element of `urls').
   name ? ""
@@ -146,7 +152,14 @@ stdenvNoCC.mkDerivation {
 
   outputHashMode = if (recursiveHash || executable) then "recursive" else "flat";
 
-  inherit curlOpts showURLs mirrorsFile postFetch downloadToTemp executable;
+  curlOpts = lib.warnIf (lib.isList curlOpts) ''
+    fetchurl for ${toString (builtins.head urls_)}: curlOpts is a list (${lib.generators.toPretty { multiline = false; } curlOpts}), which is not supported anymore.
+    - If you wish to get the same effect as before, for elements with spaces (even if escaped) to expand to multiple curl arguments, use a string argument instead:
+      curlOpts = ${lib.strings.escapeNixString (toString curlOpts)};
+    - If you wish for each list element to be passed as a separate curl argument, allowing arguments to contain spaces, use curlOptsList instead:
+      curlOptsList = [ ${lib.concatMapStringsSep " " lib.strings.escapeNixString curlOpts} ];'' curlOpts;
+  curlOptsList = lib.escapeShellArgs curlOptsList;
+  inherit showURLs mirrorsFile postFetch downloadToTemp executable;
 
   impureEnvVars = impureEnvVars ++ netrcImpureEnvVars;
 
@@ -160,5 +173,5 @@ stdenvNoCC.mkDerivation {
   '';
 
   inherit meta;
-  inherit passthru;
+  passthru = { inherit url; } // passthru;
 }
diff --git a/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix b/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
index 954c88d1bafa..3a765089bd2e 100644
--- a/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
+++ b/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
@@ -18,6 +18,7 @@
 
   # Apache
   apache = [
+    "https://dlcdn.apache.org/"
     "https://www-eu.apache.org/dist/"
     "https://ftp.wayne.edu/apache/"
     "https://www.apache.org/dist/"
@@ -164,6 +165,11 @@
     "https://ftp.postgresql.org/pub/"
   ];
 
+  # Qt
+  qt = [
+    "https://download.qt.io/"
+  ];
+
   # Roy marples mirrors
   roy = [
     "https://roy.marples.name/downloads/"
@@ -317,7 +323,6 @@
     "https://luarocks.org/"
     "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/"
     "https://luafr.org/moonrocks/"
-    "http://luarocks.logiceditor.com/rocks/"
   ];
 
   # Python PyPI
diff --git a/nixpkgs/pkgs/build-support/fetchurl/tests.nix b/nixpkgs/pkgs/build-support/fetchurl/tests.nix
new file mode 100644
index 000000000000..fc7fb25e158f
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/fetchurl/tests.nix
@@ -0,0 +1,13 @@
+{ invalidateFetcherByDrvHash, fetchurl, jq, moreutils, ... }: {
+  # Tests that we can send custom headers with spaces in them
+  header =
+    let headerValue = "Test '\" <- These are some quotes";
+    in invalidateFetcherByDrvHash fetchurl {
+      url = "https://httpbin.org/headers";
+      sha256 = builtins.hashString "sha256" (headerValue + "\n");
+      curlOptsList = [ "-H" "Hello: ${headerValue}" ];
+      postFetch = ''
+        ${jq}/bin/jq -r '.headers.Hello' $out | ${moreutils}/bin/sponge $out
+      '';
+    };
+}
diff --git a/nixpkgs/pkgs/build-support/fetchzip/default.nix b/nixpkgs/pkgs/build-support/fetchzip/default.nix
index a3f22de58c71..10142134792f 100644
--- a/nixpkgs/pkgs/build-support/fetchzip/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchzip/default.nix
@@ -5,13 +5,14 @@
 # (e.g. due to minor changes in the compression algorithm, or changes
 # in timestamps).
 
-{ lib, fetchurl, unzip }:
+{ lib, fetchurl, unzip, glibcLocalesUtf8 }:
 
 { # Optionally move the contents of the unpacked tree up one level.
   stripRoot ? true
 , url ? ""
 , urls ? []
 , extraPostFetch ? ""
+, postFetch ? ""
 , name ? "source"
 , nativeBuildInputs ? [ ]
 , # Allows to set the extension for the intermediate downloaded
@@ -20,6 +21,8 @@
   extension ? null
 , ... } @ args:
 
+
+lib.warnIf (extraPostFetch != "") "use 'postFetch' instead of 'extraPostFetch' with 'fetchzip' and 'fetchFromGitHub'."
 (fetchurl (let
   tmpFilename =
     if extension != null
@@ -32,7 +35,10 @@ in {
 
   downloadToTemp = true;
 
-  nativeBuildInputs = [ unzip ] ++ nativeBuildInputs;
+  # 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;
 
   postFetch =
     ''
@@ -60,11 +66,14 @@ in {
       mv "$unpackDir" "$out"
     '')
     + ''
+      ${postFetch}
+    '' + ''
       ${extraPostFetch}
     ''
+
     # Remove non-owner write permissions
     # Fixes https://github.com/NixOS/nixpkgs/issues/38649
     + ''
       chmod 755 "$out"
     '';
-} // removeAttrs args [ "stripRoot" "extraPostFetch" "extension" "nativeBuildInputs" ]))
+} // removeAttrs args [ "stripRoot" "extraPostFetch" "postFetch" "extension" "nativeBuildInputs" ]))
diff --git a/nixpkgs/pkgs/build-support/fetchzip/tests.nix b/nixpkgs/pkgs/build-support/fetchzip/tests.nix
new file mode 100644
index 000000000000..f1a1ed65817b
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/fetchzip/tests.nix
@@ -0,0 +1,17 @@
+{ testers, fetchzip, ... }:
+
+let
+  url = "https://gist.github.com/glandium/01d54cefdb70561b5f6675e08f2990f2/archive/2f430f0c136a69b0886281d0c76708997d8878af.zip";
+in
+{
+  simple = testers.invalidateFetcherByDrvHash fetchzip {
+    inherit url;
+    sha256 = "sha256-0ecwgL8qUavSj1+WkaxpmRBmu7cvj53V5eXQV71fddU=";
+  };
+
+  postFetch = testers.invalidateFetcherByDrvHash fetchzip {
+    inherit url;
+    sha256 = "sha256-7sAOzKa+9vYx5XyndHxeY2ffWAjOsgCkXC9anK6cuV0=";
+    postFetch = ''touch $out/filee'';
+  };
+}
diff --git a/nixpkgs/pkgs/build-support/go/garble.nix b/nixpkgs/pkgs/build-support/go/garble.nix
deleted file mode 100644
index c9bcf2cec153..000000000000
--- a/nixpkgs/pkgs/build-support/go/garble.nix
+++ /dev/null
@@ -1,35 +0,0 @@
-{ stdenv
-, buildGoModule
-, fetchFromGitHub
-, lib
-, git
-}:
-buildGoModule rec {
-  pname = "garble";
-  version = "0.5.1";
-
-  src = fetchFromGitHub {
-    owner = "burrowers";
-    repo = pname;
-    rev = "v${version}";
-    sha256 = "sha256-F8O/33o//yGnum9sZo1dzcvf3ifRalva6SDC36iPbDA==";
-  };
-
-  vendorSha256 = "sha256-iNH/iBEOTkIhVlDGfI66ZYyVjyH6WrLbUSMyONPjUc4=";
-
-  # Used for some of the tests.
-  checkInputs = [git];
-
-  preBuild = lib.optionalString (!stdenv.isx86_64) ''
-    # The test assumex amd64 assembly
-    rm testdata/scripts/asm.txt
-  '';
-
-  meta = {
-    description = "Obfuscate Go code by wrapping the Go toolchain";
-    homepage = "https://github.com/burrowers/garble/";
-    maintainers = with lib.maintainers; [ davhau ];
-    license = lib.licenses.bsd3;
-    broken = stdenv.isDarwin; # never built on Hydra https://hydra.nixos.org/job/nixpkgs/trunk/garble.x86_64-darwin
-  };
-}
diff --git a/nixpkgs/pkgs/build-support/go/module.nix b/nixpkgs/pkgs/build-support/go/module.nix
new file mode 100644
index 000000000000..1e03d15bf7dc
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/go/module.nix
@@ -0,0 +1,317 @@
+{ go, cacert, git, lib, stdenv }:
+
+let
+  buildGoPackage =
+    { name ? "${args'.pname}-${args'.version}"
+    , src
+    , buildInputs ? []
+    , nativeBuildInputs ? []
+    , passthru ? {}
+    , patches ? []
+
+    # Go linker flags, passed to go via -ldflags
+    , ldflags ? []
+
+    # Go tags, passed to go via -tag
+    , tags ? []
+
+    # A function to override the go-modules derivation
+    , overrideModAttrs ? (_oldAttrs : {})
+
+    # path to go.mod and go.sum directory
+    , modRoot ? "./"
+
+    # vendorHash is the SRI hash of the vendored dependencies
+    #
+    # if vendorHash is null, then we won't fetch any dependencies and
+    # rely on the vendor folder within the source.
+    , vendorHash ? "_unset"
+    # same as vendorHash, but outputHashAlgo is hardcoded to sha256
+    # so regular base32 sha256 hashes work
+    , vendorSha256 ? "_unset"
+    # Whether to delete the vendor folder supplied with the source.
+    , deleteVendor ? false
+    # Whether to fetch (go mod download) and proxy the vendor directory.
+    # This is useful if your code depends on c code and go mod tidy does not
+    # include the needed sources to build or if any dependency has case-insensitive
+    # conflicts which will produce platform dependant `vendorHash` checksums.
+    , proxyVendor ? false
+
+    # We want parallel builds by default
+    , enableParallelBuilding ? true
+
+    # Do not enable this without good reason
+    # IE: programs coupled with the compiler
+    , allowGoReference ? false
+
+    , CGO_ENABLED ? go.CGO_ENABLED
+
+    , meta ? {}
+
+    # Not needed with buildGoModule
+    , goPackagePath ? ""
+
+    # needed for buildFlags{,Array} warning
+    , buildFlags ? ""
+    , buildFlagsArray ? ""
+
+    , ... }@args':
+
+    with builtins;
+
+    assert goPackagePath != "" -> throw "`goPackagePath` is not needed with `buildGoModule`";
+    assert (vendorSha256 == "_unset" && vendorHash == "_unset") -> throw "either `vendorHash` or `vendorSha256` is required";
+    assert (vendorSha256 != "_unset" && vendorHash != "_unset") -> throw "both `vendorHash` and `vendorSha256` set. only one can be set.";
+
+    let
+      hasAnyVendorHash = (vendorSha256 != null && vendorSha256 != "_unset") || (vendorHash != null && vendorHash != "_unset");
+      vendorHashType =
+        if hasAnyVendorHash then
+          if vendorSha256 != null && vendorSha256 != "_unset" then
+            "sha256"
+          else
+            "sri"
+        else
+          null;
+
+      args = removeAttrs args' [ "overrideModAttrs" "vendorSha256" "vendorHash" ];
+
+      go-modules = if hasAnyVendorHash then stdenv.mkDerivation (let modArgs = {
+
+        name = "${name}-go-modules";
+
+        nativeBuildInputs = (args.nativeBuildInputs or []) ++ [ go git cacert ];
+
+        inherit (args) src;
+        inherit (go) GOOS GOARCH;
+
+        patches = args.patches or [];
+        patchFlags = args.patchFlags or [];
+        preBuild = args.preBuild or "";
+        sourceRoot = args.sourceRoot or "";
+
+        GO111MODULE = "on";
+
+        impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
+          "GIT_PROXY_COMMAND" "SOCKS_SERVER" "GOPROXY"
+        ];
+
+        configurePhase = args.modConfigurePhase or ''
+          runHook preConfigure
+          export GOCACHE=$TMPDIR/go-cache
+          export GOPATH="$TMPDIR/go"
+          cd "${modRoot}"
+          runHook postConfigure
+        '';
+
+        buildPhase = args.modBuildPhase or ''
+          runHook preBuild
+        '' + lib.optionalString (deleteVendor == true) ''
+          if [ ! -d vendor ]; then
+            echo "vendor folder does not exist, 'deleteVendor' is not needed"
+            exit 10
+          else
+            rm -rf vendor
+          fi
+        '' + ''
+          if [ -d vendor ]; then
+            echo "vendor folder exists, please set 'vendorHash = null;' or 'vendorSha256 = null;' in your expression"
+            exit 10
+          fi
+
+        ${if proxyVendor then ''
+          mkdir -p "''${GOPATH}/pkg/mod/cache/download"
+          go mod download
+        '' else ''
+          if (( "''${NIX_DEBUG:-0}" >= 1 )); then
+            goModVendorFlags+=(-v)
+          fi
+          go mod vendor "''${goModVendorFlags[@]}"
+        ''}
+
+          mkdir -p vendor
+
+          runHook postBuild
+        '';
+
+        installPhase = args.modInstallPhase or ''
+          runHook preInstall
+
+        ${if proxyVendor then ''
+          rm -rf "''${GOPATH}/pkg/mod/cache/download/sumdb"
+          cp -r --reflink=auto "''${GOPATH}/pkg/mod/cache/download" $out
+        '' else ''
+          cp -r --reflink=auto vendor $out
+        ''}
+
+          runHook postInstall
+        '';
+
+        dontFixup = true;
+      }; in modArgs // (
+          {
+            outputHashMode = "recursive";
+          } // (if (vendorHashType == "sha256") then {
+            outputHashAlgo = "sha256";
+            outputHash = vendorSha256;
+          } else {
+            outputHash = vendorHash;
+          }) // (lib.optionalAttrs (vendorHashType == "sri" && vendorHash == "") {
+            outputHashAlgo = "sha256";
+          })
+      ) // overrideModAttrs modArgs) else "";
+
+      package = stdenv.mkDerivation (args // {
+        nativeBuildInputs = [ go ] ++ nativeBuildInputs;
+
+        inherit (go) GOOS GOARCH;
+
+        GO111MODULE = "on";
+        GOFLAGS = lib.optionals (!proxyVendor) [ "-mod=vendor" ] ++ lib.optionals (!allowGoReference) [ "-trimpath" ];
+        inherit CGO_ENABLED;
+
+        configurePhase = args.configurePhase or ''
+          runHook preConfigure
+
+          export GOCACHE=$TMPDIR/go-cache
+          export GOPATH="$TMPDIR/go"
+          export GOPROXY=off
+          export GOSUMDB=off
+          cd "$modRoot"
+        '' + lib.optionalString hasAnyVendorHash ''
+          ${if proxyVendor then ''
+            export GOPROXY=file://${go-modules}
+          '' else ''
+            rm -rf vendor
+            cp -r --reflink=auto ${go-modules} vendor
+          ''}
+        '' + ''
+
+          runHook postConfigure
+        '';
+
+        buildPhase = args.buildPhase or ''
+          runHook preBuild
+
+          exclude='\(/_\|examples\|Godeps\|testdata'
+          if [[ -n "$excludedPackages" ]]; then
+            IFS=' ' read -r -a excludedArr <<<$excludedPackages
+            printf -v excludedAlternates '%s\\|' "''${excludedArr[@]}"
+            excludedAlternates=''${excludedAlternates%\\|} # drop final \| added by printf
+            exclude+='\|'"$excludedAlternates"
+          fi
+          exclude+='\)'
+
+          buildGoDir() {
+            local cmd="$1" dir="$2"
+
+            . $TMPDIR/buildFlagsArray
+
+            declare -a flags
+            flags+=($buildFlags "''${buildFlagsArray[@]}")
+            flags+=(''${tags:+-tags=${lib.concatStringsSep "," tags}})
+            flags+=(''${ldflags:+-ldflags="$ldflags"})
+            flags+=("-v" "-p" "$NIX_BUILD_CORES")
+
+            if [ "$cmd" = "test" ]; then
+              flags+=($checkFlags)
+            fi
+
+            local OUT
+            if ! OUT="$(go $cmd "''${flags[@]}" $dir 2>&1)"; then
+              if ! echo "$OUT" | grep -qE '(no( buildable| non-test)?|build constraints exclude all) Go (source )?files'; then
+                echo "$OUT" >&2
+                return 1
+              fi
+            fi
+            if [ -n "$OUT" ]; then
+              echo "$OUT" >&2
+            fi
+            return 0
+          }
+
+          getGoDirs() {
+            local type;
+            type="$1"
+            if [ -n "$subPackages" ]; then
+              echo "$subPackages" | sed "s,\(^\| \),\1./,g"
+            else
+              find . -type f -name \*$type.go -exec dirname {} \; | grep -v "/vendor/" | sort --unique | grep -v "$exclude"
+            fi
+          }
+
+          if (( "''${NIX_DEBUG:-0}" >= 1 )); then
+            buildFlagsArray+=(-x)
+          fi
+
+          if [ ''${#buildFlagsArray[@]} -ne 0 ]; then
+            declare -p buildFlagsArray > $TMPDIR/buildFlagsArray
+          else
+            touch $TMPDIR/buildFlagsArray
+          fi
+          if [ -z "$enableParallelBuilding" ]; then
+              export NIX_BUILD_CORES=1
+          fi
+          for pkg in $(getGoDirs ""); do
+            echo "Building subPackage $pkg"
+            buildGoDir install "$pkg"
+          done
+        '' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
+          # normalize cross-compiled builds w.r.t. native builds
+          (
+            dir=$GOPATH/bin/${go.GOOS}_${go.GOARCH}
+            if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then
+              mv $dir/* $dir/..
+            fi
+            if [[ -d $dir ]]; then
+              rmdir $dir
+            fi
+          )
+        '' + ''
+          runHook postBuild
+        '';
+
+        doCheck = args.doCheck or true;
+        checkPhase = args.checkPhase or ''
+          runHook preCheck
+          # We do not set trimpath for tests, in case they reference test assets
+          export GOFLAGS=''${GOFLAGS//-trimpath/}
+
+          for pkg in $(getGoDirs test); do
+            buildGoDir test "$pkg"
+          done
+
+          runHook postCheck
+        '';
+
+        installPhase = args.installPhase or ''
+          runHook preInstall
+
+          mkdir -p $out
+          dir="$GOPATH/bin"
+          [ -e "$dir" ] && cp -r $dir $out
+
+          runHook postInstall
+        '';
+
+        strictDeps = true;
+
+        disallowedReferences = lib.optional (!allowGoReference) go;
+
+        passthru = passthru // { inherit go go-modules vendorSha256 vendorHash; };
+
+        enableParallelBuilding = enableParallelBuilding;
+
+        meta = {
+          # Add default meta information
+          platforms = go.meta.platforms or lib.platforms.all;
+        } // meta;
+      }) // {
+        overrideGoAttrs = f: buildGoPackage (args' // (f args'));
+      };
+    in
+    lib.warnIf (buildFlags != "" || buildFlagsArray != "")
+      "Use the `ldflags` and/or `tags` attributes instead of `buildFlags`/`buildFlagsArray`"
+      package;
+in
+  buildGoPackage
diff --git a/nixpkgs/pkgs/build-support/go/package.nix b/nixpkgs/pkgs/build-support/go/package.nix
new file mode 100644
index 000000000000..56c8ceeca15f
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/go/package.nix
@@ -0,0 +1,286 @@
+{ go, govers, lib, fetchgit, fetchhg, fetchbzr, rsync
+, fetchFromGitHub, stdenv }:
+
+{ buildInputs ? []
+, nativeBuildInputs ? []
+, passthru ? {}
+, preFixup ? ""
+, shellHook ? ""
+
+# Go linker flags, passed to go via -ldflags
+, ldflags ? []
+
+# Go tags, passed to go via -tag
+, tags ? []
+
+# We want parallel builds by default
+, enableParallelBuilding ? true
+
+# Go import path of the package
+, goPackagePath
+
+# Go package aliases
+, goPackageAliases ? [ ]
+
+# Extra sources to include in the gopath
+, extraSrcs ? [ ]
+
+# Extra gopaths containing src subfolder
+# with sources to include in the gopath
+, extraSrcPaths ? [ ]
+
+# go2nix dependency file
+, goDeps ? null
+
+# Whether to delete the vendor folder supplied with the source.
+, deleteVendor ? false
+
+, dontRenameImports ? false
+
+# Do not enable this without good reason
+# IE: programs coupled with the compiler
+, allowGoReference ? false
+
+, CGO_ENABLED ? go.CGO_ENABLED
+
+# needed for buildFlags{,Array} warning
+, buildFlags ? ""
+, buildFlagsArray ? ""
+
+, meta ? {}, ... } @ args:
+
+
+with builtins;
+
+let
+  dep2src = goDep:
+    {
+      inherit (goDep) goPackagePath;
+      src = if goDep.fetch.type == "git" then
+        fetchgit {
+          inherit (goDep.fetch) url rev sha256;
+        }
+      else if goDep.fetch.type == "hg" then
+        fetchhg {
+          inherit (goDep.fetch) url rev sha256;
+        }
+      else if goDep.fetch.type == "bzr" then
+        fetchbzr {
+          inherit (goDep.fetch) url rev sha256;
+        }
+      else if goDep.fetch.type == "FromGitHub" then
+        fetchFromGitHub {
+          inherit (goDep.fetch) owner repo rev sha256;
+        }
+      else abort "Unrecognized package fetch type: ${goDep.fetch.type}";
+    };
+
+  importGodeps = { depsFile }:
+    map dep2src (import depsFile);
+
+  goPath = if goDeps != null then importGodeps { depsFile = goDeps; } ++ extraSrcs
+                             else extraSrcs;
+  package = stdenv.mkDerivation (
+    (builtins.removeAttrs args [ "goPackageAliases" "disabled" "extraSrcs"]) // {
+
+    nativeBuildInputs = [ go ]
+      ++ (lib.optional (!dontRenameImports) govers) ++ nativeBuildInputs;
+    buildInputs = buildInputs;
+
+    inherit (go) GOOS GOARCH GO386;
+
+    GOHOSTARCH = go.GOHOSTARCH or null;
+    GOHOSTOS = go.GOHOSTOS or null;
+
+    inherit CGO_ENABLED;
+
+    GO111MODULE = "off";
+    GOFLAGS = lib.optionals (!allowGoReference) [ "-trimpath" ];
+
+    GOARM = toString (lib.intersectLists [(stdenv.hostPlatform.parsed.cpu.version or "")] ["5" "6" "7"]);
+
+    configurePhase = args.configurePhase or ''
+      runHook preConfigure
+
+      # Extract the source
+      cd "$NIX_BUILD_TOP"
+      mkdir -p "go/src/$(dirname "$goPackagePath")"
+      mv "$sourceRoot" "go/src/$goPackagePath"
+
+    '' + lib.optionalString (deleteVendor == true) ''
+      if [ ! -d "go/src/$goPackagePath/vendor" ]; then
+        echo "vendor folder does not exist, 'deleteVendor' is not needed"
+        exit 10
+      else
+        rm -rf "go/src/$goPackagePath/vendor"
+      fi
+    '' + lib.optionalString (goDeps != null) ''
+      if [ -d "go/src/$goPackagePath/vendor" ]; then
+        echo "vendor folder exists, 'goDeps' is not needed"
+        exit 10
+      fi
+    '' + lib.flip lib.concatMapStrings goPath ({ src, goPackagePath }: ''
+      mkdir goPath
+      (cd goPath; unpackFile "${src}")
+      mkdir -p "go/src/$(dirname "${goPackagePath}")"
+      chmod -R u+w goPath/*
+      mv goPath/* "go/src/${goPackagePath}"
+      rmdir goPath
+
+    '') + (lib.optionalString (extraSrcPaths != []) ''
+      ${rsync}/bin/rsync -a ${lib.concatMapStringsSep " " (p: "${p}/src") extraSrcPaths} go
+
+    '') + ''
+      export GOPATH=$NIX_BUILD_TOP/go:$GOPATH
+      export GOCACHE=$TMPDIR/go-cache
+
+      runHook postConfigure
+    '';
+
+    renameImports = args.renameImports or (
+      let
+        inputsWithAliases = lib.filter (x: x ? goPackageAliases)
+          (buildInputs ++ (args.propagatedBuildInputs or [ ]));
+        rename = to: from: "echo Renaming '${from}' to '${to}'; govers -d -m ${from} ${to}";
+        renames = p: lib.concatMapStringsSep "\n" (rename p.goPackagePath) p.goPackageAliases;
+      in lib.concatMapStringsSep "\n" renames inputsWithAliases);
+
+    buildPhase = args.buildPhase or ''
+      runHook preBuild
+
+      runHook renameImports
+
+      exclude='\(/_\|examples\|Godeps\|testdata'
+      if [[ -n "$excludedPackages" ]]; then
+        IFS=' ' read -r -a excludedArr <<<$excludedPackages
+        printf -v excludedAlternates '%s\\|' "''${excludedArr[@]}"
+        excludedAlternates=''${excludedAlternates%\\|} # drop final \| added by printf
+        exclude+='\|'"$excludedAlternates"
+      fi
+      exclude+='\)'
+
+      buildGoDir() {
+        local cmd="$1" dir="$2"
+
+        . $TMPDIR/buildFlagsArray
+
+        declare -a flags
+        flags+=($buildFlags "''${buildFlagsArray[@]}")
+        flags+=(''${tags:+-tags=${lib.concatStringsSep "," tags}})
+        flags+=(''${ldflags:+-ldflags="$ldflags"})
+        flags+=("-v" "-p" "$NIX_BUILD_CORES")
+
+        if [ "$cmd" = "test" ]; then
+          flags+=($checkFlags)
+        fi
+
+        local OUT
+        if ! OUT="$(go $cmd "''${flags[@]}" $dir 2>&1)"; then
+          if ! echo "$OUT" | grep -qE '(no( buildable| non-test)?|build constraints exclude all) Go (source )?files'; then
+            echo "$OUT" >&2
+            return 1
+          fi
+        fi
+        if [ -n "$OUT" ]; then
+          echo "$OUT" >&2
+        fi
+        return 0
+      }
+
+      getGoDirs() {
+        local type;
+        type="$1"
+        if [ -n "$subPackages" ]; then
+          echo "$subPackages" | sed "s,\(^\| \),\1$goPackagePath/,g"
+        else
+          pushd "$NIX_BUILD_TOP/go/src" >/dev/null
+          find "$goPackagePath" -type f -name \*$type.go -exec dirname {} \; | grep -v "/vendor/" | sort | uniq | grep -v "$exclude"
+          popd >/dev/null
+        fi
+      }
+
+      if (( "''${NIX_DEBUG:-0}" >= 1 )); then
+        buildFlagsArray+=(-x)
+      fi
+
+      if [ ''${#buildFlagsArray[@]} -ne 0 ]; then
+        declare -p buildFlagsArray > $TMPDIR/buildFlagsArray
+      else
+        touch $TMPDIR/buildFlagsArray
+      fi
+      if [ -z "$enableParallelBuilding" ]; then
+          export NIX_BUILD_CORES=1
+      fi
+      for pkg in $(getGoDirs ""); do
+        echo "Building subPackage $pkg"
+        buildGoDir install "$pkg"
+      done
+    '' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
+      # normalize cross-compiled builds w.r.t. native builds
+      (
+        dir=$NIX_BUILD_TOP/go/bin/${go.GOOS}_${go.GOARCH}
+        if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then
+          mv $dir/* $dir/..
+        fi
+        if [[ -d $dir ]]; then
+          rmdir $dir
+        fi
+      )
+    '' + ''
+      runHook postBuild
+    '';
+
+    doCheck = args.doCheck or false;
+    checkPhase = args.checkPhase or ''
+      runHook preCheck
+      # We do not set trimpath for tests, in case they reference test assets
+      export GOFLAGS=''${GOFLAGS//-trimpath/}
+
+      for pkg in $(getGoDirs test); do
+        buildGoDir test "$pkg"
+      done
+
+      runHook postCheck
+    '';
+
+    installPhase = args.installPhase or ''
+      runHook preInstall
+
+      mkdir -p $out
+      dir="$NIX_BUILD_TOP/go/bin"
+      [ -e "$dir" ] && cp -r $dir $out
+
+      runHook postInstall
+    '';
+
+    strictDeps = true;
+
+    shellHook = ''
+      d=$(mktemp -d "--suffix=-$name")
+    '' + toString (map (dep: ''
+       mkdir -p "$d/src/$(dirname "${dep.goPackagePath}")"
+       ln -s "${dep.src}" "$d/src/${dep.goPackagePath}"
+    ''
+    ) goPath) + ''
+      export GOPATH=${lib.concatStringsSep ":" ( ["$d"] ++ ["$GOPATH"] ++ ["$PWD"] ++ extraSrcPaths)}
+    '' + shellHook;
+
+    disallowedReferences = lib.optional (!allowGoReference) go
+      ++ lib.optional (!dontRenameImports) govers;
+
+    passthru = passthru //
+      { inherit go; } //
+      lib.optionalAttrs (goPackageAliases != []) { inherit goPackageAliases; };
+
+    enableParallelBuilding = enableParallelBuilding;
+
+    meta = {
+      # Add default meta information
+      homepage = "https://${goPackagePath}";
+      platforms = go.meta.platforms or lib.platforms.all;
+    } // meta;
+  });
+in
+lib.warnIf (buildFlags != "" || buildFlagsArray != "")
+  "Use the `ldflags` and/or `tags` attributes instead of `buildFlags`/`buildFlagsArray`"
+  package
diff --git a/nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix b/nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix
new file mode 100644
index 000000000000..6a797226aa67
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix
@@ -0,0 +1,16 @@
+{ runCommand }:
+
+firmware:
+
+runCommand "${firmware.name}-xz" {} ''
+  mkdir -p $out/lib
+  (cd ${firmware} && find lib/firmware -type d -print0) |
+      (cd $out && xargs -0 mkdir -v --)
+  (cd ${firmware} && find lib/firmware -type f -print0) |
+      (cd $out && xargs -0rtP "$NIX_BUILD_CORES" -n1 \
+          sh -c 'xz -9c -T1 -C crc32 --lzma2=dict=2MiB "${firmware}/$1" > "$1.xz"' --)
+  (cd ${firmware} && find lib/firmware -type l) | while read link; do
+      target="$(readlink "${firmware}/$link")"
+      ln -vs -- "''${target/^${firmware}/$out}.xz" "$out/$link.xz"
+  done
+''
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng-tool.nix b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng-tool.nix
new file mode 100644
index 000000000000..b1fbee92b32e
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng-tool.nix
@@ -0,0 +1,17 @@
+{ rustPlatform, lib, makeWrapper, patchelf, glibc, binutils }:
+
+rustPlatform.buildRustPackage {
+  pname = "make-initrd-ng";
+  version = "0.1.0";
+
+  src = ./make-initrd-ng;
+  cargoLock.lockFile = ./make-initrd-ng/Cargo.lock;
+
+  passthru.updateScript = ./make-initrd-ng/update.sh;
+
+  meta = {
+    description = "Tool for copying binaries and their dependencies";
+    maintainers = with lib.maintainers; [ das_j elvishjerricco k900 lheckemann ];
+    license = lib.licenses.mit;
+  };
+}
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix
new file mode 100644
index 000000000000..e762464fc489
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix
@@ -0,0 +1,97 @@
+let
+  # Some metadata on various compression programs, relevant to naming
+  # the initramfs file and, if applicable, generating a u-boot image
+  # from it.
+  compressors = import ./initrd-compressor-meta.nix;
+  # Get the basename of the actual compression program from the whole
+  # compression command, for the purpose of guessing the u-boot
+  # compression type and filename extension.
+  compressorName = fullCommand: builtins.elemAt (builtins.match "([^ ]*/)?([^ ]+).*" fullCommand) 1;
+in
+{ stdenvNoCC, perl, cpio, ubootTools, lib, pkgsBuildHost, makeInitrdNGTool, binutils, runCommand
+# Name of the derivation (not of the resulting file!)
+, name ? "initrd"
+
+, strip ? true
+
+# Program used to compress the cpio archive; use "cat" for no compression.
+# This can also be a function which takes a package set and returns the path to the compressor,
+# such as `pkgs: "${pkgs.lzop}/bin/lzop"`.
+, compressor ? "gzip"
+, _compressorFunction ?
+  if lib.isFunction compressor then compressor
+  else if ! builtins.hasContext compressor && builtins.hasAttr compressor compressors then compressors.${compressor}.executable
+  else _: compressor
+, _compressorExecutable ? _compressorFunction pkgsBuildHost
+, _compressorName ? compressorName _compressorExecutable
+, _compressorMeta ? compressors.${_compressorName} or {}
+
+# List of arguments to pass to the compressor program, or null to use its defaults
+, compressorArgs ? null
+, _compressorArgsReal ? if compressorArgs == null then _compressorMeta.defaultArgs or [] else compressorArgs
+
+# Filename extension to use for the compressed initramfs. This is
+# included for clarity, but $out/initrd will always be a symlink to
+# the final image.
+# If this isn't guessed, you may want to complete the metadata above and send a PR :)
+, extension ? _compressorMeta.extension or
+    (throw "Unrecognised compressor ${_compressorName}, please specify filename extension")
+
+# List of { object = path_or_derivation; symlink = "/path"; }
+# The paths are copied into the initramfs in their nix store path
+# form, then linked at the root according to `symlink`.
+, contents
+
+# List of uncompressed cpio files to prepend to the initramfs. This
+# can be used to add files in specified paths without them becoming
+# symlinks to store paths.
+, prepend ? []
+
+# Whether to wrap the initramfs in a u-boot image.
+, makeUInitrd ? stdenvNoCC.hostPlatform.linux-kernel.target == "uImage"
+
+# If generating a u-boot image, the architecture to use. The default
+# guess may not align with u-boot's nomenclature correctly, so it can
+# be overridden.
+# See https://gitlab.denx.de/u-boot/u-boot/-/blob/9bfb567e5f1bfe7de8eb41f8c6d00f49d2b9a426/common/image.c#L81-106 for a list.
+, uInitrdArch ? stdenvNoCC.hostPlatform.linuxArch
+
+# The name of the compression, as recognised by u-boot.
+# See https://gitlab.denx.de/u-boot/u-boot/-/blob/9bfb567e5f1bfe7de8eb41f8c6d00f49d2b9a426/common/image.c#L195-204 for a list.
+# If this isn't guessed, you may want to complete the metadata above and send a PR :)
+, uInitrdCompression ? _compressorMeta.ubootName or
+    (throw "Unrecognised compressor ${_compressorName}, please specify uInitrdCompression")
+}: runCommand name ({
+  compress = "${_compressorExecutable} ${lib.escapeShellArgs _compressorArgsReal}";
+  passthru = {
+    compressorExecutableFunction = _compressorFunction;
+    compressorArgs = _compressorArgsReal;
+  };
+
+  inherit extension makeUInitrd uInitrdArch prepend;
+  ${if makeUInitrd then "uInitrdCompression" else null} = uInitrdCompression;
+
+  passAsFile = ["contents"];
+  contents = lib.concatMapStringsSep "\n" ({ object, symlink, ... }: "${object}\n${if symlink == null then "" else symlink}") contents + "\n";
+
+  nativeBuildInputs = [makeInitrdNGTool cpio] ++ lib.optional makeUInitrd ubootTools ++ lib.optional strip binutils;
+
+  STRIP = if strip then "${(binutils.nativeDrv or binutils).targetPrefix}strip" else null;
+}) ''
+  mkdir ./root
+  make-initrd-ng "$contentsPath" ./root
+  mkdir "$out"
+  (cd root && find * .[^.*] -exec touch -h -d '@1' '{}' +)
+  for PREP in $prepend; do
+    cat $PREP >> $out/initrd
+  done
+  (cd root && find * .[^.*] -print0 | sort -z | cpio -o -H newc -R +0:+0 --reproducible --null | eval -- $compress >> "$out/initrd")
+
+  if [ -n "$makeUInitrd" ]; then
+      mkimage -A "$uInitrdArch" -O linux -T ramdisk -C "$uInitrdCompression" -d "$out/initrd" $out/initrd.img
+      # Compatibility symlink
+      ln -sf "initrd.img" "$out/initrd"
+  else
+      ln -s "initrd" "$out/initrd$extension"
+  fi
+''
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock
new file mode 100644
index 000000000000..cce94b3f4cfb
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.lock
@@ -0,0 +1,97 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "goblin"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91766b1121940d622933a13e20665857648681816089c9bc2075c4b75a6e4f6b"
+dependencies = [
+ "log",
+ "plain",
+ "scroll",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "make-initrd-ng"
+version = "0.1.0"
+dependencies = [
+ "goblin",
+]
+
+[[package]]
+name = "plain"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "scroll"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da"
+dependencies = [
+ "scroll_derive",
+]
+
+[[package]]
+name = "scroll_derive"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdbda6ac5cd1321e724fa9cee216f3a61885889b896f073b8f82322789c5250e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.98"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.toml b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.toml
new file mode 100644
index 000000000000..c30eccd9fec7
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "make-initrd-ng"
+version = "0.1.0"
+authors = ["Will Fancher <elvishjerricco@gmail.com>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+goblin = "0.5.0"
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/README.md b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/README.md
new file mode 100644
index 000000000000..741eba67e43f
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/README.md
@@ -0,0 +1,79 @@
+# What is this for?
+
+NixOS's traditional initrd is generated by listing the paths that
+should be included in initrd and copying the full runtime closure of
+those paths into the archive. For most things, like almost any
+executable, this involves copying the entirety of huge packages like
+glibc, when only things like the shared library files are needed. To
+solve this, NixOS does a variety of patchwork to edit the files being
+copied in so they only refer to small, patched up paths. For instance,
+executables and their shared library dependencies are copied into an
+`extraUtils` derivation, and every ELF file is patched to refer to
+files in that output.
+
+The problem with this is that it is often difficult to correctly patch
+some things. For instance, systemd bakes the path to the `mount`
+command into the binary, so patchelf is no help. Instead, it's very
+often easier to simply copy the desired files to their original store
+locations in initrd and not copy their entire runtime closure. This
+does mean that it is the burden of the developer to ensure that all
+necessary dependencies are copied in, as closures won't be
+consulted. However, it is rare that full closures are actually
+desirable, so in the traditional initrd, the developer was likely to
+do manual work on patching the dependencies explicitly anyway.
+
+# How it works
+
+This program is similar to its inspiration (`find-libs` from the
+traditional initrd), except that it also handles symlinks and
+directories according to certain rules. As input, it receives a
+sequence of pairs of paths. The first path is an object to copy into
+initrd. The second path (if not empty) is the path to a symlink that
+should be placed in the initrd, pointing to that object. How that
+object is copied depends on its type.
+
+1. A regular file is copied directly to the same absolute path in the
+   initrd.
+
+   - If it is *also* an ELF file, then all of its direct shared
+     library dependencies are also listed as objects to be copied.
+
+2. A directory's direct children are listed as objects to be copied,
+   and a directory at the same absolute path in the initrd is created.
+
+3. A symlink's target is listed as an object to be copied.
+
+There are a couple of quirks to mention here. First, the term "object"
+refers to the final file path that the developer intends to have
+copied into initrd. This means any parent directory is not considered
+an object just because its child was listed as an object in the
+program input; instead those intermediate directories are simply
+created in support of the target object. Second, shared libraries,
+directory children, and symlink targets aren't immediately recursed,
+because they simply get listed as objects themselves, and are
+therefore traversed when they themselves are processed. Finally,
+symlinks in the intermediate directories leading to an object are
+preserved, meaning an input object `/a/symlink/b` will just result in
+initrd containing `/a/symlink -> /target/b` and `/target/b`, even if
+`/target` has other children. Preserving symlinks in this manner is
+important for things like systemd.
+
+These rules automate the most important and obviously necessary
+copying that needs to be done in most cases, allowing programs and
+configuration files to go unpatched, while keeping the content of the
+initrd to a minimum.
+
+# Why Rust?
+
+- A prototype of this logic was written in Bash, in an attempt to keep
+  with its `find-libs` ancestor, but that program was difficult to
+  write, and ended up taking several minutes to run. This program runs
+  in less than a second, and the code is substantially easier to work
+  with.
+
+- This will not require end users to install a rust toolchain to use
+  NixOS, as long as this tool is cached by Hydra. And if you're
+  bootstrapping NixOS from source, rustc is already required anyway.
+
+- Rust was favored over Python for its type system, and because if you
+  want to go fast, why not go *really fast*?
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/src/main.rs b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/src/main.rs
new file mode 100644
index 000000000000..89a7c08fda7e
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/src/main.rs
@@ -0,0 +1,233 @@
+use std::collections::{HashSet, VecDeque};
+use std::env;
+use std::ffi::OsStr;
+use std::fs;
+use std::hash::Hash;
+use std::io::{BufRead, BufReader, Error};
+use std::os::unix;
+use std::path::{Component, Path, PathBuf};
+use std::process::Command;
+
+use goblin::{elf::Elf, Object};
+
+struct NonRepeatingQueue<T> {
+    queue: VecDeque<T>,
+    seen: HashSet<T>,
+}
+
+impl<T> NonRepeatingQueue<T> {
+    fn new() -> NonRepeatingQueue<T> {
+        NonRepeatingQueue {
+            queue: VecDeque::new(),
+            seen: HashSet::new(),
+        }
+    }
+}
+
+impl<T: Clone + Eq + Hash> NonRepeatingQueue<T> {
+    fn push_back(&mut self, value: T) -> bool {
+        if self.seen.contains(&value) {
+            false
+        } else {
+            self.seen.insert(value.clone());
+            self.queue.push_back(value);
+            true
+        }
+    }
+
+    fn pop_front(&mut self) -> Option<T> {
+        self.queue.pop_front()
+    }
+}
+
+fn add_dependencies<P: AsRef<Path> + AsRef<OsStr>>(
+    source: P,
+    elf: Elf,
+    queue: &mut NonRepeatingQueue<Box<Path>>,
+) {
+    if let Some(interp) = elf.interpreter {
+        queue.push_back(Box::from(Path::new(interp)));
+    }
+
+    let rpaths = if elf.runpaths.len() > 0 {
+        elf.runpaths
+    } else if elf.rpaths.len() > 0 {
+        elf.rpaths
+    } else {
+        vec![]
+    };
+
+    let rpaths_as_path = rpaths
+        .into_iter()
+        .flat_map(|p| p.split(":"))
+        .map(|p| Box::<Path>::from(Path::new(p)))
+        .collect::<Vec<_>>();
+
+    for line in elf.libraries {
+        let mut found = false;
+        for path in &rpaths_as_path {
+            let lib = path.join(line);
+            if lib.exists() {
+                // No need to recurse. The queue will bring it back round.
+                queue.push_back(Box::from(lib.as_path()));
+                found = true;
+                break;
+            }
+        }
+        if !found {
+            // glibc makes it tricky to make this an error because
+            // none of the files have a useful rpath.
+            println!(
+                "Warning: Couldn't satisfy dependency {} for {:?}",
+                line,
+                OsStr::new(&source)
+            );
+        }
+    }
+}
+
+fn copy_file<P: AsRef<Path> + AsRef<OsStr>, S: AsRef<Path> + AsRef<OsStr>>(
+    source: P,
+    target: S,
+    queue: &mut NonRepeatingQueue<Box<Path>>,
+) -> Result<(), Error> {
+    fs::copy(&source, &target)?;
+
+    let contents = fs::read(&source)?;
+
+    if let Ok(Object::Elf(e)) = Object::parse(&contents) {
+        add_dependencies(source, e, queue);
+
+        // Make file writable to strip it
+        let mut permissions = fs::metadata(&target)?.permissions();
+        permissions.set_readonly(false);
+        fs::set_permissions(&target, permissions)?;
+
+        // Strip further than normal
+        if let Ok(strip) = env::var("STRIP") {
+            if !Command::new(strip)
+                .arg("--strip-all")
+                .arg(OsStr::new(&target))
+                .output()?
+                .status
+                .success()
+            {
+                println!("{:?} was not successfully stripped.", OsStr::new(&target));
+            }
+        }
+    };
+
+    Ok(())
+}
+
+fn queue_dir<P: AsRef<Path>>(
+    source: P,
+    queue: &mut NonRepeatingQueue<Box<Path>>,
+) -> Result<(), Error> {
+    for entry in fs::read_dir(source)? {
+        let entry = entry?;
+        // No need to recurse. The queue will bring us back round here on its own.
+        queue.push_back(Box::from(entry.path().as_path()));
+    }
+
+    Ok(())
+}
+
+fn handle_path(
+    root: &Path,
+    p: &Path,
+    queue: &mut NonRepeatingQueue<Box<Path>>,
+) -> Result<(), Error> {
+    let mut source = PathBuf::new();
+    let mut target = Path::new(root).to_path_buf();
+    let mut iter = p.components().peekable();
+    while let Some(comp) = iter.next() {
+        match comp {
+            Component::Prefix(_) => panic!("This tool is not meant for Windows"),
+            Component::RootDir => {
+                target.clear();
+                target.push(root);
+                source.clear();
+                source.push("/");
+            }
+            Component::CurDir => {}
+            Component::ParentDir => {
+                // Don't over-pop the target if the path has too many ParentDirs
+                if source.pop() {
+                    target.pop();
+                }
+            }
+            Component::Normal(name) => {
+                target.push(name);
+                source.push(name);
+                let typ = fs::symlink_metadata(&source)?.file_type();
+                if typ.is_file() && !target.exists() {
+                    copy_file(&source, &target, queue)?;
+                } else if typ.is_symlink() {
+                    let link_target = fs::read_link(&source)?;
+
+                    // Create the link, then push its target to the queue
+                    if !target.exists() {
+                        unix::fs::symlink(&link_target, &target)?;
+                    }
+                    source.pop();
+                    source.push(link_target);
+                    while let Some(c) = iter.next() {
+                        source.push(c);
+                    }
+                    let link_target_path = source.as_path();
+                    if link_target_path.exists() {
+                        queue.push_back(Box::from(link_target_path));
+                    }
+                    break;
+                } else if typ.is_dir() {
+                    if !target.exists() {
+                        fs::create_dir(&target)?;
+                    }
+
+                    // Only recursively copy if the directory is the target object
+                    if iter.peek().is_none() {
+                        queue_dir(&source, queue)?;
+                    }
+                }
+            }
+        }
+    }
+
+    Ok(())
+}
+
+fn main() -> Result<(), Error> {
+    let args: Vec<String> = env::args().collect();
+    let input = fs::File::open(&args[1])?;
+    let output = &args[2];
+    let out_path = Path::new(output);
+
+    let mut queue = NonRepeatingQueue::<Box<Path>>::new();
+
+    let mut lines = BufReader::new(input).lines();
+    while let Some(obj) = lines.next() {
+        // Lines should always come in pairs
+        let obj = obj?;
+        let sym = lines.next().unwrap()?;
+
+        let obj_path = Path::new(&obj);
+        queue.push_back(Box::from(obj_path));
+        if !sym.is_empty() {
+            println!("{} -> {}", &sym, &obj);
+            // We don't care about preserving symlink structure here
+            // nearly as much as for the actual objects.
+            let link_string = format!("{}/{}", output, sym);
+            let link_path = Path::new(&link_string);
+            let mut link_parent = link_path.to_path_buf();
+            link_parent.pop();
+            fs::create_dir_all(link_parent)?;
+            unix::fs::symlink(obj_path, link_path)?;
+        }
+    }
+    while let Some(obj) = queue.pop_front() {
+        handle_path(out_path, &*obj, &mut queue)?;
+    }
+
+    Ok(())
+}
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/update.sh b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/update.sh
new file mode 100755
index 000000000000..ffc5ad3917f7
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng/update.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env nix-shell
+#!nix-shell -p cargo -i bash
+cd "$(dirname "$0")"
+cargo update
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd.nix b/nixpkgs/pkgs/build-support/kernel/make-initrd.nix
index 23ce992f0d55..9c27a142f4b6 100644
--- a/nixpkgs/pkgs/build-support/kernel/make-initrd.nix
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd.nix
@@ -18,7 +18,7 @@ let
   # compression type and filename extension.
   compressorName = fullCommand: builtins.elemAt (builtins.match "([^ ]*/)?([^ ]+).*" fullCommand) 1;
 in
-{ stdenvNoCC, perl, cpio, ubootTools, lib, pkgsBuildHost
+{ stdenvNoCC, perl, libarchive, ubootTools, lib, pkgsBuildHost
 # Name of the derivation (not of the resulting file!)
 , name ? "initrd"
 
@@ -82,7 +82,7 @@ in stdenvNoCC.mkDerivation rec {
 
   builder = ./make-initrd.sh;
 
-  nativeBuildInputs = [ perl cpio ]
+  nativeBuildInputs = [ perl libarchive ]
     ++ lib.optional makeUInitrd ubootTools;
 
   compress = "${_compressorExecutable} ${lib.escapeShellArgs _compressorArgsReal}";
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd.sh b/nixpkgs/pkgs/build-support/kernel/make-initrd.sh
index 0a87d643546a..8f64114d54c3 100644
--- a/nixpkgs/pkgs/build-support/kernel/make-initrd.sh
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd.sh
@@ -40,7 +40,7 @@ for PREP in $prepend; do
   cat $PREP >> $out/initrd
 done
 (cd root && find * .[^.*] -exec touch -h -d '@1' '{}' +)
-(cd root && find * .[^.*] -print0 | sort -z | cpio -o -H newc -R +0:+0 --reproducible --null | eval -- $compress >> "$out/initrd")
+(cd root && find * .[^.*] -print0 | sort -z | bsdtar --uid 0 --gid 0 -cnf - -T - | bsdtar --null -cf - --format=newc @- | eval -- $compress >> "$out/initrd")
 
 if [ -n "$makeUInitrd" ]; then
     mkimage -A "$uInitrdArch" -O linux -T ramdisk -C "$uInitrdCompression" -d "$out/initrd" $out/initrd.img
diff --git a/nixpkgs/pkgs/build-support/kernel/modules-closure.sh b/nixpkgs/pkgs/build-support/kernel/modules-closure.sh
index 3b3a38ea1d33..74bc490eb15c 100644
--- a/nixpkgs/pkgs/build-support/kernel/modules-closure.sh
+++ b/nixpkgs/pkgs/build-support/kernel/modules-closure.sh
@@ -81,8 +81,12 @@ for module in $(cat closure); do
     for i in $(modinfo -b $kernel --set-version "$version" -F firmware $module | grep -v '^name:'); do
         mkdir -p "$out/lib/firmware/$(dirname "$i")"
         echo "firmware for $module: $i"
-        cp "$firmware/lib/firmware/$i" "$out/lib/firmware/$i" 2>/dev/null \
-            || echo "WARNING: missing firmware $i for module $module"
+        for name in "$i" "$i.xz" ""; do
+            [ -z "$name" ] && echo "WARNING: missing firmware $i for module $module"
+            if cp "$firmware/lib/firmware/$name" "$out/lib/firmware/$name" 2>/dev/null; then
+                break
+            fi
+        done
     done
 done
 
diff --git a/nixpkgs/pkgs/build-support/libredirect/default.nix b/nixpkgs/pkgs/build-support/libredirect/default.nix
index 8f7df3386d14..b5eb21e5ba4b 100644
--- a/nixpkgs/pkgs/build-support/libredirect/default.nix
+++ b/nixpkgs/pkgs/build-support/libredirect/default.nix
@@ -27,7 +27,7 @@ else stdenv.mkDerivation rec {
 
   outputs = ["out" "hook"];
 
-  libName = "libredirect" + stdenv.targetPlatform.extensions.sharedLibrary;
+  libName = "libredirect" + stdenv.hostPlatform.extensions.sharedLibrary;
 
   buildPhase = ''
     runHook preBuild
diff --git a/nixpkgs/pkgs/build-support/make-darwin-bundle/default.nix b/nixpkgs/pkgs/build-support/make-darwin-bundle/default.nix
index b8f58882fff3..52dd54b0b2c4 100644
--- a/nixpkgs/pkgs/build-support/make-darwin-bundle/default.nix
+++ b/nixpkgs/pkgs/build-support/make-darwin-bundle/default.nix
@@ -12,14 +12,14 @@
 
 writeShellScript "make-darwin-bundle-${name}" (''
   function makeDarwinBundlePhase() {
-    mkdir -p "$out/Applications/${name}.app/Contents/MacOS"
-    mkdir -p "$out/Applications/${name}.app/Contents/Resources"
+    mkdir -p "''${!outputBin}/Applications/${name}.app/Contents/MacOS"
+    mkdir -p "''${!outputBin}/Applications/${name}.app/Contents/Resources"
 
     if [ -n "${icon}" ]; then
-      ln -s "${icon}" "$out/Applications/${name}.app/Contents/Resources"
+      ln -s "${icon}" "''${!outputBin}/Applications/${name}.app/Contents/Resources"
     fi
 
-    ${writeDarwinBundle}/bin/write-darwin-bundle "$out" "${name}" "${exec}"
+    ${writeDarwinBundle}/bin/write-darwin-bundle "''${!outputBin}" "${name}" "${exec}"
   }
 
   preDistPhases+=" makeDarwinBundlePhase"
diff --git a/nixpkgs/pkgs/build-support/make-desktopitem/default.nix b/nixpkgs/pkgs/build-support/make-desktopitem/default.nix
index d831fe24d33b..af314aa338c8 100644
--- a/nixpkgs/pkgs/build-support/make-desktopitem/default.nix
+++ b/nixpkgs/pkgs/build-support/make-desktopitem/default.nix
@@ -4,7 +4,7 @@
 # Please keep in spec order for easier maintenance.
 # When adding a new value, don't forget to update the Version field below!
 # See https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
-{ name # The name of the desktop file
+lib.makeOverridable ({ name # The name of the desktop file
 , type ? "Application"
 # version is hardcoded
 , desktopName # The name of the application
@@ -34,11 +34,6 @@
 , extraConfig ? {} # Additional values to be added literally to the final item, e.g. vendor extensions
 }:
 let
-  # FIXME: workaround until https://github.com/NixOS/nixpkgs/pull/162246 lands
-  cleanName = if lib.hasInfix " " name
-                then throw "makeDesktopItem: name must not contain spaces!"
-                else name;
-
   # There are multiple places in the FDO spec that make "boolean" values actually tristate,
   # e.g. StartupNotify, where "unset" is literally defined as "do something reasonable".
   # So, handle null values separately.
@@ -116,8 +111,8 @@ let
   content = [ mainSectionRendered ] ++ actionsRendered;
 in
 writeTextFile {
-  name = "${cleanName}.desktop";
-  destination = "/share/applications/${cleanName}.desktop";
+  name = "${name}.desktop";
+  destination = "/share/applications/${name}.desktop";
   text = builtins.concatStringsSep "\n" content;
-  checkPhase = "${buildPackages.desktop-file-utils}/bin/desktop-file-validate $target";
-}
+  checkPhase = ''${buildPackages.desktop-file-utils}/bin/desktop-file-validate "$target"'';
+})
diff --git a/nixpkgs/pkgs/build-support/make-pkgconfigitem/default.nix b/nixpkgs/pkgs/build-support/make-pkgconfigitem/default.nix
new file mode 100644
index 000000000000..288ca3810eb8
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/make-pkgconfigitem/default.nix
@@ -0,0 +1,69 @@
+{ lib, writeTextFile, buildPackages }:
+
+# See https://people.freedesktop.org/~dbn/pkg-config-guide.html#concepts
+{ name # The name of the pc file
+  # keywords
+  # provide a default description for convenience. it's not important but still required by pkg-config.
+, description ? "A pkg-config file for ${name}"
+, url ? ""
+, version ? ""
+, requires ? [ ]
+, requiresPrivate ? [ ]
+, conflicts ? [ ]
+, cflags ? [ ]
+, libs ? [ ]
+, libsPrivate ? [ ]
+, variables ? { }
+}:
+
+let
+  # only 'out' has to be changed, otherwise it would be replaced by the out of the writeTextFile
+  placeholderToSubstVar = builtins.replaceStrings [ "${placeholder "out"}" ] [ "@out@" ];
+
+  replacePlaceholderAndListToString = x:
+    if builtins.isList x
+    then placeholderToSubstVar (builtins.concatStringsSep " " x)
+    else placeholderToSubstVar x;
+
+  keywordsSection =
+    let
+      mustBeAList = attr: attrName: lib.throwIfNot (lib.isList attr) "'${attrName}' must be a list" attr;
+    in
+    {
+      "Name" = name;
+      "Description" = description;
+      "URL" = url;
+      "Version" = version;
+      "Requires" = mustBeAList requires "requires";
+      "Requires.private" = mustBeAList requiresPrivate "requiresPrivate";
+      "Conflicts" = mustBeAList conflicts "conflicts";
+      "Cflags" = mustBeAList cflags "cflags";
+      "Libs" = mustBeAList libs "libs";
+      "Libs.private" = mustBeAList libsPrivate "libsPrivate";
+    };
+
+  renderVariable = name: value:
+    lib.optionalString (value != "" && value != [ ]) "${name}=${replacePlaceholderAndListToString value}";
+  renderKeyword = name: value:
+    lib.optionalString (value != "" && value != [ ]) "${name}: ${replacePlaceholderAndListToString value}";
+
+  renderSomething = renderFunc: attrs:
+    lib.pipe attrs [
+      (lib.mapAttrsToList renderFunc)
+      (builtins.filter (v: v != ""))
+      (builtins.concatStringsSep "\n")
+      (section: ''${section}
+      '')
+    ];
+
+  variablesSectionRendered = renderSomething renderVariable variables;
+  keywordsSectionRendered = renderSomething renderKeyword keywordsSection;
+
+  content = [ variablesSectionRendered keywordsSectionRendered ];
+in
+writeTextFile {
+  name = "${name}.pc";
+  destination = "/lib/pkgconfig/${name}.pc";
+  text = builtins.concatStringsSep "\n" content;
+  checkPhase = ''${buildPackages.pkg-config}/bin/pkg-config --validate "$target"'';
+}
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js
index f3662a543616..b66e1220218d 100755
--- a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js
@@ -33,11 +33,11 @@ const urlToName = url => {
 	}
 }
 
-const downloadFileHttps = (fileName, url, expectedHash) => {
+const downloadFileHttps = (fileName, url, expectedHash, hashType = 'sha1') => {
 	return new Promise((resolve, reject) => {
 		https.get(url, (res) => {
 			const file = fs.createWriteStream(fileName)
-			const hash = crypto.createHash('sha1')
+			const hash = crypto.createHash(hashType)
 			res.pipe(file)
 			res.pipe(hash).setEncoding('hex')
 			res.on('end', () => {
@@ -100,6 +100,10 @@ const downloadPkg = (pkg, verbose) => {
 	} else if (isGitUrl(url)) {
 		return downloadGit(fileName, url.replace(/^git\+/, ''), hash)
 	} else if (url.startsWith('https://')) {
+		if (typeof pkg.integrity === 'string' || pkg.integrity instanceof String) {
+			const [ type, checksum ] = pkg.integrity.split('-')
+			return downloadFileHttps(fileName, url, Buffer.from(checksum, 'base64').toString('hex'), type)
+		}
 		return downloadFileHttps(fileName, url, hash)
 	} else if (url.startsWith('file:')) {
 		console.warn(`ignoring unsupported file:path url "${url}"`)
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix
index a781dad83072..19451466f24f 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix
@@ -1,15 +1,15 @@
-{ invalidateFetcherByDrvHash, fetchYarnDeps, ... }:
+{ testers, fetchYarnDeps, ... }:
 
 {
-  simple = invalidateFetcherByDrvHash fetchYarnDeps {
+  simple = testers.invalidateFetcherByDrvHash fetchYarnDeps {
     yarnLock = ./simple.lock;
     sha256 = "sha256-Erdkw2E8wWT09jFNLXGkrdwKl0HuSZWnUDJUrV95vSE=";
   };
-  gitDep = invalidateFetcherByDrvHash fetchYarnDeps {
+  gitDep = testers.invalidateFetcherByDrvHash fetchYarnDeps {
     yarnLock = ./git.lock;
     sha256 = "sha256-lAqN4LpoE+jgsQO1nDtuORwcVEO7ogEV53jCu2jFJUI=";
   };
-  githubDep = invalidateFetcherByDrvHash fetchYarnDeps {
+  githubDep = testers.invalidateFetcherByDrvHash fetchYarnDeps {
     yarnLock = ./github.lock;
     sha256 = "sha256-Tsfgyjxz8x6gNmfN0xR7G/NQNoEs4svxRN/N+26vfJU=";
   };
diff --git a/nixpkgs/pkgs/build-support/nuke-references/default.nix b/nixpkgs/pkgs/build-support/nuke-references/default.nix
index 03f6fe53b544..8dd9704aa4b4 100644
--- a/nixpkgs/pkgs/build-support/nuke-references/default.nix
+++ b/nixpkgs/pkgs/build-support/nuke-references/default.nix
@@ -14,6 +14,8 @@ in
 stdenvNoCC.mkDerivation {
   name = "nuke-references";
 
+  strictDeps = true;
+  enableParallelBuilding = true;
   dontUnpack = true;
   dontConfigure = true;
   dontBuild = true;
diff --git a/nixpkgs/pkgs/build-support/ocaml/dune.nix b/nixpkgs/pkgs/build-support/ocaml/dune.nix
index f82bac7d199d..2ded76d3cd4a 100644
--- a/nixpkgs/pkgs/build-support/ocaml/dune.nix
+++ b/nixpkgs/pkgs/build-support/ocaml/dune.nix
@@ -7,8 +7,8 @@ let Dune =
   { "1" = dune_1; "2" = dune_2; "3" = dune_3; }."${dune-version}"
 ; in
 
-if (args ? minimumOCamlVersion && ! lib.versionAtLeast ocaml.version args.minimumOCamlVersion) ||
-   (args ? minimalOCamlVersion && ! lib.versionAtLeast ocaml.version args.minimalOCamlVersion)
+if (args ? minimumOCamlVersion && lib.versionOlder ocaml.version args.minimumOCamlVersion) ||
+   (args ? minimalOCamlVersion && lib.versionOlder ocaml.version args.minimalOCamlVersion)
 then throw "${pname}-${version} is not available for OCaml ${ocaml.version}"
 else
 
diff --git a/nixpkgs/pkgs/build-support/ocaml/oasis.nix b/nixpkgs/pkgs/build-support/ocaml/oasis.nix
index 8f81344daf09..91daad59050d 100644
--- a/nixpkgs/pkgs/build-support/ocaml/oasis.nix
+++ b/nixpkgs/pkgs/build-support/ocaml/oasis.nix
@@ -8,7 +8,7 @@
 }@args:
 
 if args ? minimumOCamlVersion &&
-   ! lib.versionAtLeast ocaml.version args.minimumOCamlVersion
+   lib.versionOlder ocaml.version args.minimumOCamlVersion
 then throw "${pname}-${version} is not available for OCaml ${ocaml.version}"
 else
 
diff --git a/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix b/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix
index aa8f57ffb04d..312d2fe02610 100644
--- a/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix
@@ -32,6 +32,8 @@ stdenv.mkDerivation {
   pname = targetPrefix + pkg-config.pname + "-wrapper";
   inherit (pkg-config) version;
 
+  enableParallelBuilding = true;
+
   preferLocalBuild = true;
 
   shell = getBin stdenvNoCC.shell + stdenvNoCC.shell.shellPath or "";
@@ -44,6 +46,7 @@ stdenv.mkDerivation {
     inherit pkg-config;
   };
 
+  strictDeps = true;
   dontBuild = true;
   dontConfigure = true;
 
@@ -80,8 +83,6 @@ stdenv.mkDerivation {
       ln -s ${pkg-config}/share $out/share
     '';
 
-  strictDeps = true;
-
   wrapperName = "PKG_CONFIG_WRAPPER";
 
   setupHooks = [
diff --git a/nixpkgs/pkgs/build-support/prefer-remote-fetch/default.nix b/nixpkgs/pkgs/build-support/prefer-remote-fetch/default.nix
index 2e55e3707421..a1f2d0c56cff 100644
--- a/nixpkgs/pkgs/build-support/prefer-remote-fetch/default.nix
+++ b/nixpkgs/pkgs/build-support/prefer-remote-fetch/default.nix
@@ -11,9 +11,9 @@
 # $ echo 'self: super: super.prefer-remote-fetch self super' > ~/.config/nixpkgs/overlays/prefer-remote-fetch.nix
 #
 self: super: {
-  fetchurl = args: super.fetchurl (args // { preferLocalBuild = false; });
-  fetchgit = args: super.fetchgit (args // { preferLocalBuild = false; });
-  fetchhg = args: super.fetchhg (args // { preferLocalBuild = false; });
-  fetchsvn = args: super.fetchsvn (args // { preferLocalBuild = false; });
-  fetchipfs = args: super.fetchipfs (args // { preferLocalBuild = false; });
+  fetchurl = args: super.fetchurl ({ preferLocalBuild = false; } // args);
+  fetchgit = args: super.fetchgit ({ preferLocalBuild = false; } // args);
+  fetchhg = args: super.fetchhg ({ preferLocalBuild = false; } // args);
+  fetchsvn = args: super.fetchsvn ({ preferLocalBuild = false; } // args);
+  fetchipfs = args: super.fetchipfs ({ preferLocalBuild = false; } // args);
 }
diff --git a/nixpkgs/pkgs/build-support/replace-dependency.nix b/nixpkgs/pkgs/build-support/replace-dependency.nix
index 15ab50bf3974..01b93c194c39 100644
--- a/nixpkgs/pkgs/build-support/replace-dependency.nix
+++ b/nixpkgs/pkgs/build-support/replace-dependency.nix
@@ -35,7 +35,7 @@ let
             read ref_path
             if [ "$ref_path" != "$path" ]
             then
-                echo "    (builtins.storePath $ref_path)"
+                echo "    (builtins.storePath (/. + \"$ref_path\"))"
             fi
             count=$(($count - 1))
         done
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 42c5f6ab3c0f..b24398665a10 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
@@ -1,22 +1,29 @@
-{ lib, stdenv, mkRustcDepArgs, mkRustcFeatureArgs, rust }:
+{ lib, stdenv
+, mkRustcDepArgs, mkRustcFeatureArgs, needUnstableCLI
+, rust
+}:
+
 { crateName,
   dependencies,
   crateFeatures, crateRenames, libName, release, libPath,
   crateType, metadata, crateBin, hasCrateBin,
   extraRustcOpts, verbose, colors,
-  buildTests
+  buildTests,
+  codegenUnits
 }:
 
   let
     baseRustcOpts =
       [
         (if release then "-C opt-level=3" else "-C debuginfo=2")
-        "-C codegen-units=$NIX_BUILD_CORES"
+        "-C codegen-units=${toString codegenUnits}"
         "--remap-path-prefix=$NIX_BUILD_TOP=/"
         (mkRustcDepArgs dependencies crateRenames)
         (mkRustcFeatureArgs crateFeatures)
       ] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
         "--target" (rust.toRustTargetSpec stdenv.hostPlatform)
+      ] ++ lib.optionals (needUnstableCLI dependencies) [
+        "-Z" "unstable-options"
       ] ++ extraRustcOpts
       # since rustc 1.42 the "proc_macro" crate is part of the default crate prelude
       # https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix
index 1a9705591d6d..5129777c9d51 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix
@@ -2,6 +2,7 @@
 {
   build
 , buildDependencies
+, codegenUnits
 , colors
 , completeBuildDeps
 , completeDeps
@@ -24,7 +25,7 @@ let version_ = lib.splitString "-" crateVersion;
     version = lib.splitVersion (lib.head version_);
     rustcOpts = lib.foldl' (opts: opt: opts + " " + opt)
         (if release then "-C opt-level=3" else "-C debuginfo=2")
-        (["-C codegen-units=$NIX_BUILD_CORES"] ++ extraRustcOptsForBuildRs);
+        (["-C codegen-units=${toString codegenUnits}"] ++ extraRustcOptsForBuildRs);
     buildDeps = mkRustcDepArgs buildDependencies crateRenames;
     authors = lib.concatStringsSep ":" crateAuthors;
     optLevel = if release then 3 else 0;
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix
index afb938e51182..98030225bcbb 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix
@@ -46,17 +46,28 @@ let
               )
             else
               extern;
+          opts = lib.optionalString (dep.stdlib or false) "noprelude:";
+          filename =
+            if lib.any (x: x == "lib" || x == "rlib") dep.crateType
+            then "${dep.metadata}.rlib"
+            else "${dep.metadata}${stdenv.hostPlatform.extensions.sharedLibrary}";
         in
-        (if lib.any (x: x == "lib" || x == "rlib") dep.crateType then
-          " --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}.rlib"
-        else
-          " --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}${stdenv.hostPlatform.extensions.sharedLibrary}")
+        " --extern ${opts}${name}=${dep.lib}/lib/lib${extern}-${filename}"
       )
       dependencies;
 
   # Create feature arguments for rustc.
   mkRustcFeatureArgs = lib.concatMapStringsSep " " (f: ''--cfg feature=\"${f}\"'');
 
+  # Whether we need to use unstable command line flags
+  #
+  # Currently just needed for standard library dependencies, which have a
+  # special "noprelude:" modifier. If in later versions of Rust this is
+  # stabilized we can account for that here, too, so we don't opt into
+  # instability unnecessarily.
+  needUnstableCLI = dependencies:
+    lib.any (dep: dep.stdlib or false) dependencies;
+
   inherit (import ./log.nix { inherit lib; }) noisily echo_colored;
 
   configureCrate = import ./configure-crate.nix {
@@ -64,7 +75,7 @@ let
   };
 
   buildCrate = import ./build-crate.nix {
-    inherit lib stdenv mkRustcDepArgs mkRustcFeatureArgs rust;
+    inherit lib stdenv mkRustcDepArgs mkRustcFeatureArgs needUnstableCLI rust;
   };
 
   installCrate = import ./install-crate.nix { inherit stdenv; };
@@ -228,6 +239,7 @@ crate_: lib.makeOverridable
         "colors"
         "edition"
         "buildTests"
+        "codegenUnits"
       ];
       extraDerivationAttrs = builtins.removeAttrs crate processedAttrs;
       nativeBuildInputs_ = nativeBuildInputs;
@@ -277,9 +289,14 @@ crate_: lib.makeOverridable
 
       # Create a list of features that are enabled by the crate itself and
       # through the features argument of buildRustCrate. Exclude features
-      # with a forward slash, since they are passed through to dependencies.
+      # with a forward slash, since they are passed through to dependencies,
+      # and dep: features, since they're internal-only and do nothing except
+      # enable optional dependencies.
       crateFeatures = lib.optionals (crate ? features)
-        (builtins.filter (f: !lib.hasInfix "/" f) (crate.features ++ features));
+        (builtins.filter
+          (f: !(lib.hasInfix "/" f || lib.hasPrefix "dep:" f))
+          (crate.features ++ features)
+        );
 
       libName = if crate ? libName then crate.libName else crate.crateName;
       libPath = if crate ? libPath then crate.libPath else "";
@@ -310,6 +327,7 @@ crate_: lib.makeOverridable
       colors = lib.attrByPath [ "colors" ] "always" crate;
       extraLinkFlags = lib.concatStringsSep " " (crate.extraLinkFlags or [ ]);
       edition = crate.edition or null;
+      codegenUnits = if crate ? codegenUnits then crate.codegenUnits else 1;
       extraRustcOpts =
         lib.optionals (crate ? extraRustcOpts) crate.extraRustcOpts
           ++ extraRustcOpts_
@@ -324,13 +342,13 @@ crate_: lib.makeOverridable
         inherit crateName buildDependencies completeDeps completeBuildDeps crateDescription
           crateFeatures crateRenames libName build workspace_member release libPath crateVersion
           extraLinkFlags extraRustcOptsForBuildRs
-          crateAuthors crateHomepage verbose colors;
+          crateAuthors crateHomepage verbose colors codegenUnits;
       };
       buildPhase = buildCrate {
         inherit crateName dependencies
           crateFeatures crateRenames libName release libPath crateType
           metadata hasCrateBin crateBin verbose colors
-          extraRustcOpts buildTests;
+          extraRustcOpts buildTests codegenUnits;
       };
       installPhase = installCrate crateName metadata buildTests;
 
@@ -339,6 +357,9 @@ crate_: lib.makeOverridable
       outputs = if buildTests then [ "out" ] else [ "out" "lib" ];
       outputDev = if buildTests then [ "out" ] else [ "lib" ];
 
+      meta = {
+        mainProgram = crateName;
+      };
     } // extraDerivationAttrs
     )
   )
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/lib.sh b/nixpkgs/pkgs/build-support/rust/build-rust-crate/lib.sh
index d4927b025aa8..39f7d53f6f75 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/lib.sh
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/lib.sh
@@ -16,6 +16,7 @@ build_lib() {
     --out-dir target/lib \
     -L dependency=target/deps \
     --cap-lints allow \
+    $LINK \
     $LIB_RUSTC_OPTS \
     $BUILD_OUT_DIR \
     $EXTRA_BUILD \
@@ -97,7 +98,6 @@ setup_link_paths() {
      if [[ ! -z "$i" ]]; then
        for library in $i; do
          echo "-l $library" >> target/link
-         echo "-l $library" >> target/link.final
        done
      fi
   done
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/default.nix
index 2e0a29ac123a..a4536a1751c8 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/default.nix
@@ -548,6 +548,10 @@ let
       };
     };
     brotliCrates = (callPackage ./brotli-crates.nix {});
+    rcgenCrates = callPackage ./rcgen-crates.nix {
+      # Suppress deprecation warning
+      buildRustCrate = null;
+    };
     tests = lib.mapAttrs (key: value: mkTest (value // lib.optionalAttrs (!value?crateName) { crateName = key; })) cases;
   in tests // rec {
 
@@ -645,6 +649,16 @@ let
     } ''
       test -e ${pkg}/bin/brotli-decompressor && touch $out
     '';
+
+    rcgenTest = let
+      pkg = rcgenCrates.rootCrate.build;
+    in runCommand "run-rcgen-test-cmd" {
+      nativeBuildInputs = [ pkg ];
+    } (if stdenv.hostPlatform == stdenv.buildPlatform then ''
+      ${pkg}/bin/rcgen && touch $out
+    '' else ''
+      test -x '${pkg}/bin/rcgen' && touch $out
+    '');
   };
   test = releaseTools.aggregate {
     name = "buildRustCrate-tests";
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix
new file mode 100644
index 000000000000..0f97c9b724bd
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix
@@ -0,0 +1,3496 @@
+
+# This file was @generated by crate2nix 0.10.0 with the command:
+#   "generate"
+# See https://github.com/kolloch/crate2nix for more info.
+
+{ nixpkgs ? <nixpkgs>
+, pkgs ? import nixpkgs { config = {}; }
+, lib ? pkgs.lib
+, stdenv ? pkgs.stdenv
+, buildRustCrateForPkgs ? if buildRustCrate != null
+    then lib.warn "crate2nix: Passing `buildRustCrate` as argument to Cargo.nix is deprecated. If you don't customize `buildRustCrate`, replace `callPackage ./Cargo.nix {}` by `import ./Cargo.nix { inherit pkgs; }`, and if you need to customize `buildRustCrate`, use `buildRustCrateForPkgs` instead." (_: buildRustCrate)
+    else pkgs: pkgs.buildRustCrate
+  # Deprecated
+, buildRustCrate ? null
+  # This is used as the `crateOverrides` argument for `buildRustCrate`.
+, defaultCrateOverrides ? pkgs.defaultCrateOverrides
+  # The features to enable for the root_crate or the workspace_members.
+, rootFeatures ? [ "default" ]
+  # If true, throw errors instead of issueing deprecation warnings.
+, strictDeprecation ? false
+  # Used for conditional compilation based on CPU feature detection.
+, targetFeatures ? []
+  # Whether to perform release builds: longer compile times, faster binaries.
+, release ? true
+  # Additional crate2nix configuration if it exists.
+, crateConfig
+  ? if builtins.pathExists ./crate-config.nix
+    then pkgs.callPackage ./crate-config.nix {}
+    else {}
+}:
+
+rec {
+  #
+  # "public" attributes that we attempt to keep stable with new versions of crate2nix.
+  #
+
+  rootCrate = rec {
+    packageId = "rcgen";
+
+    # Use this attribute to refer to the derivation building your root crate package.
+    # You can override the features with rootCrate.build.override { features = [ "default" "feature1" ... ]; }.
+    build = internal.buildRustCrateWithFeatures {
+      inherit packageId;
+    };
+
+    # Debug support which might change between releases.
+    # File a bug if you depend on any for non-debug work!
+    debug = internal.debugCrate { inherit packageId; };
+  };
+  # Refer your crate build derivation by name here.
+  # You can override the features with
+  # workspaceMembers."${crateName}".build.override { features = [ "default" "feature1" ... ]; }.
+  workspaceMembers = {
+    "rcgen" = rec {
+      packageId = "rcgen";
+      build = internal.buildRustCrateWithFeatures {
+        packageId = "rcgen";
+      };
+
+      # Debug support which might change between releases.
+      # File a bug if you depend on any for non-debug work!
+      debug = internal.debugCrate { inherit packageId; };
+    };
+  };
+
+  # A derivation that joins the outputs of all workspace members together.
+  allWorkspaceMembers = pkgs.symlinkJoin {
+      name = "all-workspace-members";
+      paths =
+        let members = builtins.attrValues workspaceMembers;
+        in builtins.map (m: m.build) members;
+  };
+
+  #
+  # "internal" ("private") attributes that may change in every new version of crate2nix.
+  #
+
+  internal = rec {
+    # Build and dependency information for crates.
+    # Many of the fields are passed one-to-one to buildRustCrate.
+    #
+    # Noteworthy:
+    # * `dependencies`/`buildDependencies`: similar to the corresponding fields for buildRustCrate.
+    #   but with additional information which is used during dependency/feature resolution.
+    # * `resolvedDependencies`: the selected default features reported by cargo - only included for debugging.
+    # * `devDependencies` as of now not used by `buildRustCrate` but used to
+    #   inject test dependencies into the build
+
+    crates = {
+      "asn1-rs" = rec {
+        crateName = "asn1-rs";
+        version = "0.3.1";
+        edition = "2018";
+        sha256 = "0czsk1nd4dx2k83f7jzkn8klx05wbmblkx1jh51i4c170akhbzrh";
+        authors = [
+          "Pierre Chifflier <chifflier@wzdftpd.net>"
+        ];
+        dependencies = [
+          {
+            name = "asn1-rs-derive";
+            packageId = "asn1-rs-derive";
+          }
+          {
+            name = "asn1-rs-impl";
+            packageId = "asn1-rs-impl";
+          }
+          {
+            name = "displaydoc";
+            packageId = "displaydoc";
+          }
+          {
+            name = "nom";
+            packageId = "nom";
+            usesDefaultFeatures = false;
+            features = [ "std" ];
+          }
+          {
+            name = "num-traits";
+            packageId = "num-traits";
+          }
+          {
+            name = "rusticata-macros";
+            packageId = "rusticata-macros";
+          }
+          {
+            name = "thiserror";
+            packageId = "thiserror";
+          }
+          {
+            name = "time";
+            packageId = "time";
+            optional = true;
+            features = [ "macros" "parsing" "formatting" ];
+          }
+        ];
+        features = {
+          "bigint" = [ "num-bigint" ];
+          "bits" = [ "bitvec" ];
+          "bitvec" = [ "dep:bitvec" ];
+          "cookie-factory" = [ "dep:cookie-factory" ];
+          "datetime" = [ "time" ];
+          "default" = [ "std" ];
+          "num-bigint" = [ "dep:num-bigint" ];
+          "serialize" = [ "cookie-factory" ];
+          "time" = [ "dep:time" ];
+        };
+        resolvedDefaultFeatures = [ "datetime" "default" "std" "time" ];
+      };
+      "asn1-rs-derive" = rec {
+        crateName = "asn1-rs-derive";
+        version = "0.1.0";
+        edition = "2018";
+        sha256 = "1gzf9vab06lk0zjvbr07axx64fndkng2s28bnj27fnwd548pb2yv";
+        procMacro = true;
+        authors = [
+          "Pierre Chifflier <chifflier@wzdftpd.net>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+          }
+          {
+            name = "synstructure";
+            packageId = "synstructure";
+          }
+        ];
+
+      };
+      "asn1-rs-impl" = rec {
+        crateName = "asn1-rs-impl";
+        version = "0.1.0";
+        edition = "2018";
+        sha256 = "1va27bn7qxqp4wanzjlkagnynv6jnrhnwmcky2ahzb1r405p6xr7";
+        procMacro = true;
+        authors = [
+          "Pierre Chifflier <chifflier@wzdftpd.net>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+          }
+        ];
+
+      };
+      "autocfg 0.1.7" = rec {
+        crateName = "autocfg";
+        version = "0.1.7";
+        edition = "2015";
+        sha256 = "1chwgimpx5z7xbag7krr9d8asxfqbh683qhgl9kn3hxk2l0djj8x";
+        authors = [
+          "Josh Stone <cuviper@gmail.com>"
+        ];
+
+      };
+      "autocfg 1.0.1" = rec {
+        crateName = "autocfg";
+        version = "1.0.1";
+        edition = "2015";
+        sha256 = "0jj6i9zn4gjl03kjvziqdji6rwx8ykz8zk2ngpc331z2g3fk3c6d";
+        authors = [
+          "Josh Stone <cuviper@gmail.com>"
+        ];
+
+      };
+      "base64" = rec {
+        crateName = "base64";
+        version = "0.13.0";
+        edition = "2018";
+        sha256 = "1z82g23mbzjgijkpcrilc7nljpxpvpf7zxf6iyiapkgka2ngwkch";
+        authors = [
+          "Alice Maz <alice@alicemaz.com>"
+          "Marshall Pierce <marshall@mpierce.org>"
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
+      "base64ct" = rec {
+        crateName = "base64ct";
+        version = "1.1.1";
+        edition = "2018";
+        sha256 = "0p4was874qc90q2chm2i14m9mn8zmxjis8vaxihd6a2x4aqxkd76";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        features = {
+          "std" = [ "alloc" ];
+        };
+      };
+      "bitflags" = rec {
+        crateName = "bitflags";
+        version = "1.3.2";
+        edition = "2018";
+        sha256 = "12ki6w8gn1ldq7yz9y680llwk5gmrhrzszaa17g1sbrw2r2qvwxy";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        features = {
+          "compiler_builtins" = [ "dep:compiler_builtins" ];
+          "core" = [ "dep:core" ];
+          "rustc-dep-of-std" = [ "core" "compiler_builtins" ];
+        };
+        resolvedDefaultFeatures = [ "default" ];
+      };
+      "botan" = rec {
+        crateName = "botan";
+        version = "0.8.1";
+        edition = "2018";
+        sha256 = "08bmiyn7c3b0dgx20w6hr28d9jcq7cj78cchr84pc686sb2s41ik";
+        authors = [
+          "Jack Lloyd <jack@randombit.net>"
+        ];
+        dependencies = [
+          {
+            name = "botan-sys";
+            packageId = "botan-sys";
+          }
+          {
+            name = "cty";
+            packageId = "cty";
+          }
+        ];
+        features = {
+          "cstr_core" = [ "dep:cstr_core" ];
+          "no-std" = [ "cstr_core/alloc" ];
+          "vendored" = [ "botan-sys/vendored" ];
+        };
+        resolvedDefaultFeatures = [ "default" "vendored" ];
+      };
+      "botan-src" = rec {
+        crateName = "botan-src";
+        version = "0.21703.0";
+        edition = "2018";
+        sha256 = "0s2ad9q84qsrllfsbj7hjhn7gr3hab9ng6lwzwqmimia6yvja8y8";
+        authors = [
+          "Rodolphe Breard <rodolphe@what.tf>"
+          "Jack Lloyd <jack@randombit.net>"
+        ];
+
+      };
+      "botan-sys" = rec {
+        crateName = "botan-sys";
+        version = "0.8.1";
+        edition = "2015";
+        sha256 = "1m11zblxfanrhl97j7z3ap7n17rr8j0rg91sr7f9j6y2bsniaz1x";
+        authors = [
+          "Jack Lloyd <jack@randombit.net>"
+        ];
+        dependencies = [
+          {
+            name = "cty";
+            packageId = "cty";
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "botan-src";
+            packageId = "botan-src";
+            optional = true;
+          }
+        ];
+        features = {
+          "botan-src" = [ "dep:botan-src" ];
+          "vendored" = [ "botan-src" ];
+        };
+        resolvedDefaultFeatures = [ "botan-src" "default" "vendored" ];
+      };
+      "bumpalo" = rec {
+        crateName = "bumpalo";
+        version = "3.9.1";
+        edition = "2018";
+        sha256 = "1688dv6s0cbj72p9lmll8a02a85dzxvdw2is7pji490zmd35m954";
+        authors = [
+          "Nick Fitzgerald <fitzgen@gmail.com>"
+        ];
+        features = {
+        };
+        resolvedDefaultFeatures = [ "default" ];
+      };
+      "byteorder" = rec {
+        crateName = "byteorder";
+        version = "1.4.3";
+        edition = "2018";
+        sha256 = "0456lv9xi1a5bcm32arknf33ikv76p3fr9yzki4lb2897p2qkh8l";
+        authors = [
+          "Andrew Gallant <jamslam@gmail.com>"
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+      };
+      "cc" = rec {
+        crateName = "cc";
+        version = "1.0.72";
+        edition = "2018";
+        crateBin = [];
+        sha256 = "1vl50h2qh0nh0iddzj6gd1pnxnxpvwmbfxc30578c1pajmxi7a92";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        features = {
+          "jobserver" = [ "dep:jobserver" ];
+          "parallel" = [ "jobserver" ];
+        };
+      };
+      "cfg-if" = rec {
+        crateName = "cfg-if";
+        version = "1.0.0";
+        edition = "2018";
+        sha256 = "1za0vb97n4brpzpv8lsbnzmq5r8f2b0cpqqr0sy8h5bn751xxwds";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        features = {
+          "compiler_builtins" = [ "dep:compiler_builtins" ];
+          "core" = [ "dep:core" ];
+          "rustc-dep-of-std" = [ "core" "compiler_builtins" ];
+        };
+      };
+      "const-oid" = rec {
+        crateName = "const-oid";
+        version = "0.6.2";
+        edition = "2018";
+        sha256 = "12vv7csqqjj0x1l5mf51lgqiw76k5c3mb1yzfhfcqysks2j2lvwx";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        features = {
+        };
+      };
+      "crypto-bigint" = rec {
+        crateName = "crypto-bigint";
+        version = "0.2.11";
+        edition = "2018";
+        sha256 = "00qckh65nzb7s7vd60wylw6alxf9g37xh31lirb1qw0l8fxx6fzq";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        dependencies = [
+          {
+            name = "generic-array";
+            packageId = "generic-array";
+            optional = true;
+          }
+          {
+            name = "rand_core";
+            packageId = "rand_core";
+            optional = true;
+          }
+          {
+            name = "subtle";
+            packageId = "subtle";
+            usesDefaultFeatures = false;
+          }
+        ];
+        features = {
+          "default" = [ "rand" ];
+          "generic-array" = [ "dep:generic-array" ];
+          "rand" = [ "rand_core" ];
+          "rand_core" = [ "dep:rand_core" ];
+          "rlp" = [ "dep:rlp" ];
+          "zeroize" = [ "dep:zeroize" ];
+        };
+        resolvedDefaultFeatures = [ "default" "generic-array" "rand" "rand_core" ];
+      };
+      "cty" = rec {
+        crateName = "cty";
+        version = "0.2.2";
+        edition = "2015";
+        sha256 = "0d8z0pbr87wgzqqb2jk5pvj0afzc6d3rb772ach6fijhg6yglrdk";
+        authors = [
+          "Jorge Aparicio <jorge@japaric.io>"
+        ];
+
+      };
+      "data-encoding" = rec {
+        crateName = "data-encoding";
+        version = "2.3.2";
+        edition = "2018";
+        sha256 = "0mvd8bjq5mq50fcf931cff57vwmbsvs1kpxynkzrshli98y3kqiy";
+        authors = [
+          "Julien Cretin <git@ia0.eu>"
+        ];
+        features = {
+          "default" = [ "std" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "std" ];
+      };
+      "der" = rec {
+        crateName = "der";
+        version = "0.4.5";
+        edition = "2018";
+        sha256 = "1x4k0jln8va1657cghl40l6p7hyvr1ixz71v9cd6imwmgp51rdvr";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        dependencies = [
+          {
+            name = "const-oid";
+            packageId = "const-oid";
+            optional = true;
+          }
+          {
+            name = "crypto-bigint";
+            packageId = "crypto-bigint";
+            optional = true;
+            features = [ "generic-array" ];
+          }
+        ];
+        features = {
+          "bigint" = [ "crypto-bigint" ];
+          "const-oid" = [ "dep:const-oid" ];
+          "crypto-bigint" = [ "dep:crypto-bigint" ];
+          "der_derive" = [ "dep:der_derive" ];
+          "derive" = [ "der_derive" ];
+          "oid" = [ "const-oid" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "bigint" "const-oid" "crypto-bigint" "oid" "std" ];
+      };
+      "der-parser" = rec {
+        crateName = "der-parser";
+        version = "7.0.0";
+        edition = "2018";
+        sha256 = "10kfa2gzl3x20mwgrd43cyi79xgkqxyzcyrh0xylv4apa33qlfgy";
+        authors = [
+          "Pierre Chifflier <chifflier@wzdftpd.net>"
+        ];
+        dependencies = [
+          {
+            name = "asn1-rs";
+            packageId = "asn1-rs";
+          }
+          {
+            name = "displaydoc";
+            packageId = "displaydoc";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "nom";
+            packageId = "nom";
+          }
+          {
+            name = "num-bigint";
+            packageId = "num-bigint";
+            optional = true;
+          }
+          {
+            name = "num-traits";
+            packageId = "num-traits";
+          }
+          {
+            name = "rusticata-macros";
+            packageId = "rusticata-macros";
+          }
+        ];
+        features = {
+          "bigint" = [ "num-bigint" ];
+          "cookie-factory" = [ "dep:cookie-factory" ];
+          "default" = [ "std" ];
+          "num-bigint" = [ "dep:num-bigint" ];
+          "serialize" = [ "std" "cookie-factory" ];
+        };
+        resolvedDefaultFeatures = [ "bigint" "default" "num-bigint" "std" ];
+      };
+      "digest" = rec {
+        crateName = "digest";
+        version = "0.9.0";
+        edition = "2018";
+        sha256 = "0rmhvk33rgvd6ll71z8sng91a52rw14p0drjn1da0mqa138n1pfk";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        dependencies = [
+          {
+            name = "generic-array";
+            packageId = "generic-array";
+          }
+        ];
+        features = {
+          "blobby" = [ "dep:blobby" ];
+          "dev" = [ "blobby" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "std" ];
+      };
+      "displaydoc" = rec {
+        crateName = "displaydoc";
+        version = "0.2.3";
+        edition = "2018";
+        sha256 = "11i8p5snlc1hs4g5q3wiyr75dn276l6kr0si5m7xmfa6y31mvy9v";
+        procMacro = true;
+        authors = [
+          "Jane Lusby <jlusby@yaah.dev>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
+      "foreign-types" = rec {
+        crateName = "foreign-types";
+        version = "0.3.2";
+        edition = "2015";
+        sha256 = "1cgk0vyd7r45cj769jym4a6s7vwshvd0z4bqrb92q1fwibmkkwzn";
+        authors = [
+          "Steven Fackler <sfackler@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "foreign-types-shared";
+            packageId = "foreign-types-shared";
+          }
+        ];
+
+      };
+      "foreign-types-shared" = rec {
+        crateName = "foreign-types-shared";
+        version = "0.1.1";
+        edition = "2015";
+        sha256 = "0jxgzd04ra4imjv8jgkmdq59kj8fsz6w4zxsbmlai34h26225c00";
+        authors = [
+          "Steven Fackler <sfackler@gmail.com>"
+        ];
+
+      };
+      "generic-array" = rec {
+        crateName = "generic-array";
+        version = "0.14.5";
+        edition = "2015";
+        sha256 = "00qqhls43bzvyb7s26iw6knvsz3mckbxl3rhaahvypzhqwzd6j7x";
+        libName = "generic_array";
+        authors = [
+          "Bartłomiej Kamiński <fizyk20@gmail.com>"
+          "Aaron Trent <novacrazy@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "typenum";
+            packageId = "typenum";
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "version_check";
+            packageId = "version_check";
+          }
+        ];
+        features = {
+          "serde" = [ "dep:serde" ];
+        };
+      };
+      "getrandom" = rec {
+        crateName = "getrandom";
+        version = "0.2.4";
+        edition = "2018";
+        sha256 = "0k0bdr1dyf4n9fvnkx4fmwxhv4hgnyf55gj86v4m69fln743g3a1";
+        authors = [
+          "The Rand Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if";
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+            usesDefaultFeatures = false;
+            target = { target, features }: (target."unix" or false);
+          }
+          {
+            name = "wasi";
+            packageId = "wasi";
+            target = { target, features }: (target."os" == "wasi");
+          }
+        ];
+        features = {
+          "compiler_builtins" = [ "dep:compiler_builtins" ];
+          "core" = [ "dep:core" ];
+          "js" = [ "wasm-bindgen" "js-sys" ];
+          "js-sys" = [ "dep:js-sys" ];
+          "rustc-dep-of-std" = [ "compiler_builtins" "core" "libc/rustc-dep-of-std" "wasi/rustc-dep-of-std" ];
+          "wasm-bindgen" = [ "dep:wasm-bindgen" ];
+        };
+        resolvedDefaultFeatures = [ "std" ];
+      };
+      "itoa" = rec {
+        crateName = "itoa";
+        version = "1.0.1";
+        edition = "2018";
+        sha256 = "0d8wr2qf5b25a04xf10rz9r0pdbjdgb0zaw3xvf8k2sqcz1qzaqs";
+        authors = [
+          "David Tolnay <dtolnay@gmail.com>"
+        ];
+
+      };
+      "js-sys" = rec {
+        crateName = "js-sys";
+        version = "0.3.56";
+        edition = "2018";
+        sha256 = "010g8jkj5avy3xd77i3cprjzzpfa6z9z2ay0fkllqmpx617c53x3";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "wasm-bindgen";
+            packageId = "wasm-bindgen";
+          }
+        ];
+
+      };
+      "lazy_static" = rec {
+        crateName = "lazy_static";
+        version = "1.4.0";
+        edition = "2015";
+        sha256 = "0in6ikhw8mgl33wjv6q6xfrb5b9jr16q8ygjy803fay4zcisvaz2";
+        authors = [
+          "Marvin Löbel <loebel.marvin@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "spin";
+            packageId = "spin";
+            optional = true;
+          }
+        ];
+        features = {
+          "spin" = [ "dep:spin" ];
+          "spin_no_std" = [ "spin" ];
+        };
+        resolvedDefaultFeatures = [ "spin" "spin_no_std" ];
+      };
+      "libc" = rec {
+        crateName = "libc";
+        version = "0.2.116";
+        edition = "2015";
+        sha256 = "0x6sk17kv2fdsqxlm23bz9x1y79w90k7ylkflk44rgidhy4bspan";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        features = {
+          "default" = [ "std" ];
+          "rustc-dep-of-std" = [ "align" "rustc-std-workspace-core" ];
+          "rustc-std-workspace-core" = [ "dep:rustc-std-workspace-core" ];
+          "use_std" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
+      "libm" = rec {
+        crateName = "libm";
+        version = "0.2.1";
+        edition = "2018";
+        sha256 = "0akh56sh51adhagmk9l84dyrlz60gv8ri05xhr13i1b18czkpmy7";
+        authors = [
+          "Jorge Aparicio <jorge@japaric.io>"
+        ];
+        features = {
+          "musl-reference-tests" = [ "rand" ];
+          "rand" = [ "dep:rand" ];
+        };
+        resolvedDefaultFeatures = [ "default" ];
+      };
+      "log" = rec {
+        crateName = "log";
+        version = "0.4.14";
+        edition = "2015";
+        sha256 = "04175hv0v62shd82qydq58a48k3bjijmk54v38zgqlbxqkkbpfai";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if";
+          }
+        ];
+        features = {
+          "kv_unstable" = [ "value-bag" ];
+          "kv_unstable_serde" = [ "kv_unstable_std" "value-bag/serde" "serde" ];
+          "kv_unstable_std" = [ "std" "kv_unstable" "value-bag/error" ];
+          "kv_unstable_sval" = [ "kv_unstable" "value-bag/sval" "sval" ];
+          "serde" = [ "dep:serde" ];
+          "sval" = [ "dep:sval" ];
+          "value-bag" = [ "dep:value-bag" ];
+        };
+      };
+      "memchr" = rec {
+        crateName = "memchr";
+        version = "2.4.1";
+        edition = "2018";
+        sha256 = "0smq8xzd40njqpfzv5mghigj91fzlfrfg842iz8x0wqvw2dw731h";
+        authors = [
+          "Andrew Gallant <jamslam@gmail.com>"
+          "bluss"
+        ];
+        features = {
+          "compiler_builtins" = [ "dep:compiler_builtins" ];
+          "core" = [ "dep:core" ];
+          "default" = [ "std" ];
+          "libc" = [ "dep:libc" ];
+          "rustc-dep-of-std" = [ "core" "compiler_builtins" ];
+          "use_std" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "std" ];
+      };
+      "minimal-lexical" = rec {
+        crateName = "minimal-lexical";
+        version = "0.2.1";
+        edition = "2018";
+        sha256 = "16ppc5g84aijpri4jzv14rvcnslvlpphbszc7zzp6vfkddf4qdb8";
+        authors = [
+          "Alex Huszagh <ahuszagh@gmail.com>"
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "std" ];
+      };
+      "nom" = rec {
+        crateName = "nom";
+        version = "7.1.0";
+        edition = "2018";
+        sha256 = "0281jdx0xcyhjgs1jkj9pii8py1clcpazg41bgz7d71qxzhi278v";
+        authors = [
+          "contact@geoffroycouprie.com"
+        ];
+        dependencies = [
+          {
+            name = "memchr";
+            packageId = "memchr";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "minimal-lexical";
+            packageId = "minimal-lexical";
+            usesDefaultFeatures = false;
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "version_check";
+            packageId = "version_check";
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "std" = [ "alloc" "memchr/std" "minimal-lexical/std" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "std" ];
+      };
+      "num-bigint" = rec {
+        crateName = "num-bigint";
+        version = "0.4.3";
+        edition = "2018";
+        sha256 = "0py73wsa5j4izhd39nkqzqv260r0ma08vy30ky54ld3vkhlbcfpr";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "num-integer";
+            packageId = "num-integer";
+            usesDefaultFeatures = false;
+            features = [ "i128" ];
+          }
+          {
+            name = "num-traits";
+            packageId = "num-traits";
+            usesDefaultFeatures = false;
+            features = [ "i128" ];
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "autocfg";
+            packageId = "autocfg 1.0.1";
+          }
+        ];
+        features = {
+          "arbitrary" = [ "dep:arbitrary" ];
+          "default" = [ "std" ];
+          "quickcheck" = [ "dep:quickcheck" ];
+          "rand" = [ "dep:rand" ];
+          "serde" = [ "dep:serde" ];
+          "std" = [ "num-integer/std" "num-traits/std" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
+      "num-bigint-dig" = rec {
+        crateName = "num-bigint-dig";
+        version = "0.7.0";
+        edition = "2015";
+        sha256 = "1004mmipvc7pvaf3kf13i1nqh3vxf789bj72d8wl51y185aywis5";
+        authors = [
+          "dignifiedquire <dignifiedquire@gmail.com>"
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "byteorder";
+            packageId = "byteorder";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "lazy_static";
+            packageId = "lazy_static";
+            usesDefaultFeatures = false;
+            features = [ "spin_no_std" ];
+          }
+          {
+            name = "libm";
+            packageId = "libm";
+          }
+          {
+            name = "num-integer";
+            packageId = "num-integer";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "num-iter";
+            packageId = "num-iter";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "num-traits";
+            packageId = "num-traits";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "rand";
+            packageId = "rand";
+            optional = true;
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "smallvec";
+            packageId = "smallvec";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "zeroize";
+            packageId = "zeroize";
+            optional = true;
+            usesDefaultFeatures = false;
+            features = [ "zeroize_derive" ];
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "autocfg";
+            packageId = "autocfg 0.1.7";
+          }
+        ];
+        devDependencies = [
+          {
+            name = "rand";
+            packageId = "rand";
+            features = [ "small_rng" ];
+          }
+        ];
+        features = {
+          "default" = [ "std" "i128" "u64_digit" ];
+          "i128" = [ "num-integer/i128" "num-traits/i128" ];
+          "prime" = [ "rand/std_rng" ];
+          "rand" = [ "dep:rand" ];
+          "serde" = [ "dep:serde" ];
+          "std" = [ "num-integer/std" "num-traits/std" "smallvec/write" "rand/std" "serde/std" ];
+          "zeroize" = [ "dep:zeroize" ];
+        };
+        resolvedDefaultFeatures = [ "i128" "prime" "rand" "u64_digit" "zeroize" ];
+      };
+      "num-integer" = rec {
+        crateName = "num-integer";
+        version = "0.1.44";
+        edition = "2015";
+        sha256 = "1nq152y3304as1iai95hqz8prqnc94lks1s7q05sfjdmcf56kk6j";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "num-traits";
+            packageId = "num-traits";
+            usesDefaultFeatures = false;
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "autocfg";
+            packageId = "autocfg 1.0.1";
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "i128" = [ "num-traits/i128" ];
+          "std" = [ "num-traits/std" ];
+        };
+        resolvedDefaultFeatures = [ "i128" "std" ];
+      };
+      "num-iter" = rec {
+        crateName = "num-iter";
+        version = "0.1.42";
+        edition = "2015";
+        sha256 = "0ndd9wb9qar50fdr16xm3i1zk6h2g9br56nml2n22kd56y1iq0mj";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "num-integer";
+            packageId = "num-integer";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "num-traits";
+            packageId = "num-traits";
+            usesDefaultFeatures = false;
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "autocfg";
+            packageId = "autocfg 1.0.1";
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "i128" = [ "num-integer/i128" "num-traits/i128" ];
+          "std" = [ "num-integer/std" "num-traits/std" ];
+        };
+      };
+      "num-traits" = rec {
+        crateName = "num-traits";
+        version = "0.2.14";
+        edition = "2015";
+        sha256 = "144j176s2p76azy2ngk2vkdzgwdc0bc8c93jhki8c9fsbknb2r4s";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "libm";
+            packageId = "libm";
+            optional = true;
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "autocfg";
+            packageId = "autocfg 1.0.1";
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "libm" = [ "dep:libm" ];
+        };
+        resolvedDefaultFeatures = [ "default" "i128" "libm" "std" ];
+      };
+      "num_threads" = rec {
+        crateName = "num_threads";
+        version = "0.1.3";
+        edition = "2015";
+        sha256 = "05gvsnv4k6d69iksz47i7fq1r61dj1k1nh4i8xrw7qlkcfx9kflp";
+        authors = [
+          "Jacob Pratt <open-source@jhpratt.dev>"
+        ];
+        dependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+            target = { target, features }: ((target."os" == "macos") || (target."os" == "freebsd"));
+          }
+        ];
+
+      };
+      "oid-registry" = rec {
+        crateName = "oid-registry";
+        version = "0.4.0";
+        edition = "2018";
+        sha256 = "0akbah3j8231ayrp2l1y5d9zmvbvqcsj0sa6s6dz6h85z8bhgqiq";
+        authors = [
+          "Pierre Chifflier <chifflier@wzdftpd.net>"
+        ];
+        dependencies = [
+          {
+            name = "asn1-rs";
+            packageId = "asn1-rs";
+          }
+        ];
+        features = {
+          "crypto" = [ "kdf" "pkcs1" "pkcs7" "pkcs9" "pkcs12" "nist_algs" "x962" ];
+          "default" = [ "registry" ];
+        };
+        resolvedDefaultFeatures = [ "crypto" "default" "kdf" "nist_algs" "pkcs1" "pkcs12" "pkcs7" "pkcs9" "registry" "x509" "x962" ];
+      };
+      "once_cell" = rec {
+        crateName = "once_cell";
+        version = "1.9.0";
+        edition = "2018";
+        sha256 = "1mfqhrsgi368x92bwnq3vi3p5nv0n1qlrn69gfflhvkfkxfm2cns";
+        authors = [
+          "Aleksey Kladov <aleksey.kladov@gmail.com>"
+        ];
+        features = {
+          "alloc" = [ "race" ];
+          "atomic-polyfill" = [ "dep:atomic-polyfill" ];
+          "default" = [ "std" ];
+          "parking_lot" = [ "dep:parking_lot" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "race" "std" ];
+      };
+      "openssl" = rec {
+        crateName = "openssl";
+        version = "0.10.38";
+        edition = "2018";
+        sha256 = "15baqlphisr1f7ddq11jnrrzz4shdh35kwal24adyc2c4cif4yhc";
+        authors = [
+          "Steven Fackler <sfackler@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "bitflags";
+            packageId = "bitflags";
+          }
+          {
+            name = "cfg-if";
+            packageId = "cfg-if";
+          }
+          {
+            name = "foreign-types";
+            packageId = "foreign-types";
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+          }
+          {
+            name = "openssl-sys";
+            packageId = "openssl-sys";
+            rename = "ffi";
+          }
+        ];
+        features = {
+          "vendored" = [ "ffi/vendored" ];
+        };
+      };
+      "openssl-sys" = rec {
+        crateName = "openssl-sys";
+        version = "0.9.72";
+        edition = "2015";
+        sha256 = "1jq3qbcvf16qn71yasdzw54b14n8nz98vr52l1gp60in72f10iky";
+        build = "build/main.rs";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+          "Steven Fackler <sfackler@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "autocfg";
+            packageId = "autocfg 1.0.1";
+          }
+          {
+            name = "cc";
+            packageId = "cc";
+          }
+          {
+            name = "pkg-config";
+            packageId = "pkg-config";
+          }
+          {
+            name = "vcpkg";
+            packageId = "vcpkg";
+            target = {target, features}: (target."env" == "msvc");
+          }
+        ];
+        features = {
+          "openssl-src" = [ "dep:openssl-src" ];
+          "vendored" = [ "openssl-src" ];
+        };
+      };
+      "pem" = rec {
+        crateName = "pem";
+        version = "1.0.2";
+        edition = "2018";
+        sha256 = "0iqrvfnm71x9pvff39d5ajwn3gc9glxlv4d4h22max7342db18z9";
+        authors = [
+          "Jonathan Creekmore <jonathan@thecreekmores.org>"
+        ];
+        dependencies = [
+          {
+            name = "base64";
+            packageId = "base64";
+          }
+        ];
+
+      };
+      "pem-rfc7468" = rec {
+        crateName = "pem-rfc7468";
+        version = "0.2.4";
+        edition = "2018";
+        sha256 = "1m1c9jypydzabg4yscplmvff7pdcc8gg4cqg081hnlf03hxkmsc4";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        dependencies = [
+          {
+            name = "base64ct";
+            packageId = "base64ct";
+          }
+        ];
+        features = {
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" ];
+      };
+      "pkcs1" = rec {
+        crateName = "pkcs1";
+        version = "0.2.4";
+        edition = "2018";
+        sha256 = "0b2f1a0lf5h53zrjvcqbxzjhh89gcfa1myhf6z7w10ypg61fwsqi";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        dependencies = [
+          {
+            name = "der";
+            packageId = "der";
+            features = [ "bigint" "oid" ];
+          }
+          {
+            name = "pem-rfc7468";
+            packageId = "pem-rfc7468";
+            optional = true;
+          }
+          {
+            name = "zeroize";
+            packageId = "zeroize";
+            optional = true;
+            usesDefaultFeatures = false;
+            features = [ "alloc" ];
+          }
+        ];
+        features = {
+          "alloc" = [ "der/alloc" "zeroize" ];
+          "pem" = [ "alloc" "pem-rfc7468/alloc" ];
+          "pem-rfc7468" = [ "dep:pem-rfc7468" ];
+          "zeroize" = [ "dep:zeroize" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "pem" "pem-rfc7468" "std" "zeroize" ];
+      };
+      "pkcs8" = rec {
+        crateName = "pkcs8";
+        version = "0.7.6";
+        edition = "2018";
+        sha256 = "0iq46p6fa2b8xy6pj52zpmdy8ya3fg31dj4rc19x1fi69nvgjgpf";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        dependencies = [
+          {
+            name = "der";
+            packageId = "der";
+            features = [ "oid" ];
+          }
+          {
+            name = "pem-rfc7468";
+            packageId = "pem-rfc7468";
+            optional = true;
+          }
+          {
+            name = "pkcs1";
+            packageId = "pkcs1";
+            optional = true;
+            features = [ "alloc" ];
+          }
+          {
+            name = "spki";
+            packageId = "spki";
+          }
+          {
+            name = "zeroize";
+            packageId = "zeroize";
+            optional = true;
+            usesDefaultFeatures = false;
+            features = [ "alloc" ];
+          }
+        ];
+        features = {
+          "3des" = [ "encryption" "pkcs5/3des" ];
+          "alloc" = [ "der/alloc" "zeroize" ];
+          "des-insecure" = [ "encryption" "pkcs5/des-insecure" ];
+          "encryption" = [ "alloc" "pkcs5/alloc" "pkcs5/pbes2" "rand_core" ];
+          "pem" = [ "alloc" "pem-rfc7468/alloc" ];
+          "pem-rfc7468" = [ "dep:pem-rfc7468" ];
+          "pkcs1" = [ "dep:pkcs1" ];
+          "pkcs5" = [ "dep:pkcs5" ];
+          "rand_core" = [ "dep:rand_core" ];
+          "sha1" = [ "encryption" "pkcs5/sha1" ];
+          "std" = [ "alloc" "der/std" ];
+          "zeroize" = [ "dep:zeroize" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "pem" "pem-rfc7468" "pkcs1" "std" "zeroize" ];
+      };
+      "pkg-config" = rec {
+        crateName = "pkg-config";
+        version = "0.3.24";
+        edition = "2015";
+        sha256 = "1ghcyjp5537r7qigmgl3dj62j01arlpddaq93a3i414v3iskz2aq";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+
+      };
+      "ppv-lite86" = rec {
+        crateName = "ppv-lite86";
+        version = "0.2.16";
+        edition = "2018";
+        sha256 = "0wkqwnvnfcgqlrahphl45vdlgi2f1bs7nqcsalsllp1y4dp9x7zb";
+        authors = [
+          "The CryptoCorrosion Contributors"
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "simd" "std" ];
+      };
+      "proc-macro2" = rec {
+        crateName = "proc-macro2";
+        version = "1.0.36";
+        edition = "2018";
+        sha256 = "0adh6gvs31x6pfwmygypmzrv1jc7kjq568vsqcfaxk7vhdc2sd67";
+        authors = [
+          "David Tolnay <dtolnay@gmail.com>"
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        dependencies = [
+          {
+            name = "unicode-xid";
+            packageId = "unicode-xid";
+          }
+        ];
+        features = {
+          "default" = [ "proc-macro" ];
+        };
+        resolvedDefaultFeatures = [ "default" "proc-macro" ];
+      };
+      "quote" = rec {
+        crateName = "quote";
+        version = "1.0.15";
+        edition = "2018";
+        sha256 = "0id1q0875pvhkg0mlb5z8gzdm2g2rbbz76bfzhv331lrm2b3wkc6";
+        authors = [
+          "David Tolnay <dtolnay@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+            usesDefaultFeatures = false;
+          }
+        ];
+        features = {
+          "default" = [ "proc-macro" ];
+          "proc-macro" = [ "proc-macro2/proc-macro" ];
+        };
+        resolvedDefaultFeatures = [ "default" "proc-macro" ];
+      };
+      "rand" = rec {
+        crateName = "rand";
+        version = "0.8.4";
+        edition = "2018";
+        sha256 = "1n5wska2fbfj4dsfz8mc0pd0dgjlrb6c9anpk5mwym345rip6x9f";
+        authors = [
+          "The Rand Project Developers"
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+            optional = true;
+            usesDefaultFeatures = false;
+            target = { target, features }: (target."unix" or false);
+          }
+          {
+            name = "rand_chacha";
+            packageId = "rand_chacha";
+            optional = true;
+            usesDefaultFeatures = false;
+            target = { target, features }: (!(target."os" == "emscripten"));
+          }
+          {
+            name = "rand_core";
+            packageId = "rand_core";
+          }
+          {
+            name = "rand_hc";
+            packageId = "rand_hc";
+            optional = true;
+            target = { target, features }: (target."os" == "emscripten");
+          }
+        ];
+        devDependencies = [
+          {
+            name = "rand_hc";
+            packageId = "rand_hc";
+          }
+        ];
+        features = {
+          "alloc" = [ "rand_core/alloc" ];
+          "default" = [ "std" "std_rng" ];
+          "getrandom" = [ "rand_core/getrandom" ];
+          "libc" = [ "dep:libc" ];
+          "log" = [ "dep:log" ];
+          "packed_simd" = [ "dep:packed_simd" ];
+          "rand_chacha" = [ "dep:rand_chacha" ];
+          "rand_hc" = [ "dep:rand_hc" ];
+          "serde" = [ "dep:serde" ];
+          "serde1" = [ "serde" "rand_core/serde1" ];
+          "simd_support" = [ "packed_simd" ];
+          "std" = [ "rand_core/std" "rand_chacha/std" "alloc" "getrandom" "libc" ];
+          "std_rng" = [ "rand_chacha" "rand_hc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "getrandom" "libc" "rand_chacha" "rand_hc" "std" "std_rng" ];
+      };
+      "rand_chacha" = rec {
+        crateName = "rand_chacha";
+        version = "0.3.1";
+        edition = "2018";
+        sha256 = "123x2adin558xbhvqb8w4f6syjsdkmqff8cxwhmjacpsl1ihmhg6";
+        authors = [
+          "The Rand Project Developers"
+          "The Rust Project Developers"
+          "The CryptoCorrosion Contributors"
+        ];
+        dependencies = [
+          {
+            name = "ppv-lite86";
+            packageId = "ppv-lite86";
+            usesDefaultFeatures = false;
+            features = [ "simd" ];
+          }
+          {
+            name = "rand_core";
+            packageId = "rand_core";
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "serde" = [ "dep:serde" ];
+          "serde1" = [ "serde" ];
+          "std" = [ "ppv-lite86/std" ];
+        };
+        resolvedDefaultFeatures = [ "std" ];
+      };
+      "rand_core" = rec {
+        crateName = "rand_core";
+        version = "0.6.3";
+        edition = "2018";
+        sha256 = "1rxlxc3bpzgwphcg9c9yasvv9idipcg2z2y4j0vlb52jyl418kyk";
+        authors = [
+          "The Rand Project Developers"
+          "The Rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "getrandom";
+            packageId = "getrandom";
+            optional = true;
+          }
+        ];
+        features = {
+          "getrandom" = [ "dep:getrandom" ];
+          "serde" = [ "dep:serde" ];
+          "serde1" = [ "serde" ];
+          "std" = [ "alloc" "getrandom" "getrandom/std" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "getrandom" "std" ];
+      };
+      "rand_hc" = rec {
+        crateName = "rand_hc";
+        version = "0.3.1";
+        edition = "2018";
+        sha256 = "1rwpykyvhkxs4jvqdja3mzp9dqaqamzn113cxaigs9z2dmcry7nm";
+        authors = [
+          "The Rand Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "rand_core";
+            packageId = "rand_core";
+          }
+        ];
+
+      };
+      "rcgen" = rec {
+        crateName = "rcgen";
+        version = "0.9.2";
+        edition = "2018";
+        crateBin = [
+          { name = "rcgen"; path = "src/main.rs"; }
+        ];
+        sha256 = "0ppwfl9g504x2qwk7m7mag8c3l70w9mcfha93013nlzqdlw2vynp";
+        authors = [
+          "est31 <MTest31@outlook.com>"
+        ];
+        dependencies = [
+          {
+            name = "pem";
+            packageId = "pem";
+            optional = true;
+          }
+          {
+            name = "ring";
+            packageId = "ring";
+          }
+          {
+            name = "time";
+            packageId = "time";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "x509-parser";
+            packageId = "x509-parser";
+            optional = true;
+            features = [ "verify" ];
+          }
+          {
+            name = "yasna";
+            packageId = "yasna";
+            features = [ "time" "std" ];
+          }
+          {
+            name = "zeroize";
+            packageId = "zeroize";
+            optional = true;
+          }
+        ];
+        devDependencies = [
+          {
+            name = "botan";
+            packageId = "botan";
+            features = [ "vendored" ];
+          }
+          {
+            name = "openssl";
+            packageId = "openssl";
+          }
+          {
+            name = "rand";
+            packageId = "rand";
+          }
+          {
+            name = "rsa";
+            packageId = "rsa";
+          }
+          {
+            name = "webpki";
+            packageId = "webpki";
+            features = [ "std" ];
+          }
+          {
+            name = "x509-parser";
+            packageId = "x509-parser";
+            features = [ "verify" ];
+          }
+        ];
+        features = {
+          "default" = [ "pem" ];
+          "pem" = [ "dep:pem" ];
+          "x509-parser" = [ "dep:x509-parser" ];
+          "zeroize" = [ "dep:zeroize" ];
+        };
+        resolvedDefaultFeatures = [ "default" "pem" "x509-parser" "zeroize" ];
+      };
+      "ring" = rec {
+        crateName = "ring";
+        version = "0.16.20";
+        edition = "2018";
+        sha256 = "1z682xp7v38ayq9g9nkbhhfpj6ygralmlx7wdmsfv8rnw99cylrh";
+        authors = [
+          "Brian Smith <brian@briansmith.org>"
+        ];
+        dependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+            usesDefaultFeatures = false;
+            target = { target, features }: ((target."os" == "android") || (target."os" == "linux"));
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+            optional = true;
+            usesDefaultFeatures = false;
+            target = { target, features }: ((target."os" == "android") || (target."os" == "linux"));
+            features = [ "std" ];
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+            usesDefaultFeatures = false;
+            target = { target, features }: ((target."os" == "dragonfly") || (target."os" == "freebsd") || (target."os" == "illumos") || (target."os" == "netbsd") || (target."os" == "openbsd") || (target."os" == "solaris"));
+            features = [ "std" ];
+          }
+          {
+            name = "spin";
+            packageId = "spin";
+            usesDefaultFeatures = false;
+            target = { target, features }: ((target."arch" == "x86") || (target."arch" == "x86_64") || (((target."arch" == "aarch64") || (target."arch" == "arm")) && ((target."os" == "android") || (target."os" == "fuchsia") || (target."os" == "linux"))));
+          }
+          {
+            name = "untrusted";
+            packageId = "untrusted";
+          }
+          {
+            name = "web-sys";
+            packageId = "web-sys";
+            usesDefaultFeatures = false;
+            target = { target, features }: ((target."arch" == "wasm32") && (target."vendor" == "unknown") && (target."os" == "unknown") && (target."env" == ""));
+            features = [ "Crypto" "Window" ];
+          }
+          {
+            name = "winapi";
+            packageId = "winapi";
+            usesDefaultFeatures = false;
+            target = { target, features }: (target."os" == "windows");
+            features = [ "ntsecapi" "wtypesbase" ];
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "cc";
+            packageId = "cc";
+            usesDefaultFeatures = false;
+          }
+        ];
+        devDependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+            usesDefaultFeatures = false;
+            target = {target, features}: ((target."unix" or false) || (target."windows" or false));
+          }
+        ];
+        features = {
+          "default" = [ "alloc" "dev_urandom_fallback" ];
+          "dev_urandom_fallback" = [ "once_cell" ];
+          "once_cell" = [ "dep:once_cell" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "dev_urandom_fallback" "once_cell" ];
+      };
+      "rsa" = rec {
+        crateName = "rsa";
+        version = "0.5.0";
+        edition = "2018";
+        sha256 = "039676a4mj0875phdi7vc0bd37hv84dh0dql6fmk8dl2w81jcp70";
+        authors = [
+          "RustCrypto Developers"
+          "dignifiedquire <dignifiedquire@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "byteorder";
+            packageId = "byteorder";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "digest";
+            packageId = "digest";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "lazy_static";
+            packageId = "lazy_static";
+            features = [ "spin_no_std" ];
+          }
+          {
+            name = "num-bigint-dig";
+            packageId = "num-bigint-dig";
+            rename = "num-bigint";
+            usesDefaultFeatures = false;
+            features = [ "i128" "u64_digit" "prime" "zeroize" ];
+          }
+          {
+            name = "num-integer";
+            packageId = "num-integer";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "num-iter";
+            packageId = "num-iter";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "num-traits";
+            packageId = "num-traits";
+            usesDefaultFeatures = false;
+            features = [ "libm" ];
+          }
+          {
+            name = "pkcs1";
+            packageId = "pkcs1";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "pkcs8";
+            packageId = "pkcs8";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "rand";
+            packageId = "rand";
+            usesDefaultFeatures = false;
+            features = [ "std_rng" ];
+          }
+          {
+            name = "subtle";
+            packageId = "subtle";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "zeroize";
+            packageId = "zeroize";
+            features = [ "alloc" "zeroize_derive" ];
+          }
+        ];
+        features = {
+          "alloc" = [ "digest/alloc" "pkcs1/alloc" "pkcs8/alloc" "pkcs8/pkcs1" ];
+          "default" = [ "std" "pem" ];
+          "nightly" = [ "subtle/nightly" "num-bigint/nightly" ];
+          "pem" = [ "alloc" "pkcs1/pem" "pkcs8/pem" ];
+          "pkcs5" = [ "pkcs8/encryption" ];
+          "serde" = [ "num-bigint/serde" "serde_crate" ];
+          "serde_crate" = [ "dep:serde_crate" ];
+          "std" = [ "alloc" "digest/std" "pkcs1/std" "pkcs8/std" "rand/std" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "pem" "std" ];
+      };
+      "rusticata-macros" = rec {
+        crateName = "rusticata-macros";
+        version = "4.0.0";
+        edition = "2018";
+        sha256 = "03dmfxhgwzpm1360iwcpcg3y18ddgya0i0hc599am212pdvj7ib5";
+        authors = [
+          "Pierre Chifflier <chifflier@wzdftpd.net>"
+        ];
+        dependencies = [
+          {
+            name = "nom";
+            packageId = "nom";
+            usesDefaultFeatures = false;
+            features = [ "std" ];
+          }
+        ];
+
+      };
+      "smallvec" = rec {
+        crateName = "smallvec";
+        version = "1.8.0";
+        edition = "2018";
+        sha256 = "10zf4fn63p2d6sx8qap3jvyarcfw563308x3431hd4c34r35gpgj";
+        authors = [
+          "The Servo Project Developers"
+        ];
+        features = {
+          "arbitrary" = [ "dep:arbitrary" ];
+          "const_new" = [ "const_generics" ];
+          "serde" = [ "dep:serde" ];
+        };
+      };
+      "spin" = rec {
+        crateName = "spin";
+        version = "0.5.2";
+        edition = "2015";
+        sha256 = "0b84m6dbzrwf2kxylnw82d3dr8w06av7rfkr8s85fb5f43rwyqvf";
+        authors = [
+          "Mathijs van de Nes <git@mathijs.vd-nes.nl>"
+          "John Ericson <git@JohnEricson.me>"
+        ];
+
+      };
+      "spki" = rec {
+        crateName = "spki";
+        version = "0.4.1";
+        edition = "2018";
+        sha256 = "0ckgkcg6db5y94dqhmyikgn8yrsah6pyf4j197hv1c51bp0s00aw";
+        authors = [
+          "RustCrypto Developers"
+        ];
+        dependencies = [
+          {
+            name = "der";
+            packageId = "der";
+            features = [ "oid" ];
+          }
+        ];
+        features = {
+          "std" = [ "der/std" ];
+        };
+      };
+      "subtle" = rec {
+        crateName = "subtle";
+        version = "2.4.1";
+        edition = "2015";
+        sha256 = "00b6jzh9gzb0h9n25g06nqr90z3xzqppfhhb260s1hjhh4pg7pkb";
+        authors = [
+          "Isis Lovecruft <isis@patternsinthevoid.net>"
+          "Henry de Valence <hdevalence@hdevalence.ca>"
+        ];
+        features = {
+          "default" = [ "std" "i128" ];
+        };
+      };
+      "syn" = rec {
+        crateName = "syn";
+        version = "1.0.86";
+        edition = "2018";
+        sha256 = "0sqwa4nqxzm89nj8xd8sk4iz0hbrw3mb17b6hyc2w2d0zzsb6rca";
+        authors = [
+          "David Tolnay <dtolnay@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+            optional = true;
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "unicode-xid";
+            packageId = "unicode-xid";
+          }
+        ];
+        features = {
+          "default" = [ "derive" "parsing" "printing" "clone-impls" "proc-macro" ];
+          "printing" = [ "quote" ];
+          "proc-macro" = [ "proc-macro2/proc-macro" "quote/proc-macro" ];
+          "quote" = [ "dep:quote" ];
+          "test" = [ "syn-test-suite/all-features" ];
+        };
+        resolvedDefaultFeatures = [ "clone-impls" "default" "derive" "extra-traits" "full" "parsing" "printing" "proc-macro" "quote" "visit" ];
+      };
+      "synstructure" = rec {
+        crateName = "synstructure";
+        version = "0.12.6";
+        edition = "2018";
+        sha256 = "03r1lydbf3japnlpc4wka7y90pmz1i0danaj3f9a7b431akdlszk";
+        authors = [
+          "Nika Layzell <nika@thelayzells.com>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+            usesDefaultFeatures = false;
+            features = [ "derive" "parsing" "printing" "clone-impls" "visit" "extra-traits" ];
+          }
+          {
+            name = "unicode-xid";
+            packageId = "unicode-xid";
+          }
+        ];
+        features = {
+          "default" = [ "proc-macro" ];
+          "proc-macro" = [ "proc-macro2/proc-macro" "syn/proc-macro" "quote/proc-macro" ];
+        };
+        resolvedDefaultFeatures = [ "default" "proc-macro" ];
+      };
+      "thiserror" = rec {
+        crateName = "thiserror";
+        version = "1.0.30";
+        edition = "2018";
+        sha256 = "05y4wm29ck8flwq5k1q6nhwh00a3b30cz3xr0qvnbwad5vjsnjw5";
+        authors = [
+          "David Tolnay <dtolnay@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "thiserror-impl";
+            packageId = "thiserror-impl";
+          }
+        ];
+
+      };
+      "thiserror-impl" = rec {
+        crateName = "thiserror-impl";
+        version = "1.0.30";
+        edition = "2018";
+        sha256 = "0jviwmvx6wzawsj6c9msic7h419wmsbjagl9dzhpydkzc8zzscma";
+        procMacro = true;
+        authors = [
+          "David Tolnay <dtolnay@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+          }
+        ];
+
+      };
+      "time" = rec {
+        crateName = "time";
+        version = "0.3.7";
+        edition = "2018";
+        sha256 = "0gbmwlkj15dfhbqvxlzji1ffc1lidblpgg1q3b3378hgyfcbqk00";
+        authors = [
+          "Jacob Pratt <open-source@jhpratt.dev>"
+          "Time contributors"
+        ];
+        dependencies = [
+          {
+            name = "itoa";
+            packageId = "itoa";
+            optional = true;
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+            target = { target, features }: (target."family" == "unix");
+          }
+          {
+            name = "num_threads";
+            packageId = "num_threads";
+            target = { target, features }: (target."family" == "unix");
+          }
+          {
+            name = "time-macros";
+            packageId = "time-macros";
+            optional = true;
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "formatting" = [ "itoa" "std" ];
+          "itoa" = [ "dep:itoa" ];
+          "large-dates" = [ "time-macros/large-dates" ];
+          "local-offset" = [ "std" ];
+          "macros" = [ "time-macros" ];
+          "quickcheck" = [ "quickcheck-dep" "alloc" ];
+          "quickcheck-dep" = [ "dep:quickcheck-dep" ];
+          "rand" = [ "dep:rand" ];
+          "serde" = [ "dep:serde" ];
+          "serde-human-readable" = [ "serde" "formatting" "parsing" ];
+          "serde-well-known" = [ "serde/alloc" "formatting" "parsing" ];
+          "std" = [ "alloc" ];
+          "time-macros" = [ "dep:time-macros" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "formatting" "itoa" "macros" "parsing" "std" "time-macros" ];
+      };
+      "time-macros" = rec {
+        crateName = "time-macros";
+        version = "0.2.3";
+        edition = "2018";
+        sha256 = "1mj7pv8y9j2csrh1l8aabras36pgysbnfy18330srh4g8sihrsr5";
+        procMacro = true;
+        authors = [
+          "Jacob Pratt <open-source@jhpratt.dev>"
+          "Time contributors"
+        ];
+        features = {
+        };
+      };
+      "typenum" = rec {
+        crateName = "typenum";
+        version = "1.15.0";
+        edition = "2018";
+        sha256 = "11yrvz1vd43gqv738yw1v75rzngjbs7iwcgzjy3cq5ywkv2imy6w";
+        build = "build/main.rs";
+        authors = [
+          "Paho Lurie-Gregg <paho@paholg.com>"
+          "Andre Bogus <bogusandre@gmail.com>"
+        ];
+        features = {
+          "scale-info" = [ "dep:scale-info" ];
+          "scale_info" = [ "scale-info/derive" ];
+        };
+      };
+      "unicode-xid" = rec {
+        crateName = "unicode-xid";
+        version = "0.2.2";
+        edition = "2015";
+        sha256 = "1wrkgcw557v311dkdb6n2hrix9dm2qdsb1zpw7pn79l03zb85jwc";
+        authors = [
+          "erick.tryzelaar <erick.tryzelaar@gmail.com>"
+          "kwantam <kwantam@gmail.com>"
+          "Manish Goregaokar <manishsmail@gmail.com>"
+        ];
+        features = {
+        };
+        resolvedDefaultFeatures = [ "default" ];
+      };
+      "untrusted" = rec {
+        crateName = "untrusted";
+        version = "0.7.1";
+        edition = "2018";
+        sha256 = "0jkbqaj9d3v5a91pp3wp9mffvng1nhycx6sh4qkdd9qyr62ccmm1";
+        libPath = "src/untrusted.rs";
+        authors = [
+          "Brian Smith <brian@briansmith.org>"
+        ];
+
+      };
+      "vcpkg" = rec {
+        crateName = "vcpkg";
+        version = "0.2.15";
+        edition = "2015";
+        sha256 = "09i4nf5y8lig6xgj3f7fyrvzd3nlaw4znrihw8psidvv5yk4xkdc";
+        authors = [
+          "Jim McGrath <jimmc2@gmail.com>"
+        ];
+
+      };
+      "version_check" = rec {
+        crateName = "version_check";
+        version = "0.9.4";
+        edition = "2015";
+        sha256 = "0gs8grwdlgh0xq660d7wr80x14vxbizmd8dbp29p2pdncx8lp1s9";
+        authors = [
+          "Sergio Benitez <sb@sergio.bz>"
+        ];
+
+      };
+      "wasi" = rec {
+        crateName = "wasi";
+        version = "0.10.2+wasi-snapshot-preview1";
+        edition = "2018";
+        sha256 = "1ii7nff4y1mpcrxzzvbpgxm7a1nn3szjf1n21jnx37c2g6dbsvzx";
+        authors = [
+          "The Cranelift Project Developers"
+        ];
+        features = {
+          "compiler_builtins" = [ "dep:compiler_builtins" ];
+          "core" = [ "dep:core" ];
+          "default" = [ "std" ];
+          "rustc-dep-of-std" = [ "compiler_builtins" "core" "rustc-std-workspace-alloc" ];
+          "rustc-std-workspace-alloc" = [ "dep:rustc-std-workspace-alloc" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
+      "wasm-bindgen" = rec {
+        crateName = "wasm-bindgen";
+        version = "0.2.79";
+        edition = "2018";
+        sha256 = "01kc4lj2vlf0ra2w63izrgdlv8p6f8p15086hhyqln6q4dsazw95";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if";
+          }
+          {
+            name = "wasm-bindgen-macro";
+            packageId = "wasm-bindgen-macro";
+          }
+        ];
+        features = {
+          "default" = [ "spans" "std" ];
+          "enable-interning" = [ "std" ];
+          "serde" = [ "dep:serde" ];
+          "serde-serialize" = [ "serde" "serde_json" "std" ];
+          "serde_json" = [ "dep:serde_json" ];
+          "spans" = [ "wasm-bindgen-macro/spans" ];
+          "strict-macro" = [ "wasm-bindgen-macro/strict-macro" ];
+          "xxx_debug_only_print_generated_code" = [ "wasm-bindgen-macro/xxx_debug_only_print_generated_code" ];
+        };
+        resolvedDefaultFeatures = [ "default" "spans" "std" ];
+      };
+      "wasm-bindgen-backend" = rec {
+        crateName = "wasm-bindgen-backend";
+        version = "0.2.79";
+        edition = "2018";
+        sha256 = "1jpdrl5jj01961jxhmvj7v25ws928fyfj8ms7izifnhg0ggw08cb";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "bumpalo";
+            packageId = "bumpalo";
+          }
+          {
+            name = "lazy_static";
+            packageId = "lazy_static";
+          }
+          {
+            name = "log";
+            packageId = "log";
+          }
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+            features = [ "full" ];
+          }
+          {
+            name = "wasm-bindgen-shared";
+            packageId = "wasm-bindgen-shared";
+          }
+        ];
+        features = {
+          "extra-traits" = [ "syn/extra-traits" ];
+        };
+        resolvedDefaultFeatures = [ "spans" ];
+      };
+      "wasm-bindgen-macro" = rec {
+        crateName = "wasm-bindgen-macro";
+        version = "0.2.79";
+        edition = "2018";
+        sha256 = "00gdh0dlf2r77mxwh08q0z01vz2z7mvrllmj4gjjx9a0kvb06hig";
+        procMacro = true;
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "wasm-bindgen-macro-support";
+            packageId = "wasm-bindgen-macro-support";
+          }
+        ];
+        features = {
+          "spans" = [ "wasm-bindgen-macro-support/spans" ];
+          "strict-macro" = [ "wasm-bindgen-macro-support/strict-macro" ];
+        };
+        resolvedDefaultFeatures = [ "spans" ];
+      };
+      "wasm-bindgen-macro-support" = rec {
+        crateName = "wasm-bindgen-macro-support";
+        version = "0.2.79";
+        edition = "2018";
+        sha256 = "1g1fjqvrkrf3j20z8nxsf60cypxg9dfvpbachl2b53908q6s7a5z";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+            features = [ "visit" "full" ];
+          }
+          {
+            name = "wasm-bindgen-backend";
+            packageId = "wasm-bindgen-backend";
+          }
+          {
+            name = "wasm-bindgen-shared";
+            packageId = "wasm-bindgen-shared";
+          }
+        ];
+        features = {
+          "extra-traits" = [ "syn/extra-traits" ];
+          "spans" = [ "wasm-bindgen-backend/spans" ];
+        };
+        resolvedDefaultFeatures = [ "spans" ];
+      };
+      "wasm-bindgen-shared" = rec {
+        crateName = "wasm-bindgen-shared";
+        version = "0.2.79";
+        edition = "2018";
+        sha256 = "18h67l9b9jn06iw9r2p7bh9i0brh24lilcp4f26f4f24bh1qv59x";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+
+      };
+      "web-sys" = rec {
+        crateName = "web-sys";
+        version = "0.3.56";
+        edition = "2018";
+        sha256 = "1sxqmwq773ss5m6vz7z95fdm6bqlix0s2awsy0j5gllxy8cv6q60";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "js-sys";
+            packageId = "js-sys";
+          }
+          {
+            name = "wasm-bindgen";
+            packageId = "wasm-bindgen";
+          }
+        ];
+        features = {
+          "AbortSignal" = [ "EventTarget" ];
+          "AnalyserNode" = [ "AudioNode" "EventTarget" ];
+          "Animation" = [ "EventTarget" ];
+          "AnimationEvent" = [ "Event" ];
+          "AnimationPlaybackEvent" = [ "Event" ];
+          "Attr" = [ "EventTarget" "Node" ];
+          "AudioBufferSourceNode" = [ "AudioNode" "AudioScheduledSourceNode" "EventTarget" ];
+          "AudioContext" = [ "BaseAudioContext" "EventTarget" ];
+          "AudioDestinationNode" = [ "AudioNode" "EventTarget" ];
+          "AudioNode" = [ "EventTarget" ];
+          "AudioProcessingEvent" = [ "Event" ];
+          "AudioScheduledSourceNode" = [ "AudioNode" "EventTarget" ];
+          "AudioStreamTrack" = [ "EventTarget" "MediaStreamTrack" ];
+          "AudioTrackList" = [ "EventTarget" ];
+          "AudioWorklet" = [ "Worklet" ];
+          "AudioWorkletGlobalScope" = [ "WorkletGlobalScope" ];
+          "AudioWorkletNode" = [ "AudioNode" "EventTarget" ];
+          "AuthenticatorAssertionResponse" = [ "AuthenticatorResponse" ];
+          "AuthenticatorAttestationResponse" = [ "AuthenticatorResponse" ];
+          "BaseAudioContext" = [ "EventTarget" ];
+          "BatteryManager" = [ "EventTarget" ];
+          "BeforeUnloadEvent" = [ "Event" ];
+          "BiquadFilterNode" = [ "AudioNode" "EventTarget" ];
+          "BlobEvent" = [ "Event" ];
+          "Bluetooth" = [ "EventTarget" ];
+          "BluetoothAdvertisingEvent" = [ "Event" ];
+          "BluetoothDevice" = [ "EventTarget" ];
+          "BluetoothPermissionResult" = [ "EventTarget" "PermissionStatus" ];
+          "BluetoothRemoteGattCharacteristic" = [ "EventTarget" ];
+          "BluetoothRemoteGattService" = [ "EventTarget" ];
+          "BroadcastChannel" = [ "EventTarget" ];
+          "CanvasCaptureMediaStream" = [ "EventTarget" "MediaStream" ];
+          "CdataSection" = [ "CharacterData" "EventTarget" "Node" "Text" ];
+          "ChannelMergerNode" = [ "AudioNode" "EventTarget" ];
+          "ChannelSplitterNode" = [ "AudioNode" "EventTarget" ];
+          "CharacterData" = [ "EventTarget" "Node" ];
+          "ChromeWorker" = [ "EventTarget" "Worker" ];
+          "Clipboard" = [ "EventTarget" ];
+          "ClipboardEvent" = [ "Event" ];
+          "CloseEvent" = [ "Event" ];
+          "Comment" = [ "CharacterData" "EventTarget" "Node" ];
+          "CompositionEvent" = [ "Event" "UiEvent" ];
+          "ConstantSourceNode" = [ "AudioNode" "AudioScheduledSourceNode" "EventTarget" ];
+          "ConvolverNode" = [ "AudioNode" "EventTarget" ];
+          "CssAnimation" = [ "Animation" "EventTarget" ];
+          "CssConditionRule" = [ "CssGroupingRule" "CssRule" ];
+          "CssCounterStyleRule" = [ "CssRule" ];
+          "CssFontFaceRule" = [ "CssRule" ];
+          "CssFontFeatureValuesRule" = [ "CssRule" ];
+          "CssGroupingRule" = [ "CssRule" ];
+          "CssImportRule" = [ "CssRule" ];
+          "CssKeyframeRule" = [ "CssRule" ];
+          "CssKeyframesRule" = [ "CssRule" ];
+          "CssMediaRule" = [ "CssConditionRule" "CssGroupingRule" "CssRule" ];
+          "CssNamespaceRule" = [ "CssRule" ];
+          "CssPageRule" = [ "CssRule" ];
+          "CssStyleRule" = [ "CssRule" ];
+          "CssStyleSheet" = [ "StyleSheet" ];
+          "CssSupportsRule" = [ "CssConditionRule" "CssGroupingRule" "CssRule" ];
+          "CssTransition" = [ "Animation" "EventTarget" ];
+          "CustomEvent" = [ "Event" ];
+          "DedicatedWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ];
+          "DelayNode" = [ "AudioNode" "EventTarget" ];
+          "DeviceLightEvent" = [ "Event" ];
+          "DeviceMotionEvent" = [ "Event" ];
+          "DeviceOrientationEvent" = [ "Event" ];
+          "DeviceProximityEvent" = [ "Event" ];
+          "Document" = [ "EventTarget" "Node" ];
+          "DocumentFragment" = [ "EventTarget" "Node" ];
+          "DocumentTimeline" = [ "AnimationTimeline" ];
+          "DocumentType" = [ "EventTarget" "Node" ];
+          "DomMatrix" = [ "DomMatrixReadOnly" ];
+          "DomPoint" = [ "DomPointReadOnly" ];
+          "DomRect" = [ "DomRectReadOnly" ];
+          "DomRequest" = [ "EventTarget" ];
+          "DragEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "DynamicsCompressorNode" = [ "AudioNode" "EventTarget" ];
+          "Element" = [ "EventTarget" "Node" ];
+          "ErrorEvent" = [ "Event" ];
+          "EventSource" = [ "EventTarget" ];
+          "ExtendableEvent" = [ "Event" ];
+          "ExtendableMessageEvent" = [ "Event" "ExtendableEvent" ];
+          "FetchEvent" = [ "Event" "ExtendableEvent" ];
+          "FetchObserver" = [ "EventTarget" ];
+          "File" = [ "Blob" ];
+          "FileReader" = [ "EventTarget" ];
+          "FileSystemDirectoryEntry" = [ "FileSystemEntry" ];
+          "FileSystemFileEntry" = [ "FileSystemEntry" ];
+          "FocusEvent" = [ "Event" "UiEvent" ];
+          "FontFaceSet" = [ "EventTarget" ];
+          "FontFaceSetLoadEvent" = [ "Event" ];
+          "GainNode" = [ "AudioNode" "EventTarget" ];
+          "GamepadAxisMoveEvent" = [ "Event" "GamepadEvent" ];
+          "GamepadButtonEvent" = [ "Event" "GamepadEvent" ];
+          "GamepadEvent" = [ "Event" ];
+          "GpuDevice" = [ "EventTarget" ];
+          "GpuUncapturedErrorEvent" = [ "Event" ];
+          "HashChangeEvent" = [ "Event" ];
+          "Hid" = [ "EventTarget" ];
+          "HidConnectionEvent" = [ "Event" ];
+          "HidDevice" = [ "EventTarget" ];
+          "HidInputReportEvent" = [ "Event" ];
+          "HtmlAnchorElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlAreaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlAudioElement" = [ "Element" "EventTarget" "HtmlElement" "HtmlMediaElement" "Node" ];
+          "HtmlBaseElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlBodyElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlBrElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlButtonElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlCanvasElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDataElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDataListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDetailsElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDialogElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDirectoryElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDivElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDocument" = [ "Document" "EventTarget" "Node" ];
+          "HtmlElement" = [ "Element" "EventTarget" "Node" ];
+          "HtmlEmbedElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFieldSetElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFontElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFormControlsCollection" = [ "HtmlCollection" ];
+          "HtmlFormElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFrameElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFrameSetElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHeadElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHeadingElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHrElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHtmlElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlIFrameElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlImageElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlInputElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLabelElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLegendElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLiElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLinkElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMapElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMediaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMenuElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMenuItemElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMetaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMeterElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlModElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlObjectElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOptGroupElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOptionElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOptionsCollection" = [ "HtmlCollection" ];
+          "HtmlOutputElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlParagraphElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlParamElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlPictureElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlPreElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlProgressElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlQuoteElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlScriptElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSelectElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSlotElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSourceElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSpanElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlStyleElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableCaptionElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableCellElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableColElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableRowElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableSectionElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTemplateElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTextAreaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTimeElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTitleElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTrackElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlUListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlUnknownElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlVideoElement" = [ "Element" "EventTarget" "HtmlElement" "HtmlMediaElement" "Node" ];
+          "IdbCursorWithValue" = [ "IdbCursor" ];
+          "IdbDatabase" = [ "EventTarget" ];
+          "IdbFileHandle" = [ "EventTarget" ];
+          "IdbFileRequest" = [ "DomRequest" "EventTarget" ];
+          "IdbLocaleAwareKeyRange" = [ "IdbKeyRange" ];
+          "IdbMutableFile" = [ "EventTarget" ];
+          "IdbOpenDbRequest" = [ "EventTarget" "IdbRequest" ];
+          "IdbRequest" = [ "EventTarget" ];
+          "IdbTransaction" = [ "EventTarget" ];
+          "IdbVersionChangeEvent" = [ "Event" ];
+          "IirFilterNode" = [ "AudioNode" "EventTarget" ];
+          "ImageCaptureErrorEvent" = [ "Event" ];
+          "InputEvent" = [ "Event" "UiEvent" ];
+          "KeyboardEvent" = [ "Event" "UiEvent" ];
+          "KeyframeEffect" = [ "AnimationEffect" ];
+          "LocalMediaStream" = [ "EventTarget" "MediaStream" ];
+          "MediaDevices" = [ "EventTarget" ];
+          "MediaElementAudioSourceNode" = [ "AudioNode" "EventTarget" ];
+          "MediaEncryptedEvent" = [ "Event" ];
+          "MediaKeyError" = [ "Event" ];
+          "MediaKeyMessageEvent" = [ "Event" ];
+          "MediaKeySession" = [ "EventTarget" ];
+          "MediaQueryList" = [ "EventTarget" ];
+          "MediaQueryListEvent" = [ "Event" ];
+          "MediaRecorder" = [ "EventTarget" ];
+          "MediaRecorderErrorEvent" = [ "Event" ];
+          "MediaSource" = [ "EventTarget" ];
+          "MediaStream" = [ "EventTarget" ];
+          "MediaStreamAudioDestinationNode" = [ "AudioNode" "EventTarget" ];
+          "MediaStreamAudioSourceNode" = [ "AudioNode" "EventTarget" ];
+          "MediaStreamEvent" = [ "Event" ];
+          "MediaStreamTrack" = [ "EventTarget" ];
+          "MediaStreamTrackEvent" = [ "Event" ];
+          "MessageEvent" = [ "Event" ];
+          "MessagePort" = [ "EventTarget" ];
+          "MidiAccess" = [ "EventTarget" ];
+          "MidiConnectionEvent" = [ "Event" ];
+          "MidiInput" = [ "EventTarget" "MidiPort" ];
+          "MidiMessageEvent" = [ "Event" ];
+          "MidiOutput" = [ "EventTarget" "MidiPort" ];
+          "MidiPort" = [ "EventTarget" ];
+          "MouseEvent" = [ "Event" "UiEvent" ];
+          "MouseScrollEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "MutationEvent" = [ "Event" ];
+          "NetworkInformation" = [ "EventTarget" ];
+          "Node" = [ "EventTarget" ];
+          "Notification" = [ "EventTarget" ];
+          "NotificationEvent" = [ "Event" "ExtendableEvent" ];
+          "OfflineAudioCompletionEvent" = [ "Event" ];
+          "OfflineAudioContext" = [ "BaseAudioContext" "EventTarget" ];
+          "OfflineResourceList" = [ "EventTarget" ];
+          "OffscreenCanvas" = [ "EventTarget" ];
+          "OscillatorNode" = [ "AudioNode" "AudioScheduledSourceNode" "EventTarget" ];
+          "PageTransitionEvent" = [ "Event" ];
+          "PaintWorkletGlobalScope" = [ "WorkletGlobalScope" ];
+          "PannerNode" = [ "AudioNode" "EventTarget" ];
+          "PaymentMethodChangeEvent" = [ "Event" "PaymentRequestUpdateEvent" ];
+          "PaymentRequestUpdateEvent" = [ "Event" ];
+          "Performance" = [ "EventTarget" ];
+          "PerformanceMark" = [ "PerformanceEntry" ];
+          "PerformanceMeasure" = [ "PerformanceEntry" ];
+          "PerformanceNavigationTiming" = [ "PerformanceEntry" "PerformanceResourceTiming" ];
+          "PerformanceResourceTiming" = [ "PerformanceEntry" ];
+          "PermissionStatus" = [ "EventTarget" ];
+          "PointerEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "PopStateEvent" = [ "Event" ];
+          "PopupBlockedEvent" = [ "Event" ];
+          "PresentationAvailability" = [ "EventTarget" ];
+          "PresentationConnection" = [ "EventTarget" ];
+          "PresentationConnectionAvailableEvent" = [ "Event" ];
+          "PresentationConnectionCloseEvent" = [ "Event" ];
+          "PresentationConnectionList" = [ "EventTarget" ];
+          "PresentationRequest" = [ "EventTarget" ];
+          "ProcessingInstruction" = [ "CharacterData" "EventTarget" "Node" ];
+          "ProgressEvent" = [ "Event" ];
+          "PromiseRejectionEvent" = [ "Event" ];
+          "PublicKeyCredential" = [ "Credential" ];
+          "PushEvent" = [ "Event" "ExtendableEvent" ];
+          "RadioNodeList" = [ "NodeList" ];
+          "RtcDataChannel" = [ "EventTarget" ];
+          "RtcDataChannelEvent" = [ "Event" ];
+          "RtcPeerConnection" = [ "EventTarget" ];
+          "RtcPeerConnectionIceEvent" = [ "Event" ];
+          "RtcTrackEvent" = [ "Event" ];
+          "RtcdtmfSender" = [ "EventTarget" ];
+          "RtcdtmfToneChangeEvent" = [ "Event" ];
+          "Screen" = [ "EventTarget" ];
+          "ScreenOrientation" = [ "EventTarget" ];
+          "ScriptProcessorNode" = [ "AudioNode" "EventTarget" ];
+          "ScrollAreaEvent" = [ "Event" "UiEvent" ];
+          "SecurityPolicyViolationEvent" = [ "Event" ];
+          "ServiceWorker" = [ "EventTarget" ];
+          "ServiceWorkerContainer" = [ "EventTarget" ];
+          "ServiceWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ];
+          "ServiceWorkerRegistration" = [ "EventTarget" ];
+          "ShadowRoot" = [ "DocumentFragment" "EventTarget" "Node" ];
+          "SharedWorker" = [ "EventTarget" ];
+          "SharedWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ];
+          "SourceBuffer" = [ "EventTarget" ];
+          "SourceBufferList" = [ "EventTarget" ];
+          "SpeechRecognition" = [ "EventTarget" ];
+          "SpeechRecognitionError" = [ "Event" ];
+          "SpeechRecognitionEvent" = [ "Event" ];
+          "SpeechSynthesis" = [ "EventTarget" ];
+          "SpeechSynthesisErrorEvent" = [ "Event" "SpeechSynthesisEvent" ];
+          "SpeechSynthesisEvent" = [ "Event" ];
+          "SpeechSynthesisUtterance" = [ "EventTarget" ];
+          "StereoPannerNode" = [ "AudioNode" "EventTarget" ];
+          "StorageEvent" = [ "Event" ];
+          "SvgAnimateElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgAnimateMotionElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgAnimateTransformElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgAnimationElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgCircleElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgClipPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgComponentTransferFunctionElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgDefsElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgDescElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgElement" = [ "Element" "EventTarget" "Node" ];
+          "SvgEllipseElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgFilterElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgForeignObjectElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgGeometryElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgGradientElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgGraphicsElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgImageElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgLineElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgLinearGradientElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGradientElement" ];
+          "SvgMarkerElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgMaskElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgMetadataElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgPathSegArcAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegArcRel" = [ "SvgPathSeg" ];
+          "SvgPathSegClosePath" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicRel" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicSmoothAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicSmoothRel" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticRel" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticSmoothAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticSmoothRel" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoHorizontalAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoHorizontalRel" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoRel" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoVerticalAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoVerticalRel" = [ "SvgPathSeg" ];
+          "SvgPathSegMovetoAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegMovetoRel" = [ "SvgPathSeg" ];
+          "SvgPatternElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgPolygonElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgPolylineElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgRadialGradientElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGradientElement" ];
+          "SvgRectElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgScriptElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgSetElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgStopElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgStyleElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgSwitchElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgSymbolElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgTextContentElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgTextElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" "SvgTextPositioningElement" ];
+          "SvgTextPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" ];
+          "SvgTextPositioningElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" ];
+          "SvgTitleElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgUseElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgViewElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgaElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgfeBlendElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeColorMatrixElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeComponentTransferElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeCompositeElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeConvolveMatrixElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDiffuseLightingElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDisplacementMapElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDistantLightElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDropShadowElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeFloodElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeFuncAElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeFuncBElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeFuncGElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeFuncRElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeGaussianBlurElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeImageElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeMergeElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeMergeNodeElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeMorphologyElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeOffsetElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfePointLightElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeSpecularLightingElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeSpotLightElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeTileElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeTurbulenceElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvggElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgmPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgsvgElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgtSpanElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" "SvgTextPositioningElement" ];
+          "TcpServerSocket" = [ "EventTarget" ];
+          "TcpServerSocketEvent" = [ "Event" ];
+          "TcpSocket" = [ "EventTarget" ];
+          "TcpSocketErrorEvent" = [ "Event" ];
+          "TcpSocketEvent" = [ "Event" ];
+          "Text" = [ "CharacterData" "EventTarget" "Node" ];
+          "TextTrack" = [ "EventTarget" ];
+          "TextTrackCue" = [ "EventTarget" ];
+          "TextTrackList" = [ "EventTarget" ];
+          "TimeEvent" = [ "Event" ];
+          "TouchEvent" = [ "Event" "UiEvent" ];
+          "TrackEvent" = [ "Event" ];
+          "TransitionEvent" = [ "Event" ];
+          "UiEvent" = [ "Event" ];
+          "Usb" = [ "EventTarget" ];
+          "UsbConnectionEvent" = [ "Event" ];
+          "UsbPermissionResult" = [ "EventTarget" "PermissionStatus" ];
+          "UserProximityEvent" = [ "Event" ];
+          "ValueEvent" = [ "Event" ];
+          "VideoStreamTrack" = [ "EventTarget" "MediaStreamTrack" ];
+          "VideoTrackList" = [ "EventTarget" ];
+          "VrDisplay" = [ "EventTarget" ];
+          "VttCue" = [ "EventTarget" "TextTrackCue" ];
+          "WakeLockSentinel" = [ "EventTarget" ];
+          "WaveShaperNode" = [ "AudioNode" "EventTarget" ];
+          "WebGlContextEvent" = [ "Event" ];
+          "WebKitCssMatrix" = [ "DomMatrix" "DomMatrixReadOnly" ];
+          "WebSocket" = [ "EventTarget" ];
+          "WheelEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "Window" = [ "EventTarget" ];
+          "WindowClient" = [ "Client" ];
+          "Worker" = [ "EventTarget" ];
+          "WorkerDebuggerGlobalScope" = [ "EventTarget" ];
+          "WorkerGlobalScope" = [ "EventTarget" ];
+          "XmlDocument" = [ "Document" "EventTarget" "Node" ];
+          "XmlHttpRequest" = [ "EventTarget" "XmlHttpRequestEventTarget" ];
+          "XmlHttpRequestEventTarget" = [ "EventTarget" ];
+          "XmlHttpRequestUpload" = [ "EventTarget" "XmlHttpRequestEventTarget" ];
+          "Xr" = [ "EventTarget" ];
+          "XrBoundedReferenceSpace" = [ "EventTarget" "XrReferenceSpace" "XrSpace" ];
+          "XrInputSourceEvent" = [ "Event" ];
+          "XrInputSourcesChangeEvent" = [ "Event" ];
+          "XrReferenceSpace" = [ "EventTarget" "XrSpace" ];
+          "XrReferenceSpaceEvent" = [ "Event" ];
+          "XrSession" = [ "EventTarget" ];
+          "XrSessionEvent" = [ "Event" ];
+          "XrSpace" = [ "EventTarget" ];
+          "XrViewerPose" = [ "XrPose" ];
+        };
+        resolvedDefaultFeatures = [ "Crypto" "EventTarget" "Window" ];
+      };
+      "webpki" = rec {
+        crateName = "webpki";
+        version = "0.22.0";
+        edition = "2018";
+        sha256 = "1gd1gxip5kgdwmrvhj5gjxij2mgg2mavq1ych4q1h272ja0xg5gh";
+        authors = [
+          "Brian Smith <brian@briansmith.org>"
+        ];
+        dependencies = [
+          {
+            name = "ring";
+            packageId = "ring";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "untrusted";
+            packageId = "untrusted";
+          }
+        ];
+        features = {
+          "alloc" = [ "ring/alloc" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "std" ];
+      };
+      "winapi" = rec {
+        crateName = "winapi";
+        version = "0.3.9";
+        edition = "2015";
+        sha256 = "06gl025x418lchw1wxj64ycr7gha83m44cjr5sarhynd9xkrm0sw";
+        authors = [
+          "Peter Atashian <retep998@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "winapi-i686-pc-windows-gnu";
+            packageId = "winapi-i686-pc-windows-gnu";
+            target = { target, features }: (stdenv.hostPlatform.config == "i686-pc-windows-gnu");
+          }
+          {
+            name = "winapi-x86_64-pc-windows-gnu";
+            packageId = "winapi-x86_64-pc-windows-gnu";
+            target = { target, features }: (stdenv.hostPlatform.config == "x86_64-pc-windows-gnu");
+          }
+        ];
+        features = {
+          "debug" = [ "impl-debug" ];
+        };
+        resolvedDefaultFeatures = [ "ntsecapi" "wtypesbase" ];
+      };
+      "winapi-i686-pc-windows-gnu" = rec {
+        crateName = "winapi-i686-pc-windows-gnu";
+        version = "0.4.0";
+        edition = "2015";
+        sha256 = "1dmpa6mvcvzz16zg6d5vrfy4bxgg541wxrcip7cnshi06v38ffxc";
+        authors = [
+          "Peter Atashian <retep998@gmail.com>"
+        ];
+
+      };
+      "winapi-x86_64-pc-windows-gnu" = rec {
+        crateName = "winapi-x86_64-pc-windows-gnu";
+        version = "0.4.0";
+        edition = "2015";
+        sha256 = "0gqq64czqb64kskjryj8isp62m2sgvx25yyj3kpc2myh85w24bki";
+        authors = [
+          "Peter Atashian <retep998@gmail.com>"
+        ];
+
+      };
+      "x509-parser" = rec {
+        crateName = "x509-parser";
+        version = "0.13.0";
+        edition = "2018";
+        sha256 = "0f3fqbv92q3a3s51md94sw3vgzs934agl4ii5a6ym364mkdlpwg5";
+        authors = [
+          "Pierre Chifflier <chifflier@wzdftpd.net>"
+        ];
+        dependencies = [
+          {
+            name = "asn1-rs";
+            packageId = "asn1-rs";
+            features = [ "datetime" ];
+          }
+          {
+            name = "base64";
+            packageId = "base64";
+          }
+          {
+            name = "data-encoding";
+            packageId = "data-encoding";
+          }
+          {
+            name = "der-parser";
+            packageId = "der-parser";
+            features = [ "bigint" ];
+          }
+          {
+            name = "lazy_static";
+            packageId = "lazy_static";
+          }
+          {
+            name = "nom";
+            packageId = "nom";
+          }
+          {
+            name = "oid-registry";
+            packageId = "oid-registry";
+            features = [ "crypto" "x509" ];
+          }
+          {
+            name = "ring";
+            packageId = "ring";
+            optional = true;
+          }
+          {
+            name = "rusticata-macros";
+            packageId = "rusticata-macros";
+          }
+          {
+            name = "thiserror";
+            packageId = "thiserror";
+          }
+          {
+            name = "time";
+            packageId = "time";
+            features = [ "formatting" ];
+          }
+        ];
+        features = {
+          "ring" = [ "dep:ring" ];
+          "verify" = [ "ring" ];
+        };
+        resolvedDefaultFeatures = [ "default" "ring" "verify" ];
+      };
+      "yasna" = rec {
+        crateName = "yasna";
+        version = "0.5.0";
+        edition = "2018";
+        sha256 = "0k1gk11hq4rwlppv9f50bz8bnmgr73r66idpp7rybly96si38v9l";
+        authors = [
+          "Masaki Hara <ackie.h.gmai@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "time";
+            packageId = "time";
+            optional = true;
+            usesDefaultFeatures = false;
+            features = [ "std" ];
+          }
+        ];
+        features = {
+          "bit-vec" = [ "dep:bit-vec" ];
+          "num-bigint" = [ "dep:num-bigint" ];
+          "time" = [ "dep:time" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" "time" ];
+      };
+      "zeroize" = rec {
+        crateName = "zeroize";
+        version = "1.4.3";
+        edition = "2018";
+        sha256 = "068nvl3n5hk6lfn5y24grf2c7anzzqfzjjccscq3md7rqp79v3fn";
+        authors = [
+          "The RustCrypto Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "zeroize_derive";
+            packageId = "zeroize_derive";
+            optional = true;
+          }
+        ];
+        features = {
+          "default" = [ "alloc" ];
+          "zeroize_derive" = [ "dep:zeroize_derive" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "zeroize_derive" ];
+      };
+      "zeroize_derive" = rec {
+        crateName = "zeroize_derive";
+        version = "1.3.1";
+        edition = "2018";
+        sha256 = "1nzdqyryjnqcrqz0vhddpkd8sybhn0bd8rbd6l33rdhhxwzz3s41";
+        procMacro = true;
+        authors = [
+          "The RustCrypto Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+          }
+          {
+            name = "synstructure";
+            packageId = "synstructure";
+          }
+        ];
+
+      };
+    };
+
+    #
+# crate2nix/default.nix (excerpt start)
+#
+
+  /* Target (platform) data for conditional dependencies.
+    This corresponds roughly to what buildRustCrate is setting.
+  */
+  defaultTarget = {
+    unix = true;
+    windows = false;
+    fuchsia = true;
+    test = false;
+
+    # This doesn't appear to be officially documented anywhere yet.
+    # See https://github.com/rust-lang-nursery/rust-forge/issues/101.
+    os =
+      if stdenv.hostPlatform.isDarwin
+      then "macos"
+      else stdenv.hostPlatform.parsed.kernel.name;
+    arch = stdenv.hostPlatform.parsed.cpu.name;
+    family = "unix";
+    env = "gnu";
+    endian =
+      if stdenv.hostPlatform.parsed.cpu.significantByte.name == "littleEndian"
+      then "little" else "big";
+    pointer_width = toString stdenv.hostPlatform.parsed.cpu.bits;
+    vendor = stdenv.hostPlatform.parsed.vendor.name;
+    debug_assertions = false;
+  };
+
+  /* Filters common temp files and build files. */
+  # TODO(pkolloch): Substitute with gitignore filter
+  sourceFilter = name: type:
+    let
+      baseName = builtins.baseNameOf (builtins.toString name);
+    in
+      ! (
+        # Filter out git
+        baseName == ".gitignore"
+        || (type == "directory" && baseName == ".git")
+
+        # Filter out build results
+        || (
+          type == "directory" && (
+            baseName == "target"
+            || baseName == "_site"
+            || baseName == ".sass-cache"
+            || baseName == ".jekyll-metadata"
+            || baseName == "build-artifacts"
+          )
+        )
+
+        # Filter out nix-build result symlinks
+        || (
+          type == "symlink" && lib.hasPrefix "result" baseName
+        )
+
+        # Filter out IDE config
+        || (
+          type == "directory" && (
+            baseName == ".idea" || baseName == ".vscode"
+          )
+        ) || lib.hasSuffix ".iml" baseName
+
+        # Filter out nix build files
+        || baseName == "Cargo.nix"
+
+        # Filter out editor backup / swap files.
+        || lib.hasSuffix "~" baseName
+        || builtins.match "^\\.sw[a-z]$$" baseName != null
+        || builtins.match "^\\..*\\.sw[a-z]$$" baseName != null
+        || lib.hasSuffix ".tmp" baseName
+        || lib.hasSuffix ".bak" baseName
+        || baseName == "tests.nix"
+      );
+
+  /* Returns a crate which depends on successful test execution
+    of crate given as the second argument.
+
+    testCrateFlags: list of flags to pass to the test exectuable
+    testInputs: list of packages that should be available during test execution
+  */
+  crateWithTest = { crate, testCrate, testCrateFlags, testInputs, testPreRun, testPostRun }:
+    assert builtins.typeOf testCrateFlags == "list";
+    assert builtins.typeOf testInputs == "list";
+    assert builtins.typeOf testPreRun == "string";
+    assert builtins.typeOf testPostRun == "string";
+    let
+      # override the `crate` so that it will build and execute tests instead of
+      # building the actual lib and bin targets We just have to pass `--test`
+      # to rustc and it will do the right thing.  We execute the tests and copy
+      # their log and the test executables to $out for later inspection.
+      test =
+        let
+          drv = testCrate.override
+            (
+              _: {
+                buildTests = true;
+              }
+            );
+          # If the user hasn't set any pre/post commands, we don't want to
+          # insert empty lines. This means that any existing users of crate2nix
+          # don't get a spurious rebuild unless they set these explicitly.
+          testCommand = pkgs.lib.concatStringsSep "\n"
+            (pkgs.lib.filter (s: s != "") [
+              testPreRun
+              "$f $testCrateFlags 2>&1 | tee -a $out"
+              testPostRun
+            ]);
+        in
+        pkgs.runCommand "run-tests-${testCrate.name}"
+          {
+            inherit testCrateFlags;
+            buildInputs = testInputs;
+          } ''
+          set -ex
+
+          export RUST_BACKTRACE=1
+
+          # recreate a file hierarchy as when running tests with cargo
+
+          # the source for test data
+          ${pkgs.xorg.lndir}/bin/lndir ${crate.src}
+
+          # build outputs
+          testRoot=target/debug
+          mkdir -p $testRoot
+
+          # executables of the crate
+          # we copy to prevent std::env::current_exe() to resolve to a store location
+          for i in ${crate}/bin/*; do
+            cp "$i" "$testRoot"
+          done
+          chmod +w -R .
+
+          # test harness executables are suffixed with a hash, like cargo does
+          # this allows to prevent name collision with the main
+          # executables of the crate
+          hash=$(basename $out)
+          for file in ${drv}/tests/*; do
+            f=$testRoot/$(basename $file)-$hash
+            cp $file $f
+            ${testCommand}
+          done
+        '';
+    in
+    pkgs.runCommand "${crate.name}-linked"
+      {
+        inherit (crate) outputs crateName;
+        passthru = (crate.passthru or { }) // {
+          inherit test;
+        };
+      } ''
+      echo tested by ${test}
+      ${lib.concatMapStringsSep "\n" (output: "ln -s ${crate.${output}} ${"$"}${output}") crate.outputs}
+    '';
+
+  /* A restricted overridable version of builtRustCratesWithFeatures. */
+  buildRustCrateWithFeatures =
+    { packageId
+    , features ? rootFeatures
+    , crateOverrides ? defaultCrateOverrides
+    , buildRustCrateForPkgsFunc ? null
+    , runTests ? false
+    , testCrateFlags ? [ ]
+    , testInputs ? [ ]
+      # Any command to run immediatelly before a test is executed.
+    , testPreRun ? ""
+      # Any command run immediatelly after a test is executed.
+    , testPostRun ? ""
+    }:
+    lib.makeOverridable
+      (
+        { features
+        , crateOverrides
+        , runTests
+        , testCrateFlags
+        , testInputs
+        , testPreRun
+        , testPostRun
+        }:
+        let
+          buildRustCrateForPkgsFuncOverriden =
+            if buildRustCrateForPkgsFunc != null
+            then buildRustCrateForPkgsFunc
+            else
+              (
+                if crateOverrides == pkgs.defaultCrateOverrides
+                then buildRustCrateForPkgs
+                else
+                  pkgs: (buildRustCrateForPkgs pkgs).override {
+                    defaultCrateOverrides = crateOverrides;
+                  }
+              );
+          builtRustCrates = builtRustCratesWithFeatures {
+            inherit packageId features;
+            buildRustCrateForPkgsFunc = buildRustCrateForPkgsFuncOverriden;
+            runTests = false;
+          };
+          builtTestRustCrates = builtRustCratesWithFeatures {
+            inherit packageId features;
+            buildRustCrateForPkgsFunc = buildRustCrateForPkgsFuncOverriden;
+            runTests = true;
+          };
+          drv = builtRustCrates.crates.${packageId};
+          testDrv = builtTestRustCrates.crates.${packageId};
+          derivation =
+            if runTests then
+              crateWithTest
+                {
+                  crate = drv;
+                  testCrate = testDrv;
+                  inherit testCrateFlags testInputs testPreRun testPostRun;
+                }
+            else drv;
+        in
+        derivation
+      )
+      { inherit features crateOverrides runTests testCrateFlags testInputs testPreRun testPostRun; };
+
+  /* Returns an attr set with packageId mapped to the result of buildRustCrateForPkgsFunc
+    for the corresponding crate.
+  */
+  builtRustCratesWithFeatures =
+    { packageId
+    , features
+    , crateConfigs ? crates
+    , buildRustCrateForPkgsFunc
+    , runTests
+    , target ? defaultTarget
+    } @ args:
+      assert (builtins.isAttrs crateConfigs);
+      assert (builtins.isString packageId);
+      assert (builtins.isList features);
+      assert (builtins.isAttrs target);
+      assert (builtins.isBool runTests);
+      let
+        rootPackageId = packageId;
+        mergedFeatures = mergePackageFeatures
+          (
+            args // {
+              inherit rootPackageId;
+              target = target // { test = runTests; };
+            }
+          );
+        # Memoize built packages so that reappearing packages are only built once.
+        builtByPackageIdByPkgs = mkBuiltByPackageIdByPkgs pkgs;
+        mkBuiltByPackageIdByPkgs = pkgs:
+          let
+            self = {
+              crates = lib.mapAttrs (packageId: value: buildByPackageIdForPkgsImpl self pkgs packageId) crateConfigs;
+              build = mkBuiltByPackageIdByPkgs pkgs.buildPackages;
+            };
+          in
+          self;
+        buildByPackageIdForPkgsImpl = self: pkgs: packageId:
+          let
+            features = mergedFeatures."${packageId}" or [ ];
+            crateConfig' = crateConfigs."${packageId}";
+            crateConfig =
+              builtins.removeAttrs crateConfig' [ "resolvedDefaultFeatures" "devDependencies" ];
+            devDependencies =
+              lib.optionals
+                (runTests && packageId == rootPackageId)
+                (crateConfig'.devDependencies or [ ]);
+            dependencies =
+              dependencyDerivations {
+                inherit features target;
+                buildByPackageId = depPackageId:
+                  # proc_macro crates must be compiled for the build architecture
+                  if crateConfigs.${depPackageId}.procMacro or false
+                  then self.build.crates.${depPackageId}
+                  else self.crates.${depPackageId};
+                dependencies =
+                  (crateConfig.dependencies or [ ])
+                  ++ devDependencies;
+              };
+            buildDependencies =
+              dependencyDerivations {
+                inherit features target;
+                buildByPackageId = depPackageId:
+                  self.build.crates.${depPackageId};
+                dependencies = crateConfig.buildDependencies or [ ];
+              };
+            filterEnabledDependenciesForThis = dependencies: filterEnabledDependencies {
+              inherit dependencies features target;
+            };
+            dependenciesWithRenames =
+              lib.filter (d: d ? "rename")
+                (
+                  filterEnabledDependenciesForThis
+                    (
+                      (crateConfig.buildDependencies or [ ])
+                      ++ (crateConfig.dependencies or [ ])
+                      ++ devDependencies
+                    )
+                );
+            # Crate renames have the form:
+            #
+            # {
+            #    crate_name = [
+            #       { version = "1.2.3"; rename = "crate_name01"; }
+            #    ];
+            #    # ...
+            # }
+            crateRenames =
+              let
+                grouped =
+                  lib.groupBy
+                    (dependency: dependency.name)
+                    dependenciesWithRenames;
+                versionAndRename = dep:
+                  let
+                    package = crateConfigs."${dep.packageId}";
+                  in
+                  { inherit (dep) rename; version = package.version; };
+              in
+              lib.mapAttrs (name: choices: builtins.map versionAndRename choices) grouped;
+          in
+          buildRustCrateForPkgsFunc pkgs
+            (
+              crateConfig // {
+                src = crateConfig.src or (
+                  pkgs.fetchurl rec {
+                    name = "${crateConfig.crateName}-${crateConfig.version}.tar.gz";
+                    # https://www.pietroalbini.org/blog/downloading-crates-io/
+                    # Not rate-limited, CDN URL.
+                    url = "https://static.crates.io/crates/${crateConfig.crateName}/${crateConfig.crateName}-${crateConfig.version}.crate";
+                    sha256 =
+                      assert (lib.assertMsg (crateConfig ? sha256) "Missing sha256 for ${name}");
+                      crateConfig.sha256;
+                  }
+                );
+                extraRustcOpts = lib.lists.optional (targetFeatures != [ ]) "-C target-feature=${lib.concatMapStringsSep "," (x: "+${x}") targetFeatures}";
+                inherit features dependencies buildDependencies crateRenames release;
+              }
+            );
+      in
+      builtByPackageIdByPkgs;
+
+  /* Returns the actual derivations for the given dependencies. */
+  dependencyDerivations =
+    { buildByPackageId
+    , features
+    , dependencies
+    , target
+    }:
+      assert (builtins.isList features);
+      assert (builtins.isList dependencies);
+      assert (builtins.isAttrs target);
+      let
+        enabledDependencies = filterEnabledDependencies {
+          inherit dependencies features target;
+        };
+        depDerivation = dependency: buildByPackageId dependency.packageId;
+      in
+      map depDerivation enabledDependencies;
+
+  /* Returns a sanitized version of val with all values substituted that cannot
+    be serialized as JSON.
+  */
+  sanitizeForJson = val:
+    if builtins.isAttrs val
+    then lib.mapAttrs (n: v: sanitizeForJson v) val
+    else if builtins.isList val
+    then builtins.map sanitizeForJson val
+    else if builtins.isFunction val
+    then "function"
+    else val;
+
+  /* Returns various tools to debug a crate. */
+  debugCrate = { packageId, target ? defaultTarget }:
+    assert (builtins.isString packageId);
+    let
+      debug = rec {
+        # The built tree as passed to buildRustCrate.
+        buildTree = buildRustCrateWithFeatures {
+          buildRustCrateForPkgsFunc = _: lib.id;
+          inherit packageId;
+        };
+        sanitizedBuildTree = sanitizeForJson buildTree;
+        dependencyTree = sanitizeForJson
+          (
+            buildRustCrateWithFeatures {
+              buildRustCrateForPkgsFunc = _: crate: {
+                "01_crateName" = crate.crateName or false;
+                "02_features" = crate.features or [ ];
+                "03_dependencies" = crate.dependencies or [ ];
+              };
+              inherit packageId;
+            }
+          );
+        mergedPackageFeatures = mergePackageFeatures {
+          features = rootFeatures;
+          inherit packageId target;
+        };
+        diffedDefaultPackageFeatures = diffDefaultPackageFeatures {
+          inherit packageId target;
+        };
+      };
+    in
+    { internal = debug; };
+
+  /* Returns differences between cargo default features and crate2nix default
+    features.
+
+    This is useful for verifying the feature resolution in crate2nix.
+  */
+  diffDefaultPackageFeatures =
+    { crateConfigs ? crates
+    , packageId
+    , target
+    }:
+      assert (builtins.isAttrs crateConfigs);
+      let
+        prefixValues = prefix: lib.mapAttrs (n: v: { "${prefix}" = v; });
+        mergedFeatures =
+          prefixValues
+            "crate2nix"
+            (mergePackageFeatures { inherit crateConfigs packageId target; features = [ "default" ]; });
+        configs = prefixValues "cargo" crateConfigs;
+        combined = lib.foldAttrs (a: b: a // b) { } [ mergedFeatures configs ];
+        onlyInCargo =
+          builtins.attrNames
+            (lib.filterAttrs (n: v: !(v ? "crate2nix") && (v ? "cargo")) combined);
+        onlyInCrate2Nix =
+          builtins.attrNames
+            (lib.filterAttrs (n: v: (v ? "crate2nix") && !(v ? "cargo")) combined);
+        differentFeatures = lib.filterAttrs
+          (
+            n: v:
+              (v ? "crate2nix")
+              && (v ? "cargo")
+              && (v.crate2nix.features or [ ]) != (v."cargo".resolved_default_features or [ ])
+          )
+          combined;
+      in
+      builtins.toJSON {
+        inherit onlyInCargo onlyInCrate2Nix differentFeatures;
+      };
+
+  /* Returns an attrset mapping packageId to the list of enabled features.
+
+    If multiple paths to a dependency enable different features, the
+    corresponding feature sets are merged. Features in rust are additive.
+  */
+  mergePackageFeatures =
+    { crateConfigs ? crates
+    , packageId
+    , rootPackageId ? packageId
+    , features ? rootFeatures
+    , dependencyPath ? [ crates.${packageId}.crateName ]
+    , featuresByPackageId ? { }
+    , target
+      # Adds devDependencies to the crate with rootPackageId.
+    , runTests ? false
+    , ...
+    } @ args:
+      assert (builtins.isAttrs crateConfigs);
+      assert (builtins.isString packageId);
+      assert (builtins.isString rootPackageId);
+      assert (builtins.isList features);
+      assert (builtins.isList dependencyPath);
+      assert (builtins.isAttrs featuresByPackageId);
+      assert (builtins.isAttrs target);
+      assert (builtins.isBool runTests);
+      let
+        crateConfig = crateConfigs."${packageId}" or (builtins.throw "Package not found: ${packageId}");
+        expandedFeatures = expandFeatures (crateConfig.features or { }) features;
+        enabledFeatures = enableFeatures (crateConfig.dependencies or [ ]) expandedFeatures;
+        depWithResolvedFeatures = dependency:
+          let
+            packageId = dependency.packageId;
+            features = dependencyFeatures enabledFeatures dependency;
+          in
+          { inherit packageId features; };
+        resolveDependencies = cache: path: dependencies:
+          assert (builtins.isAttrs cache);
+          assert (builtins.isList dependencies);
+          let
+            enabledDependencies = filterEnabledDependencies {
+              inherit dependencies target;
+              features = enabledFeatures;
+            };
+            directDependencies = map depWithResolvedFeatures enabledDependencies;
+            foldOverCache = op: lib.foldl op cache directDependencies;
+          in
+          foldOverCache
+            (
+              cache: { packageId, features }:
+                let
+                  cacheFeatures = cache.${packageId} or [ ];
+                  combinedFeatures = sortedUnique (cacheFeatures ++ features);
+                in
+                if cache ? ${packageId} && cache.${packageId} == combinedFeatures
+                then cache
+                else
+                  mergePackageFeatures {
+                    features = combinedFeatures;
+                    featuresByPackageId = cache;
+                    inherit crateConfigs packageId target runTests rootPackageId;
+                  }
+            );
+        cacheWithSelf =
+          let
+            cacheFeatures = featuresByPackageId.${packageId} or [ ];
+            combinedFeatures = sortedUnique (cacheFeatures ++ enabledFeatures);
+          in
+          featuresByPackageId // {
+            "${packageId}" = combinedFeatures;
+          };
+        cacheWithDependencies =
+          resolveDependencies cacheWithSelf "dep"
+            (
+              crateConfig.dependencies or [ ]
+              ++ lib.optionals
+                (runTests && packageId == rootPackageId)
+                (crateConfig.devDependencies or [ ])
+            );
+        cacheWithAll =
+          resolveDependencies
+            cacheWithDependencies "build"
+            (crateConfig.buildDependencies or [ ]);
+      in
+      cacheWithAll;
+
+  /* Returns the enabled dependencies given the enabled features. */
+  filterEnabledDependencies = { dependencies, features, target }:
+    assert (builtins.isList dependencies);
+    assert (builtins.isList features);
+    assert (builtins.isAttrs target);
+
+    lib.filter
+      (
+        dep:
+        let
+          targetFunc = dep.target or (features: true);
+        in
+        targetFunc { inherit features target; }
+        && (
+          !(dep.optional or false)
+          || builtins.any (doesFeatureEnableDependency dep) features
+        )
+      )
+      dependencies;
+
+  /* Returns whether the given feature should enable the given dependency. */
+  doesFeatureEnableDependency = dependency: feature:
+    let
+      name = dependency.rename or dependency.name;
+      prefix = "${name}/";
+      len = builtins.stringLength prefix;
+      startsWithPrefix = builtins.substring 0 len feature == prefix;
+    in
+    feature == name || startsWithPrefix;
+
+  /* Returns the expanded features for the given inputFeatures by applying the
+    rules in featureMap.
+
+    featureMap is an attribute set which maps feature names to lists of further
+    feature names to enable in case this feature is selected.
+  */
+  expandFeatures = featureMap: inputFeatures:
+    assert (builtins.isAttrs featureMap);
+    assert (builtins.isList inputFeatures);
+    let
+      expandFeature = feature:
+        assert (builtins.isString feature);
+        [ feature ] ++ (expandFeatures featureMap (featureMap."${feature}" or [ ]));
+      outFeatures = lib.concatMap expandFeature inputFeatures;
+    in
+    sortedUnique outFeatures;
+
+  /* This function adds optional dependencies as features if they are enabled
+    indirectly by dependency features. This function mimics Cargo's behavior
+    described in a note at:
+    https://doc.rust-lang.org/nightly/cargo/reference/features.html#dependency-features
+  */
+  enableFeatures = dependencies: features:
+    assert (builtins.isList features);
+    assert (builtins.isList dependencies);
+    let
+      additionalFeatures = lib.concatMap
+        (
+          dependency:
+            assert (builtins.isAttrs dependency);
+            let
+              enabled = builtins.any (doesFeatureEnableDependency dependency) features;
+            in
+            if (dependency.optional or false) && enabled
+            then [ (dependency.rename or dependency.name) ]
+            else [ ]
+        )
+        dependencies;
+    in
+    sortedUnique (features ++ additionalFeatures);
+
+  /*
+    Returns the actual features for the given dependency.
+
+    features: The features of the crate that refers this dependency.
+  */
+  dependencyFeatures = features: dependency:
+    assert (builtins.isList features);
+    assert (builtins.isAttrs dependency);
+    let
+      defaultOrNil =
+        if dependency.usesDefaultFeatures or true
+        then [ "default" ]
+        else [ ];
+      explicitFeatures = dependency.features or [ ];
+      additionalDependencyFeatures =
+        let
+          dependencyPrefix = (dependency.rename or dependency.name) + "/";
+          dependencyFeatures =
+            builtins.filter (f: lib.hasPrefix dependencyPrefix f) features;
+        in
+        builtins.map (lib.removePrefix dependencyPrefix) dependencyFeatures;
+    in
+    defaultOrNil ++ explicitFeatures ++ additionalDependencyFeatures;
+
+  /* Sorts and removes duplicates from a list of strings. */
+  sortedUnique = features:
+    assert (builtins.isList features);
+    assert (builtins.all builtins.isString features);
+    let
+      outFeaturesSet = lib.foldl (set: feature: set // { "${feature}" = 1; }) { } features;
+      outFeaturesUnique = builtins.attrNames outFeaturesSet;
+    in
+    builtins.sort (a: b: a < b) outFeaturesUnique;
+
+  deprecationWarning = message: value:
+    if strictDeprecation
+    then builtins.throw "strictDeprecation enabled, aborting: ${message}"
+    else builtins.trace message value;
+
+  #
+  # crate2nix/default.nix (excerpt end)
+  #
+  };
+}
+
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 85fb0e950410..e388175ca582 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
@@ -61,8 +61,8 @@ let
     let
 
       cargoDeps =
-        if cargoVendorDir == null
-        then if cargoLock != null then importCargoLock cargoLock
+        if cargoVendorDir != null then null
+        else if cargoLock != null then importCargoLock cargoLock
         else fetchCargoTarball ({
           inherit src srcs sourceRoot unpackPhase cargoUpdateHook;
           name = cargoDepsName;
@@ -71,8 +71,7 @@ let
           hash = args.cargoHash;
         } // lib.optionalAttrs (args ? cargoSha256) {
           sha256 = args.cargoSha256;
-        } // depsExtraArgs)
-        else null;
+        } // depsExtraArgs);
 
       # If we have a cargoSha256 fixed-output derivation, validate it at build time
       # against the src fixed-output derivation to check consistency.
@@ -100,7 +99,7 @@ let
     # See https://os.phil-opp.com/testing/ for more information.
     assert useSysroot -> !(args.doCheck or true);
 
-    stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoLock" ]) // lib.optionalAttrs useSysroot {
+    stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoUpdateHook" "cargoLock" ]) // lib.optionalAttrs useSysroot {
       RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or "");
     } // {
       inherit buildAndTestSubdir cargoDeps;
diff --git a/nixpkgs/pkgs/build-support/rust/default-crate-overrides.nix b/nixpkgs/pkgs/build-support/rust/default-crate-overrides.nix
index 841cad09efa1..f6383af44e82 100644
--- a/nixpkgs/pkgs/build-support/rust/default-crate-overrides.nix
+++ b/nixpkgs/pkgs/build-support/rust/default-crate-overrides.nix
@@ -27,6 +27,7 @@
 , freetype
 , rdkafka
 , udev
+, libevdev
 , ...
 }:
 
@@ -65,6 +66,12 @@ in
     buildInputs = [ dbus ];
   };
 
+  evdev-sys = attrs: {
+    LIBGIT2_SYS_USE_PKG_CONFIG = true;
+    nativeBuildInputs = [ pkg-config ];
+    buildInputs = [ libevdev ];
+  };
+
   expat-sys = attrs: {
     nativeBuildInputs = [ cmake ];
   };
@@ -170,7 +177,7 @@ in
   };
 
   security-framework-sys = attr: {
-    propagatedBuildInputs = [ Security ];
+    propagatedBuildInputs = lib.optional stdenv.isDarwin Security;
   };
 
   sequoia-openpgp = attrs: {
diff --git a/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix b/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix
index d36200aa5f90..2f1f3547dbb0 100644
--- a/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix
@@ -23,6 +23,7 @@ in
 , patches ? []
 , sourceRoot ? ""
 , cargoUpdateHook ? ""
+, nativeBuildInputs ? []
 , ...
 } @ args:
 
@@ -32,7 +33,7 @@ let hash_ =
   else throw "fetchCargoTarball requires a hash for ${name}";
 in stdenv.mkDerivation ({
   name = "${name}-vendor.tar.gz";
-  nativeBuildInputs = [ cacert git cargo-vendor-normalise cargo ];
+  nativeBuildInputs = [ cacert git cargo-vendor-normalise cargo ] ++ nativeBuildInputs;
 
   buildPhase = ''
     runHook preBuild
@@ -82,5 +83,5 @@ in stdenv.mkDerivation ({
 
   impureEnvVars = lib.fetchers.proxyImpureEnvVars;
 } // (builtins.removeAttrs args [
-  "name" "sha256" "cargoUpdateHook"
+  "name" "sha256" "cargoUpdateHook" "nativeBuildInputs"
 ]))
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 7e2599d92240..41b313280d70 100644
--- a/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh
+++ b/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh
@@ -15,7 +15,8 @@ maturinBuildHook() {
       "CC_@rustTargetPlatform@=@ccForHost@" \
       "CXX_@rustTargetPlatform@=@cxxForHost@" \
       maturin build \
-        --cargo-extra-args="-j $NIX_BUILD_CORES --frozen" \
+        --jobs=$NIX_BUILD_CORES \
+        --frozen \
         --target @rustTargetPlatformSpec@ \
         --manylinux off \
         --strip \
diff --git a/nixpkgs/pkgs/build-support/rust/lib/default.nix b/nixpkgs/pkgs/build-support/rust/lib/default.nix
index 24adcf2cb4e2..34aaa8c516a9 100644
--- a/nixpkgs/pkgs/build-support/rust/lib/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/lib/default.nix
@@ -3,12 +3,14 @@
 rec {
   # https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch
   toTargetArch = platform:
-    if platform.isAarch32 then "arm"
+    /**/ if platform ? rustc.platform then platform.rustc.platform.arch
+    else if platform.isAarch32 then "arm"
     else platform.parsed.cpu.name;
 
   # https://doc.rust-lang.org/reference/conditional-compilation.html#target_os
   toTargetOs = platform:
-    if platform.isDarwin then "macos"
+    /**/ if platform ? rustc.platform then platform.rustc.platform.os or "none"
+    else if platform.isDarwin then "macos"
     else platform.parsed.kernel.name;
 
   # Returns the name of the rust target, even if it is custom. Adjustments are
@@ -31,7 +33,7 @@ rec {
   # Returns the name of the rust target if it is standard, or the json file
   # containing the custom target spec.
   toRustTargetSpec = platform:
-    if (platform.rustc or {}) ? platform
+    if platform ? rustc.platform
     then builtins.toFile (toRustTarget platform + ".json") (builtins.toJSON platform.rustc.platform)
     else toRustTarget platform;
 }
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.py b/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.py
index 26fd623e3da0..861d772698d0 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.py
+++ b/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.py
@@ -1,23 +1,21 @@
 #!/usr/bin/env python3
 
-from collections import defaultdict
-from contextlib import contextmanager
-from dataclasses import dataclass
-from elftools.common.exceptions import ELFError # type: ignore
-from elftools.elf.dynamic import DynamicSection # type: ignore
-from elftools.elf.elffile import ELFFile # type: ignore
-from elftools.elf.enums import ENUM_E_TYPE, ENUM_EI_OSABI # type: ignore
-from itertools import chain
-from pathlib import Path, PurePath
-
-from typing import Tuple, Optional, Iterator, List, DefaultDict, Set
-
 import argparse
 import os
 import pprint
 import subprocess
 import sys
+from collections import defaultdict
+from contextlib import contextmanager
+from dataclasses import dataclass
+from itertools import chain
+from pathlib import Path, PurePath
+from typing import DefaultDict, Iterator, List, Optional, Set, Tuple
 
+from elftools.common.exceptions import ELFError  # type: ignore
+from elftools.elf.dynamic import DynamicSection  # type: ignore
+from elftools.elf.elffile import ELFFile  # type: ignore
+from elftools.elf.enums import ENUM_E_TYPE, ENUM_EI_OSABI  # type: ignore
 
 
 @contextmanager
@@ -246,7 +244,7 @@ def auto_patchelf(
         lib_dirs: List[Path],
         runtime_deps: List[Path],
         recursive: bool =True,
-        ignore_missing: bool =False) -> None:
+        ignore_missing: List[str] = []) -> None:
 
     if not paths_to_patch:
         sys.exit("No paths to patch, stopping.")
@@ -264,12 +262,19 @@ def auto_patchelf(
     missing = [dep for dep in dependencies if not dep.found]
 
     # Print a summary of the missing dependencies at the end
+    print(f"auto-patchelf: {len(missing)} dependencies could not be satisfied")
+    failure = False
     for dep in missing:
-        print(f"auto-patchelf could not satisfy dependency {dep.name} wanted by {dep.file}")
+        if dep.name.name in ignore_missing or "*" in ignore_missing:
+            print(f"warn: auto-patchelf ignoring missing {dep.name} wanted by {dep.file}")
+        else:
+            print(f"error: auto-patchelf could not satisfy dependency {dep.name} wanted by {dep.file}")
+            failure = True
 
-    if missing and not ignore_missing:
+    if failure:
         sys.exit('auto-patchelf failed to find all the required dependencies.\n'
-                 'Add the missing dependencies to --libs or use --ignore-missing.')
+                 'Add the missing dependencies to --libs or use '
+                 '`--ignore-missing="foo.so.1 bar.so etc.so"`.')
 
 
 def main() -> None:
@@ -280,7 +285,8 @@ def main() -> None:
                     'libraries in the provided paths.')
     parser.add_argument(
         "--ignore-missing",
-        action="store_true",
+        nargs="*",
+        type=str,
         help="Do not fail when some dependencies are not found.")
     parser.add_argument(
         "--no-recurse",
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh b/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh
index 9822674196ae..b56f9ce2dbf4 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/auto-patchelf.sh
@@ -53,10 +53,18 @@ autoPatchelf() {
         esac
     done
 
+    local ignoreMissingDepsArray=($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=( "*" )
+    fi
+
     local runtimeDependenciesArray=($runtimeDependencies)
     @pythonInterpreter@ @autoPatchelfScript@                            \
         ${norecurse:+--no-recurse}                                      \
-        ${autoPatchelfIgnoreMissingDeps:+--ignore-missing}              \
+        --ignore-missing "${ignoreMissingDepsArray[@]}"                 \
         --paths "$@"                                                    \
         --libs "${autoPatchelfLibs[@]}"                                 \
                "${extraAutoPatchelfLibs[@]}"                            \
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/copy-desktop-items.sh b/nixpkgs/pkgs/build-support/setup-hooks/copy-desktop-items.sh
index b5c5ed81eb97..313ebc980344 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/copy-desktop-items.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/copy-desktop-items.sh
@@ -28,14 +28,15 @@ copyDesktopItems() {
         return
     fi
 
+    applications="${!outputBin}/share/applications"
     for desktopItem in $desktopItems; do
         if [[ -f "$desktopItem" ]]; then
-            echo "Copying '$desktopItem' into '$out/share/applications'"
-            install -D -m 444 -t "$out"/share/applications "$desktopItem"
+            echo "Copying '$desktopItem' into '${applications}'"
+            install -D -m 444 -t "${applications}" "$desktopItem"
         else
             for f in "$desktopItem"/share/applications/*.desktop; do
-                echo "Copying '$f' into '$out/share/applications'"
-                install -D -m 444 -t "$out"/share/applications "$f"
+                echo "Copying '$f' into '${applications}'"
+                install -D -m 444 -t "${applications}" "$f"
             done
         fi
     done
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/copy-pkgconfig-items.sh b/nixpkgs/pkgs/build-support/setup-hooks/copy-pkgconfig-items.sh
new file mode 100644
index 000000000000..8c04ec9b5f0e
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/setup-hooks/copy-pkgconfig-items.sh
@@ -0,0 +1,46 @@
+# shellcheck shell=bash
+
+# Setup hook that installs specified pkgconfig items.
+#
+# Example usage in a derivation:
+#
+#   { …, makePkgconfigItem, copyPkgconfigItems, … }:
+#
+#   let pkgconfigItem = makePkgconfigItem { … }; in
+#   stdenv.mkDerivation {
+#     …
+#     nativeBuildInputs = [ copyPkgconfigItems ];
+#
+#     pkgconfigItems =  [ pkgconfigItem ];
+#     …
+#   }
+#
+# This hook will copy files which are either given by full path
+# or all '*.pc' files placed inside the 'lib/pkgconfig'
+# folder of each `pkgconfigItems` argument.
+
+postInstallHooks+=(copyPkgconfigItems)
+
+copyPkgconfigItems() {
+    if [ "${dontCopyPkgconfigItems-}" = 1 ]; then return; fi
+
+    if [ -z "$pkgconfigItems" ]; then
+        return
+    fi
+
+    pkgconfigdir="${!outputDev}/lib/pkgconfig"
+    for pkgconfigItem in $pkgconfigItems; do
+        if [[ -f "$pkgconfigItem" ]]; then
+            substituteAllInPlace "$pkgconfigItem"
+            echo "Copying '$pkgconfigItem' into '${pkgconfigdir}'"
+            install -D -m 444 -t "${pkgconfigdir}" "$pkgconfigItem"
+            substituteAllInPlace "${pkgconfigdir}"/*
+        else
+            for f in "$pkgconfigItem"/lib/pkgconfig/*.pc; do
+                echo "Copying '$f' into '${pkgconfigdir}'"
+                install -D -m 444 -t "${pkgconfigdir}" "$f"
+                substituteAllInPlace "${pkgconfigdir}"/*
+            done
+        fi
+    done
+}
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh b/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh
index d54af90b6888..74c8f6d0b333 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh
@@ -163,7 +163,7 @@ convertIconTheme() {
     }
 
     iconsdir=$(getIcons "$sharePath" "apps/${iconName}" "$theme")
-    if [[ -n "$(ls -1 "$iconsdir/"*)" ]]; then
+    if [[ -n "$(ls -A1 "$iconsdir")" ]]; then
         icnsutil compose --toc "$out/${iconName}.icns" "$iconsdir/"*
     else
         echo "Warning: no icons were found. Creating an empty icon for ${iconName}.icns."
@@ -171,21 +171,41 @@ convertIconTheme() {
     fi
 }
 
+processExecFieldCodes() {
+  local -r file=$1
+  local -r execRaw=$(getDesktopParam "${file}" "Exec")
+  local -r execNoK="${execRaw/\%k/${file}}"
+  local -r execNoKC="${execNoK/\%c/$(getDesktopParam "${file}" "Name")}"
+  local -r icon=$(getDesktopParam "${file}" "Icon")
+  local -r execNoKCI="${execNoKC/\%i/${icon:+--icon }${icon}}"
+  local -r execNoKCIfu="${execNoKCI/\%[fu]/\$1}"
+  local -r exec="${execNoKCIfu/\%[FU]/\$@}"
+  if [[ "$exec" != "$execRaw" ]]; then
+    echo 1>&2 "desktopToDarwinBundle: Application bundles do not understand desktop entry field codes. Changed '$execRaw' to '$exec'."
+  fi
+  echo "$exec"
+}
+
 # For a given .desktop file, generate a darwin '.app' bundle for it.
 convertDesktopFile() {
     local -r file=$1
     local -r sharePath=$(dirname "$(dirname "$file")")
     local -r name=$(getDesktopParam "${file}" "^Name")
-    local -r exec=$(getDesktopParam "${file}" "Exec")
+    local -r macOSExec=$(getDesktopParam "${file}" "X-macOS-Exec")
+    if [[ "$macOSExec" ]]; then
+      local -r exec="$macOSExec"
+    else
+      local -r exec=$(processExecFieldCodes "${file}")
+    fi
     local -r iconName=$(getDesktopParam "${file}" "^Icon")
     local -r squircle=$(getDesktopParam "${file}" "X-macOS-SquircleIcon")
 
-    mkdir -p "$out/Applications/${name}.app/Contents/MacOS"
-    mkdir -p "$out/Applications/${name}.app/Contents/Resources"
+    mkdir -p "${!outputBin}/Applications/${name}.app/Contents/MacOS"
+    mkdir -p "${!outputBin}/Applications/${name}.app/Contents/Resources"
 
-    convertIconTheme "$out/Applications/${name}.app/Contents/Resources" "$sharePath" "$iconName"
+    convertIconTheme "${!outputBin}/Applications/${name}.app/Contents/Resources" "$sharePath" "$iconName"
 
-    write-darwin-bundle "$out" "$name" "$exec" "$iconName" "$squircle"
+    write-darwin-bundle "${!outputBin}" "$name" "$exec" "$iconName" "$squircle"
 }
 
 convertDesktopFiles() {
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix b/nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix
new file mode 100644
index 000000000000..9f52a05f61ca
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix
@@ -0,0 +1,27 @@
+{ stdenv
+, targetPackages
+, lib
+, makeSetupHook
+, dieHook
+, writeShellScript
+, tests
+, cc ? targetPackages.stdenv.cc
+, sanitizers ? []
+}:
+
+makeSetupHook {
+  deps = [ dieHook ]
+    # https://github.com/NixOS/nixpkgs/issues/148189
+    ++ lib.optional (stdenv.isDarwin && stdenv.isAarch64) cc;
+
+  substitutions = {
+    cc = "${cc}/bin/${cc.targetPrefix}cc ${lib.escapeShellArgs (map (s: "-fsanitize=${s}") sanitizers)}";
+
+    # Extract the function call used to create a binary wrapper from its embedded docstring
+    passthru.extractCmd = writeShellScript "extract-binary-wrapper-cmd" ''
+      strings -dw "$1" | sed -n '/^makeCWrapper/,/^$/ p'
+    '';
+
+    passthru.tests = tests.makeBinaryWrapper;
+  };
+} ./make-binary-wrapper.sh
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh
index 986be5b9e113..5f759d323cf6 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh
@@ -15,24 +15,28 @@ assertExecutable() {
 # makeWrapper EXECUTABLE OUT_PATH ARGS
 
 # ARGS:
-# --argv0       NAME    : set name of executed process to NAME
-#                         (otherwise it’s called …-wrapped)
-# --inherit-argv0       : the executable inherits argv0 from the wrapper.
-#                         (use instead of --argv0 '$0')
-# --set         VAR VAL : add VAR with value VAL to the executable’s
-#                         environment
-# --set-default VAR VAL : like --set, but only adds VAR if not already set in
-#                         the environment
-# --unset       VAR     : remove VAR from the environment
-# --chdir       DIR     : change working directory (use instead of --run "cd DIR")
-# --add-flags   FLAGS   : add FLAGS to invocation of executable
+# --argv0        NAME    : set the name of the executed process to NAME
+#                          (if unset or empty, defaults to EXECUTABLE)
+# --inherit-argv0        : the executable inherits argv0 from the wrapper.
+#                          (use instead of --argv0 '$0')
+# --set          VAR VAL : add VAR with value VAL to the executable's environment
+# --set-default  VAR VAL : like --set, but only adds VAR if not already set in
+#                          the environment
+# --unset        VAR     : remove VAR from the environment
+# --chdir        DIR     : change working directory (use instead of --run "cd DIR")
+# --add-flags    ARGS    : prepend ARGS to the invocation of the executable
+#                          (that is, *before* any arguments passed on the command line)
+# --append-flags ARGS    : append ARGS to the invocation of the executable
+#                          (that is, *after* any arguments passed on the command line)
 
 # --prefix          ENV SEP VAL   : suffix/prefix ENV with VAL, separated by SEP
 # --suffix
 
 # To troubleshoot a binary wrapper after you compiled it,
 # use the `strings` command or open the binary file in a text editor.
-makeWrapper() {
+makeWrapper() { makeBinaryWrapper "$@"; }
+makeBinaryWrapper() {
+    local NIX_CFLAGS_COMPILE= NIX_CFLAGS_LINK=
     local original="$1"
     local wrapper="$2"
     shift 2
@@ -42,15 +46,17 @@ makeWrapper() {
     mkdir -p "$(dirname "$wrapper")"
 
     makeDocumentedCWrapper "$original" "$@" | \
-      @CC@ \
+      @cc@ \
         -Wall -Werror -Wpedantic \
+        -Wno-overlength-strings \
         -Os \
         -x c \
         -o "$wrapper" -
 }
 
 # Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...>
-wrapProgram() {
+wrapProgram() { wrapProgramBinary "$@"; }
+wrapProgramBinary() {
     local prog="$1"
     local hidden
 
@@ -61,8 +67,6 @@ wrapProgram() {
       hidden="${hidden}_"
     done
     mv "$prog" "$hidden"
-    # Silence warning about unexpanded $0:
-    # shellcheck disable=SC2016
     makeWrapper "$hidden" "$prog" --inherit-argv0 "${@:2}"
 }
 
@@ -81,7 +85,7 @@ makeDocumentedCWrapper() {
 # makeCWrapper EXECUTABLE ARGS
 # ARGS: same as makeWrapper
 makeCWrapper() {
-    local argv0 inherit_argv0 n params cmd main flagsBefore flags executable length
+    local argv0 inherit_argv0 n params cmd main flagsBefore flagsAfter flags executable length
     local uses_prefix uses_suffix uses_assert uses_assert_success uses_stdio uses_asprintf
     executable=$(escapeStringLiteral "$1")
     params=("$@")
@@ -148,6 +152,13 @@ makeCWrapper() {
                 n=$((n + 1))
                 [ $n -ge "$length" ] && main="$main#error makeCWrapper: $p takes 1 argument"$'\n'
             ;;
+            --append-flags)
+                flags="${params[n + 1]}"
+                flagsAfter="$flagsAfter $flags"
+                uses_assert=1
+                n=$((n + 1))
+                [ $n -ge "$length" ] && main="$main#error makeCWrapper: $p takes 1 argument"$'\n'
+            ;;
             --argv0)
                 argv0=$(escapeStringLiteral "${params[n + 1]}")
                 inherit_argv0=
@@ -163,8 +174,7 @@ makeCWrapper() {
             ;;
         esac
     done
-    # shellcheck disable=SC2086
-    [ -z "$flagsBefore" ] || main="$main"${main:+$'\n'}$(addFlags $flagsBefore)$'\n'$'\n'
+    [[ -z "$flagsBefore" && -z "$flagsAfter" ]] || main="$main"${main:+$'\n'}$(addFlags "$flagsBefore" "$flagsAfter")$'\n'$'\n'
     [ -z "$inherit_argv0" ] && main="${main}argv[0] = \"${argv0:-${executable}}\";"$'\n'
     main="${main}return execv(\"${executable}\", argv);"$'\n'
 
@@ -182,21 +192,25 @@ makeCWrapper() {
 }
 
 addFlags() {
-    local result n flag flags var
+    local n flag before after var
+    # shellcheck disable=SC2086
+    before=($1) after=($2)
     var="argv_tmp"
-    flags=("$@")
-    for ((n = 0; n < ${#flags[*]}; n += 1)); do
-        flag=$(escapeStringLiteral "${flags[$n]}")
-        result="$result${var}[$((n+1))] = \"$flag\";"$'\n'
-    done
-    printf '%s\n' "char **$var = calloc($((n+1)) + argc, sizeof(*$var));"
+    printf '%s\n' "char **$var = calloc(${#before[@]} + argc + ${#after[@]} + 1, sizeof(*$var));"
     printf '%s\n' "assert($var != NULL);"
     printf '%s\n' "${var}[0] = argv[0];"
-    printf '%s' "$result"
+    for ((n = 0; n < ${#before[@]}; n += 1)); do
+        flag=$(escapeStringLiteral "${before[n]}")
+        printf '%s\n' "${var}[$((n + 1))] = \"$flag\";"
+    done
     printf '%s\n' "for (int i = 1; i < argc; ++i) {"
-    printf '%s\n' "    ${var}[$n + i] = argv[i];"
+    printf '%s\n' "    ${var}[${#before[@]} + i] = argv[i];"
     printf '%s\n' "}"
-    printf '%s\n' "${var}[$n + argc] = NULL;"
+    for ((n = 0; n < ${#after[@]}; n += 1)); do
+        flag=$(escapeStringLiteral "${after[n]}")
+        printf '%s\n' "${var}[${#before[@]} + argc + $n] = \"$flag\";"
+    done
+    printf '%s\n' "${var}[${#before[@]} + argc + ${#after[@]}] = NULL;"
     printf '%s\n' "argv = $var;"
 }
 
@@ -309,8 +323,9 @@ void set_env_suffix(char *env, char *sep, char *suffix) {
 "
 }
 
-# Embed a C string which shows up as readable text in the compiled binary wrapper
-# documentationString ARGS
+# Embed a C string which shows up as readable text in the compiled binary wrapper,
+# giving instructions for recreating the wrapper.
+# Keep in sync with makeBinaryWrapper.extractCmd
 docstring() {
     printf '%s' "const char * DOCSTRING = \"$(escapeStringLiteral "
 
@@ -331,7 +346,7 @@ makeCWrapper $(formatArgs "$@")
 
 # formatArgs EXECUTABLE ARGS
 formatArgs() {
-    printf '%s' "$1"
+    printf '%s' "${1@Q}"
     shift
     while [ $# -gt 0 ]; do
         case "$1" in
@@ -363,6 +378,10 @@ formatArgs() {
                 formatArgsLine 1 "$@"
                 shift 1
             ;;
+            --append-flags)
+                formatArgsLine 1 "$@"
+                shift 1
+            ;;
             --argv0)
                 formatArgsLine 1 "$@"
                 shift 1
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh b/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh
index fa6065832894..84e5ecee2909 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh
@@ -11,15 +11,20 @@ assertExecutable() {
 # makeWrapper EXECUTABLE OUT_PATH ARGS
 
 # ARGS:
-# --argv0       NAME    : set name of executed process to NAME
-#                         (otherwise it’s called …-wrapped)
-# --set         VAR VAL : add VAR with value VAL to the executable’s
-#                         environment
-# --set-default VAR VAL : like --set, but only adds VAR if not already set in
-#                         the environment
-# --unset       VAR     : remove VAR from the environment
-# --run         COMMAND : run command before the executable
-# --add-flags   FLAGS   : add FLAGS to invocation of executable
+# --argv0        NAME    : set the name of the executed process to NAME
+#                          (if unset or empty, defaults to EXECUTABLE)
+# --inherit-argv0        : the executable inherits argv0 from the wrapper.
+#                          (use instead of --argv0 '$0')
+# --set          VAR VAL : add VAR with value VAL to the executable's environment
+# --set-default  VAR VAL : like --set, but only adds VAR if not already set in
+#                          the environment
+# --unset        VAR     : remove VAR from the environment
+# --chdir        DIR     : change working directory (use instead of --run "cd DIR")
+# --run          COMMAND : run command before the executable
+# --add-flags    ARGS    : prepend ARGS to the invocation of the executable
+#                          (that is, *before* any arguments passed on the command line)
+# --append-flags ARGS    : append ARGS to the invocation of the executable
+#                          (that is, *after* any arguments passed on the command line)
 
 # --prefix          ENV SEP VAL   : suffix/prefix ENV with VAL, separated by SEP
 # --suffix
@@ -28,11 +33,12 @@ assertExecutable() {
 # --prefix-contents ENV SEP FILES : like --suffix-each, but contents of FILES
 #                                   are read first and used as VALS
 # --suffix-contents
-makeWrapper() {
+makeWrapper() { makeShellWrapper "$@"; }
+makeShellWrapper() {
     local original="$1"
     local wrapper="$2"
     local params varName value command separator n fileNames
-    local argv0 flagsBefore flags
+    local argv0 flagsBefore flagsAfter flags
 
     assertExecutable "$original"
 
@@ -126,6 +132,10 @@ makeWrapper() {
             varName="${params[$((n + 1))]}"
             n=$((n + 1))
             echo "unset $varName" >> "$wrapper"
+        elif [[ "$p" == "--chdir" ]]; then
+            dir="${params[$((n + 1))]}"
+            n=$((n + 1))
+            echo "cd ${dir@Q}" >> "$wrapper"
         elif [[ "$p" == "--run" ]]; then
             command="${params[$((n + 1))]}"
             n=$((n + 1))
@@ -157,16 +167,23 @@ makeWrapper() {
             flags="${params[$((n + 1))]}"
             n=$((n + 1))
             flagsBefore="$flagsBefore $flags"
+        elif [[ "$p" == "--append-flags" ]]; then
+            flags="${params[$((n + 1))]}"
+            n=$((n + 1))
+            flagsAfter="$flagsAfter $flags"
         elif [[ "$p" == "--argv0" ]]; then
             argv0="${params[$((n + 1))]}"
             n=$((n + 1))
+        elif [[ "$p" == "--inherit-argv0" ]]; then
+            # Whichever comes last of --argv0 and --inherit-argv0 wins
+            argv0='$0'
         else
             die "makeWrapper doesn't understand the arg $p"
         fi
     done
 
     echo exec ${argv0:+-a \"$argv0\"} \""$original"\" \
-         "$flagsBefore" '"$@"' >> "$wrapper"
+         "$flagsBefore" '"$@"' "$flagsAfter" >> "$wrapper"
 
     chmod +x "$wrapper"
 }
@@ -188,7 +205,8 @@ filterExisting() {
 }
 
 # Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...>
-wrapProgram() {
+wrapProgram() { wrapProgramShell "$@"; }
+wrapProgramShell() {
     local prog="$1"
     local hidden
 
@@ -199,7 +217,5 @@ wrapProgram() {
       hidden="${hidden}_"
     done
     mv "$prog" "$hidden"
-    # Silence warning about unexpanded $0:
-    # shellcheck disable=SC2016
-    makeWrapper "$hidden" "$prog" --argv0 '$0' "${@:2}"
+    makeWrapper "$hidden" "$prog" --inherit-argv0 "${@:2}"
 }
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix b/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix
new file mode 100644
index 000000000000..d0031c93c10c
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix
@@ -0,0 +1,9 @@
+{ callPackage, makeSetupHook }:
+
+(makeSetupHook {
+  name = "postgresql-test-hook";
+} ./postgresql-test-hook.sh).overrideAttrs (o: {
+  passthru.tests = {
+    simple = callPackage ./test.nix { };
+  };
+})
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh b/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh
new file mode 100644
index 000000000000..041a3f565332
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh
@@ -0,0 +1,79 @@
+preCheckHooks+=('postgresqlStart')
+postCheckHooks+=('postgresqlStop')
+
+
+postgresqlStart() {
+
+  # Add default environment variable values
+  #
+  # Client variables:
+  #  - https://www.postgresql.org/docs/current/libpq-envars.html
+  #
+  # Server variables:
+  #  - only PGDATA: https://www.postgresql.org/docs/current/creating-cluster.html
+
+  if [[ "${PGDATA:-}" == "" ]]; then
+    PGDATA="$NIX_BUILD_TOP/postgresql"
+  fi
+  export PGDATA
+
+  if [[ "${PGHOST:-}" == "" ]]; then
+    mkdir -p "$NIX_BUILD_TOP/run/postgresql"
+    PGHOST="$NIX_BUILD_TOP/run/postgresql"
+  fi
+  export PGHOST
+
+  if [[ "${PGUSER:-}" == "" ]]; then
+    PGUSER="test_user"
+  fi
+  export PGUSER
+
+  if [[ "${PGDATABASE:-}" == "" ]]; then
+    PGDATABASE="test_db"
+  fi
+  export PGDATABASE
+
+  if [[ "${postgresqlTestUserOptions:-}" == "" ]]; then
+    postgresqlTestUserOptions="LOGIN"
+  fi
+
+  if [[ "${postgresqlTestSetupSQL:-}" == "" ]]; then
+    postgresqlTestSetupSQL="$(cat <<EOF
+      CREATE ROLE "$PGUSER" $postgresqlTestUserOptions;
+      CREATE DATABASE "$PGDATABASE" OWNER '$PGUSER';
+EOF
+    )"
+  fi
+
+  if [[ "${postgresqlTestSetupCommands:-}" == "" ]]; then
+    postgresqlTestSetupCommands='echo "$postgresqlTestSetupSQL" | PGUSER=postgres psql postgres'
+  fi
+
+  if ! type initdb >/dev/null; then
+    echo >&2 'initdb not found. Did you add postgresql to the checkInputs?'
+    false
+  fi
+  header 'initializing postgresql'
+  initdb -U postgres
+
+  # Move the socket
+  echo "unix_socket_directories = '$NIX_BUILD_TOP/run/postgresql'" >>"$PGDATA/postgresql.conf"
+
+  # TCP ports can be a problem in some sandboxes,
+  # so we disable tcp listening by default
+  if ! [[ "${postgresqlEnableTCP:-}" = 1 ]]; then
+    echo "listen_addresses = ''" >>"$PGDATA/postgresql.conf"
+  fi
+
+  header 'starting postgresql'
+  eval "${postgresqlStartCommands:-pg_ctl start}"
+
+  header 'setting up postgresql'
+  eval "$postgresqlTestSetupCommands"
+
+}
+
+postgresqlStop() {
+  header 'stopping postgresql'
+  pg_ctl stop
+}
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix b/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix
new file mode 100644
index 000000000000..6d8ad6c8c7e3
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix
@@ -0,0 +1,27 @@
+{ postgresql, postgresqlTestHook, stdenv }:
+
+stdenv.mkDerivation {
+  name = "postgresql-test-hook-test";
+  buildInputs = [ postgresqlTestHook ];
+  checkInputs = [ postgresql ];
+  dontUnpack = true;
+  doCheck = true;
+  passAsFile = ["sql"];
+  sql = ''
+    CREATE TABLE hello (
+      message text
+    );
+    INSERT INTO hello VALUES ('it '||'worked');
+    SELECT * FROM hello;
+  '';
+  checkPhase = ''
+    runHook preCheck
+    psql <$sqlPath | grep 'it worked'
+    TEST_RAN=1
+    runHook postCheck
+  '';
+  installPhase = ''
+    [[ $TEST_RAN == 1 ]]
+    touch $out
+  '';
+}
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh b/nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh
index 1a23e6b198ee..593a5f64862d 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh
@@ -1,6 +1,7 @@
 export NIX_SET_BUILD_ID=1
 export NIX_LDFLAGS+=" --compress-debug-sections=zlib"
 export NIX_CFLAGS_COMPILE+=" -ggdb -Wa,--compress-debug-sections"
+export RUSTFLAGS+=" -g"
 dontStrip=1
 
 fixupOutputHooks+=(_separateDebugInfo)
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/strip.sh b/nixpkgs/pkgs/build-support/setup-hooks/strip.sh
index 2d8e66a89fa3..80bc064ced7d 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/strip.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/strip.sh
@@ -7,38 +7,39 @@ _doStrip() {
     # to $out anyways---if it does, that's a bigger problem that a lack of
     # stripping will help catch.
     local -ra flags=(dontStripHost dontStripTarget)
-    local -ra stripCmds=(STRIP TARGET_STRIP)
+    local -ra debugDirs=(stripDebugList stripDebugListTarget)
+    local -ra allDirs=(stripAllList stripAllListTarget)
+    local -ra stripCmds=(STRIP STRIP_FOR_TARGET)
+    local -ra ranlibCmds=(RANLIB RANLIB_FOR_TARGET)
 
-    # Optimization
-    if [[ "${STRIP-}" == "${TARGET_STRIP-}" ]]; then
-        dontStripTarget+=1
-    fi
+    # Strip only host paths by default. Leave targets as is.
+    stripDebugList=${stripDebugList:-lib lib32 lib64 libexec bin sbin}
+    stripDebugListTarget=${stripDebugListTarget:-}
+    stripAllList=${stripAllList:-}
+    stripAllListTarget=${stripAllListTarget:-}
 
     local i
     for i in ${!stripCmds[@]}; do
         local -n flag="${flags[$i]}"
+        local -n debugDirList="${debugDirs[$i]}"
+        local -n allDirList="${allDirs[$i]}"
         local -n stripCmd="${stripCmds[$i]}"
+        local -n ranlibCmd="${ranlibCmds[$i]}"
 
         # `dontStrip` disables them all
         if [[ "${dontStrip-}" || "${flag-}" ]] || ! type -f "${stripCmd-}" 2>/dev/null
         then continue; fi
 
-        stripDebugList=${stripDebugList:-lib lib32 lib64 libexec bin sbin}
-        if [ -n "$stripDebugList" ]; then
-            stripDirs "$stripCmd" "$stripDebugList" "${stripDebugFlags:--S}"
-        fi
-
-        stripAllList=${stripAllList:-}
-        if [ -n "$stripAllList" ]; then
-            stripDirs "$stripCmd" "$stripAllList" "${stripAllFlags:--s}"
-        fi
+        stripDirs "$stripCmd" "$ranlibCmd" "$debugDirList" "${stripDebugFlags:--S}"
+        stripDirs "$stripCmd" "$ranlibCmd" "$allDirList" "${stripAllFlags:--s}"
     done
 }
 
 stripDirs() {
     local cmd="$1"
-    local dirs="$2"
-    local stripFlags="$3"
+    local ranlibCmd="$2"
+    local dirs="$3"
+    local stripFlags="$4"
     local dirsNew=
 
     local d
@@ -50,8 +51,13 @@ stripDirs() {
     dirs=${dirsNew}
 
     if [ -n "${dirs}" ]; then
-        header "stripping (with command $cmd and flags $stripFlags) in$dirs"
+        echo "stripping (with command $cmd and flags $stripFlags) in$dirs"
         find $dirs -type f -exec $cmd $stripFlags '{}' \; 2>/dev/null
-        stopNest
+        # 'strip' does not normally preserve archive index in .a files.
+        # This usually causes linking failures against static libs like:
+        #   ld: ...-i686-w64-mingw32-stage-final-gcc-13.0.0-lib/i686-w64-mingw32/lib/libstdc++.dll.a:
+        #     error adding symbols: archive has no index; run ranlib to add one
+        # Restore the index by running 'ranlib'.
+        find $dirs -name '*.a' -type f -exec $ranlibCmd '{}' \; 2>/dev/null
     fi
 }
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix b/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix
index d0ea088bf71e..d7699b2557fc 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix
+++ b/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix
@@ -59,8 +59,8 @@ makeSetupHook {
         tested = basic;
       in testLib.runTest "basic-contains-dconf" (
         testLib.skip stdenv.isDarwin ''
-          ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GIO_EXTRA_MODULES=" "${dconf.lib}/lib/gio/modules"}
-          ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GIO_EXTRA_MODULES=" "${dconf.lib}/lib/gio/modules"}
+          ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GIO_EXTRA_MODULES" "${dconf.lib}/lib/gio/modules"}
+          ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GIO_EXTRA_MODULES" "${dconf.lib}/lib/gio/modules"}
         ''
       );
 
@@ -98,8 +98,8 @@ makeSetupHook {
       typelib-user-has-gi-typelib-path = let
         tested = typelib-user;
       in testLib.runTest "typelib-user-has-gi-typelib-path" ''
-        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH=" "${typelib-Mahjong}/lib/girepository-1.0"}
-        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH=" "${typelib-Mahjong}/lib/girepository-1.0"}
+        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH" "${typelib-Mahjong}/lib/girepository-1.0"}
+        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH" "${typelib-Mahjong}/lib/girepository-1.0"}
       '';
 
       # Simple derivation containing a gobject-introspection typelib in lib output.
@@ -143,8 +143,8 @@ makeSetupHook {
       typelib-multiout-user-has-gi-typelib-path = let
         tested = typelib-multiout-user;
       in testLib.runTest "typelib-multiout-user-has-gi-typelib-path" ''
-        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH=" "${typelib-Bechamel.lib}/lib/girepository-1.0"}
-        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH=" "${typelib-Bechamel.lib}/lib/girepository-1.0"}
+        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH" "${typelib-Bechamel.lib}/lib/girepository-1.0"}
+        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH" "${typelib-Bechamel.lib}/lib/girepository-1.0"}
       '';
 
       # Simple derivation that contains a typelib as well as a program using it.
@@ -169,8 +169,8 @@ makeSetupHook {
       typelib-self-user-has-gi-typelib-path = let
         tested = typelib-self-user;
       in testLib.runTest "typelib-self-user-has-gi-typelib-path" ''
-        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH=" "${typelib-self-user}/lib/girepository-1.0"}
-        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH=" "${typelib-self-user}/lib/girepository-1.0"}
+        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/bin/foo" "GI_TYPELIB_PATH" "${typelib-self-user}/lib/girepository-1.0"}
+        ${expectSomeLineContainingYInFileXToMentionZ "${tested}/libexec/bar" "GI_TYPELIB_PATH" "${typelib-self-user}/lib/girepository-1.0"}
       '';
     };
   };
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/tests/lib.nix b/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/tests/lib.nix
index 1757bdbbe250..42866c3419dd 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/tests/lib.nix
+++ b/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/tests/lib.nix
@@ -1,5 +1,4 @@
-{ runCommand
-}:
+{ lib, runCommand }:
 
 rec {
   runTest = name: body: runCommand name { } ''
@@ -19,12 +18,14 @@ rec {
   '';
 
   expectSomeLineContainingYInFileXToMentionZ = file: filter: expected: ''
-    if ! cat "${file}" | grep "${filter}"; then
-        ${fail "The file “${file}” should include a line containing “${filter}”."}
+    file=${lib.escapeShellArg file} filter=${lib.escapeShellArg filter} expected=${lib.escapeShellArg expected}
+
+    if ! grep --text --quiet "$filter" "$file"; then
+        ${fail "The file “$file” should include a line containing “$filter”."}
     fi
 
-    if ! cat "${file}" | grep "${filter}" | grep ${expected}; then
-        ${fail "The file “${file}” should include a line containing “${filter}” that also contains “${expected}”."}
+    if ! grep --text "$filter" "$file" | grep --text --quiet "$expected"; then
+        ${fail "The file “$file” should include a line containing “$filter” that also contains “$expected”."}
     fi
   '';
 }
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/wrap-gapps-hook.sh b/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/wrap-gapps-hook.sh
index 1a46e075dbe7..0acf4a8e6f8d 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/wrap-gapps-hook.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/wrap-gapps-hook/wrap-gapps-hook.sh
@@ -14,10 +14,6 @@ gappsWrapperArgsHook() {
         gappsWrapperArgs+=(--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE")
     fi
 
-    if [ -n "$XDG_ICON_DIRS" ]; then
-        gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "$XDG_ICON_DIRS")
-    fi
-
     if [ -n "$GSETTINGS_SCHEMAS_PATH" ]; then
         gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH")
     fi
diff --git a/nixpkgs/pkgs/build-support/skaware/build-skaware-package.nix b/nixpkgs/pkgs/build-support/skaware/build-skaware-package.nix
index cd6519654074..1988d95212c3 100644
--- a/nixpkgs/pkgs/build-support/skaware/build-skaware-package.nix
+++ b/nixpkgs/pkgs/build-support/skaware/build-skaware-package.nix
@@ -22,7 +22,7 @@
 , postInstall
   # : list Maintainer
 , maintainers ? [ ]
-  # : passtrhu arguments (e.g. tests)
+  # : passthru arguments (e.g. tests)
 , passthru ? { }
 
 }:
diff --git a/nixpkgs/pkgs/build-support/src-only/default.nix b/nixpkgs/pkgs/build-support/src-only/default.nix
index c721fdf40c69..b4e373cd058e 100644
--- a/nixpkgs/pkgs/build-support/src-only/default.nix
+++ b/nixpkgs/pkgs/build-support/src-only/default.nix
@@ -7,25 +7,15 @@
 #
 # > srcOnly pkgs.hello
 #
-{ name
-, src
-, stdenv ? orig.stdenv
-, patches ? []
-, # deprecated, use the nativeBuildInputs
-  buildInputs ? []
-, # used to pass extra unpackers
-  nativeBuildInputs ? []
-, # needed when passing an existing derivation
-  ...
-}:
-stdenv.mkDerivation {
-  inherit
-    buildInputs
-    name
-    nativeBuildInputs
-    patches
-    src
-    ;
+attrs:
+let
+  args = if builtins.hasAttr "drvAttrs" attrs then attrs.drvAttrs else attrs;
+  name = if builtins.hasAttr "name" args then args.name else "${args.pname}-${args.version}";
+in
+stdenv.mkDerivation (args // {
+  name = "${name}-source";
   installPhase = "cp -r . $out";
+  outputs = [ "out" ];
+  separateDebugInfo = false;
   phases = ["unpackPhase" "patchPhase" "installPhase"];
-}
+})
diff --git a/nixpkgs/pkgs/build-support/templaterpm/default.nix b/nixpkgs/pkgs/build-support/templaterpm/default.nix
index c98716a3fedb..56c543e8a930 100644
--- a/nixpkgs/pkgs/build-support/templaterpm/default.nix
+++ b/nixpkgs/pkgs/build-support/templaterpm/default.nix
@@ -18,7 +18,7 @@ stdenv.mkDerivation {
 
   meta = with lib; {
     description = "Create templates of nix expressions from RPM .spec files";
-    maintainers = with maintainers; [ tstrobel ];
+    maintainers = with maintainers; [ ];
     platforms = platforms.unix;
     hydraPlatforms = [];
   };
diff --git a/nixpkgs/pkgs/build-support/testers/default.nix b/nixpkgs/pkgs/build-support/testers/default.nix
new file mode 100644
index 000000000000..020352836c89
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/testers/default.nix
@@ -0,0 +1,72 @@
+{ pkgs, lib, callPackage, runCommand, stdenv }:
+# Documentation is in doc/builders/testers.chapter.md
+{
+  testEqualDerivation = callPackage ./test-equal-derivation.nix { };
+
+  testVersion =
+    { package,
+      command ? "${package.meta.mainProgram or package.pname or package.name} --version",
+      version ? package.version,
+    }: runCommand "${package.name}-test-version" { nativeBuildInputs = [ package ]; meta.timeout = 60; } ''
+      if output=$(${command} 2>&1); then
+        if grep -Fw "${version}" - <<< "$output"; then
+          touch $out
+        else
+          echo "Version string '${version}' not found!" >&2
+          echo "The output was:" >&2
+          echo "$output" >&2
+          exit 1
+        fi
+      else
+        echo -n ${lib.escapeShellArg command} >&2
+        echo " returned a non-zero exit code." >&2
+        echo "$output" >&2
+        exit 1
+      fi
+    '';
+
+  # See doc/builders/testers.chapter.md or
+  # https://nixos.org/manual/nixpkgs/unstable/#tester-invalidateFetcherByDrvHash
+  invalidateFetcherByDrvHash = f: args:
+    let
+      drvPath = (f args).drvPath;
+      # It's safe to discard the context, because we don't access the path.
+      salt = builtins.unsafeDiscardStringContext (lib.substring 0 12 (baseNameOf drvPath));
+      # New derivation incorporating the original drv hash in the name
+      salted = f (args // { name = "${args.name or "source"}-salted-${salt}"; });
+      # Make sure we did change the derivation. If the fetcher ignores `name`,
+      # `invalidateFetcherByDrvHash` doesn't work.
+      checked =
+        if salted.drvPath == drvPath
+        then throw "invalidateFetcherByDrvHash: Adding the derivation hash to the fixed-output derivation name had no effect. Make sure the fetcher's name argument ends up in the derivation name. Otherwise, the fetcher will not be re-run when its implementation changes. This is important for testing."
+        else salted;
+    in checked;
+
+  # See doc/builders/testers.chapter.md or
+  # https://nixos.org/manual/nixpkgs/unstable/#tester-invalidateFetcherByDrvHash
+  nixosTest =
+    let
+      /* The nixos/lib/testing-python.nix module, preapplied with arguments that
+       * make sense for this evaluation of Nixpkgs.
+       */
+      nixosTesting =
+        (import ../../../nixos/lib/testing-python.nix {
+          inherit (stdenv.hostPlatform) system;
+          inherit pkgs;
+          extraConfigurations = [(
+            { lib, ... }: {
+              config.nixpkgs.pkgs = lib.mkDefault pkgs;
+            }
+          )];
+        });
+    in
+      test:
+        let
+          loadedTest = if builtins.typeOf test == "path"
+            then import test
+            else test;
+          calledTest = lib.toFunction loadedTest pkgs;
+        in
+          nixosTesting.makeTest calledTest;
+
+}
diff --git a/nixpkgs/pkgs/build-support/test-equal-derivation.nix b/nixpkgs/pkgs/build-support/testers/test-equal-derivation.nix
index 5d2185ce1652..610d5f585576 100644
--- a/nixpkgs/pkgs/build-support/test-equal-derivation.nix
+++ b/nixpkgs/pkgs/build-support/testers/test-equal-derivation.nix
@@ -1,29 +1,12 @@
 { lib, runCommand, emptyFile, nix-diff }:
 
-/*
-  Checks that two packages produce the exact same build instructions.
-
-  This can be used to make sure that a certain difference of configuration,
-  such as the presence of an overlay does not cause a cache miss.
-
-  When the derivations are equal, the return value is an empty file.
-  Otherwise, the build log explains the difference via `nix-diff`.
-
-  Example:
-
-      testEqualDerivation
-        "The hello package must stay the same when enabling checks."
-        hello
-        (hello.overrideAttrs(o: { doCheck = true; }))
-
-*/
 assertion: a: b:
 let
   drvA = builtins.unsafeDiscardOutputDependency a.drvPath or (throw "testEqualDerivation second argument must be a package");
   drvB = builtins.unsafeDiscardOutputDependency b.drvPath or (throw "testEqualDerivation third argument must be a package");
   name =
     if a?name
-    then lib.strings.sanitizeDerivationName "testEqualDerivation-${a.name}"
+    then "testEqualDerivation-${a.name}"
     else "testEqualDerivation";
 in
 if drvA == drvB then
diff --git a/nixpkgs/pkgs/build-support/testers/test/README.md b/nixpkgs/pkgs/build-support/testers/test/README.md
new file mode 100644
index 000000000000..2d6b4bdc43fe
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/testers/test/README.md
@@ -0,0 +1,8 @@
+# Tests _for the testers_
+
+    cd nixpkgs
+    nix-build -A tests.testers
+
+Tests generally derive their own correctness from simplicity, which in the
+case of testers (themselves functions) does not always work out.
+Hence the need for tests that test the testers.
diff --git a/nixpkgs/pkgs/build-support/testers/test/default.nix b/nixpkgs/pkgs/build-support/testers/test/default.nix
new file mode 100644
index 000000000000..30e778cf652e
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/testers/test/default.nix
@@ -0,0 +1,27 @@
+{ testers, lib, pkgs, ... }:
+let
+  pkgs-with-overlay = pkgs.extend(final: prev: {
+    proof-of-overlay-hello = prev.hello;
+  });
+
+  dummyVersioning = {
+    revision = "test";
+    versionSuffix = "test";
+    label = "test";
+  };
+
+in
+lib.recurseIntoAttrs {
+  # Check that the wiring of nixosTest is correct.
+  # Correct operation of the NixOS test driver should be asserted elsewhere.
+  nixosTest-example = pkgs-with-overlay.testers.nixosTest ({ lib, pkgs, figlet, ... }: {
+    name = "nixosTest-test";
+    nodes.machine = { pkgs, ... }: {
+      system.nixos = dummyVersioning;
+      environment.systemPackages = [ pkgs.proof-of-overlay-hello figlet ];
+    };
+    testScript = ''
+      machine.succeed("hello | figlet >/dev/console")
+    '';
+  });
+}
diff --git a/nixpkgs/pkgs/build-support/trivial-builders.nix b/nixpkgs/pkgs/build-support/trivial-builders.nix
index 68f0f1bc4ddc..c889b3865f65 100644
--- a/nixpkgs/pkgs/build-support/trivial-builders.nix
+++ b/nixpkgs/pkgs/build-support/trivial-builders.nix
@@ -10,7 +10,6 @@ rec {
   *
   * Examples:
   * runCommand "name" {envVariable = true;} ''echo hello > $out''
-  * runCommandNoCC "name" {envVariable = true;} ''echo hello > $out'' # equivalent to prior
   * runCommandCC "name" {} ''gcc -o myfile myfile.c; cp myfile $out'';
   *
   * The `*Local` variants force a derivation to be built locally,
@@ -68,10 +67,11 @@ rec {
     # extra arguments to pass to stdenv.mkDerivation
     , name
     # name of the resulting derivation
+    # TODO(@Artturin): enable strictDeps always
     }: buildCommand:
     stdenv.mkDerivation ({
-      name = lib.strings.sanitizeDerivationName name;
-      inherit buildCommand;
+      enableParallelBuilding = true;
+      inherit buildCommand name;
       passAsFile = [ "buildCommand" ]
         ++ (derivationArgs.passAsFile or []);
     }
@@ -121,7 +121,7 @@ rec {
         allowSubstitutes = false;
       }
       ''
-        target=$out${destination}
+        target=$out${lib.escapeShellArg destination}
         mkdir -p "$(dirname "$target")"
 
         if [ -e "$textPath" ]; then
@@ -316,10 +316,10 @@ rec {
       allowSubstitutes = false;
     }
     ''
-    n=$out/bin/$name
-    mkdir -p "$(dirname "$n")"
-    mv "$codePath" code.c
-    $CC -x c code.c -o "$n"
+      n=$out/bin/$name
+      mkdir -p "$(dirname "$n")"
+      mv "$codePath" code.c
+      $CC -x c code.c -o "$n"
     '';
 
 
@@ -478,7 +478,7 @@ rec {
       cd $out
       ${lib.concatMapStrings (x: ''
           mkdir -p "$(dirname ${lib.escapeShellArg x.name})"
-          ln -s ${lib.escapeShellArg x.path} ${lib.escapeShellArg x.name}
+          ln -s ${lib.escapeShellArg "${x.path}"} ${lib.escapeShellArg x.name}
       '') entries}
     '';
 
@@ -516,15 +516,20 @@ rec {
    * # setup hook that depends on the hello package and runs ./myscript.sh
    * myhellohook = makeSetupHook { deps = [ hello ]; } ./myscript.sh;
    *
-   * # wrotes a setup hook where @bash@ myscript.sh is substituted for the
+   * # writes a Linux-exclusive setup hook where @bash@ myscript.sh is substituted for the
    * # bash interpreter.
    * myhellohookSub = makeSetupHook {
    *                 deps = [ hello ];
    *                 substitutions = { bash = "${pkgs.bash}/bin/bash"; };
+   *                 meta.platforms = lib.platforms.linux;
    *               } ./myscript.sh;
    */
-  makeSetupHook = { name ? "hook", deps ? [], substitutions ? {} }: script:
-    runCommand name substitutions
+  makeSetupHook = { name ? "hook", deps ? [], substitutions ? {}, meta ? {} }: script:
+    runCommand name
+      (substitutions // {
+        inherit meta;
+        strictDeps = true;
+      })
       (''
         mkdir -p $out/nix-support
         cp ${script} $out/nix-support/setup-hook
@@ -781,37 +786,4 @@ rec {
     outputHash = "0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5";
     preferLocalBuild = true;
   } "mkdir $out";
-
-  /* Checks the command output contains the specified version
-   *
-   * Although simplistic, this test assures that the main program
-   * can run. While there's no substitute for a real test case,
-   * it does catch dynamic linking errors and such. It also provides
-   * some protection against accidentally building the wrong version,
-   * for example when using an 'old' hash in a fixed-output derivation.
-   *
-   * Examples:
-   *
-   * passthru.tests.version = testVersion { package = hello; };
-   *
-   * passthru.tests.version = testVersion {
-   *   package = seaweedfs;
-   *   command = "weed version";
-   * };
-   *
-   * passthru.tests.version = testVersion {
-   *   package = key;
-   *   command = "KeY --help";
-   *   # Wrong '2.5' version in the code. Drop on next version.
-   *   version = "2.5";
-   * };
-   */
-  testVersion =
-    { package,
-      command ? "${package.meta.mainProgram or package.pname or package.name} --version",
-      version ? package.version,
-    }: runCommand "${package.name}-test-version" { nativeBuildInputs = [ package ]; meta.timeout = 60; } ''
-      ${command} |& grep -Fw ${version}
-      touch $out
-    '';
 }
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/test/references.nix b/nixpkgs/pkgs/build-support/trivial-builders/test/references.nix
index 989722121cb0..3e1eb16eecd0 100644
--- a/nixpkgs/pkgs/build-support/trivial-builders/test/references.nix
+++ b/nixpkgs/pkgs/build-support/trivial-builders/test/references.nix
@@ -1,4 +1,4 @@
-{ lib, nixosTest, pkgs, writeText, hello, figlet, stdenvNoCC }:
+{ lib, testers, pkgs, writeText, hello, figlet, stdenvNoCC }:
 
 # -------------------------------------------------------------------------- #
 #
@@ -22,7 +22,7 @@ let
       lib.attrValues (import file { inherit pkgs; })
     );
 in
-nixosTest {
+testers.nixosTest {
   name = "nixpkgs-trivial-builders";
   nodes.machine = { ... }: {
     virtualisation.writableStore = true;
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix b/nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix
new file mode 100644
index 000000000000..ac83a75fca4a
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix
@@ -0,0 +1,34 @@
+{ writeTextFile }:
+let
+  veryWeirdName = ''here's a name with some "bad" characters, like spaces and quotes'';
+in writeTextFile {
+  name = "weird-names";
+  destination = "/etc/${veryWeirdName}";
+  text = ''passed!'';
+  checkPhase = ''
+    # intentionally hardcode everything here, to make sure
+    # Nix does not mess with file paths
+
+    name="here's a name with some \"bad\" characters, like spaces and quotes"
+    fullPath="$out/etc/$name"
+
+    if [ -f "$fullPath" ]; then
+      echo "[PASS] File exists!"
+    else
+      echo "[FAIL] File was not created at expected path!"
+      exit 1
+    fi
+
+    content=$(<"$fullPath")
+    expected="passed!"
+
+    if [ "$content" = "$expected" ]; then
+      echo "[PASS] Contents match!"
+    else
+      echo "[FAIL] File contents don't match!"
+      echo "       Expected: $expected"
+      echo "       Got:      $content"
+      exit 2
+    fi
+  '';
+}
diff --git a/nixpkgs/pkgs/build-support/vm/default.nix b/nixpkgs/pkgs/build-support/vm/default.nix
index e466ff7ecce8..06e1deb47845 100644
--- a/nixpkgs/pkgs/build-support/vm/default.nix
+++ b/nixpkgs/pkgs/build-support/vm/default.nix
@@ -35,10 +35,10 @@ rec {
       mkdir -p $out/lib
 
       # Copy what we need from Glibc.
-      cp -p ${pkgs.stdenv.glibc.out}/lib/ld-linux*.so.? $out/lib
-      cp -p ${pkgs.stdenv.glibc.out}/lib/libc.so.* $out/lib
-      cp -p ${pkgs.stdenv.glibc.out}/lib/libm.so.* $out/lib
-      cp -p ${pkgs.stdenv.glibc.out}/lib/libresolv.so.* $out/lib
+      cp -p ${pkgs.stdenv.cc.libc}/lib/ld-linux*.so.? $out/lib
+      cp -p ${pkgs.stdenv.cc.libc}/lib/libc.so.* $out/lib
+      cp -p ${pkgs.stdenv.cc.libc}/lib/libm.so.* $out/lib
+      cp -p ${pkgs.stdenv.cc.libc}/lib/libresolv.so.* $out/lib
 
       # Copy BusyBox.
       cp -pd ${pkgs.busybox}/bin/* $out/bin
diff --git a/nixpkgs/pkgs/build-support/writers/default.nix b/nixpkgs/pkgs/build-support/writers/default.nix
index 0fb9bd939a58..3ec1796458d0 100644
--- a/nixpkgs/pkgs/build-support/writers/default.nix
+++ b/nixpkgs/pkgs/build-support/writers/default.nix
@@ -1,7 +1,7 @@
-{ pkgs, config, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gawk, gnused, gixy }:
+{ pkgs, config, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gixy }:
 
 let
-  aliases = if (config.allowAliases or true) then (import ./aliases.nix lib) else prev: {};
+  aliases = if config.allowAliases then (import ./aliases.nix lib) else prev: {};
 
   writers = with lib; rec {
   # Base implementation for non-compiled executables.
@@ -132,12 +132,17 @@ let
     libraries ? [],
     ghc ? pkgs.ghc,
     ghcArgs ? [],
+    threadedRuntime ? true,
     strip ? true
   }:
-    makeBinWriter {
+    let
+      appendIfNotSet = el: list: if elem el list then list else list ++ [ el ];
+      ghcArgs' = if threadedRuntime then appendIfNotSet "-threaded" ghcArgs else ghcArgs;
+
+    in makeBinWriter {
       compileScript = ''
         cp $contentPath tmp.hs
-        ${ghc.withPackages (_: libraries )}/bin/ghc ${lib.escapeShellArgs ghcArgs} tmp.hs
+        ${ghc.withPackages (_: libraries )}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs
         mv tmp $out
       '';
       inherit strip;
@@ -205,7 +210,7 @@ let
   writeNginxConfig = name: text: pkgs.runCommandLocal name {
     inherit text;
     passAsFile = [ "text" ];
-    nativeBuildInputs = [ gawk gnused gixy ];
+    nativeBuildInputs = [ gixy ];
   } /* sh */ ''
     # nginx-config-formatter has an error - https://github.com/1connect/nginx-config-formatter/issues/16
     awk -f ${awkFormatNginx} "$textPath" | sed '/^\s*$/d' > $out