Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 perl, 6 gcc, 7 ncurses5, 8 ncurses6, 9 gmp, 10 glibc, 11 libiconv, 12 llvmPackages, 13 coreutils, 14 targetPackages, 15}: 16 17# Prebuilt only does native 18assert stdenv.targetPlatform == stdenv.hostPlatform; 19 20let 21 useLLVM = 22 !(stdenv.targetPlatform.isx86 || stdenv.targetPlatform.isPower || stdenv.targetPlatform.isSparc); 23 24 useNcurses6 = 25 stdenv.hostPlatform.system == "x86_64-linux" 26 || (with stdenv.hostPlatform; isPower64 && isLittleEndian); 27 28 ourNcurses = if useNcurses6 then ncurses6 else ncurses5; 29 30 libPath = lib.makeLibraryPath ( 31 [ 32 ourNcurses 33 gmp 34 ] 35 ++ lib.optional (stdenv.hostPlatform.isDarwin) libiconv 36 ); 37 38 libEnvVar = lib.optionalString stdenv.hostPlatform.isDarwin "DY" + "LD_LIBRARY_PATH"; 39 40 glibcDynLinker = 41 assert stdenv.hostPlatform.isLinux; 42 if stdenv.hostPlatform.libc == "glibc" then 43 # Could be stdenv.cc.bintools.dynamicLinker, keeping as-is to avoid rebuild. 44 ''"$(cat $NIX_CC/nix-support/dynamic-linker)"'' 45 else 46 "${lib.getLib glibc}/lib/ld-linux*"; 47 48 downloadsUrl = "https://downloads.haskell.org/ghc"; 49 50 runtimeDeps = [ 51 targetPackages.stdenv.cc 52 targetPackages.stdenv.cc.bintools 53 coreutils # for cat 54 ] 55 ++ 56 lib.optionals 57 ( 58 assert useLLVM -> !(llvmPackages == null); 59 useLLVM 60 ) 61 [ 62 (lib.getBin llvmPackages.llvm) 63 ] 64 # On darwin, we need unwrapped bintools as well (for otool) 65 ++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [ 66 targetPackages.stdenv.cc.bintools.bintools 67 ]; 68 69in 70 71stdenv.mkDerivation rec { 72 version = "8.6.5"; 73 pname = "ghc-binary"; 74 75 # https://downloads.haskell.org/~ghc/8.6.5/ 76 src = fetchurl ( 77 { 78 i686-linux = { 79 # Don't use the Fedora27 build (as below) because there isn't one! 80 url = "${downloadsUrl}/${version}/ghc-${version}-i386-deb9-linux.tar.xz"; 81 sha256 = "1p2h29qghql19ajk755xa0yxkn85slbds8m9n5196ris743vkp8w"; 82 }; 83 x86_64-linux = { 84 # This is the Fedora build because it links against ncurses6 where the 85 # deb9 one links against ncurses5, see here 86 # https://github.com/NixOS/nixpkgs/issues/85924 for a discussion 87 url = "${downloadsUrl}/${version}/ghc-${version}-x86_64-fedora27-linux.tar.xz"; 88 sha256 = "18dlqm5d028fqh6ghzn7pgjspr5smw030jjzl3kq6q1kmwzbay6g"; 89 }; 90 x86_64-darwin = { 91 url = "${downloadsUrl}/${version}/ghc-${version}-x86_64-apple-darwin.tar.xz"; 92 sha256 = "0s9188vhhgf23q3rjarwhbr524z6h2qga5xaaa2pma03sfqvvhfz"; 93 }; 94 powerpc64le-linux = { 95 url = "https://downloads.haskell.org/~ghc/${version}/ghc-${version}-powerpc64le-fedora29-linux.tar.xz"; 96 sha256 = "sha256-tWSsJdPVrCiqDyIKzpBt5DaXb3b6j951tCya584kWs4="; 97 }; 98 } 99 .${stdenv.hostPlatform.system} or (throw "cannot bootstrap GHC on this platform") 100 ); 101 102 nativeBuildInputs = [ perl ]; 103 104 # Cannot patchelf beforehand due to relative RPATHs that anticipate 105 # the final install location/ 106 ${libEnvVar} = libPath; 107 108 postUnpack = 109 # GHC has dtrace probes, which causes ld to try to open /usr/lib/libdtrace.dylib 110 # during linking 111 lib.optionalString stdenv.hostPlatform.isDarwin '' 112 export NIX_LDFLAGS+=" -no_dtrace_dof" 113 # not enough room in the object files for the full path to libiconv :( 114 for exe in $(find . -type f -executable); do 115 isScript $exe && continue 116 ln -fs ${libiconv}/lib/libiconv.dylib $(dirname $exe)/libiconv.dylib 117 install_name_tool -change /usr/lib/libiconv.2.dylib @executable_path/libiconv.dylib -change /usr/local/lib/gcc/6/libgcc_s.1.dylib ${gcc.cc.lib}/lib/libgcc_s.1.dylib $exe 118 done 119 '' 120 + 121 122 # Some scripts used during the build need to have their shebangs patched 123 '' 124 patchShebangs ghc-${version}/utils/ 125 patchShebangs ghc-${version}/configure 126 test -d ghc-${version}/inplace/bin && \ 127 patchShebangs ghc-${version}/inplace/bin 128 '' 129 + 130 131 # We have to patch the GMP paths for the integer-gmp package. 132 '' 133 find . -name integer-gmp.buildinfo \ 134 -exec sed -i "s@extra-lib-dirs: @extra-lib-dirs: ${gmp.out}/lib@" {} \; 135 '' 136 + lib.optionalString stdenv.hostPlatform.isDarwin '' 137 find . -name base.buildinfo \ 138 -exec sed -i "s@extra-lib-dirs: @extra-lib-dirs: ${libiconv}/lib@" {} \; 139 '' 140 + 141 # Rename needed libraries and binaries, fix interpreter 142 lib.optionalString stdenv.hostPlatform.isLinux '' 143 find . -type f -perm -0100 \ 144 -exec patchelf \ 145 --replace-needed libncurses${lib.optionalString stdenv.hostPlatform.is64bit "w"}.so.5 libncurses.so \ 146 ${ 147 # This isn't required for x86_64-linux where we use ncurses6 148 lib.optionalString (!useNcurses6) "--replace-needed libtinfo.so libtinfo.so.5" 149 } \ 150 --interpreter ${glibcDynLinker} {} \; 151 152 sed -i "s|/usr/bin/perl|perl\x00 |" ghc-${version}/ghc/stage2/build/tmp/ghc-stage2 153 sed -i "s|/usr/bin/gcc|gcc\x00 |" ghc-${version}/ghc/stage2/build/tmp/ghc-stage2 154 '' 155 + 156 # We're kludging a glibc bindist into working with non-glibc... 157 # Here we patch up the use of `__strdup` (part of glibc binary ABI) 158 # to instead use `strdup` since musl doesn't provide __strdup 159 # (`__strdup` is defined to be an alias of `strdup` anyway[1]). 160 # [1] http://refspecs.linuxbase.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/baselib---strdup-1.html 161 # Use objcopy magic to make the change: 162 lib.optionalString stdenv.hostPlatform.isMusl '' 163 find ./ghc-${version}/rts -name "libHSrts*.a" -exec ''${OBJCOPY:-objcopy} --redefine-sym __strdup=strdup {} \; 164 ''; 165 166 configurePlatforms = [ ]; 167 configureFlags = [ 168 "--with-gmp-includes=${lib.getDev gmp}/include" 169 # Note `--with-gmp-libraries` does nothing for GHC bindists: 170 # https://gitlab.haskell.org/ghc/ghc/-/merge_requests/6124 171 ] 172 ++ lib.optional stdenv.hostPlatform.isDarwin "--with-gcc=${./gcc-clang-wrapper.sh}" 173 ++ lib.optional stdenv.hostPlatform.isMusl "--disable-ld-override"; 174 175 # No building is necessary, but calling make without flags ironically 176 # calls install-strip ... 177 dontBuild = true; 178 179 # GHC tries to remove xattrs when installing to work around Gatekeeper 180 # (see https://gitlab.haskell.org/ghc/ghc/-/issues/17418). This step normally 181 # succeeds in nixpkgs because xattrs are not allowed in the store, but it 182 # can fail when a file has the `com.apple.provenance` xattr, and it can’t be 183 # modified (such as target of the symlink to `libiconv.dylib`). 184 # The `com.apple.provenance` xattr is a new feature of macOS as of macOS 13. 185 # See: https://eclecticlight.co/2023/03/13/ventura-has-changed-app-quarantine-with-a-new-xattr/ 186 makeFlags = lib.optionals stdenv.buildPlatform.isDarwin [ "XATTR=/does-not-exist" ]; 187 188 # Patch scripts to include runtime dependencies in $PATH. 189 postInstall = '' 190 for i in "$out/bin/"*; do 191 test ! -h "$i" || continue 192 isScript "$i" || continue 193 sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i" 194 done 195 ''; 196 197 # On Linux, use patchelf to modify the executables so that they can 198 # find editline/gmp. 199 postFixup = 200 lib.optionalString stdenv.hostPlatform.isLinux '' 201 for p in $(find "$out" -type f -executable); do 202 if isELF "$p"; then 203 echo "Patchelfing $p" 204 patchelf --set-rpath "${libPath}:$(patchelf --print-rpath $p)" $p 205 fi 206 done 207 '' 208 + lib.optionalString stdenv.hostPlatform.isDarwin '' 209 # not enough room in the object files for the full path to libiconv :( 210 for exe in $(find "$out" -type f -executable); do 211 isScript $exe && continue 212 ln -fs ${libiconv}/lib/libiconv.dylib $(dirname $exe)/libiconv.dylib 213 install_name_tool -change /usr/lib/libiconv.2.dylib @executable_path/libiconv.dylib -change /usr/local/lib/gcc/6/libgcc_s.1.dylib ${gcc.cc.lib}/lib/libgcc_s.1.dylib $exe 214 done 215 216 for file in $(find "$out" -name setup-config); do 217 substituteInPlace $file --replace /usr/bin/ranlib "$(type -P ranlib)" 218 done 219 ''; 220 221 # GHC cannot currently produce outputs that are ready for `-pie` linking. 222 # Thus, disable `pie` hardening, otherwise `recompile with -fPIE` errors appear. 223 # See: 224 # * https://github.com/NixOS/nixpkgs/issues/129247 225 # * https://gitlab.haskell.org/ghc/ghc/-/issues/19580 226 hardeningDisable = [ "pie" ]; 227 228 doInstallCheck = true; 229 installCheckPhase = '' 230 # Sanity check, can ghc create executables? 231 cd $TMP 232 mkdir test-ghc; cd test-ghc 233 cat > main.hs << EOF 234 {-# LANGUAGE TemplateHaskell #-} 235 module Main where 236 main = putStrLn \$([|"yes"|]) 237 EOF 238 env -i $out/bin/ghc --make main.hs || exit 1 239 echo compilation ok 240 [ $(./main) == "yes" ] 241 ''; 242 243 passthru = { 244 targetPrefix = ""; 245 enableShared = true; 246 247 inherit llvmPackages; 248 249 # Our Cabal compiler name 250 haskellCompilerName = "ghc-${version}"; 251 }; 252 253 meta = rec { 254 license = lib.licenses.bsd3; 255 platforms = [ 256 "x86_64-linux" 257 "i686-linux" 258 "x86_64-darwin" 259 "powerpc64le-linux" 260 ]; 261 # build segfaults, use ghc8107Binary which has proper musl support instead 262 broken = stdenv.hostPlatform.isMusl; 263 maintainers = with lib.maintainers; [ 264 guibou 265 ]; 266 teams = [ lib.teams.haskell ]; 267 }; 268}