nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 479 lines 18 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 perl, 6 gcc, 7 ncurses6, 8 gmp, 9 libiconv, 10 numactl, 11 libffi, 12 coreutils, 13 targetPackages, 14 15 # minimal = true; will remove files that aren't strictly necessary for 16 # regular builds and GHC bootstrapping. 17 # This is "useful" for staying within hydra's output limits for at least the 18 # aarch64-linux architecture. 19 minimal ? false, 20}: 21 22# Prebuilt only does native 23assert stdenv.targetPlatform == stdenv.hostPlatform; 24 25let 26 downloadsUrl = "https://downloads.haskell.org/ghc"; 27 28 # Copy sha256 from https://downloads.haskell.org/~ghc/9.8.4/SHA256SUMS 29 version = "9.8.4"; 30 31 # Information about available bindists that we use in the build. 32 # 33 # # Bindist library checking 34 # 35 # The field `archSpecificLibraries` also provides a way for us get notified 36 # early when the upstream bindist changes its dependencies (e.g. because a 37 # newer Debian version is used that uses a new `ncurses` version). 38 # 39 # Usage: 40 # 41 # * You can find the `fileToCheckFor` of libraries by running `readelf -d` 42 # on the compiler binary (`exePathForLibraryCheck`). 43 # * To skip library checking for an architecture, 44 # set `exePathForLibraryCheck = null`. 45 # * To skip file checking for a specific arch specific library, 46 # set `fileToCheckFor = null`. 47 ghcBinDists = { 48 # Binary distributions for the default libc (e.g. glibc, or libSystem on Darwin) 49 # nixpkgs uses for the respective system. 50 defaultLibc = { 51 i686-linux = { 52 variantSuffix = ""; 53 src = { 54 url = "${downloadsUrl}/${version}/ghc-${version}-i386-deb10-linux.tar.xz"; 55 sha256 = "e5efce16c654d5e702986258a87dd9531e1722b8051823c8ce1150ce3c5899ae"; 56 }; 57 exePathForLibraryCheck = "bin/ghc"; 58 archSpecificLibraries = [ 59 { 60 nixPackage = gmp; 61 fileToCheckFor = null; 62 } 63 { 64 nixPackage = ncurses6; 65 fileToCheckFor = "libtinfo.so.6"; 66 } 67 ]; 68 }; 69 x86_64-linux = { 70 variantSuffix = ""; 71 src = { 72 url = "${downloadsUrl}/${version}/ghc-${version}-x86_64-deb11-linux.tar.xz"; 73 sha256 = "af151db8682b8c763f5a44f960f65453d794c95b60f151abc82dbdefcbe6f8ad"; 74 }; 75 exePathForLibraryCheck = "bin/ghc"; 76 archSpecificLibraries = [ 77 { 78 nixPackage = gmp; 79 fileToCheckFor = null; 80 } 81 { 82 nixPackage = ncurses6; 83 fileToCheckFor = "libtinfo.so.6"; 84 } 85 ]; 86 }; 87 aarch64-linux = { 88 variantSuffix = ""; 89 src = { 90 url = "${downloadsUrl}/${version}/ghc-${version}-aarch64-deb11-linux.tar.xz"; 91 sha256 = "310204daf2df6ad16087be94b3498ca414a0953b29e94e8ec8eb4a5c9bf603d3"; 92 }; 93 exePathForLibraryCheck = "bin/ghc"; 94 archSpecificLibraries = [ 95 { 96 nixPackage = gmp; 97 fileToCheckFor = null; 98 } 99 { 100 nixPackage = ncurses6; 101 fileToCheckFor = "libtinfo.so.6"; 102 } 103 ]; 104 }; 105 x86_64-darwin = { 106 variantSuffix = ""; 107 src = { 108 url = "${downloadsUrl}/${version}/ghc-${version}-x86_64-apple-darwin.tar.xz"; 109 sha256 = "de7baacfb1513ab0e4ccf8911045cceee84bc8a4e39b89bd975ed3135e5f7d96"; 110 }; 111 exePathForLibraryCheck = null; # we don't have a library check for darwin yet 112 archSpecificLibraries = [ 113 { 114 nixPackage = gmp; 115 fileToCheckFor = null; 116 } 117 { 118 nixPackage = ncurses6; 119 fileToCheckFor = null; 120 } 121 { 122 nixPackage = libiconv; 123 fileToCheckFor = null; 124 } 125 ]; 126 }; 127 aarch64-darwin = { 128 variantSuffix = ""; 129 src = { 130 url = "${downloadsUrl}/${version}/ghc-${version}-aarch64-apple-darwin.tar.xz"; 131 sha256 = "e2f12a922754fd28511512875bf6d9eb3e0cce7fc963a7266f6e1661aeabd7ed"; 132 }; 133 exePathForLibraryCheck = null; # we don't have a library check for darwin yet 134 archSpecificLibraries = [ 135 { 136 nixPackage = gmp; 137 fileToCheckFor = null; 138 } 139 { 140 nixPackage = ncurses6; 141 fileToCheckFor = null; 142 } 143 { 144 nixPackage = libiconv; 145 fileToCheckFor = null; 146 } 147 ]; 148 }; 149 }; 150 # Binary distributions for the musl libc for the respective system. 151 musl = { 152 aarch64-linux = { 153 variantSuffix = "-musl"; 154 src = { 155 url = "${downloadsUrl}/${version}/ghc-${version}-aarch64-alpine3_18-linux.tar.xz"; 156 sha256 = "b5c86a0cda0bd62d5eeeb52b1937c3bd00c70cd67dd74226ce787d5c429a4e62"; 157 }; 158 exePathForLibraryCheck = "bin/ghc"; 159 archSpecificLibraries = [ 160 { 161 nixPackage = gmp; 162 fileToCheckFor = null; 163 } 164 { 165 nixPackage = ncurses6; 166 fileToCheckFor = "libncursesw.so.6"; 167 } 168 ]; 169 }; 170 x86_64-linux = { 171 variantSuffix = "-musl"; 172 src = { 173 url = "${downloadsUrl}/${version}/ghc-${version}-x86_64-alpine3_12-linux.tar.xz"; 174 sha256 = "e34bb16e8387509adc96a3d98b4a444bab425d12864c38a3629f2860b4bec2e7"; 175 }; 176 exePathForLibraryCheck = "bin/ghc"; 177 archSpecificLibraries = [ 178 { 179 nixPackage = gmp; 180 fileToCheckFor = null; 181 } 182 { 183 nixPackage = ncurses6; 184 fileToCheckFor = "libncursesw.so.6"; 185 } 186 ]; 187 }; 188 }; 189 }; 190 191 distSetName = if stdenv.hostPlatform.isMusl then "musl" else "defaultLibc"; 192 193 binDistUsed = 194 ghcBinDists.${distSetName}.${stdenv.hostPlatform.system} 195 or (throw "cannot bootstrap GHC on this platform ('${stdenv.hostPlatform.system}' with libc '${distSetName}')"); 196 197 gmpUsed = 198 (builtins.head ( 199 builtins.filter ( 200 drv: lib.hasPrefix "gmp" (drv.nixPackage.name or "") 201 ) binDistUsed.archSpecificLibraries 202 )).nixPackage; 203 204 libPath = lib.makeLibraryPath ( 205 # Add arch-specific libraries. 206 map ({ nixPackage, ... }: nixPackage) binDistUsed.archSpecificLibraries 207 ); 208 209 libEnvVar = lib.optionalString stdenv.hostPlatform.isDarwin "DY" + "LD_LIBRARY_PATH"; 210 211 runtimeDeps = [ 212 targetPackages.stdenv.cc 213 targetPackages.stdenv.cc.bintools 214 coreutils # for cat 215 ] 216 # On darwin, we need unwrapped bintools as well (for otool) 217 ++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [ 218 targetPackages.stdenv.cc.bintools.bintools 219 ]; 220 221in 222 223stdenv.mkDerivation { 224 inherit version; 225 pname = "ghc-binary${binDistUsed.variantSuffix}"; 226 227 src = fetchurl binDistUsed.src; 228 229 nativeBuildInputs = [ perl ]; 230 231 # Set LD_LIBRARY_PATH or equivalent so that the programs running as part 232 # of the bindist installer can find the libraries they expect. 233 # Cannot patchelf beforehand due to relative RPATHs that anticipate 234 # the final install location. 235 env.${libEnvVar} = libPath; 236 237 postUnpack = 238 # Verify our assumptions of which `libtinfo.so` (ncurses) version is used, 239 # so that we know when ghc bindists upgrade that and we need to update the 240 # version used in `libPath`. 241 lib.optionalString (binDistUsed.exePathForLibraryCheck != null) 242 # Note the `*` glob because some GHCs have a suffix when unpacked, e.g. 243 # the musl bindist has dir `ghc-VERSION-x86_64-unknown-linux/`. 244 # As a result, don't shell-quote this glob when splicing the string. 245 ( 246 let 247 buildExeGlob = ''ghc-${version}*/"${binDistUsed.exePathForLibraryCheck}"''; 248 in 249 lib.concatStringsSep "\n" [ 250 '' 251 shopt -u nullglob 252 echo "Checking that ghc binary exists in bindist at ${buildExeGlob}" 253 if ! test -e ${buildExeGlob}; then 254 echo >&2 "GHC binary ${binDistUsed.exePathForLibraryCheck} could not be found in the bindist build directory (at ${buildExeGlob}) for arch ${stdenv.hostPlatform.system}, please check that ghcBinDists correctly reflect the bindist dependencies!"; exit 1; 255 fi 256 '' 257 (lib.concatMapStringsSep "\n" ( 258 { fileToCheckFor, nixPackage }: 259 lib.optionalString (fileToCheckFor != null) '' 260 echo "Checking bindist for ${fileToCheckFor} to ensure that is still used" 261 if ! readelf -d ${buildExeGlob} | grep "${fileToCheckFor}"; then 262 echo >&2 "File ${fileToCheckFor} could not be found in ${binDistUsed.exePathForLibraryCheck} for arch ${stdenv.hostPlatform.system}, please check that ghcBinDists correctly reflect the bindist dependencies!"; exit 1; 263 fi 264 265 echo "Checking that the nix package ${nixPackage} contains ${fileToCheckFor}" 266 if ! test -e "${lib.getLib nixPackage}/lib/${fileToCheckFor}"; then 267 echo >&2 "Nix package ${nixPackage} did not contain ${fileToCheckFor} for arch ${stdenv.hostPlatform.system}, please check that ghcBinDists correctly reflect the bindist dependencies!"; exit 1; 268 fi 269 '' 270 ) binDistUsed.archSpecificLibraries) 271 ] 272 ) 273 # GHC has dtrace probes, which causes ld to try to open /usr/lib/libdtrace.dylib 274 # during linking 275 + lib.optionalString stdenv.hostPlatform.isDarwin '' 276 export NIX_LDFLAGS+=" -no_dtrace_dof" 277 # not enough room in the object files for the full path to libiconv :( 278 for exe in $(find . -type f -executable); do 279 isMachO $exe || continue 280 ln -fs ${libiconv}/lib/libiconv.dylib $(dirname $exe)/libiconv.dylib 281 install_name_tool -change /usr/lib/libiconv.2.dylib @executable_path/libiconv.dylib $exe 282 done 283 '' 284 285 # We have to patch the GMP paths for the ghc-bignum package, for hadrian by 286 # modifying the package-db directly 287 + '' 288 find . -name 'ghc-bignum*.conf' \ 289 -exec sed -e '/^[a-z-]*library-dirs/a \ ${lib.getLib gmpUsed}/lib' -i {} \; 290 '' 291 # Similar for iconv and libffi on darwin 292 + lib.optionalString stdenv.hostPlatform.isDarwin '' 293 find . -name 'base*.conf' \ 294 -exec sed -e '/^[a-z-]*library-dirs/a \ ${lib.getLib libiconv}/lib' -i {} \; 295 296 # To link RTS in the end we also need libffi now 297 find . -name 'rts*.conf' \ 298 -exec sed -e '/^[a-z-]*library-dirs/a \ ${lib.getLib libffi}/lib' \ 299 -e 's@/Library/Developer/.*/usr/include/ffi@${lib.getDev libffi}/include@' \ 300 -i {} \; 301 '' 302 + 303 # Some platforms do HAVE_NUMA so -lnuma requires it in library-dirs in rts/package.conf.in 304 # FFI_LIB_DIR is a good indication of places it must be needed. 305 lib.optionalString 306 ( 307 lib.meta.availableOn stdenv.hostPlatform numactl 308 && builtins.any ({ nixPackage, ... }: nixPackage == numactl) binDistUsed.archSpecificLibraries 309 ) 310 '' 311 find . -name package.conf.in \ 312 -exec sed -i "s@FFI_LIB_DIR@FFI_LIB_DIR ${numactl.out}/lib@g" {} \; 313 '' 314 + 315 # Rename needed libraries and binaries, fix interpreter 316 lib.optionalString stdenv.hostPlatform.isLinux '' 317 find . -type f -executable -exec patchelf \ 318 --interpreter ${stdenv.cc.bintools.dynamicLinker} {} \; 319 ''; 320 321 # fix for `configure: error: Your linker is affected by binutils #16177` 322 preConfigure = lib.optionalString stdenv.targetPlatform.isAarch32 "LD=ld.gold"; 323 324 # GHC has a patched config.sub and bindists' platforms should always work 325 dontUpdateAutotoolsGnuConfigScripts = true; 326 327 configurePlatforms = [ ]; 328 configureFlags = 329 lib.optional stdenv.hostPlatform.isDarwin "--with-gcc=${./gcc-clang-wrapper.sh}" 330 # From: https://github.com/NixOS/nixpkgs/pull/43369/commits 331 ++ lib.optional stdenv.hostPlatform.isMusl "--disable-ld-override"; 332 333 # No building is necessary, but calling make without flags ironically 334 # calls install-strip ... 335 dontBuild = true; 336 337 # Patch scripts to include runtime dependencies in $PATH. 338 postInstall = '' 339 for i in "$out/bin/"*; do 340 test ! -h "$i" || continue 341 isScript "$i" || continue 342 sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i" 343 done 344 '' 345 + lib.optionalString stdenv.targetPlatform.isDarwin '' 346 # Work around building with binary GHC on Darwin due to GHCs use of `ar -L` when it 347 # detects `llvm-ar` even though the resulting archives are not supported by ld64. 348 # https://gitlab.haskell.org/ghc/ghc/-/issues/23188 349 # https://github.com/haskell/cabal/issues/8882 350 sed -i -e 's/,("ar supports -L", "YES")/,("ar supports -L", "NO")/' "$out/lib/ghc-${version}/lib/settings" 351 ''; 352 353 # Apparently necessary for the ghc Alpine (musl) bindist: 354 # When we strip, and then run the 355 # patchelf --set-rpath "${libPath}:$(patchelf --print-rpath $p)" $p 356 # below, running ghc (e.g. during `installCheckPhase)` gives some apparently 357 # corrupted rpath or whatever makes the loader work on nonsensical strings: 358 # running install tests 359 # Error relocating /nix/store/...-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/ghc: : symbol not found 360 # Error relocating /nix/store/...-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/ghc: ir6zf6c9f86pfx8sr30n2vjy-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/../lib/x86_64-linux-ghc-8.10.5/libHSexceptions-0.10.4-ghc8.10.5.so: symbol not found 361 # Error relocating /nix/store/...-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/ghc: y/lib/ghc-8.10.5/bin/../lib/x86_64-linux-ghc-8.10.5/libHStemplate-haskell-2.16.0.0-ghc8.10.5.so: symbol not found 362 # Error relocating /nix/store/...-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/ghc: 8.10.5/libHStemplate-haskell-2.16.0.0-ghc8.10.5.so: symbol not found 363 # Error relocating /nix/store/...-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/ghc: �: symbol not found 364 # Error relocating /nix/store/...-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/ghc: �?: symbol not found 365 # Error relocating /nix/store/...-ghc-8.10.2-binary/lib/ghc-8.10.5/bin/ghc: 64-linux-ghc-8.10.5/libHSexceptions-0.10.4-ghc8.10.5.so: symbol not found 366 # This is extremely bogus and should be investigated. 367 dontStrip = if stdenv.hostPlatform.isMusl then true else false; # `if` for explicitness 368 369 # On Linux, use patchelf to modify the executables so that they can 370 # find editline/gmp. 371 postFixup = 372 lib.optionalString (stdenv.hostPlatform.isLinux && !(binDistUsed.isStatic or false)) ( 373 if stdenv.hostPlatform.isAarch64 then 374 # Keep rpath as small as possible on aarch64 for patchelf#244. All Elfs 375 # are 2 directories deep from $out/lib, so pooling symlinks there makes 376 # a short rpath. 377 '' 378 (cd $out/lib; ln -s ${lib.getLib gmpUsed}/lib/libgmp.so.10) 379 '' 380 + ( 381 if stdenv.hostPlatform.isMusl then 382 '' 383 (cd $out/lib; ln -s ${ncurses6.out}/lib/libncursesw.so.6) 384 '' 385 else 386 '' 387 (cd $out/lib; ln -s ${ncurses6.out}/lib/libtinfo.so.6) 388 '' 389 ) 390 + '' 391 for p in $(find "$out/lib" -type f -name "*\.so*"); do 392 (cd $out/lib; ln -s $p) 393 done 394 395 for p in $(find "$out/lib" -type f -executable); do 396 if isELF "$p"; then 397 echo "Patchelfing $p" 398 patchelf --set-rpath "\$ORIGIN:\$ORIGIN/../.." $p 399 fi 400 done 401 '' 402 else 403 '' 404 for p in $(find "$out" -type f -executable); do 405 if isELF "$p"; then 406 echo "Patchelfing $p" 407 patchelf --set-rpath "${libPath}:$(patchelf --print-rpath $p)" $p 408 fi 409 done 410 '' 411 ) 412 + lib.optionalString stdenv.hostPlatform.isDarwin '' 413 # not enough room in the object files for the full path to libiconv :( 414 for exe in $(find "$out" -type f -executable); do 415 isMachO $exe || continue 416 ln -fs ${libiconv}/lib/libiconv.dylib $(dirname $exe)/libiconv.dylib 417 install_name_tool -change /usr/lib/libiconv.2.dylib @executable_path/libiconv.dylib $exe 418 done 419 420 for file in $(find "$out" -name setup-config); do 421 substituteInPlace $file --replace /usr/bin/ranlib "$(type -P ranlib)" 422 done 423 '' 424 # Recache package db which needs to happen for Hadrian bindists 425 # where we modify the package db before installing 426 + '' 427 package_db=("$out"/lib/ghc-*/lib/package.conf.d) 428 "$out/bin/ghc-pkg" --package-db="$package_db" recache 429 ''; 430 431 doInstallCheck = true; 432 installCheckPhase = '' 433 # Sanity check, can ghc create executables? 434 cd $TMP 435 mkdir test-ghc; cd test-ghc 436 cat > main.hs << EOF 437 {-# LANGUAGE TemplateHaskell #-} 438 module Main where 439 main = putStrLn \$([|"yes"|]) 440 EOF 441 env -i $out/bin/ghc --make main.hs || exit 1 442 echo compilation ok 443 [ $(./main) == "yes" ] 444 ''; 445 446 passthru = { 447 targetPrefix = ""; 448 enableShared = true; 449 450 llvmPackages = null; 451 452 # Our Cabal compiler name 453 haskellCompilerName = "ghc-${version}"; 454 455 # Normal GHC derivations expose the hadrian derivation used to build them 456 # here. In the case of bindists we just make sure that the attribute exists, 457 # as it is used for checking if a GHC derivation has been built with hadrian. 458 hadrian = null; 459 }; 460 461 meta = { 462 homepage = "http://haskell.org/ghc"; 463 description = "Glasgow Haskell Compiler"; 464 license = lib.licenses.bsd3; 465 # HACK: since we can't encode the libc / abi in platforms, we need 466 # to make the platform list dependent on the evaluation platform 467 # in order to avoid eval errors with musl which supports less 468 # platforms than the default libcs (i. e. glibc / libSystem). 469 # This is done for the benefit of Hydra, so `packagePlatforms` 470 # won't return any platforms that would cause an evaluation 471 # failure for `pkgsMusl.haskell.compiler.ghc922Binary`, as 472 # long as the evaluator runs on a platform that supports 473 # `pkgsMusl`. 474 platforms = builtins.attrNames ghcBinDists.${distSetName}; 475 maintainers = lib.teams.haskell.members; 476 broken = !(import ./common-have-ncg.nix { inherit lib stdenv version; }); 477 sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; 478 }; 479}