summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2021-05-01 03:03:19 +0000
committerJohn Ericson <John.Ericson@Obsidian.Systems>2021-05-14 21:29:51 +0000
commit18c38f8aee732b6202042383fc35997a39361830 (patch)
tree466554af31e75e2739adbc2f236206e37eb72fad
parente3a1c149d26bd82c4b42ba5e06fec73933ce8bf6 (diff)
downloadnixpkgs-18c38f8aee732b6202042383fc35997a39361830.tar
nixpkgs-18c38f8aee732b6202042383fc35997a39361830.tar.gz
nixpkgs-18c38f8aee732b6202042383fc35997a39361830.tar.bz2
nixpkgs-18c38f8aee732b6202042383fc35997a39361830.tar.lz
nixpkgs-18c38f8aee732b6202042383fc35997a39361830.tar.xz
nixpkgs-18c38f8aee732b6202042383fc35997a39361830.tar.zst
nixpkgs-18c38f8aee732b6202042383fc35997a39361830.zip
treewide: All the linker to be chosen independently
This will begin the process of breaking up the `useLLVM` monolith. That
is good in general, but I hope will be good for NetBSD and Darwin in
particular.

Co-authored-by: sterni <sternenseemann@systemli.org>
-rw-r--r--lib/systems/default.nix13
-rw-r--r--pkgs/applications/networking/browsers/chromium/common.nix2
-rw-r--r--pkgs/applications/networking/browsers/firefox/common.nix18
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix1
-rw-r--r--pkgs/development/compilers/llvm/10/default.nix50
-rw-r--r--pkgs/development/compilers/llvm/11/default.nix50
-rw-r--r--pkgs/development/compilers/llvm/12/default.nix50
-rw-r--r--pkgs/development/compilers/llvm/7/default.nix53
-rw-r--r--pkgs/development/compilers/llvm/8/default.nix50
-rw-r--r--pkgs/development/compilers/llvm/9/default.nix50
-rw-r--r--pkgs/os-specific/windows/default.nix2
-rw-r--r--pkgs/servers/clickhouse/default.nix4
-rw-r--r--pkgs/stdenv/cross/default.nix2
-rw-r--r--pkgs/top-level/all-packages.nix59
14 files changed, 296 insertions, 108 deletions
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index 21b00374da4..549f01b058f 100644
--- a/lib/systems/default.nix
+++ b/lib/systems/default.nix
@@ -41,6 +41,19 @@ rec {
         else if final.isNetBSD              then "nblibc"
         # TODO(@Ericson2314) think more about other operating systems
         else                                     "native/impure";
+      # Choose what linker we wish to use by default. Someday we might also
+      # choose the C compiler, runtime library, C++ standard library, etc. in
+      # this way, nice and orthogonally, and deprecate `useLLVM`. But due to
+      # the monolithic GCC build we cannot actually make those choices
+      # independently, so we are just doing `linker` and keeping `useLLVM` for
+      # now.
+      linker =
+        /**/ if final.useLLVM or false      then "lld"
+        else if final.isDarwin              then "cctools"
+        # "bfd" and "gold" both come from GNU binutils. The existance of Gold
+        # is why we use the more obscure "bfd" and not "binutils" for this
+        # choice.
+        else                                     "bfd";
       extensions = {
         sharedLibrary =
           /**/ if final.isDarwin  then ".dylib"
diff --git a/pkgs/applications/networking/browsers/chromium/common.nix b/pkgs/applications/networking/browsers/chromium/common.nix
index f84ce23309f..2cf3556e7ea 100644
--- a/pkgs/applications/networking/browsers/chromium/common.nix
+++ b/pkgs/applications/networking/browsers/chromium/common.nix
@@ -137,7 +137,7 @@ let
       ninja pkg-config
       python2WithPackages perl nodejs
       gnutar which
-      llvmPackages.lldClang.bintools
+      llvmPackages.bintools
     ] ++ lib.optionals (chromiumVersionAtLeast "92") [
       python3WithPackages
     ];
diff --git a/pkgs/applications/networking/browsers/firefox/common.nix b/pkgs/applications/networking/browsers/firefox/common.nix
index 48723249323..c97fe6efb77 100644
--- a/pkgs/applications/networking/browsers/firefox/common.nix
+++ b/pkgs/applications/networking/browsers/firefox/common.nix
@@ -98,16 +98,22 @@ let
   # clang LTO on Darwin is broken so the stdenv is not being changed.
   # Target the LLVM version that rustc -Vv reports it is built with for LTO.
   # rustPackages_1_45 -> LLVM 10, rustPackages -> LLVM 11
-  llvmPackages = if stdenv.isDarwin
-                 then buildPackages.llvmPackages
-                 else if lib.versionAtLeast rustc.llvm.version "11"
-                      then buildPackages.llvmPackages_11
-                      else buildPackages.llvmPackages_10;
+  llvmPackages0 =
+    /**/ if stdenv.isDarwin
+      then buildPackages.llvmPackages
+    else if lib.versionAtLeast rustc.llvm.version "11"
+      then buildPackages.llvmPackages_11
+    else buildPackages.llvmPackages_10;
+  # Force the use of lld and other llvm tools for LTO
+  llvmPackages = llvmPackages0.override {
+    bootBintoolsNoLibc = null;
+    bootBintools = null;
+  };
 
   # When LTO for Darwin is fixed, the following will need updating as lld
   # doesn't work on it. For now it is fine since ltoSupport implies no Darwin.
   buildStdenv = if ltoSupport
-                then overrideCC stdenv llvmPackages.lldClang
+                then overrideCC stdenv llvmPackages.clangUseLLVM
                 else stdenv;
 
   nss_pkg = if lib.versionOlder ffversion "83" then nss_3_53 else nss;
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index d2941b537b7..235d244a7c0 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -64,6 +64,7 @@ let
 
   useGccForLibs = isClang
     && libcxx == null
+    && !stdenv.targetPlatform.isDarwin
     && !(stdenv.targetPlatform.useLLVM or false)
     && !(stdenv.targetPlatform.useAndroidPrebuilt or false)
     && !(stdenv.targetPlatform.isiOS or false)
diff --git a/pkgs/development/compilers/llvm/10/default.nix b/pkgs/development/compilers/llvm/10/default.nix
index bf3784c9794..8c5d0e45d7c 100644
--- a/pkgs/development/compilers/llvm/10/default.nix
+++ b/pkgs/development/compilers/llvm/10/default.nix
@@ -3,6 +3,17 @@
 , libxml2, python3, isl, fetchurl, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
+# This is the default binutils, but with *this* version of LLD rather
+# than the default LLVM verion's, if LLD is the choice. We use these for
+# the `useLLVM` bootstrapping below.
+, bootBintoolsNoLibc ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintoolsNoLibc
+, bootBintools ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintools
 }:
 
 let
@@ -36,6 +47,15 @@ let
       ln -s "${targetLlvmLibraries.compiler-rt.out}/share" "$rsrc/share"
     '';
 
+  bintoolsNoLibc' =
+    if bootBintoolsNoLibc == null
+    then tools.bintoolsNoLibc
+    else bootBintoolsNoLibc;
+  bintools' =
+    if bootBintools == null
+    then tools.bintools
+    else bootBintools;
+
   in {
 
     libllvm = callPackage ./llvm {
@@ -117,10 +137,10 @@ let
       bintools = tools.bintools-unwrapped;
     };
 
-    lldClang = wrapCCWith rec {
+    clangUseLLVM = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = targetLlvmLibraries.libcxx;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
@@ -139,10 +159,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibcxx = wrapCCWith rec {
+    clangNoLibcxx = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -153,10 +173,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibc = wrapCCWith rec {
+    clangNoLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -166,20 +186,20 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoCompilerRt = wrapCCWith rec {
+    clangNoCompilerRt = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [ ];
       extraBuildCommands = ''
         echo "-nostartfiles" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands0 cc;
     };
 
-    lldClangNoCompilerRtWithLibc = wrapCCWith rec {
+    clangNoCompilerRtWithLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [ ];
       extraBuildCommands = mkExtraBuildCommands0 cc;
     };
@@ -193,14 +213,14 @@ let
     compiler-rt-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRtWithLibc
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
     };
 
     compiler-rt-no-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
     };
 
@@ -216,21 +236,21 @@ let
     libcxx = callPackage ./libcxx {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libcxxabi = callPackage ./libcxxabi {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libunwind = callPackage ./libunwind {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
diff --git a/pkgs/development/compilers/llvm/11/default.nix b/pkgs/development/compilers/llvm/11/default.nix
index 0e12bbbb2fc..94492890b7f 100644
--- a/pkgs/development/compilers/llvm/11/default.nix
+++ b/pkgs/development/compilers/llvm/11/default.nix
@@ -3,6 +3,17 @@
 , libxml2, python3, isl, fetchurl, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
+# This is the default binutils, but with *this* version of LLD rather
+# than the default LLVM verion's, if LLD is the choice. We use these for
+# the `useLLVM` bootstrapping below.
+, bootBintoolsNoLibc ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintoolsNoLibc
+, bootBintools ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintools
 }:
 
 let
@@ -38,6 +49,15 @@ let
       ln -s "${targetLlvmLibraries.compiler-rt.out}/share" "$rsrc/share"
     '';
 
+  bintoolsNoLibc' =
+    if bootBintoolsNoLibc == null
+    then tools.bintoolsNoLibc
+    else bootBintoolsNoLibc;
+  bintools' =
+    if bootBintools == null
+    then tools.bintools
+    else bootBintools;
+
   in {
 
     libllvm = callPackage ./llvm {
@@ -118,10 +138,10 @@ let
       bintools = tools.bintools-unwrapped;
     };
 
-    lldClang = wrapCCWith rec {
+    clangUseLLVM = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = targetLlvmLibraries.libcxx;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
@@ -140,10 +160,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibcxx = wrapCCWith rec {
+    clangNoLibcxx = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -154,10 +174,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibc = wrapCCWith rec {
+    clangNoLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -167,20 +187,20 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoCompilerRt = wrapCCWith rec {
+    clangNoCompilerRt = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [ ];
       extraBuildCommands = ''
         echo "-nostartfiles" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands0 cc;
     };
 
-    lldClangNoCompilerRtWithLibc = wrapCCWith rec {
+    clangNoCompilerRtWithLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [ ];
       extraBuildCommands = mkExtraBuildCommands0 cc;
     };
@@ -194,14 +214,14 @@ let
     compiler-rt-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRtWithLibc
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
     };
 
     compiler-rt-no-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
     };
 
@@ -217,21 +237,21 @@ let
     libcxx = callPackage ./libcxx {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libcxxabi = callPackage ./libcxxabi {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libunwind = callPackage ./libunwind {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
diff --git a/pkgs/development/compilers/llvm/12/default.nix b/pkgs/development/compilers/llvm/12/default.nix
index 2b464864222..97165e3b80b 100644
--- a/pkgs/development/compilers/llvm/12/default.nix
+++ b/pkgs/development/compilers/llvm/12/default.nix
@@ -3,6 +3,17 @@
 , libxml2, python3, isl, fetchurl, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
+# This is the default binutils, but with *this* version of LLD rather
+# than the default LLVM verion's, if LLD is the choice. We use these for
+# the `useLLVM` bootstrapping below.
+, bootBintoolsNoLibc ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintoolsNoLibc
+, bootBintools ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintools
 , darwin
 }:
 
@@ -39,6 +50,15 @@ let
       ln -s "${targetLlvmLibraries.compiler-rt.out}/share" "$rsrc/share"
     '';
 
+  bintoolsNoLibc' =
+    if bootBintoolsNoLibc == null
+    then tools.bintoolsNoLibc
+    else bootBintoolsNoLibc;
+  bintools' =
+    if bootBintools == null
+    then tools.bintools
+    else bootBintools;
+
   in {
 
     libllvm = callPackage ./llvm {
@@ -124,10 +144,10 @@ let
       bintools = tools.bintools-unwrapped;
     };
 
-    lldClang = wrapCCWith rec {
+    clangUseLLVM = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = targetLlvmLibraries.libcxx;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
@@ -146,10 +166,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibcxx = wrapCCWith rec {
+    clangNoLibcxx = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -160,10 +180,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibc = wrapCCWith rec {
+    clangNoLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -173,20 +193,20 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoCompilerRt = wrapCCWith rec {
+    clangNoCompilerRt = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [ ];
       extraBuildCommands = ''
         echo "-nostartfiles" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands0 cc;
     };
 
-    lldClangNoCompilerRtWithLibc = wrapCCWith rec {
+    clangNoCompilerRtWithLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [ ];
       extraBuildCommands = mkExtraBuildCommands0 cc;
     };
@@ -200,14 +220,14 @@ let
     compiler-rt-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRtWithLibc
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
     };
 
     compiler-rt-no-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
     };
 
@@ -223,14 +243,14 @@ let
     libcxx = callPackage ./libcxx {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libcxxabi = callPackage ./libcxxabi {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
@@ -238,7 +258,7 @@ let
       inherit llvm_meta;
       inherit (buildLlvmTools) llvm;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
diff --git a/pkgs/development/compilers/llvm/7/default.nix b/pkgs/development/compilers/llvm/7/default.nix
index 5dbe4e0d8f3..4d01ea2fae9 100644
--- a/pkgs/development/compilers/llvm/7/default.nix
+++ b/pkgs/development/compilers/llvm/7/default.nix
@@ -3,6 +3,17 @@
 , libxml2, python3, isl, fetchurl, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
+# This is the default binutils, but with *this* version of LLD rather
+# than the default LLVM verion's, if LLD is the choice. We use these for
+# the `useLLVM` bootstrapping below.
+, bootBintoolsNoLibc ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintoolsNoLibc
+, bootBintools ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintools
 }:
 
 let
@@ -35,6 +46,15 @@ let
       ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib"
     '';
 
+  bintoolsNoLibc' =
+    if bootBintoolsNoLibc == null
+    then tools.bintoolsNoLibc
+    else bootBintoolsNoLibc;
+  bintools' =
+    if bootBintools == null
+    then tools.bintools
+    else bootBintools;
+
   in {
 
     libllvm = callPackage ./llvm {
@@ -123,10 +143,10 @@ let
       bintools = tools.bintools-unwrapped;
     };
 
-    lldClang = wrapCCWith rec {
+    clangUseLLVM = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = targetLlvmLibraries.libcxx;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
@@ -145,10 +165,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibcxx = wrapCCWith rec {
+    clangNoLibcxx = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -159,10 +179,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibc = wrapCCWith rec {
+    clangNoLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -172,20 +192,20 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoCompilerRt = wrapCCWith rec {
+    clangNoCompilerRt = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [ ];
       extraBuildCommands = ''
         echo "-nostartfiles" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands0 cc;
     };
 
-    lldClangNoCompilerRtWithLibc = wrapCCWith rec {
+    clangNoCompilerRtWithLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [ ];
       extraBuildCommands = mkExtraBuildCommands0 cc;
     };
@@ -199,19 +219,20 @@ let
     compiler-rt-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRtWithLibc
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
     };
 
     compiler-rt-no-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
     };
 
     # N.B. condition is safe because without useLLVM both are the same.
-    compiler-rt = if stdenv.hostPlatform.isAndroid
+    compiler-rt =
+      if stdenv.hostPlatform.isAndroid || (stdenv.hostPlatform != stdenv.buildPlatform && stdenv.hostPlatform.isDarwin)
       then libraries.compiler-rt-libc
       else libraries.compiler-rt-no-libc;
 
@@ -222,14 +243,14 @@ let
     libcxx = callPackage ./libcxx {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libcxxabi = callPackage ./libcxxabi {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
@@ -237,7 +258,7 @@ let
       inherit llvm_meta;
       inherit (buildLlvmTools) llvm;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
diff --git a/pkgs/development/compilers/llvm/8/default.nix b/pkgs/development/compilers/llvm/8/default.nix
index 9131a873b3b..856cd6e0661 100644
--- a/pkgs/development/compilers/llvm/8/default.nix
+++ b/pkgs/development/compilers/llvm/8/default.nix
@@ -3,6 +3,17 @@
 , libxml2, python3, isl, fetchurl, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
+# This is the default binutils, but with *this* version of LLD rather
+# than the default LLVM verion's, if LLD is the choice. We use these for
+# the `useLLVM` bootstrapping below.
+, bootBintoolsNoLibc ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintoolsNoLibc
+, bootBintools ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintools
 }:
 
 let
@@ -35,6 +46,15 @@ let
       ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib"
     '';
 
+  bintoolsNoLibc' =
+    if bootBintoolsNoLibc == null
+    then tools.bintoolsNoLibc
+    else bootBintoolsNoLibc;
+  bintools' =
+    if bootBintools == null
+    then tools.bintools
+    else bootBintools;
+
   in {
 
     libllvm = callPackage ./llvm {
@@ -124,10 +144,10 @@ let
       bintools = tools.bintools-unwrapped;
     };
 
-    lldClang = wrapCCWith rec {
+    clangUseLLVM = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = targetLlvmLibraries.libcxx;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
@@ -146,10 +166,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibcxx = wrapCCWith rec {
+    clangNoLibcxx = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -160,10 +180,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibc = wrapCCWith rec {
+    clangNoLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -173,20 +193,20 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoCompilerRt = wrapCCWith rec {
+    clangNoCompilerRt = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [ ];
       extraBuildCommands = ''
         echo "-nostartfiles" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands0 cc;
     };
 
-    lldClangNoCompilerRtWithLibc = wrapCCWith rec {
+    clangNoCompilerRtWithLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [ ];
       extraBuildCommands = mkExtraBuildCommands0 cc;
     };
@@ -200,14 +220,14 @@ let
     compiler-rt-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRtWithLibc
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
     };
 
     compiler-rt-no-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
     };
 
@@ -223,21 +243,21 @@ let
     libcxx = callPackage ./libcxx {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libcxxabi = callPackage ./libcxxabi {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libunwind = callPackage ./libunwind {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
diff --git a/pkgs/development/compilers/llvm/9/default.nix b/pkgs/development/compilers/llvm/9/default.nix
index 383a1260271..d13bff1f89b 100644
--- a/pkgs/development/compilers/llvm/9/default.nix
+++ b/pkgs/development/compilers/llvm/9/default.nix
@@ -3,6 +3,17 @@
 , libxml2, python3, isl, fetchurl, overrideCC, wrapCCWith, wrapBintoolsWith
 , buildLlvmTools # tools, but from the previous stage, for cross
 , targetLlvmLibraries # libraries, but from the next stage, for cross
+# This is the default binutils, but with *this* version of LLD rather
+# than the default LLVM verion's, if LLD is the choice. We use these for
+# the `useLLVM` bootstrapping below.
+, bootBintoolsNoLibc ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintoolsNoLibc
+, bootBintools ?
+    if stdenv.targetPlatform.linker == "lld"
+    then null
+    else pkgs.bintools
 }:
 
 let
@@ -35,6 +46,15 @@ let
       ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib"
     '';
 
+  bintoolsNoLibc' =
+    if bootBintoolsNoLibc == null
+    then tools.bintoolsNoLibc
+    else bootBintoolsNoLibc;
+  bintools' =
+    if bootBintools == null
+    then tools.bintools
+    else bootBintools;
+
   in {
 
     libllvm = callPackage ./llvm {
@@ -124,10 +144,10 @@ let
       bintools = tools.bintools-unwrapped;
     };
 
-    lldClang = wrapCCWith rec {
+    clangUseLLVM = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = targetLlvmLibraries.libcxx;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
@@ -146,10 +166,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibcxx = wrapCCWith rec {
+    clangNoLibcxx = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -160,10 +180,10 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoLibc = wrapCCWith rec {
+    clangNoLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [
         targetLlvmLibraries.compiler-rt
       ];
@@ -173,20 +193,20 @@ let
       '' + mkExtraBuildCommands cc;
     };
 
-    lldClangNoCompilerRt = wrapCCWith rec {
+    clangNoCompilerRt = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      bintools = tools.bintoolsNoLibc;
+      bintools = bintoolsNoLibc';
       extraPackages = [ ];
       extraBuildCommands = ''
         echo "-nostartfiles" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands0 cc;
     };
 
-    lldClangNoCompilerRtWithLibc = wrapCCWith rec {
+    clangNoCompilerRtWithLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
       libcxx = null;
-      inherit (tools) bintools;
+      bintools = bintools';
       extraPackages = [ ];
       extraBuildCommands = mkExtraBuildCommands0 cc;
     };
@@ -200,14 +220,14 @@ let
     compiler-rt-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRtWithLibc
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
                else stdenv;
     };
 
     compiler-rt-no-libc = callPackage ./compiler-rt {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt
+               then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
                else stdenv;
     };
 
@@ -223,21 +243,21 @@ let
     libcxx = callPackage ./libcxx {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libcxxabi = callPackage ./libcxxabi {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
     libunwind = callPackage ./libunwind {
       inherit llvm_meta;
       stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoLibcxx
+               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
                else stdenv;
     };
 
diff --git a/pkgs/os-specific/windows/default.nix b/pkgs/os-specific/windows/default.nix
index 7c8041206ca..15e3d7f89ab 100644
--- a/pkgs/os-specific/windows/default.nix
+++ b/pkgs/os-specific/windows/default.nix
@@ -19,7 +19,7 @@ lib.makeScope newScope (self: with self; {
 
   crossThreadsStdenv = overrideCC crossLibcStdenv
     (if stdenv.hostPlatform.useLLVM or false
-     then buildPackages.llvmPackages_8.lldClangNoLibcxx
+     then buildPackages.llvmPackages_8.clangNoLibcxx
      else buildPackages.gccCrossStageStatic.override (old: {
        bintools = old.bintools.override {
          libc = libcCross;
diff --git a/pkgs/servers/clickhouse/default.nix b/pkgs/servers/clickhouse/default.nix
index 087f9628505..9607c435fcd 100644
--- a/pkgs/servers/clickhouse/default.nix
+++ b/pkgs/servers/clickhouse/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, fetchFromGitHub, fetchpatch, cmake, libtool, lldClang, ninja
+{ lib, stdenv, fetchFromGitHub, fetchpatch, cmake, libtool, llvm-bintools, ninja
 , boost, brotli, capnproto, cctz, clang-unwrapped, double-conversion
 , icu, jemalloc, libcpuid, libxml2, lld, llvm, lz4, libmysqlclient, openssl, perl
 , poco, protobuf, python3, rapidjson, re2, rdkafka, readline, sparsehash, unixODBC
@@ -19,7 +19,7 @@ stdenv.mkDerivation rec {
     sha256 = "0c87k0xqwj9sc3xy2f3ngfszgjiz4rzd787bdg6fxp94w1adjhny";
   };
 
-  nativeBuildInputs = [ cmake libtool lldClang.bintools ninja ];
+  nativeBuildInputs = [ cmake libtool llvm-bintools ninja ];
   buildInputs = [
     boost brotli capnproto cctz clang-unwrapped double-conversion
     icu jemalloc libcpuid libxml2 lld llvm lz4 libmysqlclient openssl perl
diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix
index ed2b291ca2a..a9fd21534ff 100644
--- a/pkgs/stdenv/cross/default.nix
+++ b/pkgs/stdenv/cross/default.nix
@@ -66,7 +66,7 @@ in lib.init bootStages ++ [
            else if crossSystem.isDarwin
              then buildPackages.llvmPackages.clang
            else if crossSystem.useLLVM or false
-             then buildPackages.llvmPackages.lldClang
+             then buildPackages.llvmPackages.clangUseLLVM
            else buildPackages.gcc;
 
       extraNativeBuildInputs = old.extraNativeBuildInputs
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 3fd6a307b43..2cbca0a5c03 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -48,7 +48,22 @@ in
       lib.mapNullable (rs: rs ++ [ bintools ]) (stdenv.allowedRequisites or null);
   };
 
-  stdenvNoLibs = mkStdenvNoLibs stdenv;
+  stdenvNoLibs =
+    if stdenv.hostPlatform != stdenv.buildPlatform && (stdenv.hostPlatform.isDarwin || stdenv.hostPlatform.isDarwin.useLLVM or false)
+    then
+      # We cannot touch binutils or cc themselves, because that will cause
+      # infinite recursion. So instead, we just choose a libc based on the
+      # current platform. That means we won't respect whatever compiler was
+      # passed in with the stdenv stage argument.
+      #
+      # TODO It would be much better to pass the `stdenvNoCC` and *unwrapped*
+      # cc, bintools, compiler-rt equivalent, etc. and create all final stdenvs
+      # as part of the stage. Then we would never be tempted to override a
+      # later thing to to create an earlier thing (leading to infinite
+      # recursion) and we also would still respect the stage arguments choices
+      # for these things.
+      overrideCC stdenv buildPackages.llvmPackages.clangNoCompilerRt
+    else mkStdenvNoLibs stdenv;
 
   gccStdenvNoLibs = mkStdenvNoLibs gccStdenv;
   clangStdenvNoLibs = mkStdenvNoLibs clangStdenv;
@@ -10451,8 +10466,8 @@ in
   gccCrossLibcStdenv = overrideCC stdenv buildPackages.gccCrossStageStatic;
 
   crossLibcStdenv =
-    if stdenv.hostPlatform.useLLVM or false
-    then overrideCC stdenv buildPackages.llvmPackages.lldClangNoLibc
+    if stdenv.hostPlatform.useLLVM or false || stdenv.hostPlatform.isDarwin
+    then overrideCC stdenv buildPackages.llvmPackages.clangNoLibc
     else gccCrossLibcStdenv;
 
   # The GCC used to build libc for the target platform. Normal gccs will be
@@ -12630,6 +12645,37 @@ in
     libc = preLibcCrossHeaders;
   };
 
+  # Here we select the default bintools implementations to be used.  Note when
+  # cross compiling these are used not for this stage but the *next* stage.
+  # That is why we choose using this stage's target platform / next stage's
+  # host platform.
+  #
+  # Because this is the *next* stages choice, it's a bit non-modular to put
+  # here. In theory, bootstraping is supposed to not be a chain but at tree,
+  # where each stage supports many "successor" stages, like multiple possible
+  # futures. We don't have a better alternative, but with this downside in
+  # mind, please be judicious when using this attribute. E.g. for building
+  # things in *this* stage you should use probably `stdenv.cc.bintools` (from a
+  # default or alternate `stdenv`), at build time, and try not to "force" a
+  # specific bintools at runtime at all.
+  #
+  # In other words, try to only use this in wrappers, and only use those
+  # wrappers from the next stage.
+  bintools-unwrapped = let
+    inherit (stdenv.targetPlatform) linker;
+  in     if linker == "lld"     then llvmPackages.bintools-unwrapped
+    else if linker == "cctools" then darwin.binutils-unwrapped
+    else if linker == "bfd"     then binutils-unwrapped
+    else if linker == "gold"    then binutils-unwrapped
+    else null;
+  bintoolsNoLibc = wrapBintoolsWith {
+    bintools = bintools-unwrapped;
+    libc = preLibcCrossHeaders;
+  };
+  bintools = wrapBintoolsWith {
+    bintools = bintools-unwrapped;
+  };
+
   bison = callPackage ../development/tools/parsing/bison { };
 
   # Ruby fails to build with current bison
@@ -14765,8 +14811,8 @@ in
   # These are used when buiding compiler-rt / libgcc, prior to building libc.
   preLibcCrossHeaders = let
     inherit (stdenv.targetPlatform) libc;
-  in     if libc == "msvcrt" then targetPackages.windows.mingw_w64_headers
-    else if libc == "nblibc" then targetPackages.netbsdCross.headers
+  in     if libc == "msvcrt" then targetPackages.windows.mingw_w64_headers or windows.mingw_w64_headers
+    else if libc == "nblibc" then targetPackages.netbsdCross.headers or netbsdCross.headers
     else null;
 
   # We can choose:
@@ -18702,7 +18748,8 @@ in
 
   clickhouse = callPackage ../servers/clickhouse {
     # upstream requires llvm10 as of v20.11.4.13
-    inherit (llvmPackages_10) clang-unwrapped lld lldClang llvm;
+    inherit (llvmPackages_10) clang-unwrapped lld llvm;
+    llvm-bintools = llvmPackages_10.bintools;
   };
 
   clickhouse-cli = with python3Packages; toPythonApplication clickhouse-cli;