Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at 23.05 353 lines 12 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 ./lldb { 188 inherit llvm_meta; 189 inherit (darwin) libobjc bootstrap_cmds; 190 inherit (darwin.apple_sdk.libs) xpc; 191 inherit (darwin.apple_sdk.frameworks) Foundation Carbon Cocoa; 192 }; 193 194 # Below, is the LLVM bootstrapping logic. It handles building a 195 # fully LLVM toolchain from scratch. No GCC toolchain should be 196 # pulled in. As a consequence, it is very quick to build different 197 # targets provided by LLVM and we can also build for what GCC 198 # doesn’t support like LLVM. Probably we should move to some other 199 # file. 200 201 bintools-unwrapped = callPackage ./bintools {}; 202 203 bintoolsNoLibc = wrapBintoolsWith { 204 bintools = tools.bintools-unwrapped; 205 libc = preLibcCrossHeaders; 206 }; 207 208 bintools = wrapBintoolsWith { 209 bintools = tools.bintools-unwrapped; 210 }; 211 212 clangUseLLVM = wrapCCWith rec { 213 cc = tools.clang-unwrapped; 214 libcxx = targetLlvmLibraries.libcxx; 215 bintools = bintools'; 216 extraPackages = [ 217 libcxx.cxxabi 218 targetLlvmLibraries.compiler-rt 219 ] ++ lib.optionals (!stdenv.targetPlatform.isWasm) [ 220 targetLlvmLibraries.libunwind 221 ]; 222 extraBuildCommands = mkExtraBuildCommands cc; 223 nixSupport.cc-cflags = 224 [ "-rtlib=compiler-rt" 225 "-Wno-unused-command-line-argument" 226 "-B${targetLlvmLibraries.compiler-rt}/lib" 227 ] 228 ++ lib.optional (!stdenv.targetPlatform.isWasm) "--unwindlib=libunwind" 229 ++ lib.optional 230 (!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false) 231 "-lunwind" 232 ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions"; 233 }; 234 235 clangNoLibcxx = wrapCCWith rec { 236 cc = tools.clang-unwrapped; 237 libcxx = null; 238 bintools = bintools'; 239 extraPackages = [ 240 targetLlvmLibraries.compiler-rt 241 ]; 242 extraBuildCommands = mkExtraBuildCommands cc; 243 nixSupport.cc-cflags = [ 244 "-rtlib=compiler-rt" 245 "-B${targetLlvmLibraries.compiler-rt}/lib" 246 "-nostdlib++" 247 ]; 248 }; 249 250 clangNoLibc = wrapCCWith rec { 251 cc = tools.clang-unwrapped; 252 libcxx = null; 253 bintools = bintoolsNoLibc'; 254 extraPackages = [ 255 targetLlvmLibraries.compiler-rt 256 ]; 257 extraBuildCommands = mkExtraBuildCommands cc; 258 nixSupport.cc-cflags = [ 259 "-rtlib=compiler-rt" 260 "-B${targetLlvmLibraries.compiler-rt}/lib" 261 ]; 262 }; 263 264 clangNoCompilerRt = wrapCCWith rec { 265 cc = tools.clang-unwrapped; 266 libcxx = null; 267 bintools = bintoolsNoLibc'; 268 extraPackages = [ ]; 269 extraBuildCommands = mkExtraBuildCommands0 cc; 270 nixSupport.cc-cflags = [ "-nostartfiles" ]; 271 }; 272 273 clangNoCompilerRtWithLibc = wrapCCWith rec { 274 cc = tools.clang-unwrapped; 275 libcxx = null; 276 bintools = bintools'; 277 extraPackages = [ ]; 278 extraBuildCommands = mkExtraBuildCommands0 cc; 279 }; 280 281 }); 282 283 libraries = lib.makeExtensible (libraries: let 284 callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake ninja libxml2 python3 release_version version monorepoSrc; }); 285 in { 286 287 compiler-rt-libc = callPackage ./compiler-rt { 288 inherit llvm_meta; 289 stdenv = if stdenv.hostPlatform.useLLVM or false 290 then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc 291 else stdenv; 292 }; 293 294 compiler-rt-no-libc = callPackage ./compiler-rt { 295 inherit llvm_meta; 296 stdenv = if stdenv.hostPlatform.useLLVM or false 297 then overrideCC stdenv buildLlvmTools.clangNoCompilerRt 298 else stdenv; 299 }; 300 301 # N.B. condition is safe because without useLLVM both are the same. 302 compiler-rt = if stdenv.hostPlatform.isAndroid 303 then libraries.compiler-rt-libc 304 else libraries.compiler-rt-no-libc; 305 306 stdenv = overrideCC stdenv buildLlvmTools.clang; 307 308 libcxxStdenv = overrideCC stdenv buildLlvmTools.libcxxClang; 309 310 libcxxabi = let 311 # CMake will "require" a compiler capable of compiling C++ programs 312 # cxx-header's build does not actually use one so it doesn't really matter 313 # what stdenv we use here, as long as CMake is happy. 314 cxx-headers = callPackage ./libcxx { 315 inherit llvm_meta; 316 headersOnly = true; 317 }; 318 319 # `libcxxabi` *doesn't* need a compiler with a working C++ stdlib but it 320 # *does* need a relatively modern C++ compiler (see: 321 # https://releases.llvm.org/15.0.0/projects/libcxx/docs/index.html#platform-and-compiler-support). 322 # 323 # So, we use the clang from this LLVM package set, like libc++ 324 # "boostrapping builds" do: 325 # https://releases.llvm.org/15.0.0/projects/libcxx/docs/BuildingLibcxx.html#bootstrapping-build 326 # 327 # We cannot use `clangNoLibcxx` because that contains `compiler-rt` which, 328 # on macOS, depends on `libcxxabi`, thus forming a cycle. 329 stdenv_ = overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc; 330 in callPackage ./libcxxabi { 331 stdenv = stdenv_; 332 inherit llvm_meta cxx-headers; 333 }; 334 335 # Like `libcxxabi` above, `libcxx` requires a fairly modern C++ compiler, 336 # so: we use the clang from this LLVM package set instead of the regular 337 # stdenv's compiler. 338 libcxx = callPackage ./libcxx { 339 inherit llvm_meta; 340 stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx; 341 }; 342 343 libunwind = callPackage ./libunwind { 344 inherit llvm_meta; 345 stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx; 346 }; 347 348 openmp = callPackage ./openmp { 349 inherit llvm_meta targetLlvm; 350 }; 351 }); 352 353in { inherit tools libraries release_version; } // libraries // tools