haskell-generic-builder: simplify "package.conf.d" management

The builder creates a temporary package.conf.d database in $TMP that
contains everything required to build the current package (i.e. the
transitive closure of the package's propagated build inputs). These
files are no longer installed, however, we just install the package.conf
file for the package we're actually building. This means that
package.conf.d directory in $out won't have collisions anymore, which
simplifies the with-packages-wrapper.nix a bit.
This commit is contained in:
Peter Simons 2015-01-10 09:12:37 +01:00
parent fa27f2af5b
commit afca6145d4
2 changed files with 83 additions and 68 deletions

View file

@ -2,42 +2,43 @@
, jailbreak-cabal, hscolour
}:
{ pname, version, sha256 ? null
{ pname
, version
, sha256 ? null
, src ? fetchurl { url = "mirror://hackage/${pname}-${version}.tar.gz"; inherit sha256; }
, buildDepends ? []
, extraLibraries ? []
, configureFlags ? []
, configureFlagsArray ? []
, pkgconfigDepends ? []
, noHaddock ? false
, buildTools ? []
, patches ? [], patchPhase ? "", prePatch ? "", postPatch ? ""
, preConfigure ? "", postConfigure ? ""
, preBuild ? "", postBuild ? ""
, installPhase ? "", preInstall ? "", postInstall ? ""
, checkPhase ? "", preCheck ? "", postCheck ? ""
, preFixup ? "", postFixup ? ""
, isExecutable ? false, isLibrary ? !isExecutable
, propagatedUserEnvPkgs ? []
, testDepends ? []
, doCheck ? stdenv.lib.versionOlder "7.4" ghc.version, testTarget ? ""
, configureFlags ? []
, description ? ""
, doCheck ? stdenv.lib.versionOlder "7.4" ghc.version
, doHoogle ? true
, jailbreak ? false
, hyperlinkSource ? true
, editedCabalFile ? null
, enableLibraryProfiling ? false
, enableSharedExecutables ? stdenv.lib.versionOlder "7.7" ghc.version
, enableSharedLibraries ? stdenv.lib.versionOlder "7.7" ghc.version
, enableSplitObjs ? !stdenv.isDarwin # http://hackage.haskell.org/trac/ghc/ticket/4013
, enableStaticLibraries ? true
, extraLibraries ? []
, homepage ? "http://hackage.haskell.org/package/${pname}"
, description ? "no description available"
, license
, editedCabalFile ? null
, platforms ? ghc.meta.platforms
, hydraPlatforms ? ghc.meta.hydraPlatforms or ghc.meta.platforms
, broken ? false
, hyperlinkSource ? true
, isExecutable ? false, isLibrary ? !isExecutable
, jailbreak ? false
, license
, maintainers ? []
, noHaddock ? false
, passthru ? {}
, pkgconfigDepends ? []
, platforms ? ghc.meta.platforms
, testDepends ? []
, testTarget ? ""
, broken ? false
, patches ? [], patchPhase ? "", prePatch ? "", postPatch ? ""
, preConfigure ? "", postConfigure ? ""
, preBuild ? "", postBuild ? ""
, preInstall ? "", postInstall ? ""
, checkPhase ? "", preCheck ? "", postCheck ? ""
, preFixup ? "", postFixup ? ""
}:
assert pkgconfigDepends != [] -> pkgconfig != null;
@ -45,7 +46,7 @@ assert pkgconfigDepends != [] -> pkgconfig != null;
let
inherit (stdenv.lib) optional optionals optionalString versionOlder
concatStringsSep enableFeature;
concatStringsSep enableFeature optionalAttrs;
defaultSetupHs = builtins.toFile "Setup.hs" ''
import Distribution.Simple
@ -69,7 +70,7 @@ let
};
in
stdenv.mkDerivation {
stdenv.mkDerivation ({
name = "${optionalString hasActiveLibrary "haskell-"}${pname}-${version}";
inherit src;
@ -79,14 +80,6 @@ stdenv.mkDerivation {
optionals doCheck testDepends;
propagatedNativeBuildInputs = buildDepends;
inherit propagatedUserEnvPkgs;
inherit patches patchPhase prePatch postPatch;
inherit preConfigure postConfigure configureFlags configureFlagsArray;
inherit preBuild postBuild;
inherit preInstall postInstall;
inherit doCheck preCheck postCheck;
inherit preFixup postFixup;
# GHC needs the locale configured during the Haddock phase.
LANG = "en_US.UTF-8";
LOCALE_ARCHIVE = optionalString stdenv.isLinux "${glibcLocales}/lib/locale/locale-archive";
@ -111,11 +104,16 @@ stdenv.mkDerivation {
setupCompileFlags="-j$NIX_BUILD_CORES"
''}
local confDir=$out/nix-support/ghc-${ghc.version}-package.conf.d
mkdir -p $confDir
for p in $propagatedNativeBuildInputs $nativeBuildInputs; do
if [ -d "$p/nix-support/ghc-${ghc.version}-package.conf.d" ]; then
cp -f "$p/nix-support/ghc-${ghc.version}-package.conf.d/"*.conf $confDir/
packageConfDir="$TMP/package.conf.d"
mkdir -p $packageConfDir
local inputClosure=""
for i in $propagatedNativeBuildInputs $nativeBuildInputs; do
findInputs $i inputClosure propagated-native-build-inputs
done
for p in $inputClosure; do
if [ -d "$p/lib/${ghc.name}/package.conf.d" ]; then
cp -f "$p/lib/${ghc.name}/package.conf.d/"*.conf $packageConfDir/
continue
fi
if [ -d "$p/include" ]; then
@ -127,8 +125,8 @@ stdenv.mkDerivation {
fi
done
done
ghc-pkg --package-db=$confDir recache
configureFlags+=" --package-db=$confDir"
ghc-pkg --package-db="$packageConfDir" recache
configureFlags+=" --package-db=$packageConfDir"
${optionalString (editedCabalFile != null) ''
echo "Replacing Cabal file with edited version ${newCabalFile}."
@ -143,17 +141,17 @@ stdenv.mkDerivation {
for i in Setup.hs Setup.lhs ${defaultSetupHs}; do
test -f $i && break
done
ghc -package-db=$confDir $setupCompileFlags --make -o Setup -odir $TMPDIR -hidir $TMPDIR $i
ghc -package-db=$packageConfDir $setupCompileFlags --make -o Setup -odir $TMPDIR -hidir $TMPDIR $i
echo configureFlags: $configureFlags
unset GHC_PACKAGE_PATH # Cabal complains about this variable if it's set.
unset GHC_PACKAGE_PATH # Cabal complains if this variable is set during configure.
./Setup configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log"
if ${gnugrep}/bin/egrep -q '^Warning:.*depends on multiple versions' "$NIX_BUILD_TOP/cabal-configure.log"; then
echo >&2 "*** abort because of serious configure-time warning from Cabal"
exit 1
fi
export GHC_PACKAGE_PATH="$confDir:"
export GHC_PACKAGE_PATH="$packageConfDir:"
runHook postConfigure
'';
@ -162,29 +160,30 @@ stdenv.mkDerivation {
runHook preBuild
./Setup build
${optionalString (!noHaddock && hasActiveLibrary) ''
./Setup haddock --html ${optionalString doHoogle "--hoogle"} ${optionalString (hasActiveLibrary && hyperlinkSource) "--hyperlink-source"}
./Setup haddock --html \
${optionalString doHoogle "--hoogle"} \
${optionalString (hasActiveLibrary && hyperlinkSource) "--hyperlink-source"}
''}
runHook postBuild
'';
checkPhase = if installPhase != "" then installPhase else ''
checkPhase = ''
runHook preCheck
./Setup test ${testTarget}
runHook postCheck
'';
installPhase = if installPhase != "" then installPhase else ''
installPhase = ''
runHook preInstall
${if !hasActiveLibrary then "./Setup install" else ''
./Setup copy
local confDir=$out/nix-support/ghc-${ghc.version}-package.conf.d
local pkgConf=$confDir/${pname}-${version}.conf
mkdir -p $confDir
./Setup register --gen-pkg-config=$pkgConf
local pkgId=$( ${gnused}/bin/sed -n -e 's|^id: ||p' $pkgConf )
mv $pkgConf $confDir/$pkgId.conf
ghc-pkg --package-db=$confDir recache
local packageConfDir="$out/lib/${ghc.name}/package.conf.d"
local packageConfFile="$packageConfDir/${pname}-${version}.conf"
mkdir -p "$packageConfDir"
./Setup register --gen-pkg-config=$packageConfFile
local pkgId=$( ${gnused}/bin/sed -n -e 's|^id: ||p' $packageConfFile )
mv $packageConfFile $packageConfDir/$pkgId.conf
''}
${optionalString (enableSharedExecutables && isExecutable && stdenv.isDarwin) ''
@ -198,7 +197,27 @@ stdenv.mkDerivation {
passthru = passthru // { inherit pname version; };
meta = {
inherit homepage license description platforms hydraPlatforms maintainers broken;
};
meta = { inherit homepage license platforms hydraPlatforms; }
// optionalAttrs broken { inherit broken; }
// optionalAttrs (description != "") { inherit description; }
// optionalAttrs (maintainers != []) { inherit maintainers; }
;
}
// optionalAttrs (configureFlags != []) { inherit configureFlags; }
// optionalAttrs (patches != []) { inherit patches; }
// optionalAttrs (patchPhase != "") { inherit patchPhase; }
// optionalAttrs (prePatch != "") { inherit prePatch; }
// optionalAttrs (postPatch != "") { inherit postPatch; }
// optionalAttrs (preConfigure != "") { inherit preConfigure; }
// optionalAttrs (postConfigure != "") { inherit postConfigure; }
// optionalAttrs (preBuild != "") { inherit preBuild; }
// optionalAttrs (postBuild != "") { inherit postBuild; }
// optionalAttrs (preInstall != "") { inherit preInstall; }
// optionalAttrs (postInstall != "") { inherit postInstall; }
// optionalAttrs (checkPhase != "") { inherit checkPhase; }
// optionalAttrs (preCheck != "") { inherit preCheck; }
// optionalAttrs (postCheck != "") { inherit postCheck; }
// optionalAttrs (preFixup != "") { inherit preFixup; }
// optionalAttrs (postFixup != "") { inherit postFixup; }
)

View file

@ -31,11 +31,12 @@ let
docDir = "$out/share/doc/ghc/html";
packageCfgDir = "${libDir}/package.conf.d";
isHaskellPkg = x: (x ? pname) && (x ? version);
paths = stdenv.lib.filter isHaskellPkg (stdenv.lib.closePropagation packages);
in
if packages == [] then ghc else
stdenv.lib.addPassthru (buildEnv {
if paths == [] then ghc else
buildEnv {
inherit (ghc) name;
paths = stdenv.lib.filter isHaskellPkg (stdenv.lib.closePropagation packages) ++ [ghc];
paths = paths ++ [ghc];
inherit ignoreCollisions;
postBuild = ''
. ${makeWrapper}/nix-support/setup-hook
@ -72,15 +73,10 @@ stdenv.lib.addPassthru (buildEnv {
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}"
done
rm $out/lib/${ghc.name}/package.conf.d
mkdir $out/lib/${ghc.name}/package.conf.d
for pkg in $paths; do
for file in "$pkg/nix-support/${ghc.name}-package.conf.d/"*.conf "$pkg/lib/${ghc.name}/package.conf.d/"*.conf; do
ln -sf $file $out/lib/${ghc.name}/package.conf.d/
done
done
$out/bin/ghc-pkg recache
$out/bin/ghc-pkg check
'';
}) { inherit (ghc) version; }
} // {
preferLocalBuild = true;
inherit (ghc) version meta;
}