forked from mirrors/nixpkgs
dc895fb281
the fix to extendDerivation in #140051 unwittingly worsened eval performance by quite a bit. set elements alone needed over 1GB extra after the change, which seems disproportionate to how small it was. if we flip the logic used to determine which outputs to install around and keep a "this one exactly" flag in the specific outputs instead of a "all of them" in the root we can avoid most of that cost.
271 lines
9 KiB
Nix
271 lines
9 KiB
Nix
{ lowPrio, newScope, pkgs, lib, stdenv, cmake
|
||
, gccForLibs, preLibcCrossHeaders
|
||
, 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
|
||
}:
|
||
|
||
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
|
||
targetConfig = stdenv.targetPlatform.config;
|
||
|
||
fetch = name: sha256: fetchurl {
|
||
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/${name}-${release_version}${candidate}.src.tar.xz";
|
||
inherit sha256;
|
||
};
|
||
|
||
clang-tools-extra_src = fetch "clang-tools-extra" "1r9a4fdz9ci58b5z2inwvm4z4cdp6scrivnaw05dggkxz7yrwrb5";
|
||
|
||
llvm_meta = {
|
||
license = lib.licenses.ncsa;
|
||
maintainers = with lib.maintainers; [ lovek323 raskin dtzWill primeos ];
|
||
platforms = lib.platforms.all;
|
||
};
|
||
|
||
tools = lib.makeExtensible (tools: let
|
||
callPackage = newScope (tools // { inherit stdenv cmake libxml2 python3 isl release_version version fetch buildLlvmTools; });
|
||
mkExtraBuildCommands0 = cc: ''
|
||
rsrc="$out/resource-root"
|
||
mkdir "$rsrc"
|
||
ln -s "${cc.lib}/lib/clang/${release_version}/include" "$rsrc"
|
||
echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
|
||
'';
|
||
mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
|
||
ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib"
|
||
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 {
|
||
inherit llvm_meta;
|
||
};
|
||
|
||
# `llvm` historically had the binaries. When choosing an output explicitly,
|
||
# we need to reintroduce `outputSpecified` to get the expected behavior e.g. of lib.get*
|
||
llvm = tools.libllvm.out // { outputSpecified = false; };
|
||
|
||
libclang = callPackage ./clang {
|
||
inherit clang-tools-extra_src llvm_meta;
|
||
};
|
||
|
||
clang-unwrapped = tools.libclang.out // { outputSpecified = false; };
|
||
|
||
# disabled until recommonmark supports sphinx 3
|
||
#Llvm-manpages = lowPrio (tools.libllvm.override {
|
||
# enableManpages = true;
|
||
# python3 = pkgs.python3; # don't use python-boot
|
||
#});
|
||
|
||
clang-manpages = lowPrio (tools.libclang.override {
|
||
enableManpages = true;
|
||
python3 = pkgs.python3; # don't use python-boot
|
||
});
|
||
|
||
# disabled until recommonmark supports sphinx 3
|
||
# lldb-manpages = lowPrio (tools.lldb.override {
|
||
# enableManpages = true;
|
||
# python3 = pkgs.python3; # don't use python-boot
|
||
# });
|
||
|
||
clang = if stdenv.cc.isGNU then tools.libstdcxxClang else tools.libcxxClang;
|
||
|
||
libstdcxxClang = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
# libstdcxx is taken from gcc in an ad-hoc way in cc-wrapper.
|
||
libcxx = null;
|
||
extraPackages = [
|
||
targetLlvmLibraries.compiler-rt
|
||
];
|
||
extraBuildCommands = mkExtraBuildCommands cc;
|
||
};
|
||
|
||
libcxxClang = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = targetLlvmLibraries.libcxx;
|
||
extraPackages = [
|
||
targetLlvmLibraries.libcxxabi
|
||
targetLlvmLibraries.compiler-rt
|
||
];
|
||
extraBuildCommands = mkExtraBuildCommands cc;
|
||
};
|
||
|
||
lld = callPackage ./lld {
|
||
inherit llvm_meta;
|
||
inherit (libraries) libunwind;
|
||
};
|
||
|
||
lldb = callPackage ./lldb {
|
||
inherit llvm_meta;
|
||
inherit (darwin) libobjc bootstrap_cmds;
|
||
inherit (darwin.apple_sdk.libs) xpc;
|
||
inherit (darwin.apple_sdk.frameworks) Foundation Carbon Cocoa;
|
||
};
|
||
|
||
# Below, is the LLVM bootstrapping logic. It handles building a
|
||
# fully LLVM toolchain from scratch. No GCC toolchain should be
|
||
# pulled in. As a consequence, it is very quick to build different
|
||
# targets provided by LLVM and we can also build for what GCC
|
||
# doesn’t support like LLVM. Probably we should move to some other
|
||
# file.
|
||
|
||
bintools-unwrapped = callPackage ./bintools {};
|
||
|
||
bintoolsNoLibc = wrapBintoolsWith {
|
||
bintools = tools.bintools-unwrapped;
|
||
libc = preLibcCrossHeaders;
|
||
};
|
||
|
||
bintools = wrapBintoolsWith {
|
||
bintools = tools.bintools-unwrapped;
|
||
};
|
||
|
||
clangUseLLVM = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = targetLlvmLibraries.libcxx;
|
||
bintools = bintools';
|
||
extraPackages = [
|
||
targetLlvmLibraries.libcxxabi
|
||
targetLlvmLibraries.compiler-rt
|
||
] ++ lib.optionals (!stdenv.targetPlatform.isWasm) [
|
||
targetLlvmLibraries.libunwind
|
||
];
|
||
extraBuildCommands = ''
|
||
echo "-rtlib=compiler-rt -Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags
|
||
echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
|
||
'' + lib.optionalString (!stdenv.targetPlatform.isWasm) ''
|
||
echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags
|
||
'' + lib.optionalString (!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false) ''
|
||
echo "-lunwind" >> $out/nix-support/cc-ldflags
|
||
'' + lib.optionalString stdenv.targetPlatform.isWasm ''
|
||
echo "-fno-exceptions" >> $out/nix-support/cc-cflags
|
||
'' + mkExtraBuildCommands cc;
|
||
};
|
||
|
||
clangNoLibcxx = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = null;
|
||
bintools = bintools';
|
||
extraPackages = [
|
||
targetLlvmLibraries.compiler-rt
|
||
];
|
||
extraBuildCommands = ''
|
||
echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
|
||
echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
|
||
echo "-nostdlib++" >> $out/nix-support/cc-cflags
|
||
'' + mkExtraBuildCommands cc;
|
||
};
|
||
|
||
clangNoLibc = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = null;
|
||
bintools = bintoolsNoLibc';
|
||
extraPackages = [
|
||
targetLlvmLibraries.compiler-rt
|
||
];
|
||
extraBuildCommands = ''
|
||
echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
|
||
echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
|
||
'' + mkExtraBuildCommands cc;
|
||
};
|
||
|
||
clangNoCompilerRt = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = null;
|
||
bintools = bintoolsNoLibc';
|
||
extraPackages = [ ];
|
||
extraBuildCommands = ''
|
||
echo "-nostartfiles" >> $out/nix-support/cc-cflags
|
||
'' + mkExtraBuildCommands0 cc;
|
||
};
|
||
|
||
clangNoCompilerRtWithLibc = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = null;
|
||
bintools = bintools';
|
||
extraPackages = [ ];
|
||
extraBuildCommands = mkExtraBuildCommands0 cc;
|
||
};
|
||
|
||
});
|
||
|
||
libraries = lib.makeExtensible (libraries: let
|
||
callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python3 isl release_version version fetch; });
|
||
in {
|
||
|
||
compiler-rt-libc = callPackage ./compiler-rt {
|
||
inherit llvm_meta;
|
||
stdenv = if stdenv.hostPlatform.useLLVM or false
|
||
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.clangNoCompilerRt
|
||
else stdenv;
|
||
};
|
||
|
||
# N.B. condition is safe because without useLLVM both are the same.
|
||
compiler-rt = if stdenv.hostPlatform.isAndroid
|
||
then libraries.compiler-rt-libc
|
||
else libraries.compiler-rt-no-libc;
|
||
|
||
stdenv = overrideCC stdenv buildLlvmTools.clang;
|
||
|
||
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 = callPackage ./libcxxabi {
|
||
inherit llvm_meta;
|
||
stdenv = if stdenv.hostPlatform.useLLVM or false
|
||
then overrideCC stdenv buildLlvmTools.clangNoLibcxx
|
||
else stdenv;
|
||
};
|
||
|
||
libunwind = callPackage ./libunwind {
|
||
inherit llvm_meta;
|
||
inherit (buildLlvmTools) llvm;
|
||
stdenv = if stdenv.hostPlatform.useLLVM or false
|
||
then overrideCC stdenv buildLlvmTools.clangNoLibcxx
|
||
else stdenv;
|
||
};
|
||
|
||
openmp = callPackage ./openmp {
|
||
inherit llvm_meta;
|
||
};
|
||
});
|
||
|
||
in { inherit tools libraries release_version; } // libraries // tools
|