nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at 17.09 135 lines 5.8 kB view raw
1{ stdenv, lib, ghc, llvmPackages, packages, symlinkJoin, makeWrapper 2, ignoreCollisions ? false, withLLVM ? false 3, postBuild ? "" 4, haskellPackages 5, ghcLibdir ? null # only used by ghcjs, when resolving plugins 6}: 7 8assert ghcLibdir != null -> (ghc.isGhcjs or false); 9 10# This wrapper works only with GHC 6.12 or later. 11assert lib.versionOlder "6.12" ghc.version || ghc.isGhcjs || ghc.isHaLVM; 12 13# It's probably a good idea to include the library "ghc-paths" in the 14# compiler environment, because we have a specially patched version of 15# that package in Nix that honors these environment variables 16# 17# NIX_GHC 18# NIX_GHCPKG 19# NIX_GHC_DOCDIR 20# NIX_GHC_LIBDIR 21# 22# instead of hard-coding the paths. The wrapper sets these variables 23# appropriately to configure ghc-paths to point back to the wrapper 24# instead of to the pristine GHC package, which doesn't know any of the 25# additional libraries. 26# 27# A good way to import the environment set by the wrapper below into 28# your shell is to add the following snippet to your ~/.bashrc: 29# 30# if [ -e ~/.nix-profile/bin/ghc ]; then 31# eval $(grep export ~/.nix-profile/bin/ghc) 32# fi 33 34let 35 isGhcjs = ghc.isGhcjs or false; 36 isHaLVM = ghc.isHaLVM or false; 37 ghc761OrLater = isGhcjs || isHaLVM || lib.versionOlder "7.6.1" ghc.version; 38 packageDBFlag = if ghc761OrLater then "--global-package-db" else "--global-conf"; 39 ghcCommand' = if isGhcjs then "ghcjs" else "ghc"; 40 crossPrefix = if (ghc.cross or null) != null then "${ghc.cross.config}-" else ""; 41 ghcCommand = "${crossPrefix}${ghcCommand'}"; 42 ghcCommandCaps= lib.toUpper ghcCommand'; 43 libDir = if isHaLVM then "$out/lib/HaLVM-${ghc.version}" else "$out/lib/${ghcCommand}-${ghc.version}"; 44 docDir = "$out/share/doc/ghc/html"; 45 packageCfgDir = "${libDir}/package.conf.d"; 46 paths = lib.filter (x: x ? isHaskellLibrary) (lib.closePropagation packages); 47 hasLibraries = lib.any (x: x.isHaskellLibrary) paths; 48 # CLang is needed on Darwin for -fllvm to work: 49 # https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/code-generators.html 50 llvm = lib.makeBinPath 51 ([ llvmPackages.llvm ] 52 ++ lib.optional stdenv.isDarwin llvmPackages.clang); 53in 54if paths == [] && !withLLVM then ghc else 55symlinkJoin { 56 # this makes computing paths from the name attribute impossible; 57 # if such a feature is needed, the real compiler name should be saved 58 # as a dedicated drv attribute, like `compiler-name` 59 name = ghc.name + "-with-packages"; 60 paths = paths ++ [ghc]; 61 extraOutputsToInstall = [ "out" "doc" ]; 62 inherit ignoreCollisions; 63 postBuild = '' 64 . ${makeWrapper}/nix-support/setup-hook 65 66 # wrap compiler executables with correct env variables 67 68 for prg in ${ghcCommand} ${ghcCommand}i ${ghcCommand}-${ghc.version} ${ghcCommand}i-${ghc.version}; do 69 if [[ -x "${ghc}/bin/$prg" ]]; then 70 rm -f $out/bin/$prg 71 makeWrapper ${ghc}/bin/$prg $out/bin/$prg \ 72 --add-flags '"-B$NIX_${ghcCommandCaps}_LIBDIR"' \ 73 --set "NIX_${ghcCommandCaps}" "$out/bin/${ghcCommand}" \ 74 --set "NIX_${ghcCommandCaps}PKG" "$out/bin/${ghcCommand}-pkg" \ 75 --set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}" \ 76 --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}" \ 77 ${lib.optionalString withLLVM ''--prefix "PATH" ":" "${llvm}"''} 78 fi 79 done 80 81 for prg in runghc runhaskell; do 82 if [[ -x "${ghc}/bin/$prg" ]]; then 83 rm -f $out/bin/$prg 84 makeWrapper ${ghc}/bin/$prg $out/bin/$prg \ 85 --add-flags "-f $out/bin/${ghcCommand}" \ 86 --set "NIX_${ghcCommandCaps}" "$out/bin/${ghcCommand}" \ 87 --set "NIX_${ghcCommandCaps}PKG" "$out/bin/${ghcCommand}-pkg" \ 88 --set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}" \ 89 --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}" 90 fi 91 done 92 93 for prg in ${ghcCommand}-pkg ${ghcCommand}-pkg-${ghc.version}; do 94 if [[ -x "${ghc}/bin/$prg" ]]; then 95 rm -f $out/bin/$prg 96 makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}" 97 fi 98 done 99 '' + (lib.optionalString stdenv.isDarwin '' 100 # Work around a linker limit in macOS Sierra (see generic-builder.nix): 101 local packageConfDir="$out/lib/${ghc.name}/package.conf.d"; 102 local dynamicLinksDir="$out/lib/links" 103 mkdir -p $dynamicLinksDir 104 # Clean up the old links that may have been (transitively) included by 105 # symlinkJoin: 106 rm -f $dynamicLinksDir/* 107 for d in $(grep dynamic-library-dirs $packageConfDir/*|awk '{print $2}'); do 108 ln -s $d/*.dylib $dynamicLinksDir 109 done 110 for f in $packageConfDir/*.conf; do 111 # Initially, $f is a symlink to a read-only file in one of the inputs 112 # (as a result of this symlinkJoin derivation). 113 # Replace it with a copy whose dynamic-library-dirs points to 114 # $dynamicLinksDir 115 cp $f $f-tmp 116 rm $f 117 sed "s,dynamic-library-dirs: .*,dynamic-library-dirs: $dynamicLinksDir," $f-tmp > $f 118 rm $f-tmp 119 done 120 '') + '' 121 ${lib.optionalString hasLibraries "$out/bin/${ghcCommand}-pkg recache"} 122 ${# ghcjs will read the ghc_libdir file when resolving plugins. 123 lib.optionalString (isGhcjs && ghcLibdir != null) '' 124 mkdir -p "${libDir}" 125 rm -f "${libDir}/ghc_libdir" 126 printf '%s' '${ghcLibdir}' > "${libDir}/ghc_libdir" 127 ''} 128 $out/bin/${ghcCommand}-pkg check 129 '' + postBuild; 130 passthru = { 131 preferLocalBuild = true; 132 inherit (ghc) version meta; 133 inherit haskellPackages; 134 }; 135}