haskellPackages.{ghcWithPackages, ghcWithHoogle}: make overrideable

This is achieved by passing the entire package set to the respective
wrappers and passing the select function as a second attribute. Together
with the new support for callPackage-ing functions this allows for
things like `ghcWithPackages.override { useLLVM = true; } (p: [ … ])`.

To make this possible for `ghcWithHoogle` as well, we need to make the
wrapper a bit more bespoke and inline the hoogle feature as well. The
hoogle wrapper, however, can remain separate and is exposed as
`hoogleWithPackages` additionally, as it can also serve standalone use.
`hoogleLocal` is kept for backwards compatibility (including the old,
suboptimal API), but will inform users about the better alternative via
a warning.
This commit is contained in:
sternenseemann
2021-11-20 17:43:12 +01:00
committed by sterni
parent baaf9459d6
commit fb075fab73
4 changed files with 69 additions and 45 deletions
@@ -41,11 +41,6 @@ self: super: {
ghcjs-base = null;
ghcjs-prim = null;
# enable using a local hoogle with extra packagages in the database
# nix-shell -p "haskellPackages.hoogleLocal { packages = with haskellPackages; [ mtl lens ]; }"
# $ hoogle server
hoogleLocal = { packages ? [] }: self.callPackage ./hoogle.nix { inherit packages; };
# Needs older QuickCheck version
attoparsec-varword = dontCheck super.attoparsec-varword;
+13 -25
View File
@@ -1,34 +1,22 @@
# Install not only the Hoogle library and executable, but also a local Hoogle
# database which provides "Source" links to all specified 'packages' -- or the
# current Haskell Platform if no custom package set is provided.
#
# It is intended to be used in config.nix similarly to:
#
# { packageOverrides = pkgs: rec {
#
# haskellPackages =
# let callPackage = pkgs.lib.callPackageWith haskellPackages;
# in pkgs.recurseIntoAttrs (pkgs.haskellPackages.override {
# extension = self: super: {
# hoogleLocal = pkgs.haskellPackages.hoogleLocal.override {
# packages = with pkgs.haskellPackages; [
# mmorph
# monadControl
# ];
# };
# };
# });
# }}
#
# This will build mmorph and monadControl, and have the hoogle installation
# refer to their documentation via symlink so they are not garbage collected.
{ lib, stdenv, buildPackages
, hoogle, writeText, ghc
, packages
{ lib, stdenv, buildPackages, haskellPackages
, writeText
}:
# This argument is a function which selects a list of Haskell packages from any
# passed Haskell package set.
#
# Example:
# (hpkgs: [ hpkgs.mtl hpkgs.lens ])
selectPackages:
let
inherit (haskellPackages) ghc hoogle;
packages = selectPackages haskellPackages;
wrapper = ./hoogle-local-wrapper.sh;
isGhcjs = ghc.isGhcjs or false;
opts = lib.optionalString;
@@ -55,7 +43,7 @@ let
in
buildPackages.stdenv.mkDerivation {
name = "hoogle-local-0.1";
name = "hoogle-with-packages";
buildInputs = [ghc hoogle];
inherit docPackages;
@@ -120,11 +120,6 @@ let
defaultScope = mkScope self;
callPackage = drv: args: callPackageWithScope defaultScope drv args;
withPackages = packages: buildPackages.callPackage ./with-packages-wrapper.nix {
inherit (self) ghc llvmPackages;
inherit packages;
};
# Use cabal2nix to create a default.nix for the package sources found at 'src'.
haskellSrc2nix = { name, src, sha256 ? null, extraCabal2nixOptions ? "" }:
let
@@ -269,22 +264,53 @@ in package-set { inherit pkgs lib callPackage; } self // {
then (modifier drv).envFunc {inherit withHoogle;}
else modifier drv;
ghcWithPackages = selectFrom: withPackages (selectFrom self);
# This can be used to easily create a derivation containing GHC and the specified set of Haskell packages.
#
# Example:
# $ nix-shell -p 'haskellPackages.ghcWithPackages (hpkgs: [ hpkgs.mtl hpkgs.lens ])'
# $ ghci # in the nix-shell
# Prelude > import Control.Lens
#
# GHC is setup with a package database with all the specified Haskell packages.
#
# ghcWithPackages :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation
ghcWithPackages = self.callPackage ./with-packages-wrapper.nix {
haskellPackages = self;
};
# Put 'hoogle' into the derivation's PATH with a database containing all
# the package's dependencies; run 'hoogle server --local' in a shell to
# host a search engine for the dependencies.
#
# Example usage:
# $ nix-shell -p 'haskellPackages.hoogleWithPackages (p: [ p.mtl p.lens ])'
# [nix-shell] $ hoogle server
#
# hoogleWithPackages :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation
#
# To reload the Hoogle server automatically on .cabal file changes try
# this:
# echo *.cabal | entr -r -- nix-shell --run 'hoogle server --local'
ghcWithHoogle = selectFrom:
let
packages = selectFrom self;
hoogle = callPackage ./hoogle.nix {
inherit packages;
};
in withPackages (packages ++ [ hoogle ]);
hoogleWithPackages = self.callPackage ./hoogle.nix {
haskellPackages = self;
};
hoogleLocal =
{ packages ? [] }:
lib.warn "hoogleLocal is deprecated, use hoogleWithPackages instead" (
self.hoogleWithPackages (_: packages)
);
# This is like a combination of ghcWithPackages and hoogleWithPackages.
# It provides a derivation containing both GHC and Hoogle with an index of
# the given Haskell package database.
#
# Example:
# $ nix-shell -p 'haskellPackages.ghcWithHoogle (hpkgs: [ hpkgs.conduit hpkgs.lens ])'
#
# ghcWithHoogle :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation
ghcWithHoogle = self.ghcWithPackages.override {
withHoogle = true;
};
# Returns a derivation whose environment contains a GHC with only
# the dependencies of packages listed in `packages`, not the
@@ -1,13 +1,20 @@
{ lib, stdenv, ghc, llvmPackages, packages, symlinkJoin, makeWrapper
{ lib, stdenv, haskellPackages, symlinkJoin, makeWrapper
# GHC will have LLVM available if necessary for the respective target,
# so useLLVM only needs to be changed if -fllvm is to be used for a
# platform that has NCG support
, useLLVM ? false
, withHoogle ? false
, hoogleWithPackages
, postBuild ? ""
, ghcLibdir ? null # only used by ghcjs, when resolving plugins
}:
assert ghcLibdir != null -> (ghc.isGhcjs or false);
# This argument is a function which selects a list of Haskell packages from any
# passed Haskell package set.
#
# Example:
# (hpkgs: [ hpkgs.mtl hpkgs.lens ])
selectPackages:
# It's probably a good idea to include the library "ghc-paths" in the
# compiler environment, because we have a specially patched version of
@@ -31,6 +38,11 @@ assert ghcLibdir != null -> (ghc.isGhcjs or false);
# fi
let
inherit (haskellPackages) llvmPackages ghc;
packages = selectPackages haskellPackages
++ lib.optional withHoogle (hoogleWithPackages selectPackages);
isGhcjs = ghc.isGhcjs or false;
isHaLVM = ghc.isHaLVM or false;
ghc761OrLater = isGhcjs || isHaLVM || lib.versionOlder "7.6.1" ghc.version;
@@ -50,6 +62,9 @@ let
([ llvmPackages.llvm ]
++ lib.optional stdenv.targetPlatform.isDarwin llvmPackages.clang);
in
assert ghcLibdir != null -> (ghc.isGhcjs or false);
if paths == [] && !useLLVM then ghc else
symlinkJoin {
# this makes computing paths from the name attribute impossible;