mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-07 13:33:12 +00:00
386aba3115
Context: https://github.com/NixOS/nixpkgs/pull/194634#discussion_r1073157093 All the subprojects seem to be uniformly licensed under NCSA and the LLVM license now (with the exception of openmp which has an additional Intel license that doesn't seem to be in SPDX?); see: - https://github.com/llvm/llvm-project/blob/llvmorg-15.0.7/compiler-rt/LICENSE.TXT - https://github.com/llvm/llvm-project/blob/llvmorg-15.0.7/libcxx/LICENSE.TXT - https://github.com/llvm/llvm-project/blob/llvmorg-15.0.7/libcxxabi/LICENSE.TXT - https://github.com/llvm/llvm-project/blob/llvmorg-15.0.7/openmp/LICENSE.TXT
306 lines
10 KiB
Nix
306 lines
10 KiB
Nix
{ lowPrio, newScope, pkgs, lib, stdenv, stdenvNoCC, cmake, ninja
|
||
, gccForLibs, preLibcCrossHeaders
|
||
, libxml2, python3, fetchFromGitHub, overrideCC, wrapCCWith, wrapBintoolsWith
|
||
, buildLlvmTools # tools, but from the previous stage, for cross
|
||
, targetLlvmLibraries # libraries, but from the next stage, for cross
|
||
, targetLlvm
|
||
# 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 = "15.0.7";
|
||
candidate = ""; # empty or "rcN"
|
||
dash-candidate = lib.optionalString (candidate != "") "-${candidate}";
|
||
rev = ""; # When using a Git commit
|
||
rev-version = ""; # When using a Git commit
|
||
version = if rev != "" then rev-version else "${release_version}${dash-candidate}";
|
||
targetConfig = stdenv.targetPlatform.config;
|
||
|
||
monorepoSrc = fetchFromGitHub {
|
||
owner = "llvm";
|
||
repo = "llvm-project";
|
||
rev = if rev != "" then rev else "llvmorg-${version}";
|
||
sha256 = "sha256-wjuZQyXQ/jsmvy6y1aksCcEDXGBjuhpgngF3XQJ/T4s=";
|
||
};
|
||
|
||
llvm_meta = {
|
||
license = with lib.licenses; [ ncsa llvm-exception ];
|
||
maintainers = lib.teams.llvm.members;
|
||
platforms = lib.platforms.all;
|
||
};
|
||
|
||
tools = lib.makeExtensible (tools: let
|
||
callPackage = newScope (tools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc 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 llvm_meta;
|
||
};
|
||
|
||
clang-unwrapped = tools.libclang.out // { outputSpecified = false; };
|
||
|
||
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
|
||
});
|
||
|
||
lldb-manpages = lowPrio (tools.lldb.override {
|
||
enableManpages = true;
|
||
python3 = pkgs.python3; # don't use python-boot
|
||
});
|
||
|
||
# pick clang appropriate for package set we are targeting
|
||
clang =
|
||
/**/ if stdenv.targetPlatform.useLLVM or false then tools.clangUseLLVM
|
||
else if (pkgs.targetPackages.stdenv or 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 = [
|
||
libcxx.cxxabi
|
||
targetLlvmLibraries.compiler-rt
|
||
];
|
||
extraBuildCommands = mkExtraBuildCommands cc;
|
||
};
|
||
|
||
lld = callPackage ./lld {
|
||
inherit llvm_meta;
|
||
};
|
||
|
||
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 = [
|
||
libcxx.cxxabi
|
||
targetLlvmLibraries.compiler-rt
|
||
] ++ lib.optionals (!stdenv.targetPlatform.isWasm) [
|
||
targetLlvmLibraries.libunwind
|
||
];
|
||
extraBuildCommands = mkExtraBuildCommands cc;
|
||
nixSupport.cc-cflags =
|
||
[ "-rtlib=compiler-rt"
|
||
"-Wno-unused-command-line-argument"
|
||
"-B${targetLlvmLibraries.compiler-rt}/lib"
|
||
]
|
||
++ lib.optional (!stdenv.targetPlatform.isWasm) "--unwindlib=libunwind"
|
||
++ lib.optional
|
||
(!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false)
|
||
"-lunwind"
|
||
++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
|
||
};
|
||
|
||
clangNoLibcxx = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = null;
|
||
bintools = bintools';
|
||
extraPackages = [
|
||
targetLlvmLibraries.compiler-rt
|
||
];
|
||
extraBuildCommands = mkExtraBuildCommands cc;
|
||
nixSupport.cc-cflags = [
|
||
"-rtlib=compiler-rt"
|
||
"-B${targetLlvmLibraries.compiler-rt}/lib"
|
||
"-nostdlib++"
|
||
];
|
||
};
|
||
|
||
clangNoLibc = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = null;
|
||
bintools = bintoolsNoLibc';
|
||
extraPackages = [
|
||
targetLlvmLibraries.compiler-rt
|
||
];
|
||
extraBuildCommands = mkExtraBuildCommands cc;
|
||
nixSupport.cc-cflags = [
|
||
"-rtlib=compiler-rt"
|
||
"-B${targetLlvmLibraries.compiler-rt}/lib"
|
||
];
|
||
};
|
||
|
||
clangNoCompilerRt = wrapCCWith rec {
|
||
cc = tools.clang-unwrapped;
|
||
libcxx = null;
|
||
bintools = bintoolsNoLibc';
|
||
extraPackages = [ ];
|
||
extraBuildCommands = mkExtraBuildCommands0 cc;
|
||
nixSupport.cc-cflags = [ "-nostartfiles" ];
|
||
};
|
||
|
||
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 ninja libxml2 python3 release_version version monorepoSrc; });
|
||
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;
|
||
|
||
libcxxabi = let
|
||
# 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;
|
||
# Note that if we use the regular stdenv here we'll get cycle errors
|
||
# when attempting to use this compiler in the stdenv.
|
||
#
|
||
# The final stdenv pulls `cxx-headers` from the package set where
|
||
# hostPlatform *is* the target platform which means that `stdenv` at
|
||
# that point attempts to use this toolchain.
|
||
#
|
||
# So, we use `stdenv_` (the stdenv containing `clang` from this package
|
||
# set, defined below) to sidestep this issue.
|
||
#
|
||
# Because we only use `cxx-headers` in `libcxxabi` (which depends on the
|
||
# clang stdenv _anyways_), this is okay.
|
||
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;
|
||
};
|
||
|
||
openmp = callPackage ./openmp {
|
||
inherit llvm_meta targetLlvm;
|
||
};
|
||
});
|
||
|
||
in { inherit tools libraries release_version; } // libraries // tools
|