nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 269 lines 8.7 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 perl, 6 gcc, 7 ncurses5, 8 ncurses6, 9 gmp, 10 libiconv, 11 numactl, 12 libffi, 13 coreutils, 14 targetPackages, 15}: 16 17# Prebuilt only does native 18assert stdenv.targetPlatform == stdenv.hostPlatform; 19 20let 21 version = "9.6.6"; 22 23 # GHC upstream doesn't release bindist tarballs for some platforms. 24 # We're using Debian's binary package, and patching it into a usable-in-Nixpkgs state. 25 ghcDebs = { 26 powerpc64-linux = { 27 src = { 28 urls = [ 29 "http://ftp.ports.debian.org/debian-ports/pool-ppc64/main/g/ghc/ghc_9.6.6-4_ppc64.deb" 30 "https://snapshot.debian.org/archive/debian-ports/20250917T193713Z/pool-ppc64/main/g/ghc/ghc_9.6.6-4_ppc64.deb" 31 ]; 32 sha256 = "722cc301b6ba70b342e5e3d9d0671440bcd749cd2f13dcccbd23c3f6a6060171"; 33 }; 34 exePathForLibraryCheck = null; 35 archSpecificLibraries = [ 36 { 37 nixPackage = gmp; 38 fileToCheckFor = null; 39 } 40 { 41 nixPackage = ncurses6; 42 fileToCheckFor = "libtinfo.so.6"; 43 } 44 { 45 nixPackage = numactl; 46 fileToCheckFor = null; 47 } 48 { 49 nixPackage = libffi; 50 fileToCheckFor = null; 51 } 52 ]; 53 }; 54 }; 55 56 debUsed = 57 ghcDebs.${stdenv.hostPlatform.system} 58 or (throw "cannot bootstrap GHC on this platform ('${stdenv.hostPlatform.system}') from Debian debs"); 59 60 gmpUsed = 61 (builtins.head ( 62 builtins.filter (drv: lib.hasPrefix "gmp" (drv.nixPackage.name or "")) debUsed.archSpecificLibraries 63 )).nixPackage; 64 65 runtimeDeps = [ 66 targetPackages.stdenv.cc 67 targetPackages.stdenv.cc.bintools 68 coreutils # for cat 69 ]; 70 71 extraLibraryMapping = { 72 gmp = gmpUsed; 73 numa = numactl; 74 ffi = libffi; 75 }; 76 77in 78 79stdenv.mkDerivation (finalAttrs: { 80 inherit version; 81 pname = "ghc-debian-binary"; 82 83 src = fetchurl debUsed.src; 84 85 nativeBuildInputs = [ perl ]; 86 87 sourceRoot = "${finalAttrs.pname}-${finalAttrs.version}"; 88 89 # Custom unpack phase to handle .deb files 90 unpackPhase = '' 91 runHook preUnpack 92 93 ar x $src 94 tar xf data.tar.xz 95 mkdir -p ${finalAttrs.sourceRoot} 96 mv -t ${finalAttrs.sourceRoot}/ usr var 97 98 runHook postUnpack 99 ''; 100 101 postUnpack = 102 # Verify our assumptions of which `libtinfo.so` (ncurses) version is used, 103 # so that we know when ghc debs upgrade that and we need to update the 104 # version used in `archSpecificLibraries`. 105 lib.optionalString (debUsed.exePathForLibraryCheck != null) ( 106 lib.concatStringsSep "\n" [ 107 '' 108 shopt -u nullglob 109 echo "Checking that ghc binary exists in deb at ${debUsed.exePathForLibraryCheck}" 110 if ! test -e ${debUsed.exePathForLibraryCheck}; then 111 echo >&2 "GHC binary ${debUsed.exePathForLibraryCheck} could not be found in the deb unpack directory for arch ${stdenv.hostPlatform.system}, please check that ghcDebs correctly reflect the deb dependencies!"; exit 1; 112 fi 113 '' 114 (lib.concatMapStringsSep "\n" ( 115 { fileToCheckFor, nixPackage }: 116 lib.optionalString (fileToCheckFor != null) '' 117 echo "Checking deb for ${fileToCheckFor} to ensure that is still used" 118 if ! readelf -d ${debUsed.exePathForLibraryCheck} | grep "${fileToCheckFor}"; then 119 echo >&2 "File ${fileToCheckFor} could not be found in ${debUsed.exePathForLibraryCheck} for arch ${stdenv.hostPlatform.system}, please check that ghcDebs correctly reflect the deb dependencies!"; exit 1; 120 fi 121 122 echo "Checking that the nix package ${nixPackage} contains ${fileToCheckFor}" 123 if ! test -e "${lib.getLib nixPackage}/lib/${fileToCheckFor}"; then 124 echo >&2 "Nix package ${nixPackage} did not contain ${fileToCheckFor} for arch ${stdenv.hostPlatform.system}, please check that ghcDebs correctly reflect the deb dependencies!"; exit 1; 125 fi 126 '' 127 ) debUsed.archSpecificLibraries) 128 ] 129 ) 130 131 # Linking to non-compiler libraries requires GHC to know about our non-FHS paths for those libraries 132 + (lib.strings.concatMapAttrsStringSep "\n" (libName: libPackage: '' 133 for packageDbDir in $(find . -name package.conf.d); do 134 for packageDb in $(grep -l 'extra-libraries:.*${libName}' "$packageDbDir"/*.conf); do 135 echo "Patching include & library path for ${libName} into package DB: $packageDb" 136 sed -i "$packageDb" \ 137 -e '/^[a-z-]*include-dirs/a \ ${lib.getDev libPackage}/include' \ 138 -e '/^[a-z-]*library-dirs/a \ ${lib.getLib libPackage}/lib' 139 done 140 done 141 '') extraLibraryMapping) 142 143 + 144 # Rename needed libraries and binaries, fix interpreter 145 lib.optionalString stdenv.hostPlatform.isLinux '' 146 find . -type f -executable -exec patchelf \ 147 --interpreter ${stdenv.cc.bintools.dynamicLinker} {} \; 148 ''; 149 150 # Not a bindist, nothing to configure 151 dontConfigure = true; 152 153 # Not a bindist, it's already built 154 dontBuild = true; 155 156 # Install prebuilt GHC files 157 installPhase = '' 158 runHook preInstall 159 160 mkdir -p $out 161 162 cp -t $out/ -a usr/* 163 rm -f $out/lib/ghc/lib/package.conf.d 164 find var -name "package.conf.d" -type d -exec cp -a {} $out/lib/ghc/lib/ \; 165 166 runHook postInstall 167 ''; 168 169 postInstall = 170 # Patch scripts to include runtime dependencies in $PATH. 171 '' 172 for i in "$out/bin/"*; do 173 test ! -h "$i" || continue 174 isScript "$i" || continue 175 sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i" 176 done 177 '' 178 179 # Patch /usr paths 180 + '' 181 for i in "$out/bin/"*; do 182 test ! -h "$i" || continue 183 isScript "$i" || continue 184 substituteInPlace "$i" \ 185 --replace-fail '="/usr' '="${placeholder "out"}' 186 done 187 find "$out/lib/ghc/lib/package.conf.d" -type f -name '*.conf' \ 188 -exec sed -i "s|/usr/|$out/|g" {} + 189 '' 190 191 # Patch ghc settings 192 + '' 193 substituteInPlace $out/lib/ghc/lib/settings \ 194 --replace-fail powerpc64-linux-gnu-gcc gcc \ 195 --replace-fail powerpc64-linux-gnu-g++ g++ \ 196 --replace-fail powerpc64-linux-gnu-ld ld \ 197 --replace-fail powerpc64-linux-gnu-ar ar \ 198 --replace-fail powerpc64-linux-gnu-ranlib ranlib \ 199 --replace-fail llc-18 llc \ 200 --replace-fail opt-18 opt 201 ''; 202 203 # On Linux, use patchelf to modify the executables so that they can 204 # find editline/gmp. 205 postFixup = 206 lib.optionalString (stdenv.hostPlatform.isLinux && !(debUsed.isStatic or false)) 207 # Keep rpath as small as possible, running autoPatchelf makes everything segfault (maybe similar to patchelf#244). 208 # All Elfs are 2 directories deep from $out/lib, so pooling symlinks there makes a short rpath. 209 '' 210 (cd $out/lib; ln -s ${ncurses6.out}/lib/libtinfo.so.6) 211 (cd $out/lib; ln -s ${lib.getLib gmpUsed}/lib/libgmp.so.10) 212 (cd $out/lib; ln -s ${numactl.out}/lib/libnuma.so.1) 213 (cd $out/lib; ln -s ${libffi.out}/lib/libffi.so.8) 214 for p in $(find "$out/lib" -type f -name "*\.so*"); do 215 (cd $out/lib; ln -s $p) 216 done 217 218 for p in $(find "$out/lib" -type f -executable); do 219 if isELF "$p"; then 220 echo "Patchelfing $p" 221 patchelf --set-rpath "\$ORIGIN:\$ORIGIN/../.." $p 222 fi 223 done 224 '' 225 # Recache package db which needs to happen because 226 # we modify the package db 227 + '' 228 "$out/bin/ghc-pkg" --package-db=$out/lib/ghc/lib/package.conf.d recache 229 ''; 230 231 doInstallCheck = true; 232 installCheckPhase = '' 233 # Sanity check, can ghc create executables? 234 cd $TMP 235 mkdir test-ghc; cd test-ghc 236 cat > main.hs << EOF 237 {-# LANGUAGE TemplateHaskell #-} 238 module Main where 239 main = putStrLn \$([|"yes"|]) 240 EOF 241 env -i $out/bin/ghc --make main.hs || exit 1 242 echo compilation ok 243 [ $(./main) == "yes" ] 244 ''; 245 246 passthru = { 247 targetPrefix = ""; 248 enableShared = true; 249 250 llvmPackages = null; 251 252 # Our Cabal compiler name 253 haskellCompilerName = "ghc-${version}"; 254 255 # Normal GHC derivations expose the hadrian derivation used to build them 256 # here. In the case of debs we just make sure that the attribute exists, 257 # as it is used for checking if a GHC derivation has been built with hadrian. 258 hadrian = null; 259 }; 260 261 meta = { 262 homepage = "http://haskell.org/ghc"; 263 description = "Glasgow Haskell Compiler"; 264 license = lib.licenses.bsd3; 265 platforms = builtins.attrNames ghcDebs; 266 maintainers = [ lib.maintainers.OPNA2608 ]; 267 teams = [ lib.teams.haskell ]; 268 }; 269})