diff --git a/ghc.nix b/ghc.nix
index d52044e0c5f78246566fe16617cc1658fb459c2c..98e7925a01133f143a8f66f1dab827ed4e20ad5a 100644
--- a/ghc.nix
+++ b/ghc.nix
@@ -37,7 +37,6 @@ args@{ system ? builtins.currentSystem
 , wasi-sdk
 , wasmtime
 , crossTarget ? null
-, crossTargetPkgs ? null # a `nixpkgs.pkgsCross` record, e.g. `riscv64`
 , withQEMU ? false
 , withLlvmLit ? false # for llvm lit tests
 }:
@@ -74,105 +73,106 @@ let
     };
   };
 
-  pkgs = import nixpkgs { inherit system; overlays = [ overlay ]; };
-  pkgs-cross = if crossTargetPkgs != null then pkgs.pkgsCross.${crossTargetPkgs} else null;
+  pkgs = let pkgs = import nixpkgs { inherit system; overlays = [ overlay ]; };
+         in if crossTarget == null then pkgs else pkgs.pkgsCross.${crossTarget};
+  inherit (pkgs)
+    lib
+    buildPackages
+    # Packages where the target architecture doesn't matter at all
+    # (eg. doc generators, plain scripts, ripgrep).
+    # We get them from pkgsBuildBuild to avoid binary cache misses.
+    # For example for some reason buildPackages.texlive is different even though
+    # it doesn't produce architecture-specific artifacts.
+    pkgsBuildBuild;
 in
 
-with pkgs;
 
 let
   llvmForGhc =
-    let
-      ps = if crossTarget == null then pkgs else pkgs-cross.buildPackages;
-    in
     if lib.versionAtLeast version "9.1"
-    then ps.llvmPackages_15
-    else ps.llvmPackages_9;
+    then buildPackages.llvmPackages_15
+    else buildPackages.llvmPackages_9;
 
   stdenv =
     if useClang
     then pkgs.clangStdenv
     else pkgs.stdenv;
 
-  crossStdenv =
-    if useClang
-    then pkgs-cross.clangStdenv
-    else pkgs-cross.stdenv;
-
-  noTest = haskell.lib.dontCheck;
+  noTest = pkgs.haskell.lib.dontCheck;
 
-  hspkgs = pkgs.haskell.packages.${bootghc};
+  hspkgs = buildPackages.haskell.packages.${bootghc};
 
   ourtexlive =
-    pkgs.texlive.combine {
-      inherit (pkgs.texlive)
+    pkgsBuildBuild.texlive.combine {
+      inherit (pkgsBuildBuild.texlive)
         scheme-medium collection-xetex fncychap titlesec tabulary varwidth
         framed capt-of wrapfig needspace dejavu-otf helvetic upquote;
     };
-  fonts = pkgs.makeFontsConf { fontDirectories = [ pkgs.dejavu_fonts ]; };
-  docsPackages = if withDocs then [ python3Packages.sphinx ourtexlive ] else [ ];
+  fonts = buildPackages.makeFontsConf { fontDirectories = [ buildPackages.dejavu_fonts ]; };
+  docsPackages = lib.optionals withDocs (with buildPackages; [
+    python3Packages.sphinx
+    ourtexlive
+  ]);
 
   depsSystem = with lib; (
-    [
+    (with buildPackages; [
       autoconf
       automake
       m4
       less
-#      gmp.dev
-#      gmp.out
       glibcLocales
-      ncurses.dev
-      ncurses.out
       perl
       git
       file
       which
       python3
       xorg.lndir # for source distribution generation
+      hlint
+      clang_15
+      gcc
+      lld_15
+    ])
+    ++ (with pkgs; [
+
+      ncurses.dev
+      ncurses.out
       zlib.out
       zlib.dev
-      hlint
-      pkgs-cross.buildPackages.clang_15
-      pkgs-cross.buildPackages.gcc
-      pkgs-cross.buildPackages.lld_15
-    ]
+    ])
     ++ docsPackages
     ++ optional withLlvm llvmForGhc.llvm
-    ++ optional withGrind valgrind
-    ++ optional withEMSDK emscripten
-    ++ optionals withWasm' [ wasi-sdk wasmtime ]
-    ++ optional withNuma numactl
-    ++ optional withDwarf elfutils
-    ++ optional withGhcid ghcid
+    ++ optional withGrind buildPackages.valgrind
+    ++ optional withEMSDK buildPackages.emscripten
+    ++ optionals withWasm' [ buildPackages.wasi-sdk buildPackages.wasmtime ]
+    ++ optional withNuma pkgs.numactl
+    ++ optional withDwarf buildPackages.elfutils
+    ++ optional withGhcid buildPackages.ghcid
     ++ optional withIde hspkgs.haskell-language-server
-    ++ optional withIde clang-tools # N.B. clang-tools for clangd
-    ++ optional withDtrace linuxPackages.systemtap
+    ++ optional withIde buildPackages.clang-tools # N.B. clang-tools for clangd
+    ++ optional withDtrace buildPackages.linuxPackages.systemtap
     ++ optionals withLlvmLit [ lit llvmForGhc.libllvm ]
-    ++ optional withQEMU qemu
-    ++ optionals (crossTargetPkgs != null) [
-      pkgs-cross.gmp.dev
-      pkgs-cross.gmp.out
-      pkgs-cross.libffi.dev
-#      pkgs-cross.glibc.out
-#      pkgs-cross.glibc.dev
-#      pkgs-cross.gcc.cc.libgcc
+    ++ optional withQEMU buildPackages.qemu
+    ++ optionals (crossTarget != null) (with pkgs; [
+      gmp.dev
+      gmp.out
+      libffi.dev
 
-      pkgs-cross.ncurses.dev
-      pkgs-cross.ncurses.out
-    ]
+      ncurses.dev
+      ncurses.out
+    ])
     ++ (if (! stdenv.isDarwin)
-    then [ pxz ]
+    then [ buildPackages.pxz ]
     else [
-      libiconv
-      darwin.libobjc
-      darwin.apple_sdk.frameworks.Foundation
+      pkgs.libiconv
+      pkgs.darwin.libobjc
+      pkgs.darwin.apple_sdk.frameworks.Foundation
     ])
   );
 
   happy =
     if lib.versionAtLeast version "9.1"
     then noTest (hspkgs.callHackage "happy" "1.20.1.1" { })
-    else noTest (haskell.packages.ghc865Binary.callHackage "happy" "1.19.12" { });
+    else noTest (buildPackages.haskell.packages.ghc865Binary.callHackage "happy" "1.19.12" { });
 
   alex =
     if lib.versionAtLeast version "9.1"
@@ -180,8 +180,8 @@ let
     else noTest (hspkgs.callHackage "alex" "3.2.5" { });
 
   # Convenient tools
-  configureGhc = writeShellScriptBin "configure_ghc" "$CONFIGURE $CONFIGURE_ARGS $@";
-  validateGhc = writeShellScriptBin "validate_ghc" "config_args='$CONFIGURE_ARGS' ./validate $@";
+  configureGhc = pkgsBuildBuild.writeShellScriptBin "configure_ghc" "$CONFIGURE $CONFIGURE_ARGS $@";
+  validateGhc = pkgsBuildBuild.writeShellScriptBin "validate_ghc" "config_args='$CONFIGURE_ARGS' ./validate $@";
 
   depsTools = [
     happy
@@ -229,8 +229,8 @@ let
         librarySystemDepends = depsSystem;
       });
 
-  findNoteDef = writeShellScriptBin "find_note_def" ''
-    ret=$(${pkgs.ripgrep}/bin/rg  --no-messages --vimgrep -i --engine pcre2 "^ ?[{\\-#*]* *\QNote [$1]\E\s*$")
+  findNoteDef = pkgsBuildBuild.writeShellScriptBin "find_note_def" ''
+    ret=$(${pkgsBuildBuild.ripgrep}/bin/rg  --no-messages --vimgrep -i --engine pcre2 "^ ?[{\\-#*]* *\QNote [$1]\E\s*$")
     n_defs=$(echo "$ret" | sed '/^$/d' | wc -l)
     while IFS= read -r line; do
       if [[ $line =~ ^([^:]+) ]] ; then
@@ -253,16 +253,16 @@ hspkgs.shellFor rec {
   packages = _pkgset: [ hsdrv ];
   nativeBuildInputs = depsTools;
   buildInputs = depsSystem;
-  passthru.pkgs = pkgs;
+  passthru.pkgs = buildPackages;
 
   hardeningDisable = [ "fortify" ]; ## Effectuated by cc-wrapper
   # Without this, we see a whole bunch of warnings about LANG, LC_ALL and locales in general.
   # In particular, this makes many tests fail because those warnings show up in test outputs too...
   # The solution is from: https://github.com/NixOS/nix/issues/318#issuecomment-52986702
-  LOCALE_ARCHIVE = if stdenv.isLinux then "${glibcLocales}/lib/locale/locale-archive" else "";
+  LOCALE_ARCHIVE = if stdenv.isLinux then "${buildPackages.glibcLocales}/lib/locale/locale-archive" else "";
 
   CONFIGURE_ARGS =
-    if crossTargetPkgs == null then
+    if crossTarget == null then with pkgs;
       [
         "--with-gmp-includes=${gmp.dev}/include"
         "--with-gmp-libraries=${gmp}/lib"
@@ -282,35 +282,35 @@ hspkgs.shellFor rec {
       ]  ++ lib.optionals (crossTarget != null) [
         "--target=${crossTarget}"
       ] else [
-      "--with-gmp-includes=${pkgs-cross.gmp.dev}/include"
-      "--with-gmp-libraries=${pkgs-cross.gmp}/lib"
-      "--with-curses-includes=${pkgs-cross.ncurses.dev}/include"
-      "--with-curses-libraries=${pkgs-cross.ncurses.out}/lib"
-      "--host=${stdenv.hostPlatform.config}"
-      "--target=${crossStdenv.hostPlatform.config}"
+      "--with-gmp-includes=${pkgs.gmp.dev}/include"
+      "--with-gmp-libraries=${pkgs.gmp}/lib"
+      "--with-curses-includes=${pkgs.ncurses.dev}/include"
+      "--with-curses-libraries=${pkgs.ncurses.out}/lib"
+      "--host=${pkgs.buildPlatform.config}"
+      "--target=${pkgs.hostPlatform.config}"
     ];
 
   targetDependentShellHook =
-    if crossTargetPkgs == null then
+    if crossTarget == null then
       ''
         export CC=${stdenv.cc}/bin/cc
       '' else
       let
-        prefix = crossStdenv.cc.targetPrefix;
+        prefix = stdenv.cc.targetPrefix;
       in
       ''
         # somehow, CC gets overridden so we set it again here.
-        export CC=${crossStdenv.cc}/bin/${prefix}cc
-        export CXX=${crossStdenv.cc}/bin/${prefix}c++
-        export AR=${crossStdenv.cc.bintools.bintools}/bin/${prefix}ar
-        export RANLIB=${crossStdenv.cc.bintools.bintools}/bin/${prefix}ranlib
-        export NM=${crossStdenv.cc.bintools.bintools}/bin/${prefix}nm
-        export LD=${crossStdenv.cc.bintools}/bin/${prefix}ld
-        export LD=${pkgs-cross.pkgsCross.riscv64.buildPackages.lld_15}/bin/ld.lld
-        export LLVMAS=${pkgs-cross.pkgsCross.riscv64.buildPackages.clang_15}/bin/${prefix}clang
+        export CC=${stdenv.cc}/bin/${prefix}cc
+        export CXX=${stdenv.cc}/bin/${prefix}c++
+        export AR=${stdenv.cc.bintools.bintools}/bin/${prefix}ar
+        export RANLIB=${stdenv.cc.bintools.bintools}/bin/${prefix}ranlib
+        export NM=${stdenv.cc.bintools.bintools}/bin/${prefix}nm
+        export LD=${stdenv.cc.bintools}/bin/${prefix}ld
+        export LD=${buildPackages.lld_15}/bin/ld.lld
+        export LLVMAS=${buildPackages.clang_15}/bin/${prefix}clang
       '';
 
-  shellHook = ''
+  shellHook = with buildPackages; ''
     export GHC=$NIX_GHC
     export GHCPKG=$NIX_GHCPKG
     export HAPPY=${happy}/bin/happy