nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ lowPrio, newScope, pkgs, lib, stdenv, cmake
2, gccForLibs, preLibcCrossHeaders
3, libxml2, python3, fetchFromGitHub, overrideCC, wrapCCWith, wrapBintoolsWith
4, buildLlvmTools # tools, but from the previous stage, for cross
5, targetLlvmLibraries # libraries, but from the next stage, for cross
6, targetLlvm
7# This is the default binutils, but with *this* version of LLD rather
8# than the default LLVM version's, if LLD is the choice. We use these for
9# the `useLLVM` bootstrapping below.
10, bootBintoolsNoLibc ?
11 if stdenv.targetPlatform.linker == "lld"
12 then null
13 else pkgs.bintoolsNoLibc
14, bootBintools ?
15 if stdenv.targetPlatform.linker == "lld"
16 then null
17 else pkgs.bintools
18, darwin
19}:
20
21let
22 release_version = "14.0.6";
23 candidate = ""; # empty or "rcN"
24 dash-candidate = lib.optionalString (candidate != "") "-${candidate}";
25 rev = ""; # When using a Git commit
26 rev-version = ""; # When using a Git commit
27 version = if rev != "" then rev-version else "${release_version}${dash-candidate}";
28 targetConfig = stdenv.targetPlatform.config;
29
30 monorepoSrc = fetchFromGitHub {
31 owner = "llvm";
32 repo = "llvm-project";
33 rev = if rev != "" then rev else "llvmorg-${version}";
34 sha256 = "sha256-vffu4HilvYwtzwgq+NlS26m65DGbp6OSSne2aje1yJE=";
35 };
36
37 llvm_meta = {
38 license = lib.licenses.ncsa;
39 maintainers = lib.teams.llvm.members;
40
41 # See llvm/cmake/config-ix.cmake.
42 platforms =
43 lib.platforms.aarch64 ++
44 lib.platforms.arm ++
45 lib.platforms.m68k ++
46 lib.platforms.mips ++
47 lib.platforms.power ++
48 lib.platforms.riscv ++
49 lib.platforms.s390x ++
50 lib.platforms.wasi ++
51 lib.platforms.x86;
52 };
53
54 tools = lib.makeExtensible (tools: let
55 callPackage = newScope (tools // { inherit stdenv cmake libxml2 python3 release_version version monorepoSrc buildLlvmTools; });
56 mkExtraBuildCommands0 = cc: ''
57 rsrc="$out/resource-root"
58 mkdir "$rsrc"
59 ln -s "${cc.lib}/lib/clang/${release_version}/include" "$rsrc"
60 echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
61 '';
62 mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
63 ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib"
64 ln -s "${targetLlvmLibraries.compiler-rt.out}/share" "$rsrc/share"
65 '';
66
67 bintoolsNoLibc' =
68 if bootBintoolsNoLibc == null
69 then tools.bintoolsNoLibc
70 else bootBintoolsNoLibc;
71 bintools' =
72 if bootBintools == null
73 then tools.bintools
74 else bootBintools;
75
76 in {
77
78 libllvm = callPackage ./llvm {
79 inherit llvm_meta;
80 };
81
82 # `llvm` historically had the binaries. When choosing an output explicitly,
83 # we need to reintroduce `outputSpecified` to get the expected behavior e.g. of lib.get*
84 llvm = tools.libllvm;
85
86 libclang = callPackage ./clang {
87 inherit llvm_meta;
88 };
89
90 clang-unwrapped = tools.libclang;
91
92 llvm-manpages = lowPrio (tools.libllvm.override {
93 enableManpages = true;
94 python3 = pkgs.python3; # don't use python-boot
95 });
96
97 clang-manpages = lowPrio (tools.libclang.override {
98 enableManpages = true;
99 python3 = pkgs.python3; # don't use python-boot
100 });
101
102 # TODO: lldb/docs/index.rst:155:toctree contains reference to nonexisting document 'design/structureddataplugins'
103 # lldb-manpages = lowPrio (tools.lldb.override {
104 # enableManpages = true;
105 # python3 = pkgs.python3; # don't use python-boot
106 # });
107
108 # pick clang appropriate for package set we are targeting
109 clang =
110 /**/ if stdenv.targetPlatform.libc == null then tools.clangNoLibc
111 else if stdenv.targetPlatform.useLLVM or false then tools.clangUseLLVM
112 else if (pkgs.targetPackages.stdenv or stdenv).cc.isGNU then tools.libstdcxxClang
113 else tools.libcxxClang;
114
115 libstdcxxClang = wrapCCWith rec {
116 cc = tools.clang-unwrapped;
117 # libstdcxx is taken from gcc in an ad-hoc way in cc-wrapper.
118 libcxx = null;
119 extraPackages = [
120 targetLlvmLibraries.compiler-rt
121 ];
122 extraBuildCommands = mkExtraBuildCommands cc;
123 };
124
125 libcxxClang = wrapCCWith rec {
126 cc = tools.clang-unwrapped;
127 libcxx = targetLlvmLibraries.libcxx;
128 extraPackages = [
129 libcxx.cxxabi
130 targetLlvmLibraries.compiler-rt
131 ];
132 extraBuildCommands = mkExtraBuildCommands cc;
133 };
134
135 lld = callPackage ./lld {
136 inherit llvm_meta;
137 };
138
139 lldb = callPackage ./lldb {
140 inherit llvm_meta;
141 inherit (darwin) libobjc bootstrap_cmds;
142 inherit (darwin.apple_sdk.libs) xpc;
143 inherit (darwin.apple_sdk.frameworks) Foundation Carbon Cocoa;
144 };
145
146 # Below, is the LLVM bootstrapping logic. It handles building a
147 # fully LLVM toolchain from scratch. No GCC toolchain should be
148 # pulled in. As a consequence, it is very quick to build different
149 # targets provided by LLVM and we can also build for what GCC
150 # doesn’t support like LLVM. Probably we should move to some other
151 # file.
152
153 bintools-unwrapped = callPackage ./bintools {};
154
155 bintoolsNoLibc = wrapBintoolsWith {
156 bintools = tools.bintools-unwrapped;
157 libc = preLibcCrossHeaders;
158 };
159
160 bintools = wrapBintoolsWith {
161 bintools = tools.bintools-unwrapped;
162 };
163
164 clangUseLLVM = wrapCCWith rec {
165 cc = tools.clang-unwrapped;
166 libcxx = targetLlvmLibraries.libcxx;
167 bintools = bintools';
168 extraPackages = [
169 libcxx.cxxabi
170 targetLlvmLibraries.compiler-rt
171 ] ++ lib.optionals (!stdenv.targetPlatform.isWasm) [
172 targetLlvmLibraries.libunwind
173 ];
174 extraBuildCommands = mkExtraBuildCommands cc;
175 nixSupport.cc-cflags =
176 [ "-rtlib=compiler-rt"
177 "-Wno-unused-command-line-argument"
178 "-B${targetLlvmLibraries.compiler-rt}/lib"
179 ]
180 ++ lib.optional (!stdenv.targetPlatform.isWasm) "--unwindlib=libunwind"
181 ++ lib.optional
182 (!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false)
183 "-lunwind"
184 ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
185 };
186
187 clangNoLibcxx = wrapCCWith rec {
188 cc = tools.clang-unwrapped;
189 libcxx = null;
190 bintools = bintools';
191 extraPackages = [
192 targetLlvmLibraries.compiler-rt
193 ];
194 extraBuildCommands = mkExtraBuildCommands cc;
195 nixSupport.cc-cflags = [
196 "-rtlib=compiler-rt"
197 "-B${targetLlvmLibraries.compiler-rt}/lib"
198 "-nostdlib++"
199 ];
200 };
201
202 clangNoLibc = wrapCCWith rec {
203 cc = tools.clang-unwrapped;
204 libcxx = null;
205 bintools = bintoolsNoLibc';
206 extraPackages = [
207 targetLlvmLibraries.compiler-rt
208 ];
209 extraBuildCommands = mkExtraBuildCommands cc;
210 nixSupport.cc-cflags = [
211 "-rtlib=compiler-rt"
212 "-B${targetLlvmLibraries.compiler-rt}/lib"
213 ];
214 };
215
216 clangNoCompilerRt = wrapCCWith rec {
217 cc = tools.clang-unwrapped;
218 libcxx = null;
219 bintools = bintoolsNoLibc';
220 extraPackages = [ ];
221 extraBuildCommands = mkExtraBuildCommands0 cc;
222 nixSupport.cc-cflags = [ "-nostartfiles" ];
223 };
224
225 clangNoCompilerRtWithLibc = wrapCCWith rec {
226 cc = tools.clang-unwrapped;
227 libcxx = null;
228 bintools = bintools';
229 extraPackages = [ ];
230 extraBuildCommands = mkExtraBuildCommands0 cc;
231 };
232
233 });
234
235 libraries = lib.makeExtensible (libraries: let
236 callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python3 release_version version monorepoSrc; });
237 in {
238
239 compiler-rt-libc = callPackage ./compiler-rt {
240 inherit llvm_meta;
241 stdenv = if stdenv.hostPlatform.useLLVM or false
242 then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
243 else stdenv;
244 };
245
246 compiler-rt-no-libc = callPackage ./compiler-rt {
247 inherit llvm_meta;
248 stdenv = if stdenv.hostPlatform.useLLVM or false
249 then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
250 else stdenv;
251 };
252
253 # N.B. condition is safe because without useLLVM both are the same.
254 compiler-rt = if stdenv.hostPlatform.isAndroid
255 then libraries.compiler-rt-libc
256 else libraries.compiler-rt-no-libc;
257
258 stdenv = overrideCC stdenv buildLlvmTools.clang;
259
260 libcxxStdenv = overrideCC stdenv buildLlvmTools.libcxxClang;
261
262 libcxx = callPackage ./libcxx {
263 inherit llvm_meta;
264 stdenv = if stdenv.hostPlatform.useLLVM or false
265 then overrideCC stdenv buildLlvmTools.clangNoLibcxx
266 else stdenv;
267 };
268
269 libcxxabi = let
270 stdenv_ = if stdenv.hostPlatform.useLLVM or false
271 then overrideCC stdenv buildLlvmTools.clangNoLibcxx
272 else stdenv;
273 cxx-headers = callPackage ./libcxx {
274 inherit llvm_meta;
275 stdenv = stdenv_;
276 headersOnly = true;
277 };
278 in callPackage ./libcxxabi {
279 stdenv = stdenv_;
280 inherit llvm_meta cxx-headers;
281 };
282
283 libunwind = callPackage ./libunwind {
284 inherit llvm_meta;
285 stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
286 };
287
288 openmp = callPackage ./openmp {
289 inherit llvm_meta targetLlvm;
290 };
291 });
292
293in { inherit tools libraries release_version; } // libraries // tools