nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 pkgs,
3 targetPackages,
4 lib,
5 stdenv,
6 preLibcHeaders,
7 fetchFromGitHub,
8 overrideCC,
9 wrapCCWith,
10 wrapBintoolsWith,
11 makeScopeWithSplicing',
12 otherSplices,
13 splicePackages,
14 # This is the default binutils, but with *this* version of LLD rather
15 # than the default LLVM version's, if LLD is the choice. We use these for
16 # the `useLLVM` bootstrapping below.
17 bootBintoolsNoLibc,
18 bootBintools,
19 darwin,
20 gitRelease ? null,
21 officialRelease ? null,
22 monorepoSrc ? null,
23 version ? null,
24 patchesFn ? lib.id,
25 cmake,
26 cmakeMinimal,
27 python3,
28 python3Minimal,
29 # Allows passthrough to packages via newScope. This makes it possible to
30 # do `(llvmPackages.override { <someLlvmDependency> = bar; }).clang` and get
31 # an llvmPackages whose packages are overridden in an internally consistent way.
32 ...
33}@args:
34
35assert lib.assertMsg (lib.xor (gitRelease != null) (officialRelease != null)) (
36 "must specify `gitRelease` or `officialRelease`"
37 + (lib.optionalString (gitRelease != null) " — not both")
38);
39
40let
41 monorepoSrc' = monorepoSrc;
42
43 metadata = rec {
44 # Import releaseInfo separately to avoid infinite recursion
45 inherit
46 (import ./common-let.nix {
47 inherit (args)
48 lib
49 gitRelease
50 officialRelease
51 version
52 ;
53 })
54 releaseInfo
55 ;
56 inherit (releaseInfo) release_version version;
57 inherit
58 (import ./common-let.nix {
59 inherit
60 lib
61 fetchFromGitHub
62 release_version
63 gitRelease
64 officialRelease
65 monorepoSrc'
66 version
67 ;
68 })
69 llvm_meta
70 monorepoSrc
71 ;
72 src = monorepoSrc;
73 versionDir =
74 (toString ../.) + "/${if (gitRelease != null) then "git" else lib.versions.major release_version}";
75 getVersionFile =
76 p:
77 builtins.path {
78 name = baseNameOf p;
79 path =
80 let
81 patches = args.patchesFn (import ./patches.nix);
82
83 constraints = patches."${p}" or null;
84 matchConstraint =
85 {
86 before ? null,
87 after ? null,
88 path,
89 }:
90 let
91 check = fn: value: if value == null then true else fn release_version value;
92 matchBefore = check lib.versionOlder before;
93 matchAfter = check lib.versionAtLeast after;
94 in
95 matchBefore && matchAfter;
96
97 patchDir =
98 toString
99 (
100 if constraints == null then
101 { path = metadata.versionDir; }
102 else
103 (lib.findFirst matchConstraint { path = metadata.versionDir; } constraints)
104 ).path;
105 in
106 "${patchDir}/${p}";
107 };
108 };
109
110 buildLlvmPackages = otherSplices.selfBuildHost;
111in
112makeScopeWithSplicing' {
113 inherit otherSplices;
114 extra = _spliced0: args // metadata // { inherit buildLlvmPackages; };
115 f =
116 self:
117 let
118 targetLlvmPackages =
119 if otherSplices.selfTargetTarget == { } then self else otherSplices.selfTargetTarget;
120
121 # FIXME: This is a tragic and unprincipled hack, but I don’t
122 # know what would actually be good instead.
123 newScope = scope: self.newScope ({ inherit (args) stdenv; } // scope);
124 callPackage = newScope { };
125
126 clangVersion = lib.versions.major metadata.release_version;
127
128 mkExtraBuildCommands0 =
129 cc:
130 ''
131 rsrc="$out/resource-root"
132 mkdir "$rsrc"
133 echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
134 ''
135 # clang standard c headers are incompatible with FreeBSD so we have to put them in -idirafter instead of -resource-dir
136 # see https://github.com/freebsd/freebsd-src/commit/f382bac49b1378da3c2dd66bf721beaa16b5d471
137 + (
138 if stdenv.targetPlatform.isFreeBSD then
139 ''
140 echo "-idirafter ${lib.getLib cc}/lib/clang/${clangVersion}/include" >> $out/nix-support/cc-cflags
141 ''
142 else
143 ''
144 ln -s "${lib.getLib cc}/lib/clang/${clangVersion}/include" "$rsrc"
145 ''
146 );
147
148 mkExtraBuildCommandsBasicRt =
149 cc:
150 mkExtraBuildCommands0 cc
151 + ''
152 ln -s "${targetLlvmPackages.compiler-rt-no-libc.out}/lib" "$rsrc/lib"
153 '';
154
155 mkExtraBuildCommands =
156 cc:
157 mkExtraBuildCommands0 cc
158 + ''
159 ln -s "${targetLlvmPackages.compiler-rt.out}/lib" "$rsrc/lib"
160 ln -s "${targetLlvmPackages.compiler-rt.out}/share" "$rsrc/share"
161 '';
162
163 bintoolsNoLibc' = if bootBintoolsNoLibc == null then self.bintoolsNoLibc else bootBintoolsNoLibc;
164 bintools' = if bootBintools == null then self.bintools else bootBintools;
165 in
166 {
167 inherit (metadata) release_version;
168
169 libllvm = callPackage ./llvm { };
170
171 # `llvm` historically had the binaries. When choosing an output explicitly,
172 # we need to reintroduce `outputSpecified` to get the expected behavior e.g. of lib.get*
173 llvm = self.libllvm;
174
175 tblgen = callPackage ./tblgen.nix {
176 patches =
177 builtins.filter
178 # Crude method to drop polly patches if present, they're not needed for tblgen.
179 (p: (!lib.hasInfix "-polly" p))
180 self.libllvm.patches;
181 clangPatches = [
182 # Would take tools.libclang.patches, but this introduces a cycle due
183 # to replacements depending on the llvm outpath (e.g. the LLVMgold patch).
184 # So take the only patch known to be necessary.
185 (metadata.getVersionFile "clang/gnu-install-dirs.patch")
186 ];
187 };
188
189 libclang = callPackage ./clang { };
190
191 clang-unwrapped = self.libclang;
192
193 llvm-manpages = lib.lowPrio (
194 self.libllvm.override {
195 enableManpages = true;
196 python3 = pkgs.python3; # don't use python-boot
197 }
198 );
199
200 clang-manpages = lib.lowPrio (
201 self.libclang.override {
202 enableManpages = true;
203 python3 = pkgs.python3; # don't use python-boot
204 }
205 );
206
207 # Wrapper for standalone command line utilities
208 clang-tools = callPackage ./clang-tools { };
209
210 # pick clang appropriate for package set we are targeting
211 clang =
212 if stdenv.targetPlatform.libc == null then
213 self.clangNoLibc
214 else if stdenv.targetPlatform.isDarwin then
215 self.systemLibcxxClang
216 else if stdenv.targetPlatform.useLLVM or false then
217 self.clangUseLLVM
218 else if (targetPackages.stdenv or stdenv).cc.isGNU then
219 self.libstdcxxClang
220 else
221 self.libcxxClang;
222
223 libstdcxxClang = wrapCCWith rec {
224 cc = self.clang-unwrapped;
225 # libstdcxx is taken from gcc in an ad-hoc way in cc-wrapper.
226 libcxx = null;
227 extraPackages = [ targetLlvmPackages.compiler-rt ];
228 extraBuildCommands = mkExtraBuildCommands cc;
229 };
230
231 libcxxClang = wrapCCWith rec {
232 cc = self.clang-unwrapped;
233 libcxx = targetLlvmPackages.libcxx;
234 extraPackages = [ targetLlvmPackages.compiler-rt ];
235 extraBuildCommands = mkExtraBuildCommands cc;
236 };
237
238 # Darwin uses the system libc++ by default. It is set up as its own clang definition so that `libcxxClang`
239 # continues to use the libc++ from LLVM.
240 systemLibcxxClang = wrapCCWith rec {
241 cc = self.clang-unwrapped;
242 libcxx = darwin.libcxx;
243 extraPackages = [ targetLlvmPackages.compiler-rt ];
244 extraBuildCommands = mkExtraBuildCommands cc;
245 };
246
247 lld = callPackage ./lld { };
248
249 lldbPlugins = lib.recurseIntoAttrs (
250 lib.makeScopeWithSplicing'
251 {
252 inherit splicePackages newScope;
253 }
254 {
255 otherSplices = lib.mapAttrs (_: selfSplice: selfSplice.lldbPlugins or { }) otherSplices;
256 f = selfLldbPlugins: {
257 llef = selfLldbPlugins.callPackage ./lldb-plugins/llef.nix { };
258 };
259 }
260 );
261
262 lldb = callPackage ./lldb { };
263
264 lldb-manpages = lib.lowPrio (
265 self.lldb.override {
266 enableManpages = true;
267 python3 = pkgs.python3; # don't use python-boot
268 }
269 );
270
271 # Below, is the LLVM bootstrapping logic. It handles building a
272 # fully LLVM toolchain from scratch. No GCC toolchain should be
273 # pulled in. As a consequence, it is very quick to build different
274 # targets provided by LLVM and we can also build for what GCC
275 # doesn’t support like LLVM. Probably we should move to some other
276 # file.
277
278 bintools-unwrapped = callPackage ./bintools.nix { };
279
280 bintoolsNoLibc = wrapBintoolsWith {
281 bintools = self.bintools-unwrapped;
282 libc = targetPackages.preLibcHeaders or preLibcHeaders;
283 };
284
285 bintools = wrapBintoolsWith {
286 bintools = self.bintools-unwrapped;
287 };
288
289 clangUseLLVM = wrapCCWith rec {
290 cc = self.clang-unwrapped;
291 libcxx = targetLlvmPackages.libcxx;
292 bintools = bintools';
293 extraPackages = [
294 targetLlvmPackages.compiler-rt
295 ]
296 ++ lib.optionals (!stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD) [
297 targetLlvmPackages.libunwind
298 ];
299 extraBuildCommands = mkExtraBuildCommands cc;
300 nixSupport.cc-cflags = [
301 "-rtlib=compiler-rt"
302 "-Wno-unused-command-line-argument"
303 "-B${targetLlvmPackages.compiler-rt}/lib"
304 ]
305 ++ lib.optional (
306 !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD
307 ) "--unwindlib=libunwind"
308 ++ lib.optional (
309 !stdenv.targetPlatform.isWasm
310 && !stdenv.targetPlatform.isFreeBSD
311 && stdenv.targetPlatform.useLLVM or false
312 ) "-lunwind"
313 ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
314 nixSupport.cc-ldflags = lib.optionals (
315 !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD
316 ) [ "-L${targetLlvmPackages.libunwind}/lib" ];
317 };
318
319 clangWithLibcAndBasicRtAndLibcxx = wrapCCWith rec {
320 cc = self.clang-unwrapped;
321 # This is used to build compiler-rt. Make sure to use the system libc++ on Darwin.
322 #
323 # FIXME: This should almost certainly use
324 # `stdenv.targetPlatform` and `targetPackages.darwin.libcxx`.
325 libcxx = if stdenv.hostPlatform.isDarwin then darwin.libcxx else targetLlvmPackages.libcxx;
326 bintools = bintools';
327 extraPackages = [
328 targetLlvmPackages.compiler-rt-no-libc
329 ]
330 ++
331 lib.optionals
332 (
333 !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD && !stdenv.targetPlatform.isDarwin
334 )
335 [
336 targetLlvmPackages.libunwind
337 ];
338 extraBuildCommands = mkExtraBuildCommandsBasicRt cc;
339 nixSupport.cc-cflags = [
340 "-rtlib=compiler-rt"
341 "-Wno-unused-command-line-argument"
342 "-B${targetLlvmPackages.compiler-rt-no-libc}/lib"
343 ]
344 ++ lib.optional (
345 !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD && !stdenv.targetPlatform.isDarwin
346 ) "--unwindlib=libunwind"
347 ++ lib.optional (
348 !stdenv.targetPlatform.isWasm
349 && !stdenv.targetPlatform.isFreeBSD
350 && stdenv.targetPlatform.useLLVM or false
351 ) "-lunwind"
352 ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
353 nixSupport.cc-ldflags = lib.optionals (
354 !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD && !stdenv.targetPlatform.isDarwin
355 ) [ "-L${targetLlvmPackages.libunwind}/lib" ];
356 };
357
358 clangWithLibcAndBasicRt = wrapCCWith rec {
359 cc = self.clang-unwrapped;
360 libcxx = null;
361 bintools = bintools';
362 extraPackages = [ targetLlvmPackages.compiler-rt-no-libc ];
363 extraBuildCommands = mkExtraBuildCommandsBasicRt cc;
364 nixSupport.cc-cflags = [
365 "-rtlib=compiler-rt"
366 "-B${targetLlvmPackages.compiler-rt-no-libc}/lib"
367 "-nostdlib++"
368 ]
369 ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
370 };
371
372 clangNoLibcWithBasicRt = wrapCCWith rec {
373 cc = self.clang-unwrapped;
374 libcxx = null;
375 bintools = bintoolsNoLibc';
376 extraPackages = [ targetLlvmPackages.compiler-rt-no-libc ];
377 extraBuildCommands = mkExtraBuildCommandsBasicRt cc;
378 nixSupport.cc-cflags = [
379 "-rtlib=compiler-rt"
380 "-B${targetLlvmPackages.compiler-rt-no-libc}/lib"
381 ]
382 ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
383 };
384
385 clangNoLibcNoRt = wrapCCWith rec {
386 cc = self.clang-unwrapped;
387 libcxx = null;
388 bintools = bintoolsNoLibc';
389 extraPackages = [ ];
390 extraBuildCommands = mkExtraBuildCommands0 cc;
391 # "-nostartfiles" used to be needed for pkgsLLVM, causes problems so don't include it.
392 nixSupport.cc-cflags = lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
393 };
394
395 # This is an "oddly ordered" bootstrap just for Darwin. Probably
396 # don't want it otherwise.
397 clangNoCompilerRtWithLibc = wrapCCWith rec {
398 cc = self.clang-unwrapped;
399 libcxx = null;
400 bintools = bintools';
401 extraPackages = [ ];
402 extraBuildCommands = mkExtraBuildCommands0 cc;
403 nixSupport.cc-cflags = lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
404 };
405
406 # Aliases
407 clangNoCompilerRt = self.clangNoLibcNoRt;
408 clangNoLibc = self.clangNoLibcWithBasicRt;
409 clangNoLibcxx = self.clangWithLibcAndBasicRt;
410
411 compiler-rt-libc = callPackage ./compiler-rt (
412 let
413 # temp rename to avoid infinite recursion
414 stdenv =
415 # Darwin needs to use a bootstrap stdenv to avoid an infinite recursion when cross-compiling.
416 if args.stdenv.hostPlatform.isDarwin then
417 overrideCC darwin.bootstrapStdenv buildLlvmPackages.clangWithLibcAndBasicRtAndLibcxx
418 else if args.stdenv.hostPlatform.useLLVM or false then
419 overrideCC args.stdenv buildLlvmPackages.clangWithLibcAndBasicRtAndLibcxx
420 else
421 args.stdenv;
422 in
423 {
424 inherit stdenv;
425 }
426 );
427
428 compiler-rt-no-libc = callPackage ./compiler-rt {
429 doFakeLibgcc = stdenv.hostPlatform.useLLVM or false;
430 stdenv =
431 # Darwin needs to use a bootstrap stdenv to avoid an infinite recursion when cross-compiling.
432 if stdenv.hostPlatform.isDarwin then
433 overrideCC darwin.bootstrapStdenv buildLlvmPackages.clangNoLibcNoRt
434 else
435 overrideCC stdenv buildLlvmPackages.clangNoLibcNoRt;
436 };
437
438 compiler-rt =
439 if
440 stdenv.hostPlatform.libc == null
441 # Building the with-libc compiler-rt and WASM doesn't yet work,
442 # because wasilibc doesn't provide some expected things. See
443 # compiler-rt's file for further details.
444 || stdenv.hostPlatform.isWasm
445 # Failing `#include <term.h>` in
446 # `lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp`
447 # sanitizers, not sure where to get it.
448 || stdenv.hostPlatform.isFreeBSD
449 then
450 self.compiler-rt-no-libc
451 else
452 self.compiler-rt-libc;
453
454 stdenv = overrideCC stdenv buildLlvmPackages.clang;
455
456 libcxxStdenv = overrideCC stdenv buildLlvmPackages.libcxxClang;
457
458 libcxx = callPackage ./libcxx {
459 stdenv =
460 if stdenv.hostPlatform.isDarwin then
461 overrideCC darwin.bootstrapStdenv buildLlvmPackages.clangWithLibcAndBasicRt
462 else
463 overrideCC stdenv buildLlvmPackages.clangWithLibcAndBasicRt;
464 };
465
466 libunwind = callPackage ./libunwind {
467 stdenv = overrideCC stdenv buildLlvmPackages.clangWithLibcAndBasicRt;
468 };
469
470 openmp = callPackage ./openmp { };
471
472 mlir = callPackage ./mlir { };
473
474 libclc = callPackage ./libclc { };
475 }
476 // lib.optionalAttrs (lib.versionAtLeast metadata.release_version "19") {
477 bolt = callPackage ./bolt { };
478 }
479 // lib.optionalAttrs (lib.versionAtLeast metadata.release_version "20") {
480 flang = callPackage ./flang { };
481
482 libc-overlay = callPackage ./libc {
483 isFullBuild = false;
484 # Use clang due to "gnu::naked" not working on aarch64.
485 # Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882
486 stdenv = overrideCC stdenv buildLlvmPackages.clang;
487 };
488
489 libc-full = callPackage ./libc {
490 isFullBuild = true;
491 # Use clang due to "gnu::naked" not working on aarch64.
492 # Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882
493 stdenv = overrideCC stdenv buildLlvmPackages.clangNoLibcNoRt;
494 # FIXME: This should almost certainly be `stdenv.hostPlatform`.
495 cmake = if stdenv.targetPlatform.libc == "llvm" then cmakeMinimal else cmake;
496 python3 = if stdenv.targetPlatform.libc == "llvm" then python3Minimal else python3;
497 };
498
499 libc =
500 # FIXME: This should almost certainly be `stdenv.hostPlatform`.
501 if stdenv.targetPlatform.libc == "llvm" then self.libc-full else self.libc-overlay;
502 };
503}