nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at 17.09 179 lines 7.1 kB view raw
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 }