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