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