| 
									
										
										
										
											2020-01-10 15:20:08 +01:00
										 |  |  | { lib, stdenv, ghc, llvmPackages, packages, symlinkJoin, makeWrapper | 
					
						
							| 
									
										
										
										
											2021-05-02 13:07:49 +02:00
										 |  |  | , withLLVM ? !(stdenv.hostPlatform.isx86_64 || stdenv.hostPlatform.isPowerPC) | 
					
						
							| 
									
										
										
										
											2015-04-28 13:14:05 +02:00
										 |  |  | , postBuild ? "" | 
					
						
							| 
									
										
										
										
											2017-02-25 17:45:40 -05:00
										 |  |  | , ghcLibdir ? null # only used by ghcjs, when resolving plugins | 
					
						
							| 
									
										
										
										
											2015-04-28 13:14:05 +02:00
										 |  |  | }: | 
					
						
							| 
									
										
										
										
											2015-03-09 22:11:23 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-25 17:45:40 -05:00
										 |  |  | assert ghcLibdir != null -> (ghc.isGhcjs or false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  | # This wrapper works only with GHC 6.12 or later. | 
					
						
							| 
									
										
										
										
											2017-02-04 11:19:14 -06:00
										 |  |  | assert lib.versionOlder "6.12" ghc.version || ghc.isGhcjs || ghc.isHaLVM; | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | # It's probably a good idea to include the library "ghc-paths" in the | 
					
						
							|  |  |  | # compiler environment, because we have a specially patched version of | 
					
						
							|  |  |  | # that package in Nix that honors these environment variables | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #   NIX_GHC | 
					
						
							|  |  |  | #   NIX_GHCPKG | 
					
						
							|  |  |  | #   NIX_GHC_DOCDIR | 
					
						
							|  |  |  | #   NIX_GHC_LIBDIR | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # instead of hard-coding the paths. The wrapper sets these variables | 
					
						
							|  |  |  | # appropriately to configure ghc-paths to point back to the wrapper | 
					
						
							|  |  |  | # instead of to the pristine GHC package, which doesn't know any of the | 
					
						
							|  |  |  | # additional libraries. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # A good way to import the environment set by the wrapper below into | 
					
						
							|  |  |  | # your shell is to add the following snippet to your ~/.bashrc: | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #   if [ -e ~/.nix-profile/bin/ghc ]; then | 
					
						
							|  |  |  | #     eval $(grep export ~/.nix-profile/bin/ghc) | 
					
						
							|  |  |  | #   fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							| 
									
										
										
										
											2015-03-29 11:02:31 +02:00
										 |  |  |   isGhcjs       = ghc.isGhcjs or false; | 
					
						
							| 
									
										
										
										
											2017-02-04 11:19:14 -06:00
										 |  |  |   isHaLVM       = ghc.isHaLVM or false; | 
					
						
							|  |  |  |   ghc761OrLater = isGhcjs || isHaLVM || lib.versionOlder "7.6.1" ghc.version; | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  |   packageDBFlag = if ghc761OrLater then "--global-package-db" else "--global-conf"; | 
					
						
							| 
									
										
										
										
											2017-09-10 15:36:48 -04:00
										 |  |  |   ghcCommand'    = if isGhcjs then "ghcjs" else "ghc"; | 
					
						
							|  |  |  |   ghcCommand = "${ghc.targetPrefix}${ghcCommand'}"; | 
					
						
							| 
									
										
										
										
											2017-01-13 21:21:21 -05:00
										 |  |  |   ghcCommandCaps= lib.toUpper ghcCommand'; | 
					
						
							| 
									
										
										
										
											2018-06-26 16:34:03 -04:00
										 |  |  |   libDir        = if isHaLVM then "$out/lib/HaLVM-${ghc.version}" | 
					
						
							|  |  |  |                   else "$out/lib/${ghcCommand}-${ghc.version}"; | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  |   docDir        = "$out/share/doc/ghc/html"; | 
					
						
							|  |  |  |   packageCfgDir = "${libDir}/package.conf.d"; | 
					
						
							| 
									
										
										
										
											2017-12-05 09:36:08 +01:00
										 |  |  |   paths         = lib.filter (x: x ? isHaskellLibrary) (lib.closePropagation packages); | 
					
						
							| 
									
										
										
										
											2015-03-29 05:24:35 +03:00
										 |  |  |   hasLibraries  = lib.any (x: x.isHaskellLibrary) paths; | 
					
						
							| 
									
										
										
										
											2015-03-09 22:11:23 +03:00
										 |  |  |   # CLang is needed on Darwin for -fllvm to work: | 
					
						
							| 
									
										
										
										
											2018-01-02 23:19:22 -05:00
										 |  |  |   # https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm | 
					
						
							| 
									
										
										
										
											2016-04-13 15:53:51 +03:00
										 |  |  |   llvm          = lib.makeBinPath | 
					
						
							| 
									
										
										
										
											2015-03-09 22:11:23 +03:00
										 |  |  |                   ([ llvmPackages.llvm ] | 
					
						
							| 
									
										
										
										
											2018-08-20 14:43:41 -04:00
										 |  |  |                    ++ lib.optional stdenv.targetPlatform.isDarwin llvmPackages.clang); | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  | in | 
					
						
							| 
									
										
										
										
											2015-03-09 22:11:23 +03:00
										 |  |  | if paths == [] && !withLLVM then ghc else | 
					
						
							| 
									
										
										
										
											2020-01-10 15:20:08 +01:00
										 |  |  | symlinkJoin { | 
					
						
							| 
									
										
										
										
											2016-11-16 13:45:59 +01:00
										 |  |  |   # this makes computing paths from the name attribute impossible; | 
					
						
							|  |  |  |   # if such a feature is needed, the real compiler name should be saved | 
					
						
							|  |  |  |   # as a dedicated drv attribute, like `compiler-name` | 
					
						
							|  |  |  |   name = ghc.name + "-with-packages"; | 
					
						
							| 
									
										
										
										
											2015-01-10 09:12:37 +01:00
										 |  |  |   paths = paths ++ [ghc]; | 
					
						
							| 
									
										
										
										
											2021-03-02 22:33:53 +00:00
										 |  |  |   nativeBuildInputs = [ makeWrapper ]; | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  |   postBuild = ''
 | 
					
						
							| 
									
										
										
										
											2017-01-16 00:13:13 +01:00
										 |  |  |     # wrap compiler executables with correct env variables | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-06 15:56:02 -04:00
										 |  |  |     for prg in ${ghcCommand} ${ghcCommand}i ${ghcCommand}-${ghc.version} ${ghcCommand}i-${ghc.version}; do | 
					
						
							|  |  |  |       if [[ -x "${ghc}/bin/$prg" ]]; then | 
					
						
							|  |  |  |         rm -f $out/bin/$prg | 
					
						
							|  |  |  |         makeWrapper ${ghc}/bin/$prg $out/bin/$prg                           \ | 
					
						
							|  |  |  |           --add-flags '"-B$NIX_${ghcCommandCaps}_LIBDIR"'                   \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}"        "$out/bin/${ghcCommand}"     \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}PKG"     "$out/bin/${ghcCommand}-pkg" \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}"                  \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}"                  \ | 
					
						
							| 
									
										
										
										
											2017-10-31 15:10:47 -07:00
										 |  |  |           ${lib.optionalString (ghc.isGhcjs or false) | 
					
						
							|  |  |  |             ''--set NODE_PATH "${ghc.socket-io}/lib/node_modules"'' | 
					
						
							|  |  |  |           } \ | 
					
						
							| 
									
										
										
										
											2015-05-06 15:56:02 -04:00
										 |  |  |           ${lib.optionalString withLLVM ''--prefix "PATH" ":" "${llvm}"''} | 
					
						
							|  |  |  |       fi | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  |     done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for prg in runghc runhaskell; do | 
					
						
							| 
									
										
										
										
											2015-05-06 15:56:02 -04:00
										 |  |  |       if [[ -x "${ghc}/bin/$prg" ]]; then | 
					
						
							|  |  |  |         rm -f $out/bin/$prg | 
					
						
							|  |  |  |         makeWrapper ${ghc}/bin/$prg $out/bin/$prg                           \ | 
					
						
							|  |  |  |           --add-flags "-f $out/bin/${ghcCommand}"                           \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}"        "$out/bin/${ghcCommand}"     \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}PKG"     "$out/bin/${ghcCommand}-pkg" \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}"                  \ | 
					
						
							|  |  |  |           --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}" | 
					
						
							|  |  |  |       fi | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  |     done | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-12 23:20:56 -04:00
										 |  |  |     for prg in ${ghcCommand}-pkg ${ghcCommand}-pkg-${ghc.version}; do | 
					
						
							| 
									
										
										
										
											2015-05-06 15:56:02 -04:00
										 |  |  |       if [[ -x "${ghc}/bin/$prg" ]]; then | 
					
						
							|  |  |  |         rm -f $out/bin/$prg | 
					
						
							|  |  |  |         makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}" | 
					
						
							|  |  |  |       fi | 
					
						
							| 
									
										
										
										
											2015-01-07 20:31:32 +01:00
										 |  |  |     done | 
					
						
							| 
									
										
										
										
											2018-03-15 18:55:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # haddock was referring to the base ghc, https://github.com/NixOS/nixpkgs/issues/36976 | 
					
						
							|  |  |  |     if [[ -x "${ghc}/bin/haddock" ]]; then | 
					
						
							|  |  |  |       rm -f $out/bin/haddock | 
					
						
							|  |  |  |       makeWrapper ${ghc}/bin/haddock $out/bin/haddock    \ | 
					
						
							|  |  |  |         --add-flags '"-B$NIX_${ghcCommandCaps}_LIBDIR"'  \ | 
					
						
							|  |  |  |         --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}" | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-20 14:43:41 -04:00
										 |  |  |   '' + (lib.optionalString (stdenv.targetPlatform.isDarwin && !isGhcjs && !stdenv.targetPlatform.isiOS) '' | 
					
						
							| 
									
										
										
										
											2017-08-07 00:05:18 +02:00
										 |  |  |     # Work around a linker limit in macOS Sierra (see generic-builder.nix): | 
					
						
							| 
									
										
										
										
											2017-05-05 09:53:08 -07:00
										 |  |  |     local packageConfDir="$out/lib/${ghc.name}/package.conf.d"; | 
					
						
							|  |  |  |     local dynamicLinksDir="$out/lib/links" | 
					
						
							|  |  |  |     mkdir -p $dynamicLinksDir | 
					
						
							|  |  |  |     # Clean up the old links that may have been (transitively) included by | 
					
						
							|  |  |  |     # symlinkJoin: | 
					
						
							|  |  |  |     rm -f $dynamicLinksDir/*
 | 
					
						
							| 
									
										
										
										
											2020-05-28 22:10:36 +02:00
										 |  |  |     for d in $(grep -Poz "dynamic-library-dirs:\s*\K .+\n" $packageConfDir/*|awk '{print $2}'|sort -u); do
 | 
					
						
							| 
									
										
										
										
											2017-05-05 09:53:08 -07:00
										 |  |  |       ln -s $d/*.dylib $dynamicLinksDir
 | 
					
						
							|  |  |  |     done | 
					
						
							|  |  |  |     for f in $packageConfDir/*.conf; do
 | 
					
						
							|  |  |  |       # Initially, $f is a symlink to a read-only file in one of the inputs | 
					
						
							|  |  |  |       # (as a result of this symlinkJoin derivation). | 
					
						
							|  |  |  |       # Replace it with a copy whose dynamic-library-dirs points to | 
					
						
							|  |  |  |       # $dynamicLinksDir | 
					
						
							|  |  |  |       cp $f $f-tmp | 
					
						
							|  |  |  |       rm $f | 
					
						
							| 
									
										
										
										
											2020-05-28 22:10:36 +02:00
										 |  |  |       sed "N;s,dynamic-library-dirs:\s*.*,dynamic-library-dirs: $dynamicLinksDir," $f-tmp > $f | 
					
						
							| 
									
										
										
										
											2017-05-05 09:53:08 -07:00
										 |  |  |       rm $f-tmp | 
					
						
							|  |  |  |     done | 
					
						
							|  |  |  |   '') + '' | 
					
						
							| 
									
										
										
										
											2020-04-17 17:17:06 +02:00
										 |  |  |     ${lib.optionalString hasLibraries ''
 | 
					
						
							|  |  |  |      # GHC 8.10 changes. | 
					
						
							|  |  |  |      # Instead of replacing package.cache[.lock] with the new file, | 
					
						
							|  |  |  |      # ghc-pkg is now trying to open the file.  These file are symlink | 
					
						
							|  |  |  |      # to another nix derivation, so they are not writable.  Removing | 
					
						
							|  |  |  |      # them allow the correct behavior of ghc-pkg recache | 
					
						
							|  |  |  |      # See: https://github.com/NixOS/nixpkgs/issues/79441 | 
					
						
							|  |  |  |      rm $out/lib/${ghc.name}/package.conf.d/package.cache.lock | 
					
						
							|  |  |  |      rm $out/lib/${ghc.name}/package.conf.d/package.cache | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      $out/bin/${ghcCommand}-pkg recache | 
					
						
							|  |  |  |      ''}
 | 
					
						
							| 
									
										
										
										
											2017-02-25 17:45:40 -05:00
										 |  |  |     ${# ghcjs will read the ghc_libdir file when resolving plugins. | 
					
						
							|  |  |  |       lib.optionalString (isGhcjs && ghcLibdir != null) ''
 | 
					
						
							|  |  |  |       mkdir -p "${libDir}" | 
					
						
							|  |  |  |       rm -f "${libDir}/ghc_libdir" | 
					
						
							|  |  |  |       printf '%s' '${ghcLibdir}' > "${libDir}/ghc_libdir" | 
					
						
							|  |  |  |     ''}
 | 
					
						
							| 
									
										
										
										
											2015-03-12 23:20:56 -04:00
										 |  |  |     $out/bin/${ghcCommand}-pkg check | 
					
						
							| 
									
										
										
										
											2015-04-28 13:14:05 +02:00
										 |  |  |   '' + postBuild;
 | 
					
						
							| 
									
										
										
										
											2015-01-22 18:10:08 -05:00
										 |  |  |   passthru = { | 
					
						
							|  |  |  |     preferLocalBuild = true; | 
					
						
							|  |  |  |     inherit (ghc) version meta; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2015-01-10 09:12:37 +01:00
										 |  |  | } |