nixpkgs/pkgs/build-support/cabal/default.nix

194 lines
8.1 KiB
Nix
Raw Normal View History

# generic builder for Cabal packages
haskell-packages.nix: fix the implementation of 'cabalNoTest' The previous implementation used the following tying-the-knot trickery to override 'doCheck' to false for the given build: cabalNoTest = { mkDerivation = x: rec { final = self.cabal.mkDerivation (self: (x final) // { doCheck = false; }); }.final; }; That seemed to work, but for some reason it caused trouble with some builds -- not all -- that use jailbreakCabal. The problem was the 'stdenv' attribute couldn't be evaluated properly anymore: $ nix-build ~/pkgs/top-level/release-haskell.nix -A optparseApplicative.ghc6104.x86_64-linux --show-trace error: while evaluating the attribute `drvPath' at `/nix/store/qkj5cxknwspz8ak0ganm97zfr2bhksgn-nix-1.5.2pre3082_2398417/share/nix/corepkgs/derivation.nix:19:9': while evaluating the builtin function `derivationStrict': while instantiating the derivation named `haskell-optparse-applicative-ghc6.10.4-0.5.2.1' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:40:13': while evaluating the derivation attribute `configurePhase' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:107:13': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/strings.nix:55:26': while evaluating the attribute `outPath' at `/nix/store/qkj5cxknwspz8ak0ganm97zfr2bhksgn-nix-1.5.2pre3082_2398417/share/nix/corepkgs/derivation.nix:18:9': while evaluating the builtin function `getAttr': while evaluating the builtin function `derivationStrict': while instantiating the derivation named `jailbreak-cabal-1.1' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:40:13': while evaluating the derivation attribute `nativeBuildInputs' at `/home/simons/.nix-defexpr/pkgs/stdenv/generic/default.nix:76:17': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/lists.nix:135:21': while evaluating the attribute `buildInputs' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:22:17': while evaluating the builtin function `filter': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:22:60': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:119:17': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/customisation.nix:61:22': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/customisation.nix:56:24': while evaluating the builtin function `isAttrs': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/development/libraries/haskell/Cabal/1.14.0.nix:1:1': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:113:20': while evaluating the attribute `final' at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:114:7': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:9:5': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/stdenv/generic/default.nix:51:24': while evaluating the attribute `meta.license' at `/home/simons/.nix-defexpr/pkgs/development/libraries/haskell/Cabal/1.14.0.nix:17:5': infinite recursion encountered I tried to figure out why this happens, but eventually gave up. The new implementation passes an argument called 'enableCheckPhase' to the Cabal builder, which determines whether the user-specified doCheck value has any effect or not. Now, a normal override can be used to disable unit testing.
2013-04-19 10:31:08 +02:00
{ stdenv, fetchurl, lib, pkgconfig, ghc, Cabal, jailbreakCabal
, enableLibraryProfiling ? false
, enableCheckPhase ? true
}:
# 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;
{
mkDerivation =
args : # arguments for the individual package, can modify the defaults
let # These attributes are removed in the end. This is in order not to spoil the build
# environment overly, but also to keep hash-backwards-compatible with the old cabal.nix.
internalAttrs = [
"internalAttrs" "buildDepends" "buildTools" "extraLibraries" "pkgconfigDepends"
"isLibrary" "isExecutable" "testDepends"
];
# Stuff happening after the user preferences have been processed. We remove
# internal attributes and strip null elements from the dependency lists, all
# 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;
haskell-packages.nix: fix the implementation of 'cabalNoTest' The previous implementation used the following tying-the-knot trickery to override 'doCheck' to false for the given build: cabalNoTest = { mkDerivation = x: rec { final = self.cabal.mkDerivation (self: (x final) // { doCheck = false; }); }.final; }; That seemed to work, but for some reason it caused trouble with some builds -- not all -- that use jailbreakCabal. The problem was the 'stdenv' attribute couldn't be evaluated properly anymore: $ nix-build ~/pkgs/top-level/release-haskell.nix -A optparseApplicative.ghc6104.x86_64-linux --show-trace error: while evaluating the attribute `drvPath' at `/nix/store/qkj5cxknwspz8ak0ganm97zfr2bhksgn-nix-1.5.2pre3082_2398417/share/nix/corepkgs/derivation.nix:19:9': while evaluating the builtin function `derivationStrict': while instantiating the derivation named `haskell-optparse-applicative-ghc6.10.4-0.5.2.1' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:40:13': while evaluating the derivation attribute `configurePhase' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:107:13': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/strings.nix:55:26': while evaluating the attribute `outPath' at `/nix/store/qkj5cxknwspz8ak0ganm97zfr2bhksgn-nix-1.5.2pre3082_2398417/share/nix/corepkgs/derivation.nix:18:9': while evaluating the builtin function `getAttr': while evaluating the builtin function `derivationStrict': while instantiating the derivation named `jailbreak-cabal-1.1' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:40:13': while evaluating the derivation attribute `nativeBuildInputs' at `/home/simons/.nix-defexpr/pkgs/stdenv/generic/default.nix:76:17': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/lists.nix:135:21': while evaluating the attribute `buildInputs' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:22:17': while evaluating the builtin function `filter': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:22:60': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:119:17': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/customisation.nix:61:22': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/customisation.nix:56:24': while evaluating the builtin function `isAttrs': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/development/libraries/haskell/Cabal/1.14.0.nix:1:1': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:113:20': while evaluating the attribute `final' at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:114:7': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:9:5': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/stdenv/generic/default.nix:51:24': while evaluating the attribute `meta.license' at `/home/simons/.nix-defexpr/pkgs/development/libraries/haskell/Cabal/1.14.0.nix:17:5': infinite recursion encountered I tried to figure out why this happens, but eventually gave up. The new implementation passes an argument called 'enableCheckPhase' to the Cabal builder, which determines whether the user-specified doCheck value has any effect or not. Now, a normal override can be used to disable unit testing.
2013-04-19 10:31:08 +02:00
doCheck = enableCheckPhase && x.doCheck;
};
defaults =
self : { # self is the final version of the attribute set
# pname should be defined by the client to be the package basename
# version should be defined by the client to be the package version
# fname is the internal full name of the package
fname = "${self.pname}-${self.version}";
# name is the external full name of the package; usually we prefix
# all packages with haskell- to avoid name clashes for libraries;
# if that is not desired (for applications), name can be set to
# fname.
name = if self.isLibrary then
if enableLibraryProfiling then
"haskell-${self.pname}-ghc${ghc.ghc.version}-${self.version}-profiling"
else
"haskell-${self.pname}-ghc${ghc.ghc.version}-${self.version}"
else
"${self.pname}-${self.version}";
# the default download location for Cabal packages is Hackage,
# you still have to specify the checksum
src = fetchurl {
# cannot use mirrors system because of subtly different directory structures
urls = ["http://hackage.haskell.org/packages/archive/${self.pname}/${self.version}/${self.fname}.tar.gz"
"http://hdiff.luite.com/packages/archive/${self.pname}/${self.fname}.tar.gz"];
inherit (self) sha256;
};
# default buildInputs are just ghc, if more buildInputs are required
# buildInputs can be extended by the client by using extraBuildInputs,
# but often propagatedBuildInputs is preferable anyway
buildInputs = [ghc Cabal] ++ self.extraBuildInputs;
extraBuildInputs = self.buildTools ++
(stdenv.lib.optionals self.doCheck self.testDepends) ++
(if self.pkgconfigDepends == [] then [] else [pkgconfig]) ++
(if self.isLibrary then [] else self.buildDepends ++ self.extraLibraries ++ self.pkgconfigDepends);
# we make sure that propagatedBuildInputs is defined, so that we don't
# have to check for its existence
propagatedBuildInputs = if self.isLibrary then self.buildDepends ++ self.extraLibraries ++ self.pkgconfigDepends else [];
# library directories that have to be added to the Cabal files
extraLibDirs = [];
# build-depends Cabal field
buildDepends = [];
# build-depends Cabal fields stated in test-suite stanzas
testDepends = [];
# build-tools Cabal field
buildTools = [];
# extra-libraries Cabal field
extraLibraries = [];
# pkgconfig-depends Cabal field
pkgconfigDepends = [];
isLibrary = ! self.isExecutable;
isExecutable = false;
# ignore version restrictions on the build inputs that the cabal file might specify
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
);
# pass the '--enable-tests' flag to cabal in the configure stage
# and run any regression test suites the package might have
haskell-packages.nix: fix the implementation of 'cabalNoTest' The previous implementation used the following tying-the-knot trickery to override 'doCheck' to false for the given build: cabalNoTest = { mkDerivation = x: rec { final = self.cabal.mkDerivation (self: (x final) // { doCheck = false; }); }.final; }; That seemed to work, but for some reason it caused trouble with some builds -- not all -- that use jailbreakCabal. The problem was the 'stdenv' attribute couldn't be evaluated properly anymore: $ nix-build ~/pkgs/top-level/release-haskell.nix -A optparseApplicative.ghc6104.x86_64-linux --show-trace error: while evaluating the attribute `drvPath' at `/nix/store/qkj5cxknwspz8ak0ganm97zfr2bhksgn-nix-1.5.2pre3082_2398417/share/nix/corepkgs/derivation.nix:19:9': while evaluating the builtin function `derivationStrict': while instantiating the derivation named `haskell-optparse-applicative-ghc6.10.4-0.5.2.1' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:40:13': while evaluating the derivation attribute `configurePhase' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:107:13': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/strings.nix:55:26': while evaluating the attribute `outPath' at `/nix/store/qkj5cxknwspz8ak0ganm97zfr2bhksgn-nix-1.5.2pre3082_2398417/share/nix/corepkgs/derivation.nix:18:9': while evaluating the builtin function `getAttr': while evaluating the builtin function `derivationStrict': while instantiating the derivation named `jailbreak-cabal-1.1' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:40:13': while evaluating the derivation attribute `nativeBuildInputs' at `/home/simons/.nix-defexpr/pkgs/stdenv/generic/default.nix:76:17': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/lists.nix:135:21': while evaluating the attribute `buildInputs' at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:22:17': while evaluating the builtin function `filter': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:22:60': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:119:17': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/customisation.nix:61:22': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/lib/customisation.nix:56:24': while evaluating the builtin function `isAttrs': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/development/libraries/haskell/Cabal/1.14.0.nix:1:1': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:113:20': while evaluating the attribute `final' at `/home/simons/.nix-defexpr/pkgs/top-level/haskell-packages.nix:114:7': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/build-support/cabal/default.nix:9:5': while evaluating the function at `/home/simons/.nix-defexpr/pkgs/stdenv/generic/default.nix:51:24': while evaluating the attribute `meta.license' at `/home/simons/.nix-defexpr/pkgs/development/libraries/haskell/Cabal/1.14.0.nix:17:5': infinite recursion encountered I tried to figure out why this happens, but eventually gave up. The new implementation passes an argument called 'enableCheckPhase' to the Cabal builder, which determines whether the user-specified doCheck value has any effect or not. Now, a normal override can be used to disable unit testing.
2013-04-19 10:31:08 +02:00
doCheck = enableCheckPhase;
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");
# compiles Setup and configures
configurePhase = ''
eval "$preConfigure"
${lib.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/include" ]; then
extraConfigureFlags+=" --extra-include-dir=$p/include"
fi
for d in lib{,64}; do
if [ -d "$p/$d" ]; then
extraConfigureFlags+=" --extra-lib-dir=$p/$d"
fi
done
done
echo "configure flags: $extraConfigureFlags $configureFlags"
./Setup configure --verbose --prefix="$out" $extraConfigureFlags $configureFlags
eval "$postConfigure"
'';
# builds via Cabal
buildPhase = ''
eval "$preBuild"
./Setup build
export GHC_PACKAGE_PATH=$(ghc-packages)
[ -n "$noHaddock" ] || ./Setup haddock
eval "$postBuild"
'';
checkPhase = stdenv.lib.optional self.doCheck ''
eval "$preCheck"
./Setup test
eval "$postCheck"
'';
# installs via Cabal; creates a registration file for nix-support
# so that the package can be used in other Haskell-builds; also
# adds all propagated build inputs to the user environment packages
installPhase = ''
eval "$preInstall"
./Setup copy
ensureDir $out/bin # necessary to get it added to PATH
local confDir=$out/lib/ghc-pkgs/ghc-${ghc.ghc.version}
local installedPkgConf=$confDir/${self.fname}.installedconf
local pkgConf=$confDir/${self.fname}.conf
ensureDir $confDir
./Setup register --gen-pkg-config=$pkgConf
if test -f $pkgConf; then
echo '[]' > $installedPkgConf
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
'';
# We inherit stdenv and ghc so that they can be used
# in Cabal derivations.
inherit stdenv ghc;
};
in stdenv.mkDerivation (postprocess ((rec { f = defaults f // args f; }).f)) ;
}