ghc: several enhancements to the new "with-packages" wrapper

1) The wrapper erroneously used the ghc-pkg flag "--package-db" instead of
    "--global-package-db". The result was that packages installed locally in
    ~/.ghc and ~/.cabal were invisible to GHC. This has been fixed.

 2) The wrapper now deals gracefully with an empty package set: if no package
    is requested to be included in the wrapped environment, the wrapper just
    installs a pristine GHC.

 3) Correctly configure the "docdir" path returned by ghc-paths.

 4) Added some comments that describe the idea behind our ghc-paths patches and
    gives users same sample shell code that can be used to import our special
    environment variables into the currently running shell, so that programs
    outside of the wrapped environment can use them, too.
This commit is contained in:
Peter Simons 2013-11-09 20:36:25 +01:00
parent 46581c6918
commit 981c287355

View File

@ -1,14 +1,38 @@
{ stdenv, ghc, packages, buildEnv, makeWrapper, ignoreCollisions ? false }: { stdenv, ghc, packages, buildEnv, makeWrapper, ignoreCollisions ? false }:
assert packages != []; # This wrapper works only with GHC 6.12 or later.
assert stdenv.lib.versionOlder "6.12" ghc.version;
# 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 let
ghc761OrLater = stdenv.lib.versionOlder "7.6.1" ghc.version; ghc761OrLater = stdenv.lib.versionOlder "7.6.1" ghc.version;
packageDBFlag = if ghc761OrLater then "--package-db" else "--package-conf"; packageDBFlag = if ghc761OrLater then "--global-package-db" else "--global-conf";
libDir = "$out/lib/ghc-${ghc.version}"; libDir = "$out/lib/ghc-${ghc.version}";
docDir = "$out/share/doc/ghc/html";
packageCfgDir = "${libDir}/package.conf.d"; packageCfgDir = "${libDir}/package.conf.d";
isHaskellPkg = x: (x ? pname) && (x ? version); isHaskellPkg = x: (x ? pname) && (x ? version);
in in
if packages == [] then ghc else
buildEnv { buildEnv {
name = "haskell-env-${ghc.name}"; name = "haskell-env-${ghc.name}";
paths = stdenv.lib.filter isHaskellPkg (stdenv.lib.closePropagation packages) ++ [ghc]; paths = stdenv.lib.filter isHaskellPkg (stdenv.lib.closePropagation packages) ++ [ghc];
@ -22,6 +46,7 @@ buildEnv {
--add-flags '"-B$NIX_GHC_LIBDIR"' \ --add-flags '"-B$NIX_GHC_LIBDIR"' \
--set "NIX_GHC" "$out/bin/ghc" \ --set "NIX_GHC" "$out/bin/ghc" \
--set "NIX_GHCPKG" "$out/bin/ghc-pkg" \ --set "NIX_GHCPKG" "$out/bin/ghc-pkg" \
--set "NIX_GHC_DOCDIR" "${docDir}" \
--set "NIX_GHC_LIBDIR" "${libDir}" --set "NIX_GHC_LIBDIR" "${libDir}"
done done
@ -31,12 +56,13 @@ buildEnv {
--add-flags "-f $out/bin/ghc" \ --add-flags "-f $out/bin/ghc" \
--set "NIX_GHC" "$out/bin/ghc" \ --set "NIX_GHC" "$out/bin/ghc" \
--set "NIX_GHCPKG" "$out/bin/ghc-pkg" \ --set "NIX_GHCPKG" "$out/bin/ghc-pkg" \
--set "NIX_GHC_DOCDIR" "${docDir}" \
--set "NIX_GHC_LIBDIR" "${libDir}" --set "NIX_GHC_LIBDIR" "${libDir}"
done done
for prg in ghc-pkg ghc-pkg-${ghc.version}; do for prg in ghc-pkg ghc-pkg-${ghc.version}; do
rm -f $out/bin/$prg rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag} ${packageCfgDir}" makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}"
done done
$out/bin/ghc-pkg recache $out/bin/ghc-pkg recache