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