Back-port Haskell-related improvements from stdenv-updates.

* There now is full support for building Haskell packages as shared libraries
   for GHC versions 7.4.2 or later. The Cabal builder recognizes the following
   attributes:

    - enableSharedLibraries configures Cabal to build of shared libraries in
      addition to static ones. This option requires that all dependencies of
      the package have been compiled for use in shared libraries, too.

    - enableSharedExecutables configures Cabal to prefer shared libraries when
      linking executables.

   The default values for these attributes are arguments to the haskellPackages
   expression.

 * Haskell builds now run in a LANG="en_US.UTF-8" environment to avoid plenty
   of build and test suite errors. Without this setting, GHC seems unable to
   deal with the UTF-8 character encoding that's generally considered standard
   in the Haskell world.

 * The Cabal builder supports a new attribute 'testTarget' to specify the exact
   set of tests to be run during the check phase.

 * The ghc-wrapper attribute ghcVersion has been removed. Instead, we use the
   ghc.version attribute, which exists in unwrapped GHC derivations, too.
This commit is contained in:
Peter Simons
2013-10-26 18:33:09 +02:00
parent 5580abd60a
commit d64917ad17
21 changed files with 184 additions and 211 deletions

View File

@@ -36,10 +36,10 @@ stdenv.mkDerivation rec {
''
mkdir "$TMP/bin"
for i in strip; do
echo '#!/bin/sh' >> "$TMP/bin/$i"
echo '#! ${stdenv.shell}' > "$TMP/bin/$i"
chmod +x "$TMP/bin/$i"
PATH="$TMP/bin:$PATH"
done
PATH="$TMP/bin:$PATH"
'' +
# On Linux, use patchelf to modify the executables so that they can
# find editline/gmp.

View File

@@ -30,10 +30,10 @@ stdenv.mkDerivation rec {
''
mkdir "$TMP/bin"
for i in strip; do
echo '#!/bin/sh' >> "$TMP/bin/$i"
echo '#! ${stdenv.shell}' > "$TMP/bin/$i"
chmod +x "$TMP/bin/$i"
PATH="$TMP/bin:$PATH"
done
PATH="$TMP/bin:$PATH"
'' +
# On Linux, use patchelf to modify the executables so that they can
# find editline/gmp.

View File

@@ -28,10 +28,10 @@ stdenv.mkDerivation rec {
''
mkdir "$TMP/bin"
for i in strip; do
echo '#!/bin/sh' >> "$TMP/bin/$i"
echo '#! ${stdenv.shell}' > "$TMP/bin/$i"
chmod +x "$TMP/bin/$i"
PATH="$TMP/bin:$PATH"
done
PATH="$TMP/bin:$PATH"
'' +
# We have to patch the GMP paths for the integer-gmp package.
''

View File

@@ -38,10 +38,10 @@ stdenv.mkDerivation rec {
''
mkdir "$TMP/bin"
for i in strip; do
echo '#!/bin/sh' >> "$TMP/bin/$i"
echo '#! ${stdenv.shell}' > "$TMP/bin/$i"
chmod +x "$TMP/bin/$i"
PATH="$TMP/bin:$PATH"
done
PATH="$TMP/bin:$PATH"
'' +
# We have to patch the GMP paths for the integer-gmp package.
''

View File

@@ -38,10 +38,10 @@ stdenv.mkDerivation rec {
''
mkdir "$TMP/bin"
for i in strip; do
echo '#!/bin/sh' >> "$TMP/bin/$i"
echo '#! ${stdenv.shell}' > "$TMP/bin/$i"
chmod +x "$TMP/bin/$i"
PATH="$TMP/bin:$PATH"
done
PATH="$TMP/bin:$PATH"
'' +
# We have to patch the GMP paths for the integer-gmp package.
''

View File

@@ -22,6 +22,7 @@ stdenv.mkDerivation rec {
preConfigure = ''
echo "${buildMK}" > mk/build.mk
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure
export NIX_LDFLAGS="$NIX_LDFLAGS -rpath $out/lib/ghc-${version}"
'';
configureFlags=[

View File

@@ -22,11 +22,10 @@ stdenv.mkDerivation rec {
preConfigure = ''
echo "${buildMK}" > mk/build.mk
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure
export NIX_LDFLAGS="$NIX_LDFLAGS -rpath $out/lib/ghc-${version}"
'';
configureFlags = [
"--with-gcc=${stdenv.gcc}/bin/gcc"
];
configureFlags = "--with-gcc=${stdenv.gcc}/bin/gcc";
# required, because otherwise all symbols from HSffi.o are stripped, and
# that in turn causes GHCi to abort

View File

@@ -22,6 +22,7 @@ stdenv.mkDerivation rec {
preConfigure = ''
echo "${buildMK}" > mk/build.mk
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure
export NIX_LDFLAGS="$NIX_LDFLAGS -rpath $out/lib/ghc-${version}"
'';
configureFlags = "--with-gcc=${stdenv.gcc}/bin/gcc";

View File

@@ -1,127 +1,42 @@
{stdenv, ghc, packages ? [], makeWrapper}:
{ stdenv, ghc, packages, buildEnv, makeWrapper }:
stdenv.mkDerivation rec {
assert packages != [];
let
ghc761OrLater = stdenv.lib.versionOlder "7.6.1" ghc.version;
packageDBFlag = if ghc761OrLater then "--package-db" else "--package-conf";
libDir = "$out/lib/ghc-${ghc.version}";
packageCfgDir = "${libDir}/package.conf.d";
in
buildEnv {
name = "haskell-env-${ghc.name}";
allPackages = stdenv.lib.closePropagation packages;
buildInputs = allPackages ++ [makeWrapper];
propagatedBuildInputs = packages;
unpackPhase = "true";
installPhase = ''
numversion=$(${ghc}/bin/ghc --numeric-version)
majorversion=''${numversion%%.*}
minorversion=''${numversion#*.}
minorversion=''${minorversion%%.*}
if [[ $majorversion -gt 6 ]] && [[ $minorversion -gt 4 ]]; then
globalConf="--global-package-db"
else
globalConf="--global-conf"
fi
originalTopDir="${ghc}/lib/ghc-${ghc.version}"
originalPkgDir="$originalTopDir/package.conf.d"
linkedTopDir="$out/lib"
linkedPkgDir="$linkedTopDir/package.conf.d"
mkdir -p $out/bin
mkdir -p $linkedTopDir
mkdir -p $linkedPkgDir
echo "Linking GHC core libraries:"
echo -n "Linking $originalTopDir "
for f in "$originalTopDir/"*; do
if test -f $f; then
ln -s $f $linkedTopDir
echo -n .
fi
done
echo
echo -n "Linking $originalPkgDir "
for f in "$originalPkgDir/"*.conf; do
ln -s $f $linkedPkgDir
echo -n .
done
echo
echo "Linking selected packages and dependencies:"
for currentPath in ${stdenv.lib.concatStringsSep " " allPackages}; do
currentPkgDir="$currentPath/lib/ghc-pkgs/ghc-${ghc.version}"
# Check if current path is a Cabal package for the current GHC
if test -d $currentPkgDir; then
echo -n "Linking $currentPath "
for f in "$currentPath/bin/"*; do
ln -s $f $out/bin
echo -n .
done
for f in "$currentPath/etc/bash_completion.d/"*; do
mkdir -p $out/etc/bash_completion.d
ln -s $f $out/etc/bash_completion.d/
echo -n .
done
for s in 1 2 3 4 5 6 7 8 9; do
for f in "$currentPath/share/man/man$s/"*; do
mkdir -p $out/share/man/man$s
ln -sv $f $out/share/man/man$s/
echo -n .
done
done
for f in "$currentPath/share/emacs/site-lisp/"*; do
mkdir -p $out/share/emacs/site-lisp
ln -s $f $out/share/emacs/site-lisp/
echo -n .
done
for f in "$currentPath/share/ghci/"*; do
mkdir -p $out/share/ghci
ln -s $f $out/share/ghci/
echo -n .
done
for f in "$currentPkgDir/"*.conf; do
ln -s $f $linkedPkgDir
echo -n .
done
echo
fi
done
echo -n "Generating package cache "
${ghc}/bin/ghc-pkg $globalConf $linkedPkgDir recache
echo .
echo -n "Generating wrappers "
paths = stdenv.lib.filter (x: x ? ghc) (stdenv.lib.closePropagation (packages ++ [ghc]));
postBuild = ''
. ${makeWrapper}/nix-support/setup-hook
for prg in ghc ghci ghc-${ghc.version} ghci-${ghc.version}; do
# The NIX env-vars are picked up by our patched version of ghc-paths.
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
--add-flags "-B$linkedTopDir" \
--set "NIX_GHC" "$out/bin/ghc" \
--set "NIX_GHCPKG" "$out/bin/ghc-pkg" \
--set "NIX_GHC_LIBDIR" "$linkedTopDir"
echo -n .
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
--add-flags '"-B$NIX_GHC_LIBDIR"' \
--set "NIX_GHC" "$out/bin/ghc" \
--set "NIX_GHCPKG" "$out/bin/ghc-pkg" \
--set "NIX_GHC_LIBDIR" "${libDir}"
done
for prg in runghc runhaskell; do
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "-f $out/bin/ghc"
echo -n .
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
--add-flags "-f $out/bin/ghc" \
--set "NIX_GHC" "$out/bin/ghc" \
--set "NIX_GHCPKG" "$out/bin/ghc-pkg" \
--set "NIX_GHC_LIBDIR" "${libDir}"
done
for prg in ghc-pkg ghc-pkg-${ghc.version}; do
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "$globalConf $linkedPkgDir"
echo -n .
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag} ${packageCfgDir}"
done
for prg in hp2ps hpc hasktags hsc2hs haddock haddock-${ghc.version}; do
if test -x ${ghc}/bin/$prg -a ! -x $out/bin/$prg; then
ln -s ${ghc}/bin/$prg $out/bin/$prg && echo -n .
fi
done
echo
$out/bin/ghc-pkg recache
'';
meta = ghc.meta;
}

View File

@@ -1,10 +1,53 @@
{ stdenv, ghc, makeWrapper, coreutils, forUserEnv ? false }:
{ stdenv, ghc, makeWrapper, coreutils, writeScript }:
let
ghc761OrLater = !stdenv.lib.versionOlder ghc.version "7.6.1";
packageDBFlag = if ghc761OrLater then "-package-db" else "-package-conf";
GHCGetPackages = writeScript "ghc-get-packages.sh" ''
#! ${stdenv.shell}
# Usage:
# $1: version of GHC
# $2: invocation path of GHC
# $3: prefix
version="$1"
if test -z "$3"; then
prefix="${packageDBFlag} "
else
prefix="$3"
fi
PATH="$2:$PATH"
IFS=":"
for p in $PATH; do
PkgDir="$p/../lib/ghc-$version/package.conf.d"
for i in "$PkgDir/"*.installedconf; do
# output takes place here
test -f $i && echo -n " $prefix$i"
done
done
test -f "$2/../lib/ghc-$version/package.conf" && echo -n " $prefix$2/../lib/ghc-$version/package.conf"
'';
GHCPackages = writeScript "ghc-packages.sh" ''
#! ${stdenv.shell} -e
declare -A GHC_PACKAGES_HASH # using bash4 hashs to get uniq paths
for arg in $(${GHCGetPackages} ${ghc.version} "$(dirname $0)"); do
case "$arg" in
${packageDBFlag}) ;;
*)
CANONICALIZED="$(${coreutils}/bin/readlink -f -- "$arg")"
GHC_PACKAGES_HASH["$CANONICALIZED"]= ;;
esac
done
for path in ''${!GHC_PACKAGES_HASH[@]}; do
echo -n "$path:"
done
'';
in
stdenv.mkDerivation ({
stdenv.mkDerivation {
name = "ghc-${ghc.version}-wrapper";
buildInputs = [makeWrapper];
@@ -12,53 +55,32 @@ stdenv.mkDerivation ({
unpackPhase = "true";
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp $GHCGetPackages $out/bin/ghc-get-packages.sh
chmod 755 $out/bin/ghc-get-packages.sh
for prg in ghc ghci ghc-${ghc.version} ghci-${ghc.version}; do
makeWrapper $ghc/bin/$prg $out/bin/$prg --add-flags "\$($out/bin/ghc-get-packages.sh ${ghc.version} \"\$(dirname \$0)\")"
makeWrapper $ghc/bin/$prg $out/bin/$prg --add-flags "\$(${GHCGetPackages} ${ghc.version} \"\$(dirname \$0)\")"
done
for prg in runghc runhaskell; do
makeWrapper $ghc/bin/$prg $out/bin/$prg --add-flags "\$($out/bin/ghc-get-packages.sh ${ghc.version} \"\$(dirname \$0)\" \" ${packageDBFlag} --ghc-arg=\")"
makeWrapper $ghc/bin/$prg $out/bin/$prg --add-flags "\$(${GHCGetPackages} ${ghc.version} \"\$(dirname \$0)\" \" ${packageDBFlag} --ghc-arg=\")"
done
for prg in ghc-pkg ghc-pkg-${ghc.version}; do
makeWrapper $ghc/bin/$prg $out/bin/$prg --add-flags "\$($out/bin/ghc-get-packages.sh ${ghc.version} \"\$(dirname \$0)\" -${packageDBFlag}=)"
makeWrapper $ghc/bin/$prg $out/bin/$prg --add-flags "\$(${GHCGetPackages} ${ghc.version} \"\$(dirname \$0)\" -${packageDBFlag}=)"
done
for prg in hp2ps hpc hasktags hsc2hs; do
test -x $ghc/bin/$prg && ln -s $ghc/bin/$prg $out/bin/$prg
done
cat >> $out/bin/ghc-packages << EOF
#! /bin/bash -e
declare -A GHC_PACKAGES_HASH # using bash4 hashs to get uniq paths
for arg in \$($out/bin/ghc-get-packages.sh ${ghc.version} \"\$(dirname \$0)\"); do
case "\$arg" in
${packageDBFlag}) ;;
*)
CANONICALIZED="\$(${stdenv.lib.optionalString stdenv.isDarwin "${coreutils}/bin/"}readlink -f "\$arg")"
GHC_PACKAGES_HASH["\$CANONICALIZED"]= ;;
esac
done
for path in \''${!GHC_PACKAGES_HASH[@]}; do
echo -n "\$path:"
done
EOF
chmod +x $out/bin/ghc-packages
mkdir -p $out/nix-support
ln -s $out/nix-support/propagated-build-inputs $out/nix-support/propagated-user-env-packages
mkdir -p $out/share/doc
ln -s $ghc/lib $out/lib
ln -s $ghc/share/doc/ghc $out/share/doc/ghc-${ghc.version}
runHook postInstall
'';
GHCGetPackages = ./ghc-get-packages.sh;
inherit ghc;
inherit (ghc) meta;
ghcVersion = ghc.version;
} // (stdenv.lib.optionalAttrs ghc761OrLater { preFixup = "sed -i -e 's|-package-conf|${packageDBFlag}|' $out/bin/ghc-get-packages.sh"; })
// (stdenv.lib.optionalAttrs forUserEnv {
postFixup= ''
ln -s $ghc/lib $out/lib;
mkdir -p $out/share/doc
ln -s $ghc/share/doc/ghc $out/share/doc/ghc-${ghc.version}
'';
}))
inherit ghc GHCGetPackages GHCPackages;
inherit (ghc) meta version;
}

View File

@@ -4,7 +4,7 @@
# this check won't be needed anymore after ghc-wrapper is fixed
# to show ghc-builtin packages in "ghc-pkg list" output.
let binaryIsBuiltIn = builtins.compareVersions "7.2.1" ghc.ghcVersion != 1;
let binaryIsBuiltIn = builtins.compareVersions "7.2.1" ghc.version != 1;
in stdenv.mkDerivation {
name = "uhc-svn-git20120502";