about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authorPeter Simons <simons@cryp.to>2013-10-26 18:33:09 +0200
committerPeter Simons <simons@cryp.to>2013-10-27 10:09:36 +0100
commitd64917ad17277b8e16893ee31533ec2e33446fa7 (patch)
tree5f43890f54aba657e63e7a8d3896aefd25c6347f /pkgs/build-support
parent5580abd60a4b7f0ee7d4354ceb5a7281dd6ab305 (diff)
downloadnixlib-d64917ad17277b8e16893ee31533ec2e33446fa7.tar
nixlib-d64917ad17277b8e16893ee31533ec2e33446fa7.tar.gz
nixlib-d64917ad17277b8e16893ee31533ec2e33446fa7.tar.bz2
nixlib-d64917ad17277b8e16893ee31533ec2e33446fa7.tar.lz
nixlib-d64917ad17277b8e16893ee31533ec2e33446fa7.tar.xz
nixlib-d64917ad17277b8e16893ee31533ec2e33446fa7.tar.zst
nixlib-d64917ad17277b8e16893ee31533ec2e33446fa7.zip
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.
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/cabal/default.nix93
1 files changed, 67 insertions, 26 deletions
diff --git a/pkgs/build-support/cabal/default.nix b/pkgs/build-support/cabal/default.nix
index ca985181a532..9b6d8c4e80ed 100644
--- a/pkgs/build-support/cabal/default.nix
+++ b/pkgs/build-support/cabal/default.nix
@@ -1,12 +1,29 @@
 # generic builder for Cabal packages
 
-{ stdenv, fetchurl, lib, pkgconfig, ghc, Cabal, jailbreakCabal
+{ stdenv, fetchurl, lib, pkgconfig, ghc, Cabal, jailbreakCabal, glibcLocales
 , enableLibraryProfiling ? false
-, enableCheckPhase ? true
+, enableSharedLibraries ? false
+, enableSharedExecutables ? false
+, enableCheckPhase ? stdenv.lib.versionOlder "7.4" ghc.version
 }:
 
-# The Cabal library shipped with GHC versions older than 7.x doesn't accept the --enable-tests configure flag.
-assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
+let
+  enableFeature         = stdenv.lib.enableFeature;
+  versionOlder          = stdenv.lib.versionOlder;
+  optional              = stdenv.lib.optional;
+  optionals             = stdenv.lib.optionals;
+  optionalString        = stdenv.lib.optionalString;
+  filter                = stdenv.lib.filter;
+in
+
+# Cabal shipped with GHC 6.12.4 or earlier doesn't know the "--enable-tests configure" flag.
+assert enableCheckPhase -> versionOlder "7" ghc.version;
+
+# GHC prior to 7.4.x doesn't know the "--enable-executable-dynamic" flag.
+assert enableSharedExecutables -> versionOlder "7.4" ghc.version;
+
+# Our GHC 6.10.x builds do not provide sharable versions of their core libraries.
+assert enableSharedLibraries -> versionOlder "6.12" ghc.version;
 
 {
   mkDerivation =
@@ -23,8 +40,8 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
         # in the interest of keeping hashes stable.
         postprocess =
           x : (removeAttrs x internalAttrs) // {
-                buildInputs           = stdenv.lib.filter (y : ! (y == null)) x.buildInputs;
-                propagatedBuildInputs = stdenv.lib.filter (y : ! (y == null)) x.propagatedBuildInputs;
+                buildInputs           = filter (y : ! (y == null)) x.buildInputs;
+                propagatedBuildInputs = filter (y : ! (y == null)) x.propagatedBuildInputs;
                 doCheck               = enableCheckPhase && x.doCheck;
               };
 
@@ -42,8 +59,12 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
             # if that is not desired (for applications), name can be set to
             # fname.
             name = if self.isLibrary then
-                     if enableLibraryProfiling then
+                     if enableLibraryProfiling && self.enableSharedLibraries then
+                       "haskell-${self.pname}-ghc${ghc.ghc.version}-${self.version}-profiling-shared"
+                     else if enableLibraryProfiling && !self.enableSharedLibraries then
                        "haskell-${self.pname}-ghc${ghc.ghc.version}-${self.version}-profiling"
+                     else if !enableLibraryProfiling && self.enableSharedLibraries then
+                       "haskell-${self.pname}-ghc${ghc.ghc.version}-${self.version}-shared"
                      else
                        "haskell-${self.pname}-ghc${ghc.ghc.version}-${self.version}"
                    else
@@ -63,7 +84,7 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
             # but often propagatedBuildInputs is preferable anyway
             buildInputs = [ghc Cabal] ++ self.extraBuildInputs;
             extraBuildInputs = self.buildTools ++
-                               (stdenv.lib.optionals self.doCheck self.testDepends) ++
+                               (optionals self.doCheck self.testDepends) ++
                                (if self.pkgconfigDepends == [] then [] else [pkgconfig]) ++
                                (if self.isLibrary then [] else self.buildDepends ++ self.extraLibraries ++ self.pkgconfigDepends);
 
@@ -80,6 +101,9 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
             # build-depends Cabal fields stated in test-suite stanzas
             testDepends = [];
 
+            # target(s) passed to the cabal test phase as an argument
+            testTarget = "";
+
             # build-tools Cabal field
             buildTools = [];
 
@@ -96,42 +120,61 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
             jailbreak = false;
 
             # pass the '--enable-split-objs' flag to cabal in the configure stage
-            enableSplitObjs = !(  stdenv.isDarwin         # http://hackage.haskell.org/trac/ghc/ticket/4013
-                               || stdenv.lib.versionOlder "7.6.99" ghc.ghcVersion  # -fsplit-ojbs is broken in 7.7 snapshot
+            enableSplitObjs = !(  stdenv.isDarwin                       # http://hackage.haskell.org/trac/ghc/ticket/4013
+                               || versionOlder "7.6.99" ghc.version     # -fsplit-ojbs is broken in 7.7 snapshot
                                );
 
             # pass the '--enable-tests' flag to cabal in the configure stage
             # and run any regression test suites the package might have
             doCheck = enableCheckPhase;
 
+            # pass the '--enable-shared' flag to cabal in the configure
+            # stage to enable building shared libraries
+            inherit enableSharedLibraries;
+
+            # pass the '--enable-executable-dynamic' flag to cabal in
+            # the configure stage to enable linking shared libraries
+            inherit enableSharedExecutables;
+
             extraConfigureFlags = [
-              (stdenv.lib.enableFeature enableLibraryProfiling "library-profiling")
-              (stdenv.lib.enableFeature self.enableSplitObjs "split-objs")
-            ] ++ stdenv.lib.optional (stdenv.lib.versionOlder "7" ghc.ghcVersion) (stdenv.lib.enableFeature self.doCheck "tests");
+              (enableFeature self.enableSplitObjs "split-objs")
+              (enableFeature enableLibraryProfiling "library-profiling")
+              (enableFeature self.enableSharedLibraries "shared")
+              (optional (versionOlder "7.4" ghc.version) (enableFeature self.enableSharedExecutables "executable-dynamic"))
+              (optional (versionOlder "7" ghc.version) (enableFeature self.doCheck "tests"))
+            ];
+
+            # GHC needs the locale configured during the Haddock phase.
+            LANG = "en_US.UTF-8";
+            LOCALE_ARCHIVE = optionalString stdenv.isLinux "${glibcLocales}/lib/locale/locale-archive";
 
             # compiles Setup and configures
             configurePhase = ''
               eval "$preConfigure"
 
-              ${lib.optionalString self.jailbreak "${jailbreakCabal}/bin/jailbreak-cabal ${self.pname}.cabal"}
+              ${optionalString self.jailbreak "${jailbreakCabal}/bin/jailbreak-cabal ${self.pname}.cabal"}
 
               for i in Setup.hs Setup.lhs; do
                 test -f $i && ghc --make $i
               done
 
               for p in $extraBuildInputs $propagatedNativeBuildInputs; do
+                if [ -d "$p/lib/ghc-${ghc.ghc.version}/package.conf.d" ]; then
+                  # Haskell packages don't need any extra configuration.
+                  continue;
+                fi
                 if [ -d "$p/include" ]; then
-                  extraConfigureFlags+=" --extra-include-dir=$p/include"
+                  extraConfigureFlags+=" --extra-include-dirs=$p/include"
                 fi
                 for d in lib{,64}; do
                   if [ -d "$p/$d" ]; then
-                    extraConfigureFlags+=" --extra-lib-dir=$p/$d"
+                    extraConfigureFlags+=" --extra-lib-dirs=$p/$d"
                   fi
                 done
               done
 
               echo "configure flags: $extraConfigureFlags $configureFlags"
-              ./Setup configure --verbose --prefix="$out" $extraConfigureFlags $configureFlags
+              ./Setup configure --verbose --prefix="$out" --libdir='$prefix/lib/$compiler' --libsubdir='$pkgid' $extraConfigureFlags $configureFlags
 
               eval "$postConfigure"
             '';
@@ -142,16 +185,16 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
 
               ./Setup build
 
-              export GHC_PACKAGE_PATH=$(ghc-packages)
-              [ -n "$noHaddock" ] || ./Setup haddock
+              export GHC_PACKAGE_PATH=$(${ghc.GHCPackages})
+              test -n "$noHaddock" || ./Setup haddock
 
               eval "$postBuild"
             '';
 
-            checkPhase = stdenv.lib.optional self.doCheck ''
+            checkPhase = optional self.doCheck ''
               eval "$preCheck"
 
-              ./Setup test
+              ./Setup test ${self.testTarget}
 
               eval "$postCheck"
             '';
@@ -166,7 +209,7 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
 
               ensureDir $out/bin # necessary to get it added to PATH
 
-              local confDir=$out/lib/ghc-pkgs/ghc-${ghc.ghc.version}
+              local confDir=$out/lib/ghc-${ghc.ghc.version}/package.conf.d
               local installedPkgConf=$confDir/${self.fname}.installedconf
               local pkgConf=$confDir/${self.fname}.conf
               ensureDir $confDir
@@ -176,13 +219,11 @@ assert enableCheckPhase -> stdenv.lib.versionOlder "7" ghc.ghcVersion;
                 GHC_PACKAGE_PATH=$installedPkgConf ghc-pkg --global register $pkgConf --force
               fi
 
-              eval "$postInstall"
-            '';
-
-            postFixup = ''
               if test -f $out/nix-support/propagated-native-build-inputs; then
                 ln -s $out/nix-support/propagated-native-build-inputs $out/nix-support/propagated-user-env-packages
               fi
+
+              eval "$postInstall"
             '';
 
             # We inherit stdenv and ghc so that they can be used