about summary refs log tree commit diff
path: root/pkgs/development/compilers/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/compilers/llvm')
-rw-r--r--pkgs/development/compilers/llvm/12/default.nix51
-rw-r--r--pkgs/development/compilers/llvm/12/lldb/gnu-install-dirs.patch19
-rw-r--r--pkgs/development/compilers/llvm/13/default.nix55
-rw-r--r--pkgs/development/compilers/llvm/13/lldb/gnu-install-dirs.patch19
-rw-r--r--pkgs/development/compilers/llvm/14/default.nix42
-rw-r--r--pkgs/development/compilers/llvm/15/default.nix42
-rw-r--r--pkgs/development/compilers/llvm/16/compiler-rt/asan-offset.patch11
-rw-r--r--pkgs/development/compilers/llvm/16/compiler-rt/freebsd-i386.patch21
-rw-r--r--pkgs/development/compilers/llvm/16/default.nix52
-rw-r--r--pkgs/development/compilers/llvm/17/default.nix59
-rw-r--r--pkgs/development/compilers/llvm/17/llvm/gnu-install-dirs.patch8
-rw-r--r--pkgs/development/compilers/llvm/18/default.nix53
-rw-r--r--pkgs/development/compilers/llvm/common/clang-tools/default.nix59
-rwxr-xr-xpkgs/development/compilers/llvm/common/clang-tools/wrapper27
-rw-r--r--pkgs/development/compilers/llvm/common/clang/default.nix32
-rw-r--r--pkgs/development/compilers/llvm/common/compiler-rt/default.nix23
-rw-r--r--pkgs/development/compilers/llvm/common/libcxx/default.nix43
-rw-r--r--pkgs/development/compilers/llvm/common/lld/default.nix2
-rw-r--r--pkgs/development/compilers/llvm/common/lldb.nix2
-rw-r--r--pkgs/development/compilers/llvm/common/lldb/gnu-install-dirs.patch19
-rw-r--r--pkgs/development/compilers/llvm/common/llvm/default.nix93
-rw-r--r--pkgs/development/compilers/llvm/common/mlir/default.nix3
-rw-r--r--pkgs/development/compilers/llvm/git/clang/gnu-install-dirs.patch20
-rw-r--r--pkgs/development/compilers/llvm/git/default.nix57
24 files changed, 534 insertions, 278 deletions
diff --git a/pkgs/development/compilers/llvm/12/default.nix b/pkgs/development/compilers/llvm/12/default.nix
index 82a9d63ab3300..c7c119a45b8ae 100644
--- a/pkgs/development/compilers/llvm/12/default.nix
+++ b/pkgs/development/compilers/llvm/12/default.nix
@@ -1,7 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, substitute, substituteAll, fetchFromGitHub, fetchpatch
-, libxml2, python3, isl, fetchurl, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub, fetchpatch, fetchurl
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -17,29 +17,36 @@
     then null
     else pkgs.bintools
 , darwin
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 let
-  release_version = "12.0.1";
   candidate = ""; # empty or "rcN"
   dash-candidate = lib.optionalString (candidate != "") "-${candidate}";
-  version = "${release_version}${dash-candidate}"; # differentiating these (variables) is important for RCs
 
-  fetch = name: sha256: fetchurl {
-    url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/${name}-${release_version}${candidate}.src.tar.xz";
-    inherit sha256;
+  metadata = rec {
+    release_version = "12.0.1";
+    version = "${release_version}${dash-candidate}"; # differentiating these (variables) is important for RCs
+    inherit (import ../common/common-let.nix { inherit lib release_version; }) llvm_meta;
+    fetch = name: sha256: fetchurl {
+      url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${metadata.version}/${name}-${metadata.release_version}${candidate}.src.tar.xz";
+      inherit sha256;
+    };
+    clang-tools-extra_src = fetch "clang-tools-extra" "1r9a4fdz9ci58b5z2inwvm4z4cdp6scrivnaw05dggkxz7yrwrb5";
   };
 
-  clang-tools-extra_src = fetch "clang-tools-extra" "1r9a4fdz9ci58b5z2inwvm4z4cdp6scrivnaw05dggkxz7yrwrb5";
+  inherit (metadata) fetch;
 
-  inherit (import ../common/common-let.nix { inherit lib release_version; }) llvm_meta;
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake libxml2 python3 isl release_version version fetch buildLlvmTools; });
+    callPackage = newScope (tools // args // metadata);
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
-      ln -s "${cc.lib}/lib/clang/${release_version}/include" "$rsrc"
+      ln -s "${cc.lib}/lib/clang/${metadata.release_version}/include" "$rsrc"
       echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
     '';
     mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
@@ -104,7 +111,6 @@ let
       pollyPatches = [
         ./llvm/gnu-install-dirs-polly.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -122,7 +128,6 @@ let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit clang-tools-extra_src llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -144,6 +149,9 @@ let
     #   python3 = pkgs.python3;  # don't use python-boot
     # });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.libc == null then tools.clangNoLibc
@@ -175,7 +183,6 @@ let
       patches = [
         ./lld/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
       inherit (libraries) libunwind;
     };
 
@@ -196,7 +203,6 @@ let
           resourceDirPatch
           ./lldb/gnu-install-dirs.patch
         ];
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -287,7 +293,7 @@ let
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python3 isl release_version version fetch; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata);
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -306,7 +312,6 @@ let
         ../common/compiler-rt/armv6-sync-ops-no-thumb.patch
         ../common/compiler-rt/armv6-no-ldrexd-strexd.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -328,7 +333,6 @@ let
         ../common/compiler-rt/armv6-sync-ops-no-thumb.patch
         ../common/compiler-rt/armv6-no-ldrexd-strexd.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -347,7 +351,7 @@ let
       src = fetchFromGitHub {
         owner = "llvm";
         repo = "llvm-project";
-        rev = "refs/tags/llvmorg-${version}";
+        rev = "refs/tags/llvmorg-${metadata.version}";
         sparseCheckout = [
           "libcxx"
           "libcxxabi"
@@ -372,7 +376,6 @@ let
           ];
         })
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -381,7 +384,6 @@ let
       patches = [
         ./libunwind/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -394,9 +396,8 @@ let
           hash = "sha256-UxIlAifXnexF/MaraPW0Ut6q+sf3e7y1fMdEv1q103A=";
         })
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)
diff --git a/pkgs/development/compilers/llvm/12/lldb/gnu-install-dirs.patch b/pkgs/development/compilers/llvm/12/lldb/gnu-install-dirs.patch
index afc945ce26147..9a4d2b272acbe 100644
--- a/pkgs/development/compilers/llvm/12/lldb/gnu-install-dirs.patch
+++ b/pkgs/development/compilers/llvm/12/lldb/gnu-install-dirs.patch
@@ -89,3 +89,22 @@ index b5633e2..86e4738 100644
    endif()
    get_target_property(lldb_python_bindings_dir swig_wrapper_python BINARY_DIR)
    finish_swig_python("lldb-python" "${lldb_python_bindings_dir}" "${lldb_python_target_dir}")
+diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
+index b5633e2..86e4738 100644
+--- a/source/API/CMakeLists.txt	2024-05-30 19:08:14.241656491 -0700
++++ b/source/API/CMakeLists.txt	2024-05-30 19:08:48.218219667 -0700
+@@ -113,14 +113,6 @@
+   ${option_install_prefix}
+ )
+ 
+-# lib/pythonX.Y/dist-packages/lldb/_lldb.so is a symlink to lib/liblldb.so,
+-# which depends on lib/libLLVM*.so (BUILD_SHARED_LIBS) or lib/libLLVM-10git.so
+-# (LLVM_LINK_LLVM_DYLIB). Add an additional rpath $ORIGIN/../../../../lib so
+-# that _lldb.so can be loaded from Python.
+-if(LLDB_ENABLE_PYTHON AND (BUILD_SHARED_LIBS OR LLVM_LINK_LLVM_DYLIB) AND UNIX AND NOT APPLE)
+-  set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "\$ORIGIN/../../../../lib${LLVM_LIBDIR_SUFFIX}")
+-endif()
+-
+ if(Python3_RPATH)
+   set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "${Python3_RPATH}")
+   set_property(TARGET liblldb APPEND PROPERTY BUILD_RPATH   "${Python3_RPATH}")
diff --git a/pkgs/development/compilers/llvm/13/default.nix b/pkgs/development/compilers/llvm/13/default.nix
index 9348e19e6de39..ffbbe1deb0d4e 100644
--- a/pkgs/development/compilers/llvm/13/default.nix
+++ b/pkgs/development/compilers/llvm/13/default.nix
@@ -1,7 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, fetchpatch
-, libxml2, python3, isl, fetchFromGitHub, substitute, substituteAll, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub, fetchpatch
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -40,8 +40,11 @@
 # to you to make sure that the LLVM repo given matches the release configuration
 # specified.
 , monorepoSrc ? null
-
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 assert
   lib.assertMsg
@@ -53,19 +56,23 @@ assert
 let
   monorepoSrc' = monorepoSrc;
 in let
-  # Import releaseInfo separately to avoid infinite recursion
-  inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
-  inherit (releaseInfo) release_version version;
-  inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
-
-  src = monorepoSrc;
+  metadata = rec {
+    # Import releaseInfo separately to avoid infinite recursion
+    inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
+    inherit (releaseInfo) release_version version;
+    inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+    src = monorepoSrc;
+  };
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake libxml2 python3 isl release_version version src buildLlvmTools; });
+    callPackage = newScope (tools // args // metadata
+      # Previously monorepoSrc was erroneously not being passed through.
+      // { monorepoSrc = null; } # Preserve a bug during #307211, TODO: remove; causes llvm 13 rebuild.
+    );
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
-      ln -s "${cc.lib}/lib/clang/${release_version}/include" "$rsrc"
+      ln -s "${cc.lib}/lib/clang/${metadata.release_version}/include" "$rsrc"
       echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
     '';
     mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
@@ -125,7 +132,6 @@ in let
       pollyPatches = [
         ./llvm/gnu-install-dirs-polly.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -148,7 +154,6 @@ in let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -169,6 +174,9 @@ in let
     #   python3 = pkgs.python3;  # don't use python-boot
     # });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.libc == null then tools.clangNoLibc
@@ -199,7 +207,6 @@ in let
       patches = [
         ./lld/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
     };
 
     lldb = callPackage ../common/lldb.nix {
@@ -232,7 +239,6 @@ in let
             && !stdenv.targetPlatform.isAarch64
             && (lib.versionOlder darwin.apple_sdk.sdk.version "11.0")
         ) ./lldb/cpu_subtype_arm64e_replacement.patch;
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -323,7 +329,10 @@ in let
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python3 isl release_version version src; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata
+      # Previously monorepoSrc was erroneously not being passed through.
+      // { monorepoSrc = null; } # Preserve a bug during #307211, TODO: remove; causes llvm 13 rebuild.
+    );
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -344,7 +353,6 @@ in let
         ../common/compiler-rt/armv6-scudo-no-yield.patch
         ../common/compiler-rt/armv6-scudo-libatomic.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -368,7 +376,6 @@ in let
         ../common/compiler-rt/armv6-scudo-no-yield.patch
         ../common/compiler-rt/armv6-scudo-libatomic.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -399,16 +406,15 @@ in let
           ];
         })
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
-      monorepoSrc = src;
+      # TODO: remove this, causes LLVM 13 packages rebuild.
+      inherit (metadata) monorepoSrc; # Preserve bug during #307211 refactor.
     };
 
     libunwind = callPackage ../common/libunwind {
       patches = [
         ./libunwind/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -420,9 +426,8 @@ in let
           hash = "sha256-UxIlAifXnexF/MaraPW0Ut6q+sf3e7y1fMdEv1q103A=";
         })
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)
diff --git a/pkgs/development/compilers/llvm/13/lldb/gnu-install-dirs.patch b/pkgs/development/compilers/llvm/13/lldb/gnu-install-dirs.patch
index afc945ce26147..eba6fbabac626 100644
--- a/pkgs/development/compilers/llvm/13/lldb/gnu-install-dirs.patch
+++ b/pkgs/development/compilers/llvm/13/lldb/gnu-install-dirs.patch
@@ -89,3 +89,22 @@ index b5633e2..86e4738 100644
    endif()
    get_target_property(lldb_python_bindings_dir swig_wrapper_python BINARY_DIR)
    finish_swig_python("lldb-python" "${lldb_python_bindings_dir}" "${lldb_python_target_dir}")
+diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
+index b5633e2..86e4738 100644
+--- a/source/API/CMakeLists.txt	2024-05-30 21:38:39.829955586 -0700
++++ b/source/API/CMakeLists.txt	2024-05-30 21:38:48.015673758 -0700
+@@ -112,14 +112,6 @@
+   ${option_install_prefix}
+ )
+ 
+-# lib/pythonX.Y/dist-packages/lldb/_lldb.so is a symlink to lib/liblldb.so,
+-# which depends on lib/libLLVM*.so (BUILD_SHARED_LIBS) or lib/libLLVM-10git.so
+-# (LLVM_LINK_LLVM_DYLIB). Add an additional rpath $ORIGIN/../../../../lib so
+-# that _lldb.so can be loaded from Python.
+-if(LLDB_ENABLE_PYTHON AND (BUILD_SHARED_LIBS OR LLVM_LINK_LLVM_DYLIB) AND UNIX AND NOT APPLE)
+-  set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "\$ORIGIN/../../../../lib${LLVM_LIBDIR_SUFFIX}")
+-endif()
+-
+ if(Python3_RPATH)
+   set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "${Python3_RPATH}")
+   set_property(TARGET liblldb APPEND PROPERTY BUILD_RPATH   "${Python3_RPATH}")
diff --git a/pkgs/development/compilers/llvm/14/default.nix b/pkgs/development/compilers/llvm/14/default.nix
index f7368050d6149..06972af065c98 100644
--- a/pkgs/development/compilers/llvm/14/default.nix
+++ b/pkgs/development/compilers/llvm/14/default.nix
@@ -1,6 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, libxml2, python3, fetchFromGitHub, substitute, substituteAll, fetchpatch, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub, fetchpatch
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -39,7 +40,11 @@
 # to you to make sure that the LLVM repo given matches the release configuration
 # specified.
 , monorepoSrc ? null
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 assert
   lib.assertMsg
@@ -51,17 +56,20 @@ assert
 let
   monorepoSrc' = monorepoSrc;
 in let
-  # Import releaseInfo separately to avoid infinite recursion
-  inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
-  inherit (releaseInfo) release_version version;
-  inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+
+  metadata = rec {
+    # Import releaseInfo separately to avoid infinite recursion
+    inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
+    inherit (releaseInfo) release_version version;
+    inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  };
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake libxml2 python3 release_version version monorepoSrc buildLlvmTools; });
+    callPackage = newScope (tools // args // metadata);
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
-      ln -s "${cc.lib}/lib/clang/${release_version}/include" "$rsrc"
+      ln -s "${cc.lib}/lib/clang/${metadata.release_version}/include" "$rsrc"
       echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
     '';
     mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
@@ -100,7 +108,6 @@ in let
       pollyPatches = [
         ./llvm/gnu-install-dirs-polly.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -118,7 +125,6 @@ in let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -139,6 +145,9 @@ in let
     #   python3 = pkgs.python3;  # don't use python-boot
     # });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.libc == null then tools.clangNoLibc
@@ -170,7 +179,6 @@ in let
         ./lld/gnu-install-dirs.patch
         ./lld/fix-root-src-dir.patch
       ];
-      inherit llvm_meta;
     };
 
     lldb = callPackage ../common/lldb.nix {
@@ -203,7 +211,6 @@ in let
             && !stdenv.targetPlatform.isAarch64
             && (lib.versionOlder darwin.apple_sdk.sdk.version "11.0")
         ) ./lldb/cpu_subtype_arm64e_replacement.patch;
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -296,7 +303,7 @@ in let
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python3 release_version version monorepoSrc; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata);
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -318,7 +325,6 @@ in let
         ../common/compiler-rt/armv6-scudo-no-yield.patch
         ../common/compiler-rt/armv6-scudo-libatomic.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -343,7 +349,6 @@ in let
         ../common/compiler-rt/armv6-scudo-no-yield.patch
         ../common/compiler-rt/armv6-scudo-libatomic.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -374,7 +379,6 @@ in let
           ];
         })
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -382,7 +386,6 @@ in let
       patches = [
         ./libunwind/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -391,9 +394,8 @@ in let
         ./openmp/gnu-install-dirs.patch
         ./openmp/run-lit-directly.patch
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)
diff --git a/pkgs/development/compilers/llvm/15/default.nix b/pkgs/development/compilers/llvm/15/default.nix
index 5003ef32d1ee0..e50e35b2c4eb0 100644
--- a/pkgs/development/compilers/llvm/15/default.nix
+++ b/pkgs/development/compilers/llvm/15/default.nix
@@ -1,6 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake, ninja
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, libxml2, python3, fetchFromGitHub, fetchpatch, substitute, substituteAll, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub, fetchpatch
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -39,7 +40,11 @@
 # to you to make sure that the LLVM repo given matches the release configuration
 # specified.
 , monorepoSrc ? null
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 assert
   lib.assertMsg
@@ -51,10 +56,13 @@ assert
 let
   monorepoSrc' = monorepoSrc;
 in let
-  # Import releaseInfo separately to avoid infinite recursion
-  inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
-  inherit (releaseInfo) release_version version;
-  inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+
+  metadata = rec {
+    # Import releaseInfo separately to avoid infinite recursion
+    inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
+    inherit (releaseInfo) release_version version;
+    inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  };
 
   lldbPlugins = lib.makeExtensible (lldbPlugins: let
     callPackage = newScope (lldbPlugins // { inherit stdenv; inherit (tools) lldb; });
@@ -63,11 +71,11 @@ in let
   });
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc buildLlvmTools; });
+    callPackage = newScope (tools // args // metadata);
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
-      ln -s "${cc.lib}/lib/clang/${release_version}/include" "$rsrc"
+      ln -s "${cc.lib}/lib/clang/${metadata.release_version}/include" "$rsrc"
       echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
     '';
     mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
@@ -144,7 +152,6 @@ in let
         # Just like the `llvm-lit-cfg` patch, but for `polly`.
         ./llvm/polly-lit-cfg-add-libs-to-dylib-path.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -162,7 +169,6 @@ in let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -182,6 +188,9 @@ in let
       python3 = pkgs.python3;  # don't use python-boot
     });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.libc == null then tools.clangNoLibc
@@ -212,7 +221,6 @@ in let
       patches = [
         ./lld/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
     };
 
     lldb = callPackage ../common/lldb.nix {
@@ -245,7 +253,6 @@ in let
             && !stdenv.targetPlatform.isAarch64
             && (lib.versionOlder darwin.apple_sdk.sdk.version "11.0")
         ) ./lldb/cpu_subtype_arm64e_replacement.patch;
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -348,7 +355,7 @@ in let
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata);
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -365,7 +372,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -385,7 +391,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -427,7 +432,6 @@ in let
           ];
         })
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -435,7 +439,6 @@ in let
       patches = [
         ./libunwind/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -445,9 +448,8 @@ in let
         ./openmp/gnu-install-dirs.patch
         ./openmp/run-lit-directly.patch
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version lldbPlugins; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries lldbPlugins; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)
diff --git a/pkgs/development/compilers/llvm/16/compiler-rt/asan-offset.patch b/pkgs/development/compilers/llvm/16/compiler-rt/asan-offset.patch
new file mode 100644
index 0000000000000..46afe5c007347
--- /dev/null
+++ b/pkgs/development/compilers/llvm/16/compiler-rt/asan-offset.patch
@@ -0,0 +1,11 @@
+--- a/lib/asan/CMakeLists.txt        2022-06-22 16:46:24.000000000 +0000
++++ b/lib/asan/CMakeLists.txt
+@@ -46,7 +46,7 @@ set(ASAN_STATIC_SOURCES
+   asan_rtl_static.cpp
+   )
+ 
+-if (NOT WIN32 AND NOT APPLE)
++if (LINUX)
+   list(APPEND ASAN_STATIC_SOURCES
+     asan_rtl_x86_64.S
+   )
diff --git a/pkgs/development/compilers/llvm/16/compiler-rt/freebsd-i386.patch b/pkgs/development/compilers/llvm/16/compiler-rt/freebsd-i386.patch
new file mode 100644
index 0000000000000..0a221750552a0
--- /dev/null
+++ b/pkgs/development/compilers/llvm/16/compiler-rt/freebsd-i386.patch
@@ -0,0 +1,21 @@
+--- a/lib/builtins/fp_lib.h	1969-12-31 16:00:01.000000000 -0800
++++ b/lib/builtins/fp_lib.h	2023-12-21 23:39:36.066927293 -0800
+@@ -26,18 +26,6 @@
+ #include <stdbool.h>
+ #include <stdint.h>
+ 
+-// x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in
+-// 32-bit mode.
+-#if defined(__FreeBSD__) && defined(__i386__)
+-#include <sys/param.h>
+-#if __FreeBSD_version < 903000 // v9.3
+-#define uint64_t unsigned long long
+-#define int64_t long long
+-#undef UINT64_C
+-#define UINT64_C(c) (c##ULL)
+-#endif
+-#endif
+-
+ #if defined SINGLE_PRECISION
+ 
+ typedef uint16_t half_rep_t;
diff --git a/pkgs/development/compilers/llvm/16/default.nix b/pkgs/development/compilers/llvm/16/default.nix
index 79d5f8589044c..80b2424b14cc0 100644
--- a/pkgs/development/compilers/llvm/16/default.nix
+++ b/pkgs/development/compilers/llvm/16/default.nix
@@ -1,6 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake, ninja
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, libxml2, python3, fetchFromGitHub, substituteAll, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -39,7 +40,11 @@
 # to you to make sure that the LLVM repo given matches the release configuration
 # specified.
 , monorepoSrc ? null
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 assert
   lib.assertMsg
@@ -51,10 +56,13 @@ assert
 let
   monorepoSrc' = monorepoSrc;
 in let
-  # Import releaseInfo separately to avoid infinite recursion
-  inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
-  inherit (releaseInfo) release_version version;
-  inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+
+  metadata = rec {
+    # Import releaseInfo separately to avoid infinite recursion
+    inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
+    inherit (releaseInfo) release_version version;
+    inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  };
 
   lldbPlugins = lib.makeExtensible (lldbPlugins: let
     callPackage = newScope (lldbPlugins // { inherit stdenv; inherit (tools) lldb; });
@@ -63,8 +71,8 @@ in let
   });
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc buildLlvmTools; });
-    major = lib.versions.major release_version;
+    callPackage = newScope (tools // args // metadata);
+    major = lib.versions.major metadata.release_version;
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
@@ -138,7 +146,6 @@ in let
         # Just like the `llvm-lit-cfg` patch, but for `polly`.
         ./llvm/polly-lit-cfg-add-libs-to-dylib-path.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -156,7 +163,6 @@ in let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -176,6 +182,9 @@ in let
       python3 = pkgs.python3;  # don't use python-boot
     });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.useLLVM or false then tools.clangUseLLVM
@@ -206,15 +215,12 @@ in let
         ./lld/gnu-install-dirs.patch
         ./lld/add-table-base.patch
       ];
-      inherit llvm_meta;
     };
 
-    mlir = callPackage ../common/mlir {
-      inherit llvm_meta;
-    };
+    mlir = callPackage ../common/mlir {};
 
     lldb = callPackage ../common/lldb.nix {
-      src = callPackage ({ runCommand }: runCommand "lldb-src-${version}" {} ''
+      src = callPackage ({ runCommand }: runCommand "lldb-src-${metadata.version}" {} ''
         mkdir -p "$out"
         cp -r ${monorepoSrc}/cmake "$out"
         cp -r ${monorepoSrc}/lldb "$out"
@@ -248,7 +254,6 @@ in let
             && !stdenv.targetPlatform.isAarch64
             && (lib.versionOlder darwin.apple_sdk.sdk.version "11.0")
         ) ./lldb/cpu_subtype_arm64e_replacement.patch;
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -351,13 +356,11 @@ in let
     # Has to be in tools despite mostly being a library,
     # because we use a native helper executable from a
     # non-cross build in cross builds.
-    libclc = callPackage ../common/libclc.nix {
-      inherit buildLlvmTools;
-    };
+    libclc = callPackage ../common/libclc.nix {};
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata);
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -374,7 +377,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false || (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isStatic)
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -394,7 +396,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -413,7 +414,6 @@ in let
     # so: we use the clang from this LLVM package set instead of the regular
     # stdenv's compiler.
     libcxx = callPackage ../common/libcxx {
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -421,7 +421,6 @@ in let
       patches = [
         ./libunwind/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -431,9 +430,8 @@ in let
         ./openmp/gnu-install-dirs.patch
         ./openmp/run-lit-directly.patch
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version lldbPlugins; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries lldbPlugins; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)
diff --git a/pkgs/development/compilers/llvm/17/default.nix b/pkgs/development/compilers/llvm/17/default.nix
index b4039540badf4..f23dd19507dfe 100644
--- a/pkgs/development/compilers/llvm/17/default.nix
+++ b/pkgs/development/compilers/llvm/17/default.nix
@@ -1,6 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake, ninja
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, libxml2, python3, fetchFromGitHub, fetchpatch, substituteAll, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub, fetchpatch
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -39,7 +40,11 @@
 # to you to make sure that the LLVM repo given matches the release configuration
 # specified.
 , monorepoSrc ? null
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 assert
   lib.assertMsg
@@ -51,15 +56,17 @@ assert
 let
   monorepoSrc' = monorepoSrc;
 in let
-  inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
 
-  inherit (releaseInfo) release_version version;
-
-  inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  metadata = rec {
+    # Import releaseInfo separately to avoid infinite recursion
+    inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
+    inherit (releaseInfo) release_version version;
+    inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub gitRelease release_version officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  };
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc buildLlvmTools; });
-    major = lib.versions.major release_version;
+    callPackage = newScope (tools // args // metadata);
+    major = lib.versions.major metadata.release_version;
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
@@ -126,6 +133,14 @@ in let
         # It's not clear to me why this isn't an issue for LLVM developers running
         # on macOS (nothing about this _seems_ nix specific)..
         ./llvm/lit-shell-script-runner-set-dyld-library-path.patch
+
+        # resolves https://github.com/llvm/llvm-project/issues/75168
+        (fetchpatch {
+          name = "fix-fzero-call-used-regs.patch";
+          url = "https://github.com/llvm/llvm-project/commit/f800c1f3b207e7bcdc8b4c7192928d9a078242a0.patch";
+          stripLen = 1;
+          hash = "sha256-e8YKrMy2rGcSJGC6er2V66cOnAnI+u1/yImkvsRsmg8=";
+        })
       ];
       pollyPatches = [
         ./llvm/gnu-install-dirs-polly.patch
@@ -133,7 +148,6 @@ in let
         # Just like the `llvm-lit-cfg` patch, but for `polly`.
         ./llvm/polly-lit-cfg-add-libs-to-dylib-path.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -151,7 +165,6 @@ in let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -171,6 +184,9 @@ in let
       python3 = pkgs.python3;  # don't use python-boot
     });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.useLLVM or false then tools.clangUseLLVM
@@ -201,15 +217,12 @@ in let
         ./lld/gnu-install-dirs.patch
         ./lld/add-table-base.patch
       ];
-      inherit llvm_meta;
     };
 
-    mlir = callPackage ../common/mlir {
-      inherit llvm_meta;
-    };
+    mlir = callPackage ../common/mlir {};
 
     lldb = callPackage ../common/lldb.nix {
-      src = callPackage ({ runCommand }: runCommand "lldb-src-${version}" {} ''
+      src = callPackage ({ runCommand }: runCommand "lldb-src-${metadata.version}" {} ''
         mkdir -p "$out"
         cp -r ${monorepoSrc}/cmake "$out"
         cp -r ${monorepoSrc}/lldb "$out"
@@ -233,7 +246,6 @@ in let
             && !stdenv.targetPlatform.isAarch64
             && (lib.versionOlder darwin.apple_sdk.sdk.version "11.0")
         ) ./lldb/cpu_subtype_arm64e_replacement.patch;
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -336,13 +348,11 @@ in let
     # Has to be in tools despite mostly being a library,
     # because we use a native helper executable from a
     # non-cross build in cross builds.
-    libclc = callPackage ../common/libclc.nix {
-      inherit buildLlvmTools;
-    };
+    libclc = callPackage ../common/libclc.nix {};
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata);
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -359,7 +369,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false || (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isStatic)
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -379,7 +388,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -406,12 +414,10 @@ in let
           hash = "sha256-jo+DYA6zuSv9OH3A0bYwY5TlkWprup4OKQ7rfK1WHBI=";
         })
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
     libunwind = callPackage ../common/libunwind {
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -421,9 +427,8 @@ in let
         ./openmp/gnu-install-dirs.patch
         ./openmp/run-lit-directly.patch
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)
diff --git a/pkgs/development/compilers/llvm/17/llvm/gnu-install-dirs.patch b/pkgs/development/compilers/llvm/17/llvm/gnu-install-dirs.patch
index e2122ebf603d9..eb9f6098d1c9a 100644
--- a/pkgs/development/compilers/llvm/17/llvm/gnu-install-dirs.patch
+++ b/pkgs/development/compilers/llvm/17/llvm/gnu-install-dirs.patch
@@ -72,8 +72,8 @@ index 230620c37027..dd16cab1835e 100644
 +    # As noted in the differential above, an alternative solution is to have
 +    # all rdeps of nixpkgs' LLVM (that use the AddLLVM.cmake machinery) set
 +    # `CMAKE_INSTALL_RPATH`.
-+    set(_build_rpath "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
-+    set(_install_rpath "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
++    set(_build_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
++    set(_install_rpath ${extra_libdir})
      if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
        set_property(TARGET ${name} APPEND_STRING PROPERTY
                     LINK_FLAGS " -Wl,-z,origin ")
@@ -86,10 +86,10 @@ index 891c9e6d618c..8d963f3b0069 100644
  
    if( APPLE )
 -    set(ocaml_rpath "@executable_path/../../../lib${LLVM_LIBDIR_SUFFIX}")
-+    set(ocaml_rpath "@executable_path/../../../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}")
++    set(ocaml_rpath "${LLVM_LIBRARY_DIR}")
    elseif( UNIX )
 -    set(ocaml_rpath "\\$ORIGIN/../../../lib${LLVM_LIBDIR_SUFFIX}")
-+    set(ocaml_rpath "\\$ORIGIN/../../../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}")
++    set(ocaml_rpath "${LLVM_LIBRARY_DIR}")
    endif()
    list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}")
  
diff --git a/pkgs/development/compilers/llvm/18/default.nix b/pkgs/development/compilers/llvm/18/default.nix
index ea5323db9b0f3..25ecfb3a4c907 100644
--- a/pkgs/development/compilers/llvm/18/default.nix
+++ b/pkgs/development/compilers/llvm/18/default.nix
@@ -1,6 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake, ninja
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, libxml2, python3, fetchFromGitHub, substituteAll, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -25,7 +26,7 @@
   #   rev-version = /* human readable version; i.e. "unstable-2022-26-07" */;
   #   sha256 = /* checksum for this release, can omit if specifying your own `monorepoSrc` */;
   # }
-, officialRelease ? { version = "18.1.4"; sha256 = "sha256-LyQEb4ZJXm2hkPOM9XITIploMT2VKIQWxUFio7SXrc0="; }
+, officialRelease ? { version = "18.1.8"; sha256 = "sha256-iiZKMRo/WxJaBXct9GdAcAT3cz9d9pnAcO1mmR6oPNE="; }
   # i.e.:
   # {
   #   version = /* i.e. "15.0.0" */;
@@ -39,7 +40,11 @@
 # to you to make sure that the LLVM repo given matches the release configuration
 # specified.
 , monorepoSrc ? null
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 assert
   lib.assertMsg
@@ -51,15 +56,17 @@ assert
 let
   monorepoSrc' = monorepoSrc;
 in let
-  inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
 
-  inherit (releaseInfo) release_version version;
-
-  inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  metadata = rec {
+    # Import releaseInfo separately to avoid infinite recursion
+    inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
+    inherit (releaseInfo) release_version version;
+    inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub gitRelease release_version officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  };
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc buildLlvmTools; });
-    major = lib.versions.major release_version;
+    callPackage = newScope (tools // args // metadata);
+    major = lib.versions.major metadata.release_version;
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
@@ -133,7 +140,6 @@ in let
         # Just like the `llvm-lit-cfg` patch, but for `polly`.
         ./llvm/polly-lit-cfg-add-libs-to-dylib-path.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -151,7 +157,6 @@ in let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -171,6 +176,9 @@ in let
       python3 = pkgs.python3;  # don't use python-boot
     });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.useLLVM or false then tools.clangUseLLVM
@@ -200,15 +208,12 @@ in let
       patches = [
         ./lld/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
     };
 
-    mlir = callPackage ../common/mlir {
-      inherit llvm_meta;
-    };
+    mlir = callPackage ../common/mlir {};
 
     lldb = callPackage ../common/lldb.nix {
-      src = callPackage ({ runCommand }: runCommand "lldb-src-${version}" {} ''
+      src = callPackage ({ runCommand }: runCommand "lldb-src-${metadata.version}" {} ''
         mkdir -p "$out"
         cp -r ${monorepoSrc}/cmake "$out"
         cp -r ${monorepoSrc}/lldb "$out"
@@ -232,7 +237,6 @@ in let
             && !stdenv.targetPlatform.isAarch64
             && (lib.versionOlder darwin.apple_sdk.sdk.version "11.0")
         ) ./lldb/cpu_subtype_arm64e_replacement.patch;
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -335,13 +339,11 @@ in let
     # Has to be in tools despite mostly being a library,
     # because we use a native helper executable from a
     # non-cross build in cross builds.
-    libclc = callPackage ../common/libclc.nix {
-      inherit buildLlvmTools;
-    };
+    libclc = callPackage ../common/libclc.nix {};
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata);
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -355,7 +357,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false || (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isStatic)
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -372,7 +373,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -395,12 +395,10 @@ in let
         # https://github.com/llvm/llvm-project/issues/64226
         ./libcxx/0001-darwin-10.12-mbstate_t-fix.patch
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
     libunwind = callPackage ../common/libunwind {
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -409,9 +407,8 @@ in let
         ./openmp/fix-find-tool.patch
         ./openmp/run-lit-directly.patch
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)
diff --git a/pkgs/development/compilers/llvm/common/clang-tools/default.nix b/pkgs/development/compilers/llvm/common/clang-tools/default.nix
new file mode 100644
index 0000000000000..7ecf0c5c431de
--- /dev/null
+++ b/pkgs/development/compilers/llvm/common/clang-tools/default.nix
@@ -0,0 +1,59 @@
+{
+  lib,
+  stdenv,
+  clang-unwrapped,
+  clang,
+  libcxxClang,
+  llvm_meta,
+  # enableLibcxx will use the c++ headers from clang instead of gcc.
+  # This shouldn't have any effect on platforms that use clang as the default compiler already.
+  enableLibcxx ? false,
+}:
+
+stdenv.mkDerivation {
+  unwrapped = clang-unwrapped;
+
+  pname = "clang-tools";
+  version = lib.getVersion clang-unwrapped;
+  dontUnpack = true;
+  clang = if enableLibcxx then libcxxClang else clang;
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out/bin
+
+    for tool in $unwrapped/bin/clang-*; do
+      tool=$(basename "$tool")
+
+      # Compilers have their own derivation, no need to include them here:
+      if [[ $tool == "clang-cl" || $tool == "clang-cpp" ]]; then
+        continue
+      fi
+
+      # Clang's derivation produces a lot of binaries, but the tools we are
+      # interested in follow the `clang-something` naming convention - except
+      # for clang-$version (e.g. clang-13), which is the compiler again:
+      if [[ ! $tool =~ ^clang\-[a-zA-Z_\-]+$ ]]; then
+        continue
+      fi
+
+      ln -s $out/bin/clangd $out/bin/$tool
+    done
+
+    if [[ -z "$(ls -A $out/bin)" ]]; then
+      echo "Found no binaries - maybe their location or naming convention changed?"
+      exit 1
+    fi
+
+    substituteAll ${./wrapper} $out/bin/clangd
+    chmod +x $out/bin/clangd
+
+    runHook postInstall
+  '';
+
+  meta = llvm_meta // {
+    description = "Standalone command line tools for C++ development";
+    maintainers = with lib.maintainers; [ patryk27 ];
+  };
+}
diff --git a/pkgs/development/compilers/llvm/common/clang-tools/wrapper b/pkgs/development/compilers/llvm/common/clang-tools/wrapper
new file mode 100755
index 0000000000000..1008023fdc0d1
--- /dev/null
+++ b/pkgs/development/compilers/llvm/common/clang-tools/wrapper
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+buildcpath() {
+  local path after
+  while (( $# )); do
+    case $1 in
+        -isystem)
+            shift
+            path=$path${path:+':'}$1
+            ;;
+        -idirafter)
+            shift
+            after=$after${after:+':'}$1
+            ;;
+    esac
+    shift
+  done
+  echo $path${after:+':'}$after
+}
+
+export CPATH=${CPATH}${CPATH:+':'}$(buildcpath ${NIX_CFLAGS_COMPILE} \
+                                               $(<@clang@/nix-support/libc-cflags)):@clang@/resource-root/include
+export CPLUS_INCLUDE_PATH=${CPLUS_INCLUDE_PATH}${CPLUS_INCLUDE_PATH:+':'}$(buildcpath ${NIX_CFLAGS_COMPILE} \
+                                                                                      $(<@clang@/nix-support/libcxx-cxxflags) \
+                                                                                      $(<@clang@/nix-support/libc-cflags)):@clang@/resource-root/include
+
+exec -a "$0" @unwrapped@/bin/$(basename $0) "$@"
diff --git a/pkgs/development/compilers/llvm/common/clang/default.nix b/pkgs/development/compilers/llvm/common/clang/default.nix
index 58af0340a1399..922eb8657cee5 100644
--- a/pkgs/development/compilers/llvm/common/clang/default.nix
+++ b/pkgs/development/compilers/llvm/common/clang/default.nix
@@ -93,6 +93,8 @@ let
 
       mkdir -p $lib/lib/clang
       mv $lib/lib/17 $lib/lib/clang/17
+    '') + (lib.optionalString (lib.versionAtLeast release_version "19") ''
+      mv $out/lib/clang $lib/lib/clang
     '') + ''
 
       # Move libclang to 'lib' output
@@ -134,20 +136,30 @@ let
     passthru = {
       inherit libllvm;
       isClang = true;
-    } // (lib.optionalAttrs (lib.versionAtLeast release_version "15") {
-      hardeningUnsupportedFlags = [
-        "fortify3"
-      ];
       hardeningUnsupportedFlagsByTargetPlatform = targetPlatform:
-        lib.optional (!(targetPlatform.isx86_64 || targetPlatform.isAarch64)) "zerocallusedregs"
+        [ "fortify3" ]
+        ++ lib.optional (
+          (lib.versionOlder release_version "11")
+          || (targetPlatform.isAarch64 && (lib.versionOlder release_version "18.1"))
+          || (targetPlatform.isFreeBSD && (lib.versionOlder release_version "15"))
+          || !(targetPlatform.isLinux || targetPlatform.isFreeBSD)
+          || !(
+            targetPlatform.isx86
+            || targetPlatform.isPower64
+            || targetPlatform.isS390x
+            || targetPlatform.isAarch64
+          )
+        ) "stackclashprotection"
+        ++ lib.optional (
+          (lib.versionOlder release_version "15")
+          || !(targetPlatform.isx86_64 || targetPlatform.isAarch64)
+        ) "zerocallusedregs"
         ++ (finalAttrs.passthru.hardeningUnsupportedFlags or []);
-    }) // (lib.optionalAttrs (lib.versionOlder release_version "15") {
-      hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ];
-    });
+    };
 
     meta = llvm_meta // {
       homepage = "https://clang.llvm.org/";
-      description = "A C language family frontend for LLVM";
+      description = "C language family frontend for LLVM";
       longDescription = ''
         The Clang project provides a language front-end and tooling
         infrastructure for languages in the C language family (C, C++, Objective
@@ -196,7 +208,7 @@ let
       '';
     })
   // (lib.optionalAttrs (lib.versionAtLeast release_version "15") {
-    env = lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) {
+    env = lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform && !stdenv.hostPlatform.useLLVM) {
       # The following warning is triggered with (at least) gcc >=
       # 12, but appears to occur only for cross compiles.
       NIX_CFLAGS_COMPILE = "-Wno-maybe-uninitialized";
diff --git a/pkgs/development/compilers/llvm/common/compiler-rt/default.nix b/pkgs/development/compilers/llvm/common/compiler-rt/default.nix
index 4f44d6396d301..67f9661cf7438 100644
--- a/pkgs/development/compilers/llvm/common/compiler-rt/default.nix
+++ b/pkgs/development/compilers/llvm/common/compiler-rt/default.nix
@@ -14,7 +14,18 @@
 , libllvm
 , linuxHeaders
 , libxcrypt
+
+# Some platforms have switched to using compiler-rt, but still want a
+# libgcc.a for ABI compat purposes. The use case would be old code that
+# expects to link `-lgcc` but doesn't care exactly what its contents
+# are, so long as it provides some builtins.
 , doFakeLibgcc ? stdenv.hostPlatform.isFreeBSD
+
+# In recent releases, the compiler-rt build seems to produce
+# many `libclang_rt*` libraries, but not a single unified
+# `libcompiler_rt` library, at least under certain configurations. Some
+# platforms stil expect this, however, so we symlink one into place.
+, forceLinkCompilerRt ? stdenv.hostPlatform.isOpenBSD
 }:
 
 let
@@ -128,11 +139,17 @@ stdenv.mkDerivation ({
   '') + ''
     substituteInPlace lib/builtins/int_util.c \
       --replace "#include <stdlib.h>" ""
+  '' + (if stdenv.hostPlatform.isFreeBSD then
+    # As per above, but in FreeBSD assert is a macro and simply allowing it to be implicitly declared causes Issues!!!!!
+    ''
+    substituteInPlace lib/builtins/clear_cache.c lib/builtins/cpu_model${lib.optionalString (lib.versionAtLeast version "18") "/x86"}.c \
+      --replace "#include <assert.h>" "#define assert(e) ((e)?(void)0:__assert(__FUNCTION__,__FILE__,__LINE__,#e))"
+    '' else ''
     substituteInPlace lib/builtins/clear_cache.c \
       --replace "#include <assert.h>" ""
     substituteInPlace lib/builtins/cpu_model${lib.optionalString (lib.versionAtLeast version "18") "/x86"}.c \
       --replace "#include <assert.h>" ""
-  '');
+  ''));
 
   # Hack around weird upsream RPATH bug
   postInstall = lib.optionalString (stdenv.hostPlatform.isDarwin) ''
@@ -149,7 +166,9 @@ stdenv.mkDerivation ({
     ln -s $out/lib/*/clang_rt.crtbegin_shared-*.o $out/lib/crtbeginS.o
     ln -s $out/lib/*/clang_rt.crtend_shared-*.o $out/lib/crtendS.o
   '' + lib.optionalString doFakeLibgcc ''
-     ln -s $out/lib/freebsd/libclang_rt.builtins-*.a $out/lib/libgcc.a
+     ln -s $out/lib/*/libclang_rt.builtins-*.a $out/lib/libgcc.a
+  '' + lib.optionalString forceLinkCompilerRt ''
+     ln -s $out/lib/*/libclang_rt.builtins-*.a $out/lib/libcompiler_rt.a
   '';
 
   meta = llvm_meta // {
diff --git a/pkgs/development/compilers/llvm/common/libcxx/default.nix b/pkgs/development/compilers/llvm/common/libcxx/default.nix
index 0e91f50551c55..38813766897e4 100644
--- a/pkgs/development/compilers/llvm/common/libcxx/default.nix
+++ b/pkgs/development/compilers/llvm/common/libcxx/default.nix
@@ -13,8 +13,8 @@
 , python3
 , fixDarwinDylibNames
 , version
-, cxxabi ? if stdenv.hostPlatform.isFreeBSD then libcxxrt else null
-, libcxxrt
+, freebsd
+, cxxabi ? if stdenv.hostPlatform.isFreeBSD then freebsd.libcxxrt else null
 , libunwind
 , enableShared ? !stdenv.hostPlatform.isStatic
 }:
@@ -67,6 +67,12 @@ let
 
   cxxCMakeFlags = [
     "-DLIBCXX_CXX_ABI=${cxxabiName}"
+  ] ++ lib.optionals (cxxabi == null && lib.versionAtLeast release_version "16") [
+    # Note: llvm < 16 doesn't support this flag (or it's broken); handled in postInstall instead.
+    # Include libc++abi symbols within libc++.a for static linking libc++;
+    # dynamic linking includes them through libc++.so being a linker script
+    # which includes both shared objects.
+    "-DLIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY=ON"
   ] ++ lib.optionals (cxxabi != null) [
     "-DLIBCXX_CXX_ABI_INCLUDE_PATHS=${lib.getDev cxxabi}/include"
   ] ++ lib.optionals (stdenv.hostPlatform.isMusl || stdenv.hostPlatform.isWasi) [
@@ -83,16 +89,12 @@ let
     "-DLIBCXX_ENABLE_EXCEPTIONS=OFF"
   ] ++ lib.optionals (!enableShared) [
     "-DLIBCXX_ENABLE_SHARED=OFF"
+  ] ++ lib.optionals (cxxabi != null && cxxabi.libName == "cxxrt") [
+    "-DLIBCXX_ENABLE_NEW_DELETE_DEFINITIONS=ON"
   ];
 
   cmakeFlags = [
     "-DLLVM_ENABLE_RUNTIMES=${lib.concatStringsSep ";" runtimes}"
-  ] ++ lib.optionals (useLLVM && !stdenv.hostPlatform.isWasm) [
-    # libcxxabi's CMake looks as though it treats -nostdlib++ as implying -nostdlib,
-    # but that does not appear to be the case for example when building
-    # pkgsLLVM.libcxxabi (which uses clangNoCompilerRtWithLibc).
-    "-DCMAKE_EXE_LINKER_FLAGS=-nostdlib"
-    "-DCMAKE_SHARED_LINKER_FLAGS=-nostdlib"
   ] ++ lib.optionals stdenv.hostPlatform.isWasm [
     "-DCMAKE_C_COMPILER_WORKS=ON"
     "-DCMAKE_CXX_COMPILER_WORKS=ON"
@@ -126,6 +128,31 @@ stdenv.mkDerivation (rec {
   postInstall = lib.optionalString (cxxabi != null) ''
     lndir ${lib.getDev cxxabi}/include $dev/include/c++/v1
     lndir ${lib.getLib cxxabi}/lib $out/lib
+    libcxxabi=$out/lib/lib${cxxabi.libName}.a
+  ''
+  # LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY=ON doesn't work for LLVM < 16 or
+  # external cxxabi libraries so merge libc++abi.a into libc++.a ourselves.
+
+  # GNU binutils emits objects in LIFO order in MRI scripts so after the merge
+  # the objects are in reversed order so a second MRI script is required so the
+  # objects in the archive are listed in proper order (libc++.a, libc++abi.a)
+  + lib.optionalString (cxxabi != null || lib.versionOlder release_version "16") ''
+    libcxxabi=''${libcxxabi-$out/lib/libc++abi.a}
+    if [[ -f $out/lib/libc++.a && -e $libcxxabi ]]; then
+      $AR -M <<MRI
+        create $out/lib/libc++.a
+        addlib $out/lib/libc++.a
+        addlib $libcxxabi
+        save
+        end
+    MRI
+      $AR -M <<MRI
+        create $out/lib/libc++.a
+        addlib $out/lib/libc++.a
+        save
+        end
+    MRI
+    fi
   '';
 
   passthru = {
diff --git a/pkgs/development/compilers/llvm/common/lld/default.nix b/pkgs/development/compilers/llvm/common/lld/default.nix
index be296be91e770..99bb150a817dc 100644
--- a/pkgs/development/compilers/llvm/common/lld/default.nix
+++ b/pkgs/development/compilers/llvm/common/lld/default.nix
@@ -64,7 +64,7 @@ stdenv.mkDerivation (rec {
 
   meta = llvm_meta // {
     homepage = "https://lld.llvm.org/";
-    description = "The LLVM linker (unwrapped)";
+    description = "LLVM linker (unwrapped)";
     longDescription = ''
       LLD is a linker from the LLVM project that is a drop-in replacement for
       system linkers and runs much faster than them. It also provides features
diff --git a/pkgs/development/compilers/llvm/common/lldb.nix b/pkgs/development/compilers/llvm/common/lldb.nix
index 59e427e846c46..71afcb159a440 100644
--- a/pkgs/development/compilers/llvm/common/lldb.nix
+++ b/pkgs/development/compilers/llvm/common/lldb.nix
@@ -174,7 +174,7 @@ stdenv.mkDerivation (rec {
 
   meta = llvm_meta // {
     homepage = "https://lldb.llvm.org/";
-    description = "A next-generation high-performance debugger";
+    description = "Next-generation high-performance debugger";
     longDescription = ''
       LLDB is a next generation, high-performance debugger. It is built as a set
       of reusable components which highly leverage existing libraries in the
diff --git a/pkgs/development/compilers/llvm/common/lldb/gnu-install-dirs.patch b/pkgs/development/compilers/llvm/common/lldb/gnu-install-dirs.patch
index 093b9a8ba3ec3..ec550764be818 100644
--- a/pkgs/development/compilers/llvm/common/lldb/gnu-install-dirs.patch
+++ b/pkgs/development/compilers/llvm/common/lldb/gnu-install-dirs.patch
@@ -47,3 +47,22 @@ index 7d48491ec89a..c04543585588 100644
  install(TARGETS lldbIntelFeatures
 -  LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX})
 +  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX})
+diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
+index 7d48491ec89a..c04543585588 100644
+--- a/source/API/CMakeLists.txt	2024-05-30 18:59:13.449269853 -0700
++++ b/source/API/CMakeLists.txt	2024-05-30 19:00:33.721858164 -0700
+@@ -115,14 +115,6 @@
+   ${option_install_prefix}
+ )
+ 
+-# lib/pythonX.Y/dist-packages/lldb/_lldb.so is a symlink to lib/liblldb.so,
+-# which depends on lib/libLLVM*.so (BUILD_SHARED_LIBS) or lib/libLLVM-10git.so
+-# (LLVM_LINK_LLVM_DYLIB). Add an additional rpath $ORIGIN/../../../../lib so
+-# that _lldb.so can be loaded from Python.
+-if(LLDB_ENABLE_PYTHON AND (BUILD_SHARED_LIBS OR LLVM_LINK_LLVM_DYLIB) AND UNIX AND NOT APPLE)
+-  set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "\$ORIGIN/../../../../lib${LLVM_LIBDIR_SUFFIX}")
+-endif()
+-
+ if(Python3_RPATH)
+   set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "${Python3_RPATH}")
+   set_property(TARGET liblldb APPEND PROPERTY BUILD_RPATH   "${Python3_RPATH}")
diff --git a/pkgs/development/compilers/llvm/common/llvm/default.nix b/pkgs/development/compilers/llvm/common/llvm/default.nix
index 0716453c34c94..f780c87d0e4b1 100644
--- a/pkgs/development/compilers/llvm/common/llvm/default.nix
+++ b/pkgs/development/compilers/llvm/common/llvm/default.nix
@@ -28,8 +28,9 @@
 , sysctl
 , buildLlvmTools
 , debugVersion ? false
-, doCheck ? (if lib.versionOlder release_version "15" then stdenv.isLinux else true)
+, doCheck ? !stdenv.isAarch32 && (if lib.versionOlder release_version "15" then stdenv.isLinux else true)
   && (!stdenv.isx86_32 /* TODO: why */) && (!stdenv.hostPlatform.isMusl)
+  && !(stdenv.hostPlatform.isPower64 && stdenv.hostPlatform.isBigEndian)
   && (stdenv.hostPlatform == stdenv.buildPlatform)
 , enableManpages ? false
 , enableSharedLibraries ? !stdenv.hostPlatform.isStatic
@@ -38,6 +39,7 @@
   # broken for the armv7l builder
   && !stdenv.hostPlatform.isAarch
 , enablePolly ? lib.versionAtLeast release_version "14"
+, enableTerminfo ? true
 }:
 
 let
@@ -123,59 +125,54 @@ stdenv.mkDerivation (rec {
     substituteInPlace cmake/modules/AddLLVM.cmake \
       --replace 'set(_install_name_dir INSTALL_NAME_DIR "@rpath")' "set(_install_name_dir)" \
       --replace 'set(_install_rpath "@loader_path/../''${CMAKE_INSTALL_LIBDIR}''${LLVM_LIBDIR_SUFFIX}" ''${extra_libdir})' ""
-  '' + (optionalString (lib.versionAtLeast release_version "15") (''
-
+  '' +
     # As of LLVM 15, marked as XFAIL on arm64 macOS but lit doesn't seem to pick
     # this up: https://github.com/llvm/llvm-project/blob/c344d97a125b18f8fed0a64aace73c49a870e079/llvm/test/MC/ELF/cfi-version.ll#L7
+    (optionalString (lib.versionAtLeast release_version "15") (''
     rm test/MC/ELF/cfi-version.ll
 
+  '' +
     # This test tries to call `sw_vers` by absolute path (`/usr/bin/sw_vers`)
     # and thus fails under the sandbox:
-  '' + (if lib.versionAtLeast release_version "16" then ''
+    (if lib.versionAtLeast release_version "16" then ''
     substituteInPlace unittests/TargetParser/Host.cpp \
       --replace '/usr/bin/sw_vers' "${(builtins.toString darwin.DarwinTools) + "/bin/sw_vers" }"
   '' else ''
     substituteInPlace unittests/Support/Host.cpp \
       --replace '/usr/bin/sw_vers' "${(builtins.toString darwin.DarwinTools) + "/bin/sw_vers" }"
-  '') + optionalString (lib.versionAtLeast release_version "16") ''
-
+  '') +
     # This test tries to call the intrinsics `@llvm.roundeven.f32` and
     # `@llvm.roundeven.f64` which seem to (incorrectly?) lower to `roundevenf`
-    # and `roundeven` on macOS.
+    # and `roundeven` on macOS and FreeBSD.
     #
     # However these functions are glibc specific so the test fails:
     #   - https://www.gnu.org/software/gnulib/manual/html_node/roundevenf.html
     #   - https://www.gnu.org/software/gnulib/manual/html_node/roundeven.html
     #
+    # TODO(@rrbutani): this seems to run fine on `aarch64-darwin`, why does it
+    # pass there?
+    optionalString (lib.versionAtLeast release_version "16") ''
     substituteInPlace test/ExecutionEngine/Interpreter/intrinsics.ll \
       --replace "%roundeven32 = call float @llvm.roundeven.f32(float 0.000000e+00)" "" \
       --replace "%roundeven64 = call double @llvm.roundeven.f64(double 0.000000e+00)" ""
-  '' + optionalString (!stdenv.hostPlatform.isx86 && lib.versionAtLeast release_version "18") ''
-
+  '' +
     # fails when run in sandbox
+    optionalString (!stdenv.hostPlatform.isx86 && lib.versionAtLeast release_version "18") ''
     substituteInPlace unittests/Support/VirtualFileSystemTest.cpp \
       --replace "PhysicalFileSystemWorkingDirFailure" "DISABLED_PhysicalFileSystemWorkingDirFailure"
-  ''))) + optionalString (stdenv.isDarwin && stdenv.hostPlatform.isx86 && lib.versionAtLeast release_version "15") (optionalString (lib.versionOlder release_version "16") ''
-    # This test tries to call the intrinsics `@llvm.roundeven.f32` and
-    # `@llvm.roundeven.f64` which seem to (incorrectly?) lower to `roundevenf`
-    # and `roundeven` on x86_64 macOS.
-    #
-    # However these functions are glibc specific so the test fails:
-    #   - https://www.gnu.org/software/gnulib/manual/html_node/roundevenf.html
-    #   - https://www.gnu.org/software/gnulib/manual/html_node/roundeven.html
-    #
-    # TODO(@rrbutani): this seems to run fine on `aarch64-darwin`, why does it
-    # pass there?
+  ''))) +
+    # dup of above patch with different conditions
+    optionalString (stdenv.isDarwin && stdenv.hostPlatform.isx86 && lib.versionAtLeast release_version "15") (optionalString (lib.versionOlder release_version "16") ''
     substituteInPlace test/ExecutionEngine/Interpreter/intrinsics.ll \
       --replace "%roundeven32 = call float @llvm.roundeven.f32(float 0.000000e+00)" "" \
       --replace "%roundeven64 = call double @llvm.roundeven.f64(double 0.000000e+00)" ""
 
-  '' + ((optionalString (lib.versionAtLeast release_version "18") ''
-
+  '' +
     # fails when run in sandbox
+    ((optionalString (lib.versionAtLeast release_version "18") ''
     substituteInPlace unittests/Support/VirtualFileSystemTest.cpp \
       --replace "PhysicalFileSystemWorkingDirFailure" "DISABLED_PhysicalFileSystemWorkingDirFailure"
-  '') + ''
+  '') +
     # This test fails on darwin x86_64 because `sw_vers` reports a different
     # macOS version than what LLVM finds by reading
     # `/System/Library/CoreServices/SystemVersion.plist` (which is passed into
@@ -204,19 +201,20 @@ stdenv.mkDerivation (rec {
     # not clear to me when/where/for what this even gets used in LLVM.
     #
     # TODO(@rrbutani): fix/follow-up
-  '' + (if lib.versionAtLeast release_version "16" then ''
+    (if lib.versionAtLeast release_version "16" then ''
     substituteInPlace unittests/TargetParser/Host.cpp \
       --replace "getMacOSHostVersion" "DISABLED_getMacOSHostVersion"
   '' else ''
     substituteInPlace unittests/Support/Host.cpp \
       --replace "getMacOSHostVersion" "DISABLED_getMacOSHostVersion"
-  '') + ''
-
+  '') +
     # This test fails with a `dysmutil` crash; have not yet dug into what's
     # going on here (TODO(@rrbutani)).
+    lib.optionalString (lib.versionOlder release_version "19") ''
     rm test/tools/dsymutil/ARM/obfuscated.test
-  '')) + ''
+  '')) +
     # FileSystem permissions tests fail with various special bits
+  ''
     substituteInPlace unittests/Support/CMakeLists.txt \
       --replace "Path.cpp" ""
     rm unittests/Support/Path.cpp
@@ -228,22 +226,24 @@ stdenv.mkDerivation (rec {
   '' + lib.optionalString (lib.versionOlder release_version "13") ''
     # TODO: Fix failing tests:
     rm test/DebugInfo/X86/vla-multi.ll
-  '' + lib.optionalString (lib.versionAtLeast release_version "16") (''
-
+  '' +
     # Fails in the presence of anti-virus software or other intrusion-detection software that
     # modifies the atime when run. See #284056.
+    lib.optionalString (lib.versionAtLeast release_version "16") (''
     rm test/tools/llvm-objcopy/ELF/strip-preserve-atime.test
   '' + lib.optionalString (lib.versionOlder release_version "17") ''
 
-  '') + lib.optionalString (lib.versionAtLeast release_version "15" && lib.versionOlder release_version "17") ''
+  '') +
     # timing-based tests are trouble
+    lib.optionalString (lib.versionAtLeast release_version "15" && lib.versionOlder release_version "17") ''
     rm utils/lit/tests/googletest-timeout.py
-  '' + optionalString stdenv.hostPlatform.isMusl ''
+  '' +
+    # valgrind unhappy with musl or glibc, but fails w/musl only
+    optionalString stdenv.hostPlatform.isMusl ''
     patch -p1 -i ${./TLI-musl.patch}
     substituteInPlace unittests/Support/CMakeLists.txt \
       --replace "add_subdirectory(DynamicLibrary)" ""
     rm unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
-    # valgrind unhappy with musl or glibc, but fails w/musl only
     rm test/CodeGen/AArch64/wineh4.mir
   '' + optionalString stdenv.hostPlatform.isAarch32 ''
     # skip failing X86 test cases on 32-bit ARM
@@ -253,18 +253,28 @@ stdenv.mkDerivation (rec {
     rm test/tools/dsymutil/X86/op-convert.test
     rm test/tools/gold/X86/split-dwarf.ll
     rm test/tools/llvm-objcopy/MachO/universal-object.test
-  '' + optionalString (stdenv.hostPlatform.system == "armv6l-linux") ''
+  '' +
     # Seems to require certain floating point hardware (NEON?)
+    optionalString (stdenv.hostPlatform.system == "armv6l-linux") ''
     rm test/ExecutionEngine/frem.ll
+  '' +
+    # 1. TODO: Why does this test fail on FreeBSD?
+    # It seems to reference /usr/local/lib/libfile.a, which is clearly a problem.
+    # 2. This test fails for the same reason it fails on MacOS, but the fix is
+    # not trivial to apply.
+    optionalString stdenv.isFreeBSD ''
+    rm test/tools/llvm-libtool-darwin/L-and-l.test
+    rm test/ExecutionEngine/Interpreter/intrinsics.ll
   '' + ''
     patchShebangs test/BugPoint/compile-custom.ll.py
-  '' + (lib.optionalString (lib.versionOlder release_version "13") ''
+  '' +
     # Tweak tests to ignore namespace part of type to support
     # gcc-12: https://gcc.gnu.org/PR103598.
     # The change below mangles strings like:
     #    CHECK-NEXT: Starting llvm::Function pass manager run.
     # to:
     #    CHECK-NEXT: Starting {{.*}}Function pass manager run.
+    (lib.optionalString (lib.versionOlder release_version "13") (''
     for f in \
       test/Other/new-pass-manager.ll \
       test/Other/new-pm-O0-defaults.ll \
@@ -285,24 +295,25 @@ stdenv.mkDerivation (rec {
         --replace 'Starting llvm::' 'Starting {{.*}}' \
         --replace 'Finished llvm::' 'Finished {{.*}}'
     done
+  '' +
     # gcc-13 fix
+  ''
     sed -i '/#include <string>/i#include <cstdint>' \
       include/llvm/DebugInfo/Symbolize/DIPrinter.h
-  '');
+  ''));
 
+  # Workaround for configure flags that need to have spaces
   preConfigure = if lib.versionAtLeast release_version "15" then ''
-    # Workaround for configure flags that need to have spaces
     cmakeFlagsArray+=(
       -DLLVM_LIT_ARGS="-svj''${NIX_BUILD_CORES} --no-progress-bar"
     )
   '' else ''
-    # Workaround for configure flags that need to have spaces
     cmakeFlagsArray+=(
       -DLLVM_LIT_ARGS='-svj''${NIX_BUILD_CORES} --no-progress-bar'
     )
   '';
 
-  # E.g. mesa.drivers use the build-id as a cache key (see #93946):
+  # E.g. Mesa uses the build-id as a cache key (see #93946):
   LDFLAGS = optionalString (enableSharedLibraries && !stdenv.isDarwin) "-Wl,--build-id=sha1";
 
   cmakeBuildType = if debugVersion then "Debug" else "Release";
@@ -331,9 +342,13 @@ stdenv.mkDerivation (rec {
     "-DLLVM_HOST_TRIPLE=${stdenv.hostPlatform.config}"
     "-DLLVM_DEFAULT_TARGET_TRIPLE=${stdenv.hostPlatform.config}"
     "-DLLVM_ENABLE_DUMP=ON"
+    (lib.cmakeBool "LLVM_ENABLE_TERMINFO" enableTerminfo)
+  ] ++ optionals (!doCheck) [
+    "-DLLVM_INCLUDE_TESTS=OFF"
   ] ++ optionals stdenv.hostPlatform.isStatic [
     # Disables building of shared libs, -fPIC is still injected by cc-wrapper
     "-DLLVM_ENABLE_PIC=OFF"
+    "-DCMAKE_SKIP_INSTALL_RPATH=ON"
     "-DLLVM_BUILD_STATIC=ON"
     # libxml2 needs to be disabled because the LLVM build system ignores its .la
     # file and doesn't link zlib as well.
@@ -416,7 +431,7 @@ stdenv.mkDerivation (rec {
   requiredSystemFeatures = [ "big-parallel" ];
   meta = llvm_meta // {
     homepage = "https://llvm.org/";
-    description = "A collection of modular and reusable compiler and toolchain technologies";
+    description = "Collection of modular and reusable compiler and toolchain technologies";
     longDescription = ''
       The LLVM Project is a collection of modular and reusable compiler and
       toolchain technologies. Despite its name, LLVM has little to do with
diff --git a/pkgs/development/compilers/llvm/common/mlir/default.nix b/pkgs/development/compilers/llvm/common/mlir/default.nix
index 044e5c673108b..891e66b1d57c5 100644
--- a/pkgs/development/compilers/llvm/common/mlir/default.nix
+++ b/pkgs/development/compilers/llvm/common/mlir/default.nix
@@ -48,7 +48,8 @@ stdenv.mkDerivation rec {
     "-DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF"
     "-DMLIR_TOOLS_INSTALL_DIR=${placeholder "out"}/bin/"
     "-DLLVM_ENABLE_IDE=OFF"
-    "-DMLIR_INSTALL_PACKAGE_DIR=${placeholder "out"}/lib/cmake/mlir"
+    "-DMLIR_INSTALL_PACKAGE_DIR=${placeholder "dev"}/lib/cmake/mlir"
+    "-DMLIR_INSTALL_CMAKE_DIR=${placeholder "dev"}/lib/cmake/mlir"
     "-DLLVM_BUILD_TESTS=${if doCheck then "ON" else "OFF"}"
     "-DLLVM_ENABLE_FFI=ON"
     "-DLLVM_HOST_TRIPLE=${stdenv.hostPlatform.config}"
diff --git a/pkgs/development/compilers/llvm/git/clang/gnu-install-dirs.patch b/pkgs/development/compilers/llvm/git/clang/gnu-install-dirs.patch
index 9517df973ad09..b8c1c110cf22d 100644
--- a/pkgs/development/compilers/llvm/git/clang/gnu-install-dirs.patch
+++ b/pkgs/development/compilers/llvm/git/clang/gnu-install-dirs.patch
@@ -1,5 +1,5 @@
 diff --git a/cmake/modules/AddClang.cmake b/cmake/modules/AddClang.cmake
-index 75b0080f6715..c895b884cd27 100644
+index 75b0080f6..c895b884c 100644
 --- a/cmake/modules/AddClang.cmake
 +++ b/cmake/modules/AddClang.cmake
 @@ -119,8 +119,8 @@ macro(add_clang_library name)
@@ -14,22 +14,22 @@ index 75b0080f6715..c895b884cd27 100644
  
          if (NOT LLVM_ENABLE_IDE)
 diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
-index f2b0c5cddcbb..52f37fc368ce 100644
+index e6ae4e19e..5ef01aea2 100644
 --- a/lib/Headers/CMakeLists.txt
 +++ b/lib/Headers/CMakeLists.txt
-@@ -473,6 +473,7 @@ add_header_target("windows-resource-headers" ${windows_only_files})
- add_header_target("utility-resource-headers" ${utility_files})
+@@ -337,6 +337,7 @@ set(llvm_libc_wrapper_files
  
- get_clang_resource_dir(header_install_dir SUBDIR include)
+ include(GetClangResourceDir)
+ get_clang_resource_dir(output_dir PREFIX ${LLVM_LIBRARY_OUTPUT_INTDIR}/.. SUBDIR include)
 +set(header_install_dir ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION_MAJOR}/include)
+ set(out_files)
+ set(generated_files)
  
- #############################################################
- # Install rules for the catch-all clang-resource-headers target
 diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
-index 4f23065a2472..6a0f55991e24 100644
+index b5b6d2807..6b592d255 100644
 --- a/tools/libclang/CMakeLists.txt
 +++ b/tools/libclang/CMakeLists.txt
-@@ -234,7 +234,7 @@ foreach(PythonVersion ${CLANG_PYTHON_BINDINGS_VERSIONS})
+@@ -246,7 +246,7 @@ foreach(PythonVersion ${CLANG_PYTHON_BINDINGS_VERSIONS})
            COMPONENT
              libclang-python-bindings
            DESTINATION
@@ -39,7 +39,7 @@ index 4f23065a2472..6a0f55991e24 100644
  if(NOT LLVM_ENABLE_IDE)
    add_custom_target(libclang-python-bindings)
 diff --git a/tools/scan-build-py/CMakeLists.txt b/tools/scan-build-py/CMakeLists.txt
-index 3aca22c0b0a8..3115353e3fe3 100644
+index 3aca22c0b..3115353e3 100644
 --- a/tools/scan-build-py/CMakeLists.txt
 +++ b/tools/scan-build-py/CMakeLists.txt
 @@ -88,7 +88,7 @@ foreach(lib ${LibScanbuild})
diff --git a/pkgs/development/compilers/llvm/git/default.nix b/pkgs/development/compilers/llvm/git/default.nix
index c995845fb6b38..ff76aad22a718 100644
--- a/pkgs/development/compilers/llvm/git/default.nix
+++ b/pkgs/development/compilers/llvm/git/default.nix
@@ -1,6 +1,7 @@
-{ lowPrio, newScope, pkgs, lib, stdenv, cmake, ninja
+{ lowPrio, newScope, pkgs, lib, stdenv
 , preLibcCrossHeaders
-, libxml2, python3, fetchFromGitHub, substituteAll, overrideCC, wrapCCWith, wrapBintoolsWith
+, substitute, substituteAll, fetchFromGitHub, fetchpatch
+, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
 , targetLlvm
@@ -19,9 +20,9 @@
 # LLVM release information; specify one of these but not both:
 , gitRelease ? {
     version = "19.0.0-git";
-    rev = "cebf77fb936a7270c7e3fa5c4a7e76216321d385";
-    rev-version = "19.0.0-unstable-2024-04-07";
-    sha256 = "sha256-616tscgsiFgHQcXW4KzK5srrudYizQFnJVM6K0qRf+I=";
+    rev = "a9ac31910db3975d5e92a6265ab29dafd6a4691d";
+    rev-version = "19.0.0-unstable-2024-06-23";
+    sha256 = "sha256-MTt2FU84rgu6FqB9aCO6M54VZexoogkdx5RKS1NzSkk=";
 }
   # i.e.:
   # {
@@ -44,7 +45,11 @@
 # to you to make sure that the LLVM repo given matches the release configuration
 # specified.
 , monorepoSrc ? null
-}:
+# Allows passthrough to packages via newScope. This makes it possible to
+# do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
+# an llvmPackages whose packages are overridden in an internally consistent way.
+, ...
+}@args:
 
 assert
   lib.assertMsg
@@ -56,15 +61,17 @@ assert
 let
   monorepoSrc' = monorepoSrc;
 in let
-  inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
 
-  inherit (releaseInfo) release_version version;
-
-  inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub release_version gitRelease officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  metadata = rec {
+    # Import releaseInfo separately to avoid infinite recursion
+    inherit (import ../common/common-let.nix { inherit lib gitRelease officialRelease; }) releaseInfo;
+    inherit (releaseInfo) release_version version;
+    inherit (import ../common/common-let.nix { inherit lib fetchFromGitHub gitRelease release_version officialRelease monorepoSrc'; }) llvm_meta monorepoSrc;
+  };
 
   tools = lib.makeExtensible (tools: let
-    callPackage = newScope (tools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc buildLlvmTools; });
-    major = lib.versions.major release_version;
+    callPackage = newScope (tools // args // metadata);
+    major = lib.versions.major metadata.release_version;
     mkExtraBuildCommands0 = cc: ''
       rsrc="$out/resource-root"
       mkdir "$rsrc"
@@ -138,7 +145,6 @@ in let
         # Just like the `llvm-lit-cfg` patch, but for `polly`.
         ./llvm/polly-lit-cfg-add-libs-to-dylib-path.patch
       ];
-      inherit llvm_meta;
     };
 
     # `llvm` historically had the binaries.  When choosing an output explicitly,
@@ -156,7 +162,6 @@ in let
           libllvmLibdir = "${tools.libllvm.lib}/lib";
         })
       ];
-      inherit llvm_meta;
     };
 
     clang-unwrapped = tools.libclang;
@@ -176,6 +181,9 @@ in let
       python3 = pkgs.python3;  # don't use python-boot
     });
 
+    # Wrapper for standalone command line utilities
+    clang-tools = callPackage ../common/clang-tools { };
+
     # pick clang appropriate for package set we are targeting
     clang =
       /**/ if stdenv.targetPlatform.useLLVM or false then tools.clangUseLLVM
@@ -205,15 +213,12 @@ in let
       patches = [
         ./lld/gnu-install-dirs.patch
       ];
-      inherit llvm_meta;
     };
 
-    mlir = callPackage ../common/mlir {
-      inherit llvm_meta;
-    };
+    mlir = callPackage ../common/mlir {};
 
     lldb = callPackage ../common/lldb.nix {
-      src = callPackage ({ runCommand }: runCommand "lldb-src-${version}" {} ''
+      src = callPackage ({ runCommand }: runCommand "lldb-src-${metadata.version}" {} ''
         mkdir -p "$out"
         cp -r ${monorepoSrc}/cmake "$out"
         cp -r ${monorepoSrc}/lldb "$out"
@@ -237,7 +242,6 @@ in let
             && !stdenv.targetPlatform.isAarch64
             && (lib.versionOlder darwin.apple_sdk.sdk.version "11.0")
         ) ./lldb/cpu_subtype_arm64e_replacement.patch;
-      inherit llvm_meta;
     };
 
     # Below, is the LLVM bootstrapping logic. It handles building a
@@ -340,13 +344,11 @@ in let
     # Has to be in tools despite mostly being a library,
     # because we use a native helper executable from a
     # non-cross build in cross builds.
-    libclc = callPackage ../common/libclc.nix {
-      inherit buildLlvmTools;
-    };
+    libclc = callPackage ../common/libclc.nix {};
   });
 
   libraries = lib.makeExtensible (libraries: let
-    callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc; });
+    callPackage = newScope (libraries // buildLlvmTools // args // metadata);
   in {
 
     compiler-rt-libc = callPackage ../common/compiler-rt {
@@ -360,7 +362,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false || (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isStatic)
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
@@ -377,7 +378,6 @@ in let
         # See: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r999829893
         # ../common/compiler-rt/armv7l-15.patch
       ];
-      inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
                then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
@@ -400,12 +400,10 @@ in let
         # https://github.com/llvm/llvm-project/issues/64226
         ./libcxx/0001-darwin-10.12-mbstate_t-fix.patch
       ];
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
     libunwind = callPackage ../common/libunwind {
-      inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
     };
 
@@ -414,9 +412,8 @@ in let
         ./openmp/fix-find-tool.patch
         ./openmp/run-lit-directly.patch
       ];
-      inherit llvm_meta targetLlvm;
     };
   });
   noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ];
 
-in { inherit tools libraries release_version; } // (noExtend libraries) // (noExtend tools)
+in { inherit tools libraries; inherit (metadata) release_version; } // (noExtend libraries) // (noExtend tools)