Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at 23.11 384 lines 13 kB view raw
1{ lowPrio, newScope, pkgs, lib, stdenv, cmake, ninja 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# LLVM release information; specify one of these but not both: 20, gitRelease ? null 21 # i.e.: 22 # { 23 # version = /* i.e. "15.0.0" */; 24 # rev = /* commit SHA */; 25 # rev-version = /* human readable version; i.e. "unstable-2022-26-07" */; 26 # sha256 = /* checksum for this release, can omit if specifying your own `monorepoSrc` */; 27 # } 28, officialRelease ? { version = "15.0.7"; sha256 = "sha256-wjuZQyXQ/jsmvy6y1aksCcEDXGBjuhpgngF3XQJ/T4s="; } 29 # i.e.: 30 # { 31 # version = /* i.e. "15.0.0" */; 32 # candidate = /* optional; if specified, should be: "rcN" */ 33 # sha256 = /* checksum for this release, can omit if specifying your own `monorepoSrc` */; 34 # } 35# By default, we'll try to fetch a release from `github:llvm/llvm-project` 36# corresponding to the `gitRelease` or `officialRelease` specified. 37# 38# You can provide your own LLVM source by specifying this arg but then it's up 39# to you to make sure that the LLVM repo given matches the release configuration 40# specified. 41, monorepoSrc ? null 42}: 43assert let 44 int = a: if a then 1 else 0; 45 xor = a: b: ((builtins.bitXor (int a) (int b)) == 1); 46in 47 lib.assertMsg 48 (xor 49 (gitRelease != null) 50 (officialRelease != null)) 51 ("must specify `gitRelease` or `officialRelease`" + 52 (lib.optionalString (gitRelease != null) " not both")); 53let 54 monorepoSrc' = monorepoSrc; 55in let 56 releaseInfo = if gitRelease != null then rec { 57 original = gitRelease; 58 release_version = original.version; 59 version = gitRelease.rev-version; 60 } else rec { 61 original = officialRelease; 62 release_version = original.version; 63 version = if original ? candidate then 64 "${release_version}-${original.candidate}" 65 else 66 release_version; 67 }; 68 69 monorepoSrc = if monorepoSrc' != null then 70 monorepoSrc' 71 else let 72 sha256 = releaseInfo.original.sha256; 73 rev = if gitRelease != null then 74 gitRelease.rev 75 else 76 "llvmorg-${releaseInfo.version}"; 77 in fetchFromGitHub { 78 owner = "llvm"; 79 repo = "llvm-project"; 80 inherit rev sha256; 81 }; 82 83 inherit (releaseInfo) release_version version; 84 85 llvm_meta = { 86 license = lib.licenses.ncsa; 87 maintainers = lib.teams.llvm.members; 88 89 # See llvm/cmake/config-ix.cmake. 90 platforms = 91 lib.platforms.aarch64 ++ 92 lib.platforms.arm ++ 93 lib.platforms.m68k ++ 94 lib.platforms.mips ++ 95 lib.platforms.power ++ 96 lib.platforms.riscv ++ 97 lib.platforms.s390x ++ 98 lib.platforms.wasi ++ 99 lib.platforms.x86; 100 }; 101 102 tools = lib.makeExtensible (tools: let 103 callPackage = newScope (tools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc buildLlvmTools; }); 104 mkExtraBuildCommands0 = cc: '' 105 rsrc="$out/resource-root" 106 mkdir "$rsrc" 107 ln -s "${cc.lib}/lib/clang/${release_version}/include" "$rsrc" 108 echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags 109 ''; 110 mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + '' 111 ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib" 112 ln -s "${targetLlvmLibraries.compiler-rt.out}/share" "$rsrc/share" 113 ''; 114 115 bintoolsNoLibc' = 116 if bootBintoolsNoLibc == null 117 then tools.bintoolsNoLibc 118 else bootBintoolsNoLibc; 119 bintools' = 120 if bootBintools == null 121 then tools.bintools 122 else bootBintools; 123 124 in { 125 126 libllvm = callPackage ./llvm { 127 inherit llvm_meta; 128 }; 129 130 # `llvm` historically had the binaries. When choosing an output explicitly, 131 # we need to reintroduce `outputSpecified` to get the expected behavior e.g. of lib.get* 132 llvm = tools.libllvm; 133 134 libclang = callPackage ./clang { 135 inherit llvm_meta; 136 }; 137 138 clang-unwrapped = tools.libclang; 139 140 llvm-manpages = lowPrio (tools.libllvm.override { 141 enableManpages = true; 142 python3 = pkgs.python3; # don't use python-boot 143 }); 144 145 clang-manpages = lowPrio (tools.libclang.override { 146 enableManpages = true; 147 python3 = pkgs.python3; # don't use python-boot 148 }); 149 150 # TODO: lldb/docs/index.rst:155:toctree contains reference to nonexisting document 'design/structureddataplugins' 151 # lldb-manpages = lowPrio (tools.lldb.override { 152 # enableManpages = true; 153 # python3 = pkgs.python3; # don't use python-boot 154 # }); 155 156 # pick clang appropriate for package set we are targeting 157 clang = 158 /**/ if stdenv.targetPlatform.libc == null then tools.clangNoLibc 159 else if stdenv.targetPlatform.useLLVM or false then tools.clangUseLLVM 160 else if (pkgs.targetPackages.stdenv or stdenv).cc.isGNU then tools.libstdcxxClang 161 else tools.libcxxClang; 162 163 libstdcxxClang = wrapCCWith rec { 164 cc = tools.clang-unwrapped; 165 # libstdcxx is taken from gcc in an ad-hoc way in cc-wrapper. 166 libcxx = null; 167 extraPackages = [ 168 targetLlvmLibraries.compiler-rt 169 ]; 170 extraBuildCommands = mkExtraBuildCommands cc; 171 }; 172 173 libcxxClang = wrapCCWith rec { 174 cc = tools.clang-unwrapped; 175 libcxx = targetLlvmLibraries.libcxx; 176 extraPackages = [ 177 libcxx.cxxabi 178 targetLlvmLibraries.compiler-rt 179 ]; 180 extraBuildCommands = mkExtraBuildCommands cc; 181 }; 182 183 lld = callPackage ./lld { 184 inherit llvm_meta; 185 }; 186 187 lldb = callPackage ../common/lldb.nix { 188 src = callPackage ({ runCommand }: runCommand "lldb-src-${version}" {} '' 189 mkdir -p "$out" 190 cp -r ${monorepoSrc}/cmake "$out" 191 cp -r ${monorepoSrc}/lldb "$out" 192 '') { }; 193 patches = 194 let 195 resourceDirPatch = callPackage 196 ({ substituteAll, libclang }: substituteAll 197 { 198 src = ./lldb/resource-dir.patch; 199 clangLibDir = "${libclang.lib}/lib"; 200 }) 201 { }; 202 in 203 [ 204 ./lldb/procfs.patch # FIXME: do we need this? 205 resourceDirPatch 206 ./lldb/gnu-install-dirs.patch 207 ]; 208 inherit llvm_meta; 209 }; 210 211 # Below, is the LLVM bootstrapping logic. It handles building a 212 # fully LLVM toolchain from scratch. No GCC toolchain should be 213 # pulled in. As a consequence, it is very quick to build different 214 # targets provided by LLVM and we can also build for what GCC 215 # doesn’t support like LLVM. Probably we should move to some other 216 # file. 217 218 bintools-unwrapped = callPackage ../common/bintools.nix { }; 219 220 bintoolsNoLibc = wrapBintoolsWith { 221 bintools = tools.bintools-unwrapped; 222 libc = preLibcCrossHeaders; 223 }; 224 225 bintools = wrapBintoolsWith { 226 bintools = tools.bintools-unwrapped; 227 }; 228 229 clangUseLLVM = wrapCCWith rec { 230 cc = tools.clang-unwrapped; 231 libcxx = targetLlvmLibraries.libcxx; 232 bintools = bintools'; 233 extraPackages = [ 234 libcxx.cxxabi 235 targetLlvmLibraries.compiler-rt 236 ] ++ lib.optionals (!stdenv.targetPlatform.isWasm) [ 237 targetLlvmLibraries.libunwind 238 ]; 239 extraBuildCommands = mkExtraBuildCommands cc; 240 nixSupport.cc-cflags = 241 [ "-rtlib=compiler-rt" 242 "-Wno-unused-command-line-argument" 243 "-B${targetLlvmLibraries.compiler-rt}/lib" 244 ] 245 ++ lib.optional (!stdenv.targetPlatform.isWasm) "--unwindlib=libunwind" 246 ++ lib.optional 247 (!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false) 248 "-lunwind" 249 ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions"; 250 }; 251 252 clangNoLibcxx = wrapCCWith rec { 253 cc = tools.clang-unwrapped; 254 libcxx = null; 255 bintools = bintools'; 256 extraPackages = [ 257 targetLlvmLibraries.compiler-rt 258 ]; 259 extraBuildCommands = mkExtraBuildCommands cc; 260 nixSupport.cc-cflags = [ 261 "-rtlib=compiler-rt" 262 "-B${targetLlvmLibraries.compiler-rt}/lib" 263 "-nostdlib++" 264 ]; 265 }; 266 267 clangNoLibc = wrapCCWith rec { 268 cc = tools.clang-unwrapped; 269 libcxx = null; 270 bintools = bintoolsNoLibc'; 271 extraPackages = [ 272 targetLlvmLibraries.compiler-rt 273 ]; 274 extraBuildCommands = mkExtraBuildCommands cc; 275 nixSupport.cc-cflags = [ 276 "-rtlib=compiler-rt" 277 "-B${targetLlvmLibraries.compiler-rt}/lib" 278 ]; 279 }; 280 281 clangNoCompilerRt = wrapCCWith rec { 282 cc = tools.clang-unwrapped; 283 libcxx = null; 284 bintools = bintoolsNoLibc'; 285 extraPackages = [ ]; 286 extraBuildCommands = mkExtraBuildCommands0 cc; 287 nixSupport.cc-cflags = [ "-nostartfiles" ]; 288 }; 289 290 clangNoCompilerRtWithLibc = wrapCCWith rec { 291 cc = tools.clang-unwrapped; 292 libcxx = null; 293 bintools = bintools'; 294 extraPackages = [ ]; 295 extraBuildCommands = mkExtraBuildCommands0 cc; 296 }; 297 298 }); 299 300 libraries = lib.makeExtensible (libraries: let 301 callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc; }); 302 in { 303 304 compiler-rt-libc = callPackage ./compiler-rt { 305 inherit llvm_meta; 306 stdenv = if stdenv.hostPlatform.useLLVM or false 307 then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc 308 else stdenv; 309 }; 310 311 compiler-rt-no-libc = callPackage ./compiler-rt { 312 inherit llvm_meta; 313 stdenv = if stdenv.hostPlatform.useLLVM or false 314 then overrideCC stdenv buildLlvmTools.clangNoCompilerRt 315 else stdenv; 316 }; 317 318 # N.B. condition is safe because without useLLVM both are the same. 319 compiler-rt = if stdenv.hostPlatform.isAndroid 320 then libraries.compiler-rt-libc 321 else libraries.compiler-rt-no-libc; 322 323 stdenv = overrideCC stdenv buildLlvmTools.clang; 324 325 libcxxStdenv = overrideCC stdenv buildLlvmTools.libcxxClang; 326 327 libcxxabi = let 328 # CMake will "require" a compiler capable of compiling C++ programs 329 # cxx-header's build does not actually use one so it doesn't really matter 330 # what stdenv we use here, as long as CMake is happy. 331 cxx-headers = callPackage ./libcxx { 332 inherit llvm_meta; 333 # Note that if we use the regular stdenv here we'll get cycle errors 334 # when attempting to use this compiler in the stdenv. 335 # 336 # The final stdenv pulls `cxx-headers` from the package set where 337 # hostPlatform *is* the target platform which means that `stdenv` at 338 # that point attempts to use this toolchain. 339 # 340 # So, we use `stdenv_` (the stdenv containing `clang` from this package 341 # set, defined below) to sidestep this issue. 342 # 343 # Because we only use `cxx-headers` in `libcxxabi` (which depends on the 344 # clang stdenv _anyways_), this is okay. 345 stdenv = stdenv_; 346 headersOnly = true; 347 }; 348 349 # `libcxxabi` *doesn't* need a compiler with a working C++ stdlib but it 350 # *does* need a relatively modern C++ compiler (see: 351 # https://releases.llvm.org/15.0.0/projects/libcxx/docs/index.html#platform-and-compiler-support). 352 # 353 # So, we use the clang from this LLVM package set, like libc++ 354 # "boostrapping builds" do: 355 # https://releases.llvm.org/15.0.0/projects/libcxx/docs/BuildingLibcxx.html#bootstrapping-build 356 # 357 # We cannot use `clangNoLibcxx` because that contains `compiler-rt` which, 358 # on macOS, depends on `libcxxabi`, thus forming a cycle. 359 stdenv_ = overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc; 360 in callPackage ./libcxxabi { 361 stdenv = stdenv_; 362 inherit llvm_meta cxx-headers; 363 }; 364 365 # Like `libcxxabi` above, `libcxx` requires a fairly modern C++ compiler, 366 # so: we use the clang from this LLVM package set instead of the regular 367 # stdenv's compiler. 368 libcxx = callPackage ./libcxx { 369 inherit llvm_meta; 370 stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx; 371 }; 372 373 libunwind = callPackage ./libunwind { 374 inherit llvm_meta; 375 stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx; 376 }; 377 378 openmp = callPackage ./openmp { 379 inherit llvm_meta targetLlvm; 380 }; 381 }); 382 noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ]; 383 384in { inherit tools libraries release_version; } // (noExtend libraries) // (noExtend tools)