b2e9096f68
The correct ghc version was not passed through anymore, I'm not entirely
sure this is the correct fix or if this is the only argument that was
missing.
broken by 5e31e828f8
cc @Ericson2314
208 lines
8.3 KiB
Nix
208 lines
8.3 KiB
Nix
# This expression takes a file like `hackage-packages.nix` and constructs
|
|
# a full package set out of that.
|
|
|
|
{ # package-set used for build tools (all of nixpkgs)
|
|
buildPackages
|
|
|
|
, # package-set used for non-haskell dependencies (all of nixpkgs)
|
|
pkgs
|
|
|
|
, # stdenv to use for building haskell packages
|
|
stdenv
|
|
|
|
, haskellLib
|
|
|
|
, # hashes for downloading Hackage packages
|
|
all-cabal-hashes
|
|
|
|
, # compiler to use
|
|
ghc
|
|
|
|
, # A function that takes `{ pkgs, stdenv, callPackage }` as the first arg and `self`
|
|
# as second, and returns a set of haskell packages
|
|
package-set
|
|
|
|
, # The final, fully overriden package set usable with the nixpkgs fixpoint
|
|
# overriding functionality
|
|
extensible-self
|
|
}:
|
|
|
|
# return value: a function from self to the package set
|
|
self:
|
|
|
|
let
|
|
inherit (stdenv) buildPlatform hostPlatform;
|
|
|
|
inherit (stdenv.lib) fix' extends makeOverridable;
|
|
inherit (haskellLib) overrideCabal;
|
|
|
|
buildHaskellPackages = if hostPlatform != buildPlatform
|
|
then self.ghc.bootPkgs
|
|
else self;
|
|
|
|
mkDerivationImpl = pkgs.callPackage ./generic-builder.nix {
|
|
inherit stdenv;
|
|
nodejs = buildPackages.nodejs-slim;
|
|
inherit (buildHaskellPackages) jailbreak-cabal;
|
|
inherit (self) ghc;
|
|
hscolour = overrideCabal buildHaskellPackages.hscolour (drv: {
|
|
isLibrary = false;
|
|
doHaddock = false;
|
|
hyperlinkSource = false; # Avoid depending on hscolour for this build.
|
|
postFixup = "rm -rf $out/lib $out/share $out/nix-support";
|
|
});
|
|
cpphs = overrideCabal (self.cpphs.overrideScope (self: super: {
|
|
mkDerivation = drv: super.mkDerivation (drv // {
|
|
enableSharedExecutables = false;
|
|
enableSharedLibraries = false;
|
|
doHaddock = false;
|
|
useCpphs = false;
|
|
});
|
|
})) (drv: {
|
|
isLibrary = false;
|
|
postFixup = "rm -rf $out/lib $out/share $out/nix-support";
|
|
});
|
|
};
|
|
|
|
mkDerivation = makeOverridable mkDerivationImpl;
|
|
|
|
# manualArgs are the arguments that were explictly passed to `callPackage`, like:
|
|
#
|
|
# callPackage foo { bar = null; };
|
|
#
|
|
# here `bar` is a manual argument.
|
|
callPackageWithScope = scope: fn: manualArgs:
|
|
let
|
|
# this code is copied from callPackage in lib/customisation.nix
|
|
#
|
|
# we cannot use `callPackage` here because we want to call `makeOverridable`
|
|
# on `drvScope` (we cannot add `overrideScope` after calling `callPackage` because then it is
|
|
# lost on `.override`) but determine the auto-args based on `drv` (the problem here
|
|
# is that nix has no way to "passthrough" args while preserving the reflection
|
|
# info that callPackage uses to determine the arguments).
|
|
drv = if builtins.isFunction fn then fn else import fn;
|
|
auto = builtins.intersectAttrs (builtins.functionArgs drv) scope;
|
|
|
|
# this wraps the `drv` function to add a `overrideScope` function to the result.
|
|
drvScope = allArgs: drv allArgs // {
|
|
overrideScope = f:
|
|
let newScope = mkScope (fix' (extends f scope.__unfix__));
|
|
# note that we have to be careful here: `allArgs` includes the auto-arguments that
|
|
# weren't manually specified. If we would just pass `allArgs` to the recursive call here,
|
|
# then we wouldn't look up any packages in the scope in the next interation, because it
|
|
# appears as if all arguments were already manually passed, so the scope change would do
|
|
# nothing.
|
|
in callPackageWithScope newScope drv manualArgs;
|
|
};
|
|
in stdenv.lib.makeOverridable drvScope (auto // manualArgs);
|
|
|
|
mkScope = scope: pkgs // pkgs.xorg // pkgs.gnome2 // { inherit stdenv; } // scope;
|
|
defaultScope = mkScope self;
|
|
callPackage = drv: args: callPackageWithScope defaultScope drv args;
|
|
|
|
withPackages = packages: buildPackages.callPackage ./with-packages-wrapper.nix {
|
|
inherit (self) llvmPackages;
|
|
inherit ghc;
|
|
inherit packages;
|
|
};
|
|
|
|
haskellSrc2nix = { name, src, sha256 ? null }:
|
|
let
|
|
sha256Arg = if isNull sha256 then "--sha256=" else ''--sha256="${sha256}"'';
|
|
in pkgs.buildPackages.stdenv.mkDerivation {
|
|
name = "cabal2nix-${name}";
|
|
nativeBuildInputs = [ pkgs.buildPackages.haskellPackages.cabal2nix ];
|
|
preferLocalBuild = true;
|
|
phases = ["installPhase"];
|
|
LANG = "en_US.UTF-8";
|
|
LOCALE_ARCHIVE = pkgs.lib.optionalString buildPlatform.isLinux "${buildPackages.glibcLocales}/lib/locale/locale-archive";
|
|
installPhase = ''
|
|
export HOME="$TMP"
|
|
mkdir -p "$out"
|
|
cabal2nix --compiler=${self.ghc.name} --system=${stdenv.system} ${sha256Arg} "${src}" > "$out/default.nix"
|
|
'';
|
|
};
|
|
|
|
all-cabal-hashes-component = name: version: pkgs.runCommand "all-cabal-hashes-component-${name}-${version}" {} ''
|
|
tar --wildcards -xzvf ${all-cabal-hashes} \*/${name}/${version}/${name}.{json,cabal}
|
|
mkdir -p $out
|
|
mv */${name}/${version}/${name}.{json,cabal} $out
|
|
'';
|
|
|
|
hackage2nix = name: version: let component = all-cabal-hashes-component name version; in self.haskellSrc2nix {
|
|
name = "${name}-${version}";
|
|
sha256 = ''$(sed -e 's/.*"SHA256":"//' -e 's/".*$//' "${component}/${name}.json")'';
|
|
src = "${component}/${name}.cabal";
|
|
};
|
|
|
|
in package-set { inherit pkgs stdenv callPackage; } self // {
|
|
|
|
inherit mkDerivation callPackage haskellSrc2nix hackage2nix;
|
|
|
|
callHackage = name: version: self.callPackage (self.hackage2nix name version);
|
|
|
|
# Creates a Haskell package from a source package by calling cabal2nix on the source.
|
|
callCabal2nix = name: src: args: if builtins.typeOf src != "path"
|
|
then self.callPackage (haskellSrc2nix { inherit name src; }) args
|
|
else
|
|
# When `src` is a Nix path literal, only use `cabal2nix` on
|
|
# the cabal file, so that the "import-from-derivation" is only
|
|
# recomputed when the cabal file changes, and so your source
|
|
# code isn't duplicated into the nix store on every change.
|
|
# This can only be done when `src` is a Nix path literal
|
|
# because that is the only kind of source that
|
|
# `builtins.filterSource` works on. But this filtering isn't
|
|
# usually important on other kinds of sources, like
|
|
# `fetchFromGitHub`.
|
|
overrideCabal (self.callPackage (haskellSrc2nix {
|
|
inherit name;
|
|
src = builtins.filterSource (path: type:
|
|
pkgs.lib.hasSuffix "${name}.cabal" path || pkgs.lib.hasSuffix "package.yaml" path
|
|
) src;
|
|
}) args) (_: { inherit src; });
|
|
|
|
# : Map Name (Either Path VersionNumber) -> HaskellPackageOverrideSet
|
|
# Given a set whose values are either paths or version strings, produces
|
|
# a package override set (i.e. (self: super: { etc. })) that sets
|
|
# the packages named in the input set to the corresponding versions
|
|
packageSourceOverrides =
|
|
overrides: self: super: pkgs.lib.mapAttrs (name: src:
|
|
let isPath = x: builtins.substring 0 1 (toString x) == "/";
|
|
generateExprs = if isPath src
|
|
then self.callCabal2nix
|
|
else self.callHackage;
|
|
in generateExprs name src {}) overrides;
|
|
|
|
# : { root : Path
|
|
# , source-overrides : Defaulted (Either Path VersionNumber)
|
|
# , overrides : Defaulted (HaskellPackageOverrideSet)
|
|
# } -> NixShellAwareDerivation
|
|
# Given a path to a haskell package directory whose cabal file is
|
|
# named the same as the directory name, an optional set of
|
|
# source overrides as appropriate for the 'packageSourceOverrides'
|
|
# function, and an optional set of arbitrary overrides,
|
|
# return a derivation appropriate for nix-build or nix-shell
|
|
# to build that package.
|
|
developPackage = { root, source-overrides ? {}, overrides ? self: super: {} }:
|
|
let name = builtins.baseNameOf root;
|
|
drv =
|
|
(extensible-self.extend (pkgs.lib.composeExtensions (self.packageSourceOverrides source-overrides) overrides)).callCabal2nix name root {};
|
|
in if pkgs.lib.inNixShell then drv.env else drv;
|
|
|
|
ghcWithPackages = selectFrom: withPackages (selectFrom self);
|
|
|
|
ghcWithHoogle = selectFrom:
|
|
let
|
|
packages = selectFrom self;
|
|
hoogle = callPackage ./hoogle.nix {
|
|
inherit packages;
|
|
};
|
|
in withPackages (packages ++ [ hoogle ]);
|
|
|
|
ghc = ghc // {
|
|
withPackages = self.ghcWithPackages;
|
|
withHoogle = self.ghcWithHoogle;
|
|
};
|
|
|
|
}
|