about summary refs log tree commit diff
path: root/pkgs/development/compilers
diff options
context:
space:
mode:
authorRahul Butani <rrbutani@users.noreply.github.com>2022-10-07 15:22:55 -0500
committerRahul Butani <rrbutani@users.noreply.github.com>2023-01-27 13:29:21 -0800
commitca59a201ca1dfe77bdd5b6ce98b7ac75142549d2 (patch)
tree8fcfd4ff670389c559c649289e6554946230a391 /pkgs/development/compilers
parent4fabcf49458fc01f89ce494d0e5c18ec9ce167fb (diff)
downloadnixlib-ca59a201ca1dfe77bdd5b6ce98b7ac75142549d2.tar
nixlib-ca59a201ca1dfe77bdd5b6ce98b7ac75142549d2.tar.gz
nixlib-ca59a201ca1dfe77bdd5b6ce98b7ac75142549d2.tar.bz2
nixlib-ca59a201ca1dfe77bdd5b6ce98b7ac75142549d2.tar.lz
nixlib-ca59a201ca1dfe77bdd5b6ce98b7ac75142549d2.tar.xz
nixlib-ca59a201ca1dfe77bdd5b6ce98b7ac75142549d2.tar.zst
nixlib-ca59a201ca1dfe77bdd5b6ce98b7ac75142549d2.zip
llvmPackages_15.libcxx: use clang 15 instead of the stdenv's compiler
libc++ has switched to using `__attribute__((using_if_exists))` to handle
incomplete libc implementations; see: https://github.com/llvm/llvm-project/commit/a9c9183ca42629fa83cdda297d1d30c7bc1d7c91

These essentially require a modern C++ compiler (clang gained support in
LLVM 13: https://github.com/llvm/llvm-project/commit/369c64839946d89cf5697550b6feeea031b2f270,
gcc appears to not have support yet: https://gcc.gnu.org/bugzilla//show_bug.cgi?id=105584).

Previously this was not an issue for us (despite the transition happening
around LLVM 13) but something about the changes to the libc++/libc++-abi
build has made it so that on platforms with incomplete libc impls (i.e.
Darwin is missing `quick_exit`/`at_quick_exit`) we error during the `libcxx-abi`
build when the stdenv's (older, not supporting `using_if_exists`) compiler
tries to import libc symbols that aren't present.

The libc++ docs suggest we use a modern compiler to build libc++ anyways
(https://releases.llvm.org/15.0.0/projects/libcxx/docs/index.html#platform-and-compiler-support)
so this commit uses stdenv's containing the package set's clang to build
libcxx/libcxx-abi.

This is similar to how libc++ bootstrapping builds (https://releases.llvm.org/15.0.0/projects/libcxx/docs/BuildingLibcxx.html#bootstrapping-build)
work.
Diffstat (limited to 'pkgs/development/compilers')
-rw-r--r--pkgs/development/compilers/llvm/15/default.nix34
-rw-r--r--pkgs/development/compilers/llvm/15/libcxxabi/default.nix7
2 files changed, 30 insertions, 11 deletions
diff --git a/pkgs/development/compilers/llvm/15/default.nix b/pkgs/development/compilers/llvm/15/default.nix
index 964ec5acd58d..d9b117ee2343 100644
--- a/pkgs/development/compilers/llvm/15/default.nix
+++ b/pkgs/development/compilers/llvm/15/default.nix
@@ -247,27 +247,39 @@ let
 
     libcxxStdenv = overrideCC stdenv buildLlvmTools.libcxxClang;
 
-    libcxx = callPackage ./libcxx {
-      inherit llvm_meta;
-      stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
-               else stdenv;
-    };
-
     libcxxabi = let
-      stdenv_ = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.clangNoLibcxx
-               else stdenv;
+      # CMake will "require" a compiler capable of compiling C++ programs
+      # cxx-header's build does not actually use one so it doesn't really matter
+      # what stdenv we use here, as long as CMake is happy.
       cxx-headers = callPackage ./libcxx {
         inherit llvm_meta;
-        stdenv = stdenv_;
         headersOnly = true;
       };
+
+      # `libcxxabi` *doesn't* need a compiler with a working C++ stdlib but it
+      # *does* need a relatively modern C++ compiler (see:
+      # https://releases.llvm.org/15.0.0/projects/libcxx/docs/index.html#platform-and-compiler-support).
+      #
+      # So, we use the clang from this LLVM package set, like libc++
+      # "boostrapping builds" do:
+      # https://releases.llvm.org/15.0.0/projects/libcxx/docs/BuildingLibcxx.html#bootstrapping-build
+      #
+      # We cannot use `clangNoLibcxx` because that contains `compiler-rt` which,
+      # on macOS, depends on `libcxxabi`, thus forming a cycle.
+      stdenv_ = overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc;
     in callPackage ./libcxxabi {
       stdenv = stdenv_;
       inherit llvm_meta cxx-headers;
     };
 
+    # Like `libcxxabi` above, `libcxx` requires a fairly modern C++ compiler,
+    # so: we use the clang from this LLVM package set instead of the regular
+    # stdenv's compiler.
+    libcxx = callPackage ./libcxx {
+      inherit llvm_meta;
+      stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
+    };
+
     libunwind = callPackage ./libunwind {
       inherit llvm_meta;
       stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
diff --git a/pkgs/development/compilers/llvm/15/libcxxabi/default.nix b/pkgs/development/compilers/llvm/15/libcxxabi/default.nix
index 22fbcc67c935..ea9f7cb0772e 100644
--- a/pkgs/development/compilers/llvm/15/libcxxabi/default.nix
+++ b/pkgs/development/compilers/llvm/15/libcxxabi/default.nix
@@ -58,6 +58,13 @@ stdenv.mkDerivation rec {
   cmakeFlags = [
     "-DLLVM_ENABLE_RUNTIMES=libcxxabi"
     "-DLIBCXXABI_LIBCXX_INCLUDES=${cxx-headers}/include/c++/v1"
+
+    # `libcxxabi`'s build does not need a toolchain with a c++ stdlib attached
+    # (we specify the headers it should use explicitly above).
+    #
+    # CMake however checks for this anyways; this flag tells it not to. See:
+    # https://github.com/llvm/llvm-project/blob/4bd3f3759259548e159aeba5c76efb9a0864e6fa/llvm/runtimes/CMakeLists.txt#L243
+    "-DCMAKE_CXX_COMPILER_WORKS=ON"
   ] ++ lib.optionals (stdenv.hostPlatform.useLLVM or false) [
     "-DLLVM_ENABLE_LIBCXX=ON"
     "-DLIBCXXABI_USE_LLVM_UNWINDER=ON"