nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 927 lines 36 kB view raw
1{ 2 version, 3 rev ? null, 4 sha256, 5 url ? 6 if rev != null then 7 "https://gitlab.haskell.org/ghc/ghc.git" 8 else 9 "https://downloads.haskell.org/ghc/${version}/ghc-${version}-src.tar.xz", 10 postFetch ? null, 11}: 12 13{ 14 lib, 15 stdenv, 16 stdenvNoCC, 17 pkgsBuildTarget, 18 pkgsHostTarget, 19 buildPackages, 20 targetPackages, 21 fetchpatch, 22 23 # build-tools 24 bootPkgs, 25 autoreconfHook, 26 coreutils, 27 fetchurl, 28 fetchgit, 29 perl, 30 python3, 31 sphinx, 32 xattr, 33 autoSignDarwinBinariesHook, 34 bash, 35 srcOnly, 36 37 libiconv ? null, 38 ncurses, 39 40 # GHC can be built with system libffi or a bundled one. 41 libffi ? null, 42 43 useLLVM ? !(import ./common-have-ncg.nix { inherit lib stdenv version; }), 44 # LLVM is conceptually a run-time-only dependency, but for 45 # non-x86, we need LLVM to bootstrap later stages, so it becomes a 46 # build-time dependency too. 47 buildTargetLlvmPackages, 48 llvmPackages, 49 50 # If enabled, GHC will be built with the GPL-free but slightly slower native 51 # bignum backend instead of the faster but GPLed gmp backend. 52 enableNativeBignum ? 53 !(lib.meta.availableOn stdenv.hostPlatform gmp && lib.meta.availableOn stdenv.targetPlatform gmp) 54 || stdenv.targetPlatform.isGhcjs, 55 gmp, 56 57 # If enabled, use -fPIC when compiling static libs. 58 enableRelocatedStaticLibs ? 59 stdenv.targetPlatform != stdenv.hostPlatform && !stdenv.targetPlatform.isWindows, 60 61 # Exceeds Hydra output limit (at the time of writing ~3GB) when cross compiled to riscv64. 62 # A riscv64 cross-compiler fits into the limit comfortably. 63 enableProfiledLibs ? !stdenv.hostPlatform.isRiscV64, 64 65 # Whether to build dynamic libs for the standard library (on the target 66 # platform). Static libs are always built. 67 enableShared ? with stdenv.targetPlatform; !isWindows && !useiOSPrebuilt && !isStatic && !isGhcjs, 68 69 # Whether to build terminfo. 70 enableTerminfo ? 71 !( 72 stdenv.targetPlatform.isWindows 73 || stdenv.targetPlatform.isGhcjs 74 # Before <https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13932>, 75 # we couldn't force hadrian to build terminfo for different triples. 76 || ( 77 lib.versionOlder version "9.15.20250808" 78 && ( 79 stdenv.buildPlatform.config != stdenv.hostPlatform.config 80 || stdenv.hostPlatform.config != stdenv.targetPlatform.config 81 ) 82 ) 83 ), 84 85 # Libdw.c only supports x86_64, i686 and s390x as of 2022-08-04 86 enableDwarf ? 87 (stdenv.targetPlatform.isx86 || (stdenv.targetPlatform.isS390 && stdenv.targetPlatform.is64bit)) 88 && lib.meta.availableOn stdenv.hostPlatform elfutils 89 && lib.meta.availableOn stdenv.targetPlatform elfutils 90 && 91 # HACK: elfutils is marked as broken on static platforms 92 # which availableOn can't tell. 93 !stdenv.targetPlatform.isStatic 94 && !stdenv.hostPlatform.isStatic, 95 elfutils, 96 97 # Enable NUMA support in RTS 98 enableNuma ? lib.meta.availableOn stdenv.targetPlatform numactl, 99 numactl, 100 101 # What flavour to build. Flavour string may contain a flavour and flavour 102 # transformers as accepted by hadrian. 103 ghcFlavour ? 104 let 105 # TODO(@sternenseemann): does using the static flavour make sense? 106 baseFlavour = "release"; 107 # Note: in case hadrian's flavour transformers cease being expressive 108 # enough for us, we'll need to resort to defining a "nixpkgs" flavour 109 # in hadrianUserSettings and using that instead. 110 transformers = 111 lib.optionals useLLVM [ "llvm" ] 112 ++ lib.optionals (!enableShared) [ 113 "no_dynamic_libs" 114 "no_dynamic_ghc" 115 ] 116 ++ lib.optionals (!enableProfiledLibs) [ "no_profiled_libs" ] 117 # While split sections are now enabled by default in ghc 8.8 for windows, 118 # they seem to lead to `too many sections` errors when building base for 119 # profiling. 120 ++ (if stdenv.targetPlatform.isWindows then [ "no_split_sections" ] else [ "split_sections" ]); 121 in 122 baseFlavour + lib.concatMapStrings (t: "+${t}") transformers, 123 124 # Contents of the UserSettings.hs file to use when compiling hadrian. 125 hadrianUserSettings ? '' 126 module UserSettings ( 127 userFlavours, userPackages, userDefaultFlavour, 128 verboseCommand, buildProgressColour, successColour, finalStage 129 ) where 130 131 import Flavour.Type 132 import Expression 133 import {-# SOURCE #-} Settings.Default 134 135 -- no way to set this via the command line 136 finalStage :: Stage 137 finalStage = ${ 138 # N. B. hadrian ignores this setting if it doesn't agree it's possible, 139 # i.e. when its cross-compiling setting is true. So while we could, in theory, 140 # build Stage2 if hostPlatform.canExecute targetPlatform, hadrian won't play 141 # ball (with make, Stage2 was built if hostPlatform.system == targetPlatform.system). 142 if stdenv.hostPlatform == stdenv.targetPlatform then 143 "Stage2" # native compiler 144 else 145 "Stage1" # cross compiler 146 } 147 148 userDefaultFlavour :: String 149 userDefaultFlavour = "release" 150 151 userFlavours :: [Flavour] 152 userFlavours = [] 153 154 -- Disable Colours 155 buildProgressColour :: BuildProgressColour 156 buildProgressColour = mkBuildProgressColour (Dull Reset) 157 successColour :: SuccessColour 158 successColour = mkSuccessColour (Dull Reset) 159 160 -- taken from src/UserSettings.hs unchanged, need to be there 161 userPackages :: [Package] 162 userPackages = [] 163 verboseCommand :: Predicate 164 verboseCommand = do 165 verbosity <- expr getVerbosity 166 return $ verbosity >= Verbose 167 '', 168 169 ghcSrc ? srcOnly { 170 name = "ghc-${version}"; # -source appended by srcOnly 171 src = (if rev != null then fetchgit else fetchurl) ( 172 { 173 inherit url sha256; 174 } 175 // lib.optionalAttrs (rev != null) { 176 inherit rev; 177 } 178 // lib.optionalAttrs (postFetch != null) { 179 inherit postFetch; 180 } 181 ); 182 183 patches = 184 let 185 enableHyperlinkedSource = 186 # Disable haddock generating pretty source listings to stay under 3GB on aarch64-linux 187 !(stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isLinux) 188 # 9.8 and 9.10 don't run into this problem for some reason 189 || (lib.versionAtLeast version "9.8" && lib.versionOlder version "9.11"); 190 in 191 192 lib.optionals (lib.versionOlder version "9.8") [ 193 # Fix unlit being installed under a different name than is used in the 194 # settings file: https://gitlab.haskell.org/ghc/ghc/-/issues/23317 krank:ignore-line 195 (fetchpatch { 196 name = "ghc-9.6-fix-unlit-path.patch"; 197 url = "https://gitlab.haskell.org/ghc/ghc/-/commit/8fde4ac84ec7b1ead238cb158bbef48555d12af9.patch"; 198 hash = "sha256-3+CyRBpebEZi8YpS22SsdGQHqi0drR7cCKPtKbR3zyE="; 199 }) 200 ] 201 ++ lib.optionals (stdenv.targetPlatform.isDarwin && stdenv.targetPlatform.isAarch64) [ 202 # Prevent the paths module from emitting symbols that we don't use 203 # when building with separate outputs. 204 # 205 # These cause problems as they're not eliminated by GHC's dead code 206 # elimination on aarch64-darwin. (see 207 # https://github.com/NixOS/nixpkgs/issues/140774 for details). krank:ignore-line 208 ( 209 if lib.versionOlder version "9.10" then 210 ./Cabal-at-least-3.6-paths-fix-cycle-aarch64-darwin.patch 211 else if lib.versionOlder version "9.14" then 212 ./Cabal-3.12-paths-fix-cycle-aarch64-darwin.patch 213 else 214 ./Cabal-3.16-paths-fix-cycle-aarch64-darwin.patch 215 ) 216 ] 217 # Prevents passing --hyperlinked-source to haddock. Note that this can 218 # be configured via a user defined flavour now. Unfortunately, it is 219 # impossible to import an existing flavour in UserSettings, so patching 220 # the defaults is actually simpler and less maintenance intensive 221 # compared to keeping an entire flavour definition in sync with upstream 222 # manually. 223 # See also https://gitlab.haskell.org/ghc/ghc/-/issues/23625 krank:ignore-line 224 ++ lib.optionals (!enableHyperlinkedSource) [ 225 ( 226 if lib.versionOlder version "9.8" then 227 ../../tools/haskell/hadrian/disable-hyperlinked-source-pre-9.8.patch 228 else 229 ../../tools/haskell/hadrian/disable-hyperlinked-source-extra-args.patch 230 ) 231 ] 232 ++ lib.optionals (lib.versionAtLeast version "9.8" && lib.versionOlder version "9.12") [ 233 (fetchpatch { 234 name = "enable-ignore-build-platform-mismatch.patch"; 235 url = "https://gitlab.haskell.org/ghc/ghc/-/commit/4ee094d46effd06093090fcba70f0a80d2a57e6c.patch"; 236 includes = [ "configure.ac" ]; 237 hash = "sha256-L3FQvcm9QB59BOiR2g5/HACAufIG08HiT53EIOjj64g="; 238 }) 239 ] 240 ++ lib.optionals (lib.versionOlder version "9.12.1") [ 241 (fetchpatch { 242 name = "ghc-ppc-support-elf-v2-on-powerpc64-big-endian.patch"; 243 url = "https://gitlab.haskell.org/ghc/ghc/-/commit/ead75532c9dc915bfa9ebaef0ef5d148e793cc0a.patch"; 244 # ghc-platform was split out of ghc-boot in ddcdd88c2c95445a87ee028f215d1e876939a4d9 245 postFetch = lib.optionalString (lib.versionOlder version "9.10.1") '' 246 substituteInPlace $out \ 247 --replace-fail 'libraries/ghc-platform/src/GHC' 'libraries/ghc-boot/GHC' 248 ''; 249 hash = 250 if lib.versionOlder version "9.10.1" then 251 "sha256-5SVSW1aYoItqHli5QjnudH4zGporYNLDeEo4gZksBZw=" 252 else 253 "sha256-vtjT+TL/7sYPu4rcVV3xCqJQ+uqkyBbf9l0KIi97j/0="; 254 }) 255 ] 256 ++ 257 lib.optionals 258 ( 259 (lib.versions.majorMinor version == "9.12" && lib.versionOlder version "9.12.3") 260 || (lib.versions.majorMinor version != "9.12" && lib.versionOlder version "9.14.1") 261 ) 262 [ 263 (fetchpatch { 264 name = "ghc-rts-Fix-compile-on-powerpc64-elf-v1.patch"; 265 url = "https://gitlab.haskell.org/ghc/ghc/-/commit/05e5785a3157c71e327a8e9bdc80fa7082918739.patch"; 266 hash = "sha256-xP5v3cKhXeTRSFvRiKEn9hPxGXgVgykjTILKjh/pdDU="; 267 }) 268 ] 269 # Fix build with gcc15 270 # https://gitlab.haskell.org/ghc/ghc/-/issues/25662 271 # https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13863 272 ++ 273 lib.optionals 274 ( 275 lib.versionOlder version "9.12.3" 276 && !(lib.versionAtLeast version "9.10.2" && lib.versionOlder version "9.12") 277 ) 278 [ 279 (fetchpatch { 280 name = "ghc-hp2ps-c-gnu17.patch"; 281 url = "https://src.fedoraproject.org/rpms/ghc/raw/9c26d7c3c3de73509a25806e5663b37bcf2e0b4e/f/hp2ps-C-gnu17.patch"; 282 hash = "sha256-Vr5wkiSE1S5e+cJ8pWUvG9KFpxtmvQ8wAy08ElGNp5E="; 283 }) 284 ] 285 # Fixes stack overrun in rts which crashes an process whenever 286 # freeHaskellFunPtr is called with nixpkgs' hardening flags. 287 # https://gitlab.haskell.org/ghc/ghc/-/issues/25485 krank:ignore-line 288 # https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13599 289 ++ lib.optionals (lib.versionOlder version "9.13") [ 290 (fetchpatch { 291 name = "ghc-rts-adjustor-fix-i386-stack-overrun.patch"; 292 url = "https://gitlab.haskell.org/ghc/ghc/-/commit/39bb6e583d64738db51441a556d499aa93a4fc4a.patch"; 293 sha256 = "0w5fx413z924bi2irsy1l4xapxxhrq158b5gn6jzrbsmhvmpirs0"; 294 }) 295 ] 296 297 # Unreleased or still in-progress upstream cross fixes 298 ++ lib.optionals (lib.versionAtLeast version "9.10.2" && lib.versionOlder version "9.15") [ 299 # https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13919 300 (fetchpatch { 301 name = "include-modern-utimbuf.patch"; 302 url = "https://gitlab.haskell.org/ghc/ghc/-/commit/7e75928ed0f1c4654de6ddd13d0b00bf4b5c6411.patch"; 303 hash = "sha256-sb+AHdkGkCu8MW0xoQIpD5kEc0zYX8udAMDoC+TWc0Q="; 304 }) 305 306 # https://gitlab.haskell.org/ghc/ghc/-/issues/26290 krank:ignore-line 307 ./export-heap-methods.patch 308 ] 309 ++ lib.optionals (lib.versionAtLeast version "9.10.3") [ 310 # https://gitlab.haskell.org/ghc/ghc/-/issues/26518 krank:ignore-line 311 ./ghc-define-undefined-elf-st-visibility.patch 312 ] 313 314 # Fix docs build with Sphinx >= 9 https://gitlab.haskell.org/ghc/ghc/-/issues/26810 315 ++ [ ./ghc-9.6-or-later-docs-sphinx-9.patch ] 316 317 ++ (import ./common-llvm-patches.nix { inherit lib version fetchpatch; }); 318 319 stdenv = stdenvNoCC; 320 }, 321 322 # GHC's build system hadrian built from the GHC-to-build's source tree 323 # using our bootstrap GHC. 324 hadrian ? import ../../tools/haskell/hadrian/make-hadrian.nix { inherit bootPkgs lib; } { 325 inherit ghcSrc; 326 ghcVersion = version; 327 userSettings = hadrianUserSettings; 328 }, 329 330 # Whether to build sphinx documentation. 331 # TODO(@sternenseemann): Hadrian ignores the --docs flag if finalStage = Stage1 332 enableDocs ? ( 333 # Docs disabled if we are building on musl because it's a large task to keep 334 # all `sphinx` dependencies building in this environment. 335 !stdenv.buildPlatform.isMusl 336 ), 337 338 # Whether to disable the large address space allocator 339 # necessary fix for iOS: https://www.reddit.com/r/haskell/comments/4ttdz1/building_an_osxi386_to_iosarm64_cross_compiler/d5qvd67/ 340 disableLargeAddressSpace ? stdenv.targetPlatform.isiOS, 341 342 # Whether to build an unregisterised version of GHC. 343 # GHC will normally auto-detect whether it can do a registered build, but this 344 # option will force it to do an unregistered build when set to true. 345 # See https://gitlab.haskell.org/ghc/ghc/-/wikis/building/unregisterised 346 enableUnregisterised ? false, 347}: 348 349assert !enableNativeBignum -> gmp != null; 350 351# GHC does not support building when all 3 platforms are different. 352assert stdenv.buildPlatform == stdenv.hostPlatform || stdenv.hostPlatform == stdenv.targetPlatform; 353 354# It is currently impossible to cross-compile GHC with Hadrian. 355assert lib.assertMsg (stdenv.buildPlatform == stdenv.hostPlatform) 356 "GHC >= 9.6 can't be cross-compiled. If you meant to build a GHC cross-compiler, use `buildPackages`."; 357 358let 359 inherit (stdenv) buildPlatform hostPlatform targetPlatform; 360 361 # TODO(@Ericson2314) Make unconditional 362 targetPrefix = lib.optionalString ( 363 targetPlatform.config != hostPlatform.config 364 ) "${targetPlatform.config}-"; 365 366 # TODO(@sternenseemann): there's no stage0:exe:haddock target by default, 367 # so haddock isn't available for GHC cross-compilers. Can we fix that? 368 hasHaddock = stdenv.hostPlatform == stdenv.targetPlatform; 369 370 hadrianSettings = 371 # -fexternal-dynamic-refs apparently (because it's not clear from the 372 # documentation) makes the GHC RTS able to load static libraries, which may 373 # be needed for TemplateHaskell. This solution was described in 374 # https://www.tweag.io/blog/2020-09-30-bazel-static-haskell 375 # 376 # Note `-fexternal-dynamic-refs` causes `undefined reference` errors when building GHC cross compiler for windows 377 lib.optionals enableRelocatedStaticLibs [ 378 "*.*.ghc.*.opts += -fPIC -fexternal-dynamic-refs" 379 ] 380 ++ lib.optionals targetPlatform.useAndroidPrebuilt [ 381 "*.*.ghc.c.opts += -optc-std=gnu99" 382 ] 383 # Inform GHC that we can't load dynamic libraries which forces iserv-proxy to load static libraries. 384 ++ lib.optionals targetPlatform.isStatic [ 385 "*.ghc.cabal.configure.opts += --flags=-dynamic-system-linker" 386 ]; 387 388 # Splicer will pull out correct variations 389 libDeps = 390 platform: 391 lib.optional enableTerminfo ncurses 392 ++ lib.optionals (!targetPlatform.isGhcjs) [ libffi ] 393 # Bindist configure script fails w/o elfutils in linker search path 394 # https://gitlab.haskell.org/ghc/ghc/-/issues/22081 395 ++ lib.optional enableDwarf elfutils 396 ++ lib.optional (!enableNativeBignum) gmp 397 ++ lib.optional ( 398 platform.libc != "glibc" 399 && !targetPlatform.isWindows 400 && !targetPlatform.isGhcjs 401 && !targetPlatform.useAndroidPrebuilt 402 ) libiconv; 403 404 # TODO(@sternenseemann): is buildTarget LLVM unnecessary? 405 # GHC doesn't seem to have {LLC,OPT}_HOST 406 toolsForTarget = [ 407 ( 408 if targetPlatform.isGhcjs then 409 pkgsBuildTarget.emscripten 410 else 411 pkgsBuildTarget.targetPackages.stdenv.cc 412 ) 413 ] 414 ++ lib.optional useLLVM buildTargetLlvmPackages.llvm; 415 416 buildCC = buildPackages.stdenv.cc; 417 targetCC = builtins.head toolsForTarget; 418 installCC = 419 if targetPlatform.isGhcjs then 420 pkgsHostTarget.emscripten 421 else 422 pkgsHostTarget.targetPackages.stdenv.cc; 423 424 # toolPath calculates the absolute path to the name tool associated with a 425 # given `stdenv.cc` derivation, i.e. it picks the correct derivation to take 426 # the tool from (cc, cc.bintools, cc.bintools.bintools) and adds the correct 427 # subpath of the tool. 428 toolPath = 429 name: cc: 430 let 431 tools = 432 { 433 "cc" = cc; 434 "c++" = cc; 435 as = cc.bintools; 436 437 ar = cc.bintools; 438 ranlib = cc.bintools; 439 nm = cc.bintools; 440 readelf = cc.bintools; 441 objdump = cc.bintools; 442 443 ld = cc.bintools; 444 "ld.gold" = cc.bintools; 445 446 windres = cc.bintools; 447 448 otool = cc.bintools.bintools; 449 450 # GHC needs install_name_tool on all darwin platforms. The same one can 451 # be used on both platforms. It is safe to use with linker-generated 452 # signatures because it will update the signatures automatically after 453 # modifying the target binary. 454 install_name_tool = cc.bintools.bintools; 455 456 # strip on darwin is wrapped to enable deterministic mode. 457 strip = 458 # TODO(@sternenseemann): also use wrapper if linker == "bfd" or "gold" 459 if stdenv.targetPlatform.isDarwin then cc.bintools else cc.bintools.bintools; 460 461 # clang is used as an assembler on darwin with the LLVM backend 462 clang = cc; 463 } 464 .${name}; 465 in 466 getToolExe tools name; 467 468 # targetPrefix aware lib.getExe' 469 getToolExe = drv: name: lib.getExe' drv "${drv.targetPrefix or ""}${name}"; 470 471 # Use gold either following the default, or to avoid the BFD linker due to some bugs / perf issues. 472 # But we cannot avoid BFD when using musl libc due to https://sourceware.org/bugzilla/show_bug.cgi?id=23856 473 # see #84670 and #49071 for more background. 474 useLdGold = 475 targetPlatform.linker == "gold" 476 || ( 477 targetPlatform.linker == "bfd" 478 && (targetCC.bintools.bintools.hasGold or false) 479 && !targetPlatform.isMusl 480 ); 481 482 # Makes debugging easier to see which variant is at play in `nix-store -q --tree`. 483 variantSuffix = lib.concatStrings [ 484 (lib.optionalString stdenv.hostPlatform.isMusl "-musl") 485 (lib.optionalString enableNativeBignum "-native-bignum") 486 ]; 487 488 # These libraries are library dependencies of the standard libraries bundled 489 # by GHC (core libs) users will link their compiled artifacts again. Thus, 490 # they should be taken from targetPackages. 491 # 492 # We need to use pkgsHostTarget if we are cross compiling a native GHC compiler, 493 # though (when native compiling GHC, pkgsHostTarget == targetPackages): 494 # 495 # 1. targetPackages would be empty(-ish) in this situation since we can't 496 # execute cross compiled compilers in order to obtain the libraries 497 # that would be in targetPackages. 498 # 2. pkgsHostTarget is fine to use since hostPlatform == targetPlatform in this 499 # situation. 500 # 3. The core libs used by the final GHC (stage 2) for user artifacts are also 501 # used to build stage 2 GHC itself, i.e. the core libs are both host and 502 # target. 503 targetLibs = { 504 inherit (if hostPlatform != targetPlatform then targetPackages else pkgsHostTarget) 505 elfutils 506 gmp 507 libffi 508 ncurses 509 numactl 510 ; 511 }; 512 513 # Our Cabal compiler name 514 haskellCompilerName = "ghc-${version}"; 515 516in 517 518stdenv.mkDerivation ( 519 { 520 pname = "${targetPrefix}ghc${variantSuffix}"; 521 inherit version; 522 523 # Useful as hadrianSettings often have spaces in them 524 __structuredAttrs = true; 525 526 src = ghcSrc; 527 528 enableParallelBuilding = true; 529 530 postPatch = '' 531 patchShebangs --build . 532 ''; 533 534 # GHC is a bit confused on its cross terminology. 535 # TODO(@sternenseemann): investigate coreutils dependencies and pass absolute paths 536 preConfigure = '' 537 for env in $(env | grep '^TARGET_' | sed -E 's|\+?=.*||'); do 538 export "''${env#TARGET_}=''${!env}" 539 done 540 # No need for absolute paths since these tools only need to work during the build 541 export CC_STAGE0="$CC_FOR_BUILD" 542 export LD_STAGE0="$LD_FOR_BUILD" 543 export AR_STAGE0="$AR_FOR_BUILD" 544 545 # Stage0 (build->build) which builds stage 1 546 export GHC="${bootPkgs.ghc}/bin/ghc" 547 # GHC is a bit confused on its cross terminology, as these would normally be 548 # the *host* tools. 549 export CC="${toolPath "cc" targetCC}" 550 export CXX="${toolPath "c++" targetCC}" 551 # Use gold to work around https://sourceware.org/bugzilla/show_bug.cgi?id=16177 552 export LD="${toolPath "ld${lib.optionalString useLdGold ".gold"}" targetCC}" 553 export AS="${toolPath "as" targetCC}" 554 export AR="${toolPath "ar" targetCC}" 555 export NM="${toolPath "nm" targetCC}" 556 export RANLIB="${toolPath "ranlib" targetCC}" 557 export READELF="${toolPath "readelf" targetCC}" 558 export STRIP="${toolPath "strip" targetCC}" 559 export OBJDUMP="${toolPath "objdump" targetCC}" 560 '' 561 + lib.optionalString (stdenv.targetPlatform.linker == "cctools") '' 562 export OTOOL="${toolPath "otool" targetCC}" 563 export INSTALL_NAME_TOOL="${toolPath "install_name_tool" targetCC}" 564 '' 565 + lib.optionalString useLLVM '' 566 export LLC="${getToolExe buildTargetLlvmPackages.llvm "llc"}" 567 export OPT="${getToolExe buildTargetLlvmPackages.llvm "opt"}" 568 '' 569 # LLVMAS should be a "specific LLVM compatible assembler" which needs to understand 570 # assembly produced by LLVM. The easiest way to be sure is to use clang from the same 571 # version as llc and opt. Note that the naming chosen by GHC is misleading, clang can 572 # be used as an assembler, llvm-as converts IR into machine code. 573 + lib.optionalString (useLLVM && lib.versionAtLeast version "9.10") '' 574 export LLVMAS="${getToolExe buildTargetLlvmPackages.clang "clang"}" 575 '' 576 + lib.optionalString (useLLVM && stdenv.targetPlatform.isDarwin) '' 577 # LLVM backend on Darwin needs clang: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm 578 # The executable we specify via $CLANG is used as an assembler (exclusively, it seems, but this isn't 579 # clarified in any user facing documentation). As such, it'll be called on assembly produced by $CC 580 # which usually comes from the darwin stdenv. To prevent a situation where $CLANG doesn't understand 581 # the assembly it is given, we need to make sure that it matches the LLVM version of $CC if possible. 582 # It is unclear (at the time of writing 2024-09-01) whether $CC should match the LLVM version we use 583 # for llc and opt which would require using a custom darwin stdenv for targetCC. 584 # 2025-09-06: The existence of LLVMAS suggests that matching $CC is fine (correct?) here. 585 export CLANG="${ 586 if targetCC.isClang then 587 toolPath "clang" targetCC 588 else 589 getToolExe buildTargetLlvmPackages.clang "clang" 590 }" 591 '' 592 # Haddock and sphinx need a working locale 593 + lib.optionalString (enableDocs || hasHaddock) ( 594 '' 595 export LANG="en_US.UTF-8" 596 '' 597 + lib.optionalString (stdenv.buildPlatform.libc == "glibc") '' 598 export LOCALE_ARCHIVE="${buildPackages.glibcLocales}/lib/locale/locale-archive" 599 '' 600 ) 601 + lib.optionalString (!stdenv.hostPlatform.isDarwin) '' 602 export NIX_LDFLAGS+=" -rpath $out/lib/ghc-${version}" 603 '' 604 + lib.optionalString stdenv.hostPlatform.isDarwin '' 605 export NIX_LDFLAGS+=" -no_dtrace_dof" 606 607 # GHC tries the host xattr /usr/bin/xattr by default which fails since it expects python to be 2.7 608 export XATTR=${lib.getBin xattr}/bin/xattr 609 '' 610 # If we are not using release tarballs, some files need to be generated using 611 # the boot script. 612 + lib.optionalString (rev != null) '' 613 echo ${version} > VERSION 614 echo ${rev} > GIT_COMMIT_ID 615 ./boot 616 '' 617 + lib.optionalString targetPlatform.useAndroidPrebuilt '' 618 sed -i -e '5i ,("armv7a-unknown-linux-androideabi", ("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", "cortex-a8", ""))' llvm-targets 619 '' 620 + lib.optionalString targetPlatform.isMusl '' 621 echo "patching llvm-targets for musl targets..." 622 echo "Cloning these existing '*-linux-gnu*' targets:" 623 grep linux-gnu llvm-targets | sed 's/^/ /' 624 echo "(go go gadget sed)" 625 sed -i 's,\(^.*linux-\)gnu\(.*\)$,\0\n\1musl\2,' llvm-targets 626 echo "llvm-targets now contains these '*-linux-musl*' targets:" 627 grep linux-musl llvm-targets | sed 's/^/ /' 628 629 echo "And now patching to preserve '-musleabi' as done with '-gnueabi'" 630 # (aclocal.m4 is actual source, but patch configure as well since we don't re-gen) 631 for x in configure aclocal.m4; do 632 substituteInPlace $x \ 633 --replace '*-android*|*-gnueabi*)' \ 634 '*-android*|*-gnueabi*|*-musleabi*)' 635 done 636 '' 637 # Need to make writable EM_CACHE for emscripten. The path in EM_CACHE must be absolute. 638 # https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend#configure-fails-with-sub-word-sized-atomic-operations-not-available 639 + lib.optionalString targetPlatform.isGhcjs '' 640 export EM_CACHE="$(realpath $(mktemp -d emcache.XXXXXXXXXX))" 641 cp -Lr ${ 642 targetCC # == emscripten 643 }/share/emscripten/cache/* "$EM_CACHE/" 644 chmod u+rwX -R "$EM_CACHE" 645 '' 646 + '' 647 hadrianFlags+=("-j$NIX_BUILD_CORES") 648 ''; 649 650 ${if targetPlatform.isGhcjs then "configureScript" else null} = "emconfigure ./configure"; 651 # GHC currently ships an edited config.sub so ghcjs is accepted which we can not rollback 652 ${if targetPlatform.isGhcjs then "dontUpdateAutotoolsGnuConfigScripts" else null} = true; 653 654 # TODO(@Ericson2314): Always pass "--target" and always prefix. 655 configurePlatforms = [ 656 "build" 657 "host" 658 ] 659 ++ lib.optional (targetPlatform != hostPlatform) "target"; 660 661 # `--with` flags for libraries needed for RTS linker 662 configureFlags = [ 663 "--datadir=$doc/share/doc/ghc" 664 ] 665 ++ lib.optionals enableTerminfo [ 666 "--with-curses-includes=${lib.getDev targetLibs.ncurses}/include" 667 "--with-curses-libraries=${lib.getLib targetLibs.ncurses}/lib" 668 ] 669 ++ lib.optionals (libffi != null && !targetPlatform.isGhcjs) [ 670 "--with-system-libffi" 671 "--with-ffi-includes=${targetLibs.libffi.dev}/include" 672 "--with-ffi-libraries=${targetLibs.libffi.out}/lib" 673 ] 674 ++ lib.optionals (targetPlatform == hostPlatform && !enableNativeBignum) [ 675 "--with-gmp-includes=${targetLibs.gmp.dev}/include" 676 "--with-gmp-libraries=${targetLibs.gmp.out}/lib" 677 ] 678 ++ 679 lib.optionals 680 (targetPlatform == hostPlatform && hostPlatform.libc != "glibc" && !targetPlatform.isWindows) 681 [ 682 "--with-iconv-includes=${libiconv}/include" 683 "--with-iconv-libraries=${libiconv}/lib" 684 ] 685 ++ lib.optionals (targetPlatform != hostPlatform) [ 686 "--enable-bootstrap-with-devel-snapshot" 687 ] 688 ++ lib.optionals useLdGold [ 689 "CFLAGS=-fuse-ld=gold" 690 "CONF_GCC_LINKER_OPTS_STAGE1=-fuse-ld=gold" 691 "CONF_GCC_LINKER_OPTS_STAGE2=-fuse-ld=gold" 692 ] 693 ++ lib.optionals disableLargeAddressSpace [ 694 "--disable-large-address-space" 695 ] 696 ++ lib.optionals enableDwarf [ 697 "--enable-dwarf-unwind" 698 "--with-libdw-includes=${lib.getDev targetLibs.elfutils}/include" 699 "--with-libdw-libraries=${lib.getLib targetLibs.elfutils}/lib" 700 ] 701 ++ lib.optionals enableNuma [ 702 "--enable-numa" 703 "--with-libnuma-includes=${lib.getDev targetLibs.numactl}/include" 704 "--with-libnuma-libraries=${lib.getLib targetLibs.numactl}/lib" 705 ] 706 ++ lib.optionals targetPlatform.isDarwin [ 707 # Darwin uses llvm-ar. GHC will try to use `-L` with `ar` when it is `llvm-ar` 708 # but it doesn’t currently work because Cabal never uses `-L` on Darwin. See: 709 # https://gitlab.haskell.org/ghc/ghc/-/issues/23188 710 # https://github.com/haskell/cabal/issues/8882 711 "fp_cv_prog_ar_supports_dash_l=no" 712 ] 713 ++ lib.optionals enableUnregisterised [ 714 "--enable-unregisterised" 715 ] 716 ++ 717 lib.optionals 718 (stdenv.buildPlatform.isAarch64 && stdenv.buildPlatform.isMusl && lib.versionOlder version "9.12") 719 [ 720 # The bootstrap binaries for aarch64 musl were built for the wrong triple. 721 # https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13182 722 "--enable-ignore-build-platform-mismatch" 723 ]; 724 725 # Make sure we never relax`$PATH` and hooks support for compatibility. 726 strictDeps = true; 727 728 # Don’t add -liconv to LDFLAGS automatically so that GHC will add it itself. 729 dontAddExtraLibs = true; 730 731 nativeBuildInputs = [ 732 autoreconfHook 733 perl 734 hadrian 735 bootPkgs.alex 736 bootPkgs.happy 737 bootPkgs.hscolour 738 # Python is used in a few scripts invoked by hadrian to generate e.g. rts headers. 739 python3 740 # Tool used to update GHC's settings file in postInstall 741 bootPkgs.ghc-settings-edit 742 ] 743 ++ lib.optionals (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64) [ 744 autoSignDarwinBinariesHook 745 ] 746 ++ lib.optionals enableDocs [ 747 sphinx 748 ]; 749 750 # For building runtime libs 751 depsBuildTarget = toolsForTarget; 752 # Everything the stage0 compiler needs to build stage1: CC, bintools, extra libs. 753 # See also GHC, {CC,LD,AR}_STAGE0 in preConfigure. 754 depsBuildBuild = [ 755 # N.B. We do not declare bootPkgs.ghc in any of the stdenv.mkDerivation 756 # dependency lists to prevent the bintools setup hook from adding ghc's 757 # lib directory to the linker flags. Instead we tell configure about it 758 # via the GHC environment variable. 759 buildCC 760 # stage0 builds terminfo unconditionally, so we always need ncurses 761 ncurses 762 ]; 763 764 # Prevent stage0 ghc from leaking into the final result. This was an issue 765 # with GHC 9.6. 766 disallowedReferences = [ 767 bootPkgs.ghc 768 ]; 769 770 buildInputs = [ bash ] ++ (libDeps hostPlatform); 771 772 # stage0:ghc (i.e. stage1) doesn't need to link against libnuma, so it's target specific 773 depsTargetTarget = map lib.getDev ( 774 libDeps targetPlatform ++ lib.optionals enableNuma [ targetLibs.numactl ] 775 ); 776 depsTargetTargetPropagated = map (lib.getOutput "out") ( 777 libDeps targetPlatform ++ lib.optionals enableNuma [ targetLibs.numactl ] 778 ); 779 780 hadrianFlags = [ 781 "--flavour=${ghcFlavour}" 782 "--bignum=${if enableNativeBignum then "native" else "gmp"}" 783 "--docs=${if enableDocs then "no-sphinx-pdfs" else "no-sphinx"}" 784 ] 785 ++ lib.optionals (lib.versionAtLeast version "9.8") [ 786 # In 9.14 this will be default with release flavour. 787 # See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13444 788 "--hash-unit-ids" 789 ] 790 ++ hadrianSettings; 791 792 buildPhase = '' 793 runHook preBuild 794 795 echo "hadrianFlags: ''${hadrianFlags[@]}" 796 797 # We need to go via the bindist for installing 798 hadrian "''${hadrianFlags[@]}" binary-dist-dir 799 800 runHook postBuild 801 ''; 802 803 # required, because otherwise all symbols from HSffi.o are stripped, and 804 # that in turn causes GHCi to abort 805 stripDebugFlags = [ "-S" ] ++ lib.optional (!targetPlatform.isDarwin) "--keep-file-symbols"; 806 807 checkTarget = "test"; 808 809 hardeningDisable = [ 810 "format" 811 ]; 812 813 # big-parallel allows us to build with more than 2 cores on 814 # Hydra which already warrants a significant speedup 815 requiredSystemFeatures = [ "big-parallel" ]; 816 817 outputs = [ 818 "out" 819 "doc" 820 ]; 821 822 # We need to configure the bindist *again* before installing 823 # https://gitlab.haskell.org/ghc/ghc/-/issues/22058 824 # TODO(@sternenseemann): it would be nice if the bindist could be an intermediate 825 # derivation, but since it is > 2GB even on x86_64-linux, not a good idea? 826 preInstall = '' 827 pushd _build/bindist/* 828 829 '' 830 # the bindist configure script uses different env variables than the GHC configure script 831 # see https://github.com/NixOS/nixpkgs/issues/267250 krank:ignore-line 832 # https://gitlab.haskell.org/ghc/ghc/-/issues/24211 krank:ignore-line 833 + lib.optionalString (stdenv.targetPlatform.linker == "cctools") '' 834 export InstallNameToolCmd=$INSTALL_NAME_TOOL 835 export OtoolCmd=$OTOOL 836 '' 837 # Replicate configurePhase 838 + '' 839 $configureScript "''${configureFlags[@]}" 840 ''; 841 842 postInstall = '' 843 # leave bindist directory 844 popd 845 846 settingsFile="$out/lib/${targetPrefix}${haskellCompilerName}/lib/settings" 847 848 # Make the installed GHC use the host->target tools. 849 ghc-settings-edit "$settingsFile" \ 850 "C compiler command" "${toolPath "cc" installCC}" \ 851 "Haskell CPP command" "${toolPath "cc" installCC}" \ 852 "C++ compiler command" "${toolPath "c++" installCC}" \ 853 "ld command" "${toolPath "ld${lib.optionalString useLdGold ".gold"}" installCC}" \ 854 "Merge objects command" "${toolPath "ld${lib.optionalString useLdGold ".gold"}" installCC}" \ 855 "ar command" "${toolPath "ar" installCC}" \ 856 "ranlib command" "${toolPath "ranlib" installCC}" 857 '' 858 + lib.optionalString (stdenv.targetPlatform.linker == "cctools") '' 859 ghc-settings-edit "$settingsFile" \ 860 "otool command" "${toolPath "otool" installCC}" \ 861 "install_name_tool command" "${toolPath "install_name_tool" installCC}" 862 '' 863 + lib.optionalString useLLVM '' 864 ghc-settings-edit "$settingsFile" \ 865 "LLVM llc command" "${getToolExe llvmPackages.llvm "llc"}" \ 866 "LLVM opt command" "${getToolExe llvmPackages.llvm "opt"}" 867 '' 868 # See comment for LLVMAS in preConfigure 869 + lib.optionalString (useLLVM && lib.versionAtLeast version "9.10") '' 870 ghc-settings-edit "$settingsFile" \ 871 "LLVM llvm-as command" "${getToolExe llvmPackages.clang "clang"}" 872 '' 873 + lib.optionalString (useLLVM && stdenv.targetPlatform.isDarwin) '' 874 ghc-settings-edit "$settingsFile" \ 875 "LLVM clang command" "${ 876 # See comment for CLANG in preConfigure 877 if installCC.isClang then toolPath "clang" installCC else getToolExe llvmPackages.clang "clang" 878 }" 879 '' 880 + lib.optionalString stdenv.targetPlatform.isWindows '' 881 ghc-settings-edit "$settingsFile" \ 882 "windres command" "${toolPath "windres" installCC}" 883 '' 884 + lib.optionalString (stdenv.targetPlatform.isGhcjs && lib.versionOlder version "9.12") '' 885 ghc-settings-edit "$settingsFile" \ 886 "JavaScript CPP command" "${toolPath "cc" installCC}" 887 ghc-settings-edit "$settingsFile" \ 888 "JavaScript CPP flags" "-E -CC -Wno-unicode -nostdinc" 889 '' 890 + '' 891 892 # Install the bash completion file. 893 install -Dm 644 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc 894 ''; 895 896 passthru = { 897 inherit bootPkgs targetPrefix haskellCompilerName; 898 899 inherit llvmPackages; 900 inherit enableShared; 901 inherit hasHaddock; 902 903 # Expose hadrian used for bootstrapping, for debugging purposes 904 inherit hadrian; 905 906 bootstrapAvailable = lib.meta.availableOn stdenv.buildPlatform bootPkgs.ghc; 907 }; 908 909 meta = { 910 homepage = "http://haskell.org/ghc"; 911 description = "Glasgow Haskell Compiler"; 912 maintainers = with lib.maintainers; [ 913 guibou 914 ]; 915 teams = [ lib.teams.haskell ]; 916 timeout = 24 * 3600; 917 platforms = lib.platforms.all; 918 inherit (bootPkgs.ghc.meta) license; 919 }; 920 921 dontStrip = targetPlatform.useAndroidPrebuilt || targetPlatform.isWasm; 922 } 923 // lib.optionalAttrs targetPlatform.useAndroidPrebuilt { 924 dontPatchELF = true; 925 noAuditTmpdir = true; 926 } 927)