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 , jailbreak-cabal, hscolour
}: }:
{ pname, version, sha256 ? null { pname
, version
, sha256 ? null
, src ? fetchurl { url = "mirror://hackage/${pname}-${version}.tar.gz"; inherit sha256; } , src ? fetchurl { url = "mirror://hackage/${pname}-${version}.tar.gz"; inherit sha256; }
, buildDepends ? [] , buildDepends ? []
, extraLibraries ? []
, configureFlags ? []
, configureFlagsArray ? []
, pkgconfigDepends ? []
, noHaddock ? false
, buildTools ? [] , buildTools ? []
, patches ? [], patchPhase ? "", prePatch ? "", postPatch ? "" , configureFlags ? []
, preConfigure ? "", postConfigure ? "" , description ? ""
, preBuild ? "", postBuild ? "" , doCheck ? stdenv.lib.versionOlder "7.4" ghc.version
, installPhase ? "", preInstall ? "", postInstall ? ""
, checkPhase ? "", preCheck ? "", postCheck ? ""
, preFixup ? "", postFixup ? ""
, isExecutable ? false, isLibrary ? !isExecutable
, propagatedUserEnvPkgs ? []
, testDepends ? []
, doCheck ? stdenv.lib.versionOlder "7.4" ghc.version, testTarget ? ""
, doHoogle ? true , doHoogle ? true
, jailbreak ? false , editedCabalFile ? null
, hyperlinkSource ? true
, enableLibraryProfiling ? false , enableLibraryProfiling ? false
, enableSharedExecutables ? stdenv.lib.versionOlder "7.7" ghc.version , enableSharedExecutables ? stdenv.lib.versionOlder "7.7" ghc.version
, enableSharedLibraries ? 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 , enableSplitObjs ? !stdenv.isDarwin # http://hackage.haskell.org/trac/ghc/ticket/4013
, enableStaticLibraries ? true , enableStaticLibraries ? true
, extraLibraries ? []
, homepage ? "http://hackage.haskell.org/package/${pname}" , 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 , hydraPlatforms ? ghc.meta.hydraPlatforms or ghc.meta.platforms
, broken ? false , hyperlinkSource ? true
, isExecutable ? false, isLibrary ? !isExecutable
, jailbreak ? false
, license
, maintainers ? [] , maintainers ? []
, noHaddock ? false
, passthru ? {} , 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; assert pkgconfigDepends != [] -> pkgconfig != null;
@ -45,7 +46,7 @@ assert pkgconfigDepends != [] -> pkgconfig != null;
let let
inherit (stdenv.lib) optional optionals optionalString versionOlder inherit (stdenv.lib) optional optionals optionalString versionOlder
concatStringsSep enableFeature; concatStringsSep enableFeature optionalAttrs;
defaultSetupHs = builtins.toFile "Setup.hs" '' defaultSetupHs = builtins.toFile "Setup.hs" ''
import Distribution.Simple import Distribution.Simple
@ -69,7 +70,7 @@ let
}; };
in in
stdenv.mkDerivation { stdenv.mkDerivation ({
name = "${optionalString hasActiveLibrary "haskell-"}${pname}-${version}"; name = "${optionalString hasActiveLibrary "haskell-"}${pname}-${version}";
inherit src; inherit src;
@ -79,14 +80,6 @@ stdenv.mkDerivation {
optionals doCheck testDepends; optionals doCheck testDepends;
propagatedNativeBuildInputs = buildDepends; 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. # GHC needs the locale configured during the Haddock phase.
LANG = "en_US.UTF-8"; LANG = "en_US.UTF-8";
LOCALE_ARCHIVE = optionalString stdenv.isLinux "${glibcLocales}/lib/locale/locale-archive"; LOCALE_ARCHIVE = optionalString stdenv.isLinux "${glibcLocales}/lib/locale/locale-archive";
@ -111,11 +104,16 @@ stdenv.mkDerivation {
setupCompileFlags="-j$NIX_BUILD_CORES" setupCompileFlags="-j$NIX_BUILD_CORES"
''} ''}
local confDir=$out/nix-support/ghc-${ghc.version}-package.conf.d packageConfDir="$TMP/package.conf.d"
mkdir -p $confDir mkdir -p $packageConfDir
for p in $propagatedNativeBuildInputs $nativeBuildInputs; do
if [ -d "$p/nix-support/ghc-${ghc.version}-package.conf.d" ]; then local inputClosure=""
cp -f "$p/nix-support/ghc-${ghc.version}-package.conf.d/"*.conf $confDir/ 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 continue
fi fi
if [ -d "$p/include" ]; then if [ -d "$p/include" ]; then
@ -127,8 +125,8 @@ stdenv.mkDerivation {
fi fi
done done
done done
ghc-pkg --package-db=$confDir recache ghc-pkg --package-db="$packageConfDir" recache
configureFlags+=" --package-db=$confDir" configureFlags+=" --package-db=$packageConfDir"
${optionalString (editedCabalFile != null) '' ${optionalString (editedCabalFile != null) ''
echo "Replacing Cabal file with edited version ${newCabalFile}." echo "Replacing Cabal file with edited version ${newCabalFile}."
@ -143,17 +141,17 @@ stdenv.mkDerivation {
for i in Setup.hs Setup.lhs ${defaultSetupHs}; do for i in Setup.hs Setup.lhs ${defaultSetupHs}; do
test -f $i && break test -f $i && break
done 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 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" ./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 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" echo >&2 "*** abort because of serious configure-time warning from Cabal"
exit 1 exit 1
fi fi
export GHC_PACKAGE_PATH="$confDir:" export GHC_PACKAGE_PATH="$packageConfDir:"
runHook postConfigure runHook postConfigure
''; '';
@ -162,29 +160,30 @@ stdenv.mkDerivation {
runHook preBuild runHook preBuild
./Setup build ./Setup build
${optionalString (!noHaddock && hasActiveLibrary) '' ${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 runHook postBuild
''; '';
checkPhase = if installPhase != "" then installPhase else '' checkPhase = ''
runHook preCheck runHook preCheck
./Setup test ${testTarget} ./Setup test ${testTarget}
runHook postCheck runHook postCheck
''; '';
installPhase = if installPhase != "" then installPhase else '' installPhase = ''
runHook preInstall runHook preInstall
${if !hasActiveLibrary then "./Setup install" else '' ${if !hasActiveLibrary then "./Setup install" else ''
./Setup copy ./Setup copy
local confDir=$out/nix-support/ghc-${ghc.version}-package.conf.d local packageConfDir="$out/lib/${ghc.name}/package.conf.d"
local pkgConf=$confDir/${pname}-${version}.conf local packageConfFile="$packageConfDir/${pname}-${version}.conf"
mkdir -p $confDir mkdir -p "$packageConfDir"
./Setup register --gen-pkg-config=$pkgConf ./Setup register --gen-pkg-config=$packageConfFile
local pkgId=$( ${gnused}/bin/sed -n -e 's|^id: ||p' $pkgConf ) local pkgId=$( ${gnused}/bin/sed -n -e 's|^id: ||p' $packageConfFile )
mv $pkgConf $confDir/$pkgId.conf mv $packageConfFile $packageConfDir/$pkgId.conf
ghc-pkg --package-db=$confDir recache
''} ''}
${optionalString (enableSharedExecutables && isExecutable && stdenv.isDarwin) '' ${optionalString (enableSharedExecutables && isExecutable && stdenv.isDarwin) ''
@ -198,7 +197,27 @@ stdenv.mkDerivation {
passthru = passthru // { inherit pname version; }; passthru = passthru // { inherit pname version; };
meta = { meta = { inherit homepage license platforms hydraPlatforms; }
inherit homepage license description platforms hydraPlatforms maintainers broken; // 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"; 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);
paths = stdenv.lib.filter isHaskellPkg (stdenv.lib.closePropagation packages);
in in
if packages == [] then ghc else if paths == [] then ghc else
stdenv.lib.addPassthru (buildEnv { buildEnv {
inherit (ghc) name; inherit (ghc) name;
paths = stdenv.lib.filter isHaskellPkg (stdenv.lib.closePropagation packages) ++ [ghc]; paths = paths ++ [ghc];
inherit ignoreCollisions; inherit ignoreCollisions;
postBuild = '' postBuild = ''
. ${makeWrapper}/nix-support/setup-hook . ${makeWrapper}/nix-support/setup-hook
@ -72,15 +73,10 @@ stdenv.lib.addPassthru (buildEnv {
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}" makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}"
done 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 recache
$out/bin/ghc-pkg check $out/bin/ghc-pkg check
''; '';
}) { inherit (ghc) version; } } // {
preferLocalBuild = true;
inherit (ghc) version meta;
}