nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1# This expression takes a file like `hackage-packages.nix` and constructs
2# a full package set out of that.
3
4{ # package-set used for non-haskell dependencies (all of nixpkgs)
5 pkgs
6
7, # stdenv to use for building haskell packages
8 stdenv
9
10, haskellLib
11
12, # hashes for downloading Hackage packages
13 all-cabal-hashes
14
15, # compiler to use
16 ghc
17
18, # A function that takes `{ pkgs, stdenv, callPackage }` as the first arg and `self`
19 # as second, and returns a set of haskell packages
20 package-set
21
22, # The final, fully overriden package set usable with the nixpkgs fixpoint
23 # overriding functionality
24 extensible-self
25}:
26
27# return value: a function from self to the package set
28self:
29
30let
31
32 inherit (stdenv.lib) fix' extends makeOverridable;
33 inherit (haskellLib) overrideCabal;
34
35 mkDerivationImpl = pkgs.callPackage ./generic-builder.nix {
36 inherit stdenv;
37 inherit (pkgs) fetchurl pkgconfig glibcLocales coreutils gnugrep gnused;
38 nodejs = pkgs.nodejs-slim;
39 jailbreak-cabal = if (self.ghc.cross or null) != null
40 then self.ghc.bootPkgs.jailbreak-cabal
41 else self.jailbreak-cabal;
42 inherit (self) ghc;
43 hscolour = overrideCabal self.hscolour (drv: {
44 isLibrary = false;
45 doHaddock = false;
46 hyperlinkSource = false; # Avoid depending on hscolour for this build.
47 postFixup = "rm -rf $out/lib $out/share $out/nix-support";
48 });
49 cpphs = overrideCabal (self.cpphs.overrideScope (self: super: {
50 mkDerivation = drv: super.mkDerivation (drv // {
51 enableSharedExecutables = false;
52 enableSharedLibraries = false;
53 doHaddock = false;
54 useCpphs = false;
55 });
56 })) (drv: {
57 isLibrary = false;
58 postFixup = "rm -rf $out/lib $out/share $out/nix-support";
59 });
60 };
61
62 mkDerivation = makeOverridable mkDerivationImpl;
63
64 # manualArgs are the arguments that were explictly passed to `callPackage`, like:
65 #
66 # callPackage foo { bar = null; };
67 #
68 # here `bar` is a manual argument.
69 callPackageWithScope = scope: fn: manualArgs:
70 let
71 # this code is copied from callPackage in lib/customisation.nix
72 #
73 # we cannot use `callPackage` here because we want to call `makeOverridable`
74 # on `drvScope` (we cannot add `overrideScope` after calling `callPackage` because then it is
75 # lost on `.override`) but determine the auto-args based on `drv` (the problem here
76 # is that nix has no way to "passthrough" args while preserving the reflection
77 # info that callPackage uses to determine the arguments).
78 drv = if builtins.isFunction fn then fn else import fn;
79 auto = builtins.intersectAttrs (builtins.functionArgs drv) scope;
80
81 # this wraps the `drv` function to add a `overrideScope` function to the result.
82 drvScope = allArgs: drv allArgs // {
83 overrideScope = f:
84 let newScope = mkScope (fix' (extends f scope.__unfix__));
85 # note that we have to be careful here: `allArgs` includes the auto-arguments that
86 # weren't manually specified. If we would just pass `allArgs` to the recursive call here,
87 # then we wouldn't look up any packages in the scope in the next interation, because it
88 # appears as if all arguments were already manually passed, so the scope change would do
89 # nothing.
90 in callPackageWithScope newScope drv manualArgs;
91 };
92 in stdenv.lib.makeOverridable drvScope (auto // manualArgs);
93
94 mkScope = scope: pkgs // pkgs.xorg // pkgs.gnome2 // { inherit stdenv; } // scope;
95 defaultScope = mkScope self;
96 callPackage = drv: args: callPackageWithScope defaultScope drv args;
97
98 withPackages = packages: callPackage ./with-packages-wrapper.nix {
99 inherit (self) llvmPackages;
100 haskellPackages = self;
101 inherit packages;
102 };
103
104 haskellSrc2nix = { name, src, sha256 ? null }:
105 let
106 sha256Arg = if isNull sha256 then "--sha256=" else ''--sha256="${sha256}"'';
107 in pkgs.stdenv.mkDerivation {
108 name = "cabal2nix-${name}";
109 buildInputs = [ pkgs.haskellPackages.cabal2nix ];
110 preferLocalBuild = true;
111 phases = ["installPhase"];
112 LANG = "en_US.UTF-8";
113 LOCALE_ARCHIVE = pkgs.lib.optionalString pkgs.stdenv.isLinux "${pkgs.glibcLocales}/lib/locale/locale-archive";
114 installPhase = ''
115 export HOME="$TMP"
116 mkdir -p "$out"
117 cabal2nix --compiler=${self.ghc.name} --system=${stdenv.system} ${sha256Arg} "${src}" > "$out/default.nix"
118 '';
119 };
120
121 hackage2nix = name: version: self.haskellSrc2nix {
122 name = "${name}-${version}";
123 sha256 = ''$(sed -e 's/.*"SHA256":"//' -e 's/".*$//' "${all-cabal-hashes}/${name}/${version}/${name}.json")'';
124 src = "${all-cabal-hashes}/${name}/${version}/${name}.cabal";
125 };
126
127in package-set { inherit pkgs stdenv callPackage; } self // {
128
129 inherit mkDerivation callPackage haskellSrc2nix hackage2nix;
130
131 callHackage = name: version: self.callPackage (self.hackage2nix name version);
132
133 # Creates a Haskell package from a source package by calling cabal2nix on the source.
134 callCabal2nix = name: src: self.callPackage (self.haskellSrc2nix { inherit src name; });
135
136 # : Map Name (Either Path VersionNumber) -> HaskellPackageOverrideSet
137 # Given a set whose values are either paths or version strings, produces
138 # a package override set (i.e. (self: super: { etc. })) that sets
139 # the packages named in the input set to the corresponding versions
140 packageSourceOverrides =
141 overrides: self: super: pkgs.lib.mapAttrs (name: src:
142 let isPath = x: builtins.substring 0 1 (toString x) == "/";
143 generateExprs = if isPath src
144 then self.callCabal2nix
145 else self.callHackage;
146 in generateExprs name src {}) overrides;
147
148 # : { root : Path
149 # , source-overrides : Defaulted (Either Path VersionNumber)
150 # , overrides : Defaulted (HaskellPackageOverrideSet)
151 # } -> NixShellAwareDerivation
152 # Given a path to a haskell package directory whose cabal file is
153 # named the same as the directory name, an optional set of
154 # source overrides as appropriate for the 'packageSourceOverrides'
155 # function, and an optional set of arbitrary overrides,
156 # return a derivation appropriate for nix-build or nix-shell
157 # to build that package.
158 developPackage = { root, source-overrides ? {}, overrides ? self: super: {} }:
159 let name = builtins.baseNameOf root;
160 drv =
161 (extensible-self.extend (pkgs.lib.composeExtensions (self.packageSourceOverrides source-overrides) overrides)).callCabal2nix name root {};
162 in if pkgs.lib.inNixShell then drv.env else drv;
163
164 ghcWithPackages = selectFrom: withPackages (selectFrom self);
165
166 ghcWithHoogle = selectFrom:
167 let
168 packages = selectFrom self;
169 hoogle = callPackage ./hoogle.nix {
170 inherit packages;
171 };
172 in withPackages (packages ++ [ hoogle ]);
173
174 ghc = ghc // {
175 withPackages = self.ghcWithPackages;
176 withHoogle = self.ghcWithHoogle;
177 };
178
179 }