Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
26 kB · 739 lines
Nix
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740# 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,
# A haskell package set for Setup.hs, compiler plugins, and similar # build-time uses. buildHaskellPackages,
# package-set used for non-haskell dependencies (all of nixpkgs) pkgs,
# stdenv provides our build and host platforms stdenv,
# this module provides the list of known licenses and maintainers lib,
# needed for overrideCabal & packageSourceOverrides haskellLib,
# hashes for downloading Hackage packages # This is either a directory or a .tar.gz containing the cabal files and # hashes of Hackage as exemplified by this repository: # https://github.com/commercialhaskell/all-cabal-hashes/tree/hackage all-cabal-hashes,
# compiler to use ghc,
# A function that takes `{ pkgs, lib, callPackage }` as the first arg and # `self` as second, and returns a set of haskell packages package-set,
# The final, fully overridden package set usable with the nixpkgs fixpoint # overriding functionality extensible-self,}:
# return value: a function from self to the package setself:
let inherit (stdenv) buildPlatform hostPlatform;
inherit (lib) fix' extends makeOverridable; inherit (haskellLib) overrideCabal;
mkDerivationImpl = pkgs.callPackage ./generic-builder.nix { inherit stdenv; nodejs = buildPackages.nodejs-slim; inherit (self) buildHaskellPackages ghc ghcWithHoogle ghcWithPackages ; inherit (self.buildHaskellPackages) jailbreak-cabal; hscolour = overrideCabal (drv: { isLibrary = false; doHaddock = false; hyperlinkSource = false; # Avoid depending on hscolour for this build. postFixup = "rm -rf $out/lib $out/share $out/nix-support"; }) self.buildHaskellPackages.hscolour; cpphs = overrideCabal (drv: { isLibrary = false; postFixup = "rm -rf $out/lib $out/share $out/nix-support"; }) ( self.cpphs.overrideScope ( self: super: { mkDerivation = drv: super.mkDerivation ( drv // { enableSharedExecutables = false; enableSharedLibraries = false; doHaddock = false; useCpphs = false; } ); } ) ); };
mkDerivation = makeOverridable mkDerivationImpl;
# manualArgs are the arguments that were explicitly 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 lib.isFunction fn then fn else import fn; auto = builtins.intersectAttrs (lib.functionArgs drv) scope;
# Converts a returned function to a functor attribute set if necessary ensureAttrs = v: if builtins.isFunction v then { __functor = _: v; } else v;
# this wraps the `drv` function to add `scope` and `overrideScope` to the result. drvScope = allArgs: ensureAttrs (drv allArgs) // { inherit scope; overrideScope = f: let newScope = mkScope (fix' (extends f scope.__unfix__)); in # 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. callPackageWithScope newScope drv manualArgs; }; in lib.makeOverridable drvScope (auto // manualArgs);
mkScope = scope: let ps = pkgs.__splicedPackages; scopeSpliced = pkgs.splicePackages { pkgsBuildBuild = scope.buildHaskellPackages.buildHaskellPackages; pkgsBuildHost = scope.buildHaskellPackages; pkgsBuildTarget = { }; pkgsHostHost = { }; pkgsHostTarget = scope; pkgsTargetTarget = { }; } // { # Don't splice these inherit (scope) ghc buildHaskellPackages; }; in ps // ps.xorg // ps.gnome2 // { inherit stdenv; } // scopeSpliced; defaultScope = mkScope self; callPackage = drv: args: callPackageWithScope defaultScope drv args;
# Use cabal2nix to create a default.nix for the package sources found at 'src'. haskellSrc2nix = { name, src, sha256 ? null, extraCabal2nixOptions ? "", }: let sha256Arg = if sha256 == null then "--sha256=" else ''--sha256="${sha256}"''; in buildPackages.runCommand "cabal2nix-${name}" { nativeBuildInputs = [ buildPackages.cabal2nix-unwrapped ]; preferLocalBuild = true; allowSubstitutes = false; LANG = "en_US.UTF-8"; LOCALE_ARCHIVE = pkgs.lib.optionalString ( buildPlatform.libc == "glibc" ) "${buildPackages.glibcLocales}/lib/locale/locale-archive"; } '' export HOME="$TMP" mkdir -p "$out" cabal2nix --compiler=${self.ghc.haskellCompilerName} --system=${hostPlatform.config} ${sha256Arg} "${src}" ${extraCabal2nixOptions} > "$out/default.nix" '';
# Given a package name and version, e.g. name = "async", version = "2.2.4", # gives its cabal file and hashes (JSON file) as discovered from the # all-cabal-hashes value. If that's a directory, it will copy the relevant # files to $out; if it's a tarball, it will extract and move them to $out. all-cabal-hashes-component = name: version: buildPackages.runCommand "all-cabal-hashes-component-${name}-${version}" { } '' mkdir -p $out if [ -d ${all-cabal-hashes} ] then cp ${all-cabal-hashes}/${name}/${version}/${name}.json $out cp ${all-cabal-hashes}/${name}/${version}/${name}.cabal $out else tar --wildcards -xzvf ${all-cabal-hashes} \*/${name}/${version}/${name}.{json,cabal} mv */${name}/${version}/${name}.{json,cabal} $out fi '';
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"; };
# Adds a nix file derived from cabal2nix in the passthru of the derivation it # produces. This is useful to debug callHackage / callCabal2nix by looking at # the content of the nix file pointed by `cabal2nixDeriver`. # However, it does not keep a reference to that file, which may be garbage # collected, which may be an annoyance. callPackageKeepDeriver = src: args: overrideCabal (orig: { passthru = orig.passthru or { } // { # When using callCabal2nix or callHackage, it is often useful # to debug a failure by inspecting the Nix expression # generated by cabal2nix. This can be accessed via this # cabal2nixDeriver field. cabal2nixDeriver = src; }; }) (self.callPackage src args);
inpackage-set { inherit pkgs lib callPackage; } self// {
inherit mkDerivation callPackage haskellSrc2nix hackage2nix buildHaskellPackages ;
inherit (haskellLib) packageSourceOverrides;
# callHackage :: Text -> Text -> AttrSet -> HaskellPackage # # e.g., while overriding a package set: # '... foo = self.callHackage "foo" "1.5.3" {}; ...' callHackage = name: version: callPackageKeepDeriver (self.hackage2nix name version);
# callHackageDirect # :: { pkg :: Text, ver :: Text, sha256 :: Text } # -> AttrSet # -> HaskellPackage # # This function does not depend on all-cabal-hashes and therefore will work # for any version that has been released on hackage as opposed to only # versions released before whatever version of all-cabal-hashes you happen # to be currently using. callHackageDirect = { pkg, ver, sha256, rev ? { revision = null; sha256 = null; }, }: args: let pkgver = "${pkg}-${ver}"; firstRevision = self.callCabal2nix pkg (pkgs.fetchzip { url = "mirror://hackage/${pkgver}/${pkgver}.tar.gz"; inherit sha256; }) args; in overrideCabal (orig: { revision = rev.revision; editedCabalFile = rev.sha256; }) firstRevision;
# Creates a Haskell package from a source package by calling cabal2nix on the source. callCabal2nixWithOptions = name: src: opts: args: let extraCabal2nixOptions = if builtins.isString opts then opts else opts.extraCabal2nixOptions or ""; srcModifier = opts.srcModifier or null; defaultFilter = path: type: pkgs.lib.hasSuffix ".cabal" path || baseNameOf path == "package.yaml"; expr = self.haskellSrc2nix { inherit name extraCabal2nixOptions; src = if srcModifier != null then srcModifier src else if pkgs.lib.canCleanSource src then pkgs.lib.cleanSourceWith { inherit src; filter = defaultFilter; } else src; }; in overrideCabal (orig: { inherit src; }) (callPackageKeepDeriver expr args);
callCabal2nix = name: src: args: self.callCabal2nixWithOptions name src "" args;
# : { root : Path # , name : Defaulted String # , source-overrides : Defaulted (Either Path VersionNumber) # , overrides : Defaulted (HaskellPackageOverrideSet) # , modifier : Defaulted # , returnShellEnv : Defaulted # , withHoogle : Defaulted # , cabal2nixOptions : Defaulted # } -> NixShellAwareDerivation # # Given a path to a haskell package directory, an optional package name # which defaults to the base name of the path, an optional set of source # overrides as appropriate for the 'packageSourceOverrides' function, an # optional set of arbitrary overrides, and an optional haskell package # modifier, return a derivation appropriate for nix-build or nix-shell to # build that package. # # If 'returnShellEnv' is true this returns a derivation which will give you # an environment suitable for developing the listed packages with an # incremental tool like cabal-install. # # If 'withHoogle' is true (the default if a shell environment is requested) # then 'ghcWithHoogle' is used to generate the derivation (instead of # 'ghcWithPackages'), see the documentation there for more information. # # 'cabal2nixOptions' can contain extra command line arguments to pass to # 'cabal2nix' when generating the package derivation, for example setting # a cabal flag with '--flag=myflag'. developPackage = { root, name ? lib.optionalString (builtins.typeOf root == "path") (builtins.baseNameOf root), source-overrides ? { }, overrides ? self: super: { }, modifier ? drv: drv, returnShellEnv ? pkgs.lib.inNixShell, withHoogle ? returnShellEnv, cabal2nixOptions ? "", }: let drv = (extensible-self.extend ( pkgs.lib.composeExtensions (self.packageSourceOverrides source-overrides) overrides )).callCabal2nixWithOptions name root cabal2nixOptions { }; in if returnShellEnv then (modifier drv).envFunc { inherit withHoogle; } else modifier drv;
# 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 = buildHaskellPackages.callPackage ./with-packages-wrapper.nix { haskellPackages = self; inherit (self) hoogleWithPackages; };
# 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' 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 # packages themselves. Using nix-shell on this derivation will # give you an environment suitable for developing the listed # packages with an incremental tool like cabal-install. # # In addition to the "packages" arg and "withHoogle" arg, anything that # can be passed into stdenv.mkDerivation can be included in the input attrset # # # default.nix # with import <nixpkgs> {}; # haskellPackages.extend (haskell.lib.compose.packageSourceOverrides { # frontend = ./frontend; # backend = ./backend; # common = ./common; # }) # # # shell.nix # let pkgs = import <nixpkgs> {} in # (import ./.).shellFor { # packages = p: [p.frontend p.backend p.common]; # withHoogle = true; # buildInputs = [ pkgs.python pkgs.cabal-install ]; # } # # -- cabal.project # packages: # frontend/ # backend/ # common/ # # bash$ nix-shell --run "cabal new-build all" # bash$ nix-shell --run "python" shellFor = { # Packages to create this development shell for. These are usually # your local packages. packages, # Whether or not to generate a Hoogle database for all the # dependencies. withHoogle ? false, # Whether or not to include benchmark dependencies of your local # packages. You should set this to true if you have benchmarks defined # in your local packages that you want to be able to run with cabal benchmark doBenchmark ? false, # An optional function that can modify the generic builder arguments # for the fake package that shellFor uses to construct its environment. # # Example: # let # # elided... # haskellPkgs = pkgs.haskell.packages.ghc884.override (hpArgs: { # overrides = pkgs.lib.composeExtensions (hpArgs.overrides or (_: _: { })) ( # _hfinal: hprev: { # mkDerivation = args: hprev.mkDerivation ({ # doCheck = false; # doBenchmark = false; # doHoogle = true; # doHaddock = true; # enableLibraryProfiling = false; # enableExecutableProfiling = false; # } // args); # } # ); # }); # in # haskellPkgs.shellFor { # packages = p: [ p.foo ]; # genericBuilderArgsModifier = args: args // { doCheck = true; doBenchmark = true }; # } # # This will disable tests and benchmarks for everything in "haskellPkgs" # (which will invalidate the binary cache), and then re-enable them # for the "shellFor" environment (ensuring that any test/benchmark # dependencies for "foo" will be available within the nix-shell). genericBuilderArgsModifier ? (args: args),
# Extra dependencies, in the form of cabal2nix build attributes. # # An example use case is when you have Haskell scripts that use # libraries that don't occur in your packages' dependencies. # # Example: # # extraDependencies = p: { # libraryHaskellDepends = [ p.releaser ]; # }; extraDependencies ? p: { }, ... }@args: let # A list of the packages we want to build a development shell for. # This is a list of Haskell package derivations. selected = packages self;
# This is a list of attribute sets, where each attribute set # corresponds to the build inputs of one of the packages input to shellFor. # # Each attribute has keys like buildDepends, executableHaskellDepends, # testPkgconfigDepends, etc. The values for the keys of the attribute # set are lists of dependencies. # # Example: # cabalDepsForSelected # => [ # # This may be the attribute set corresponding to the `backend` # # package in the example above. # { buildDepends = [ gcc ... ]; # libraryHaskellDepends = [ lens conduit ... ]; # ... # } # # This may be the attribute set corresponding to the `common` # # package in the example above. # { testHaskellDepends = [ tasty hspec ... ]; # libraryHaskellDepends = [ lens aeson ]; # benchmarkHaskellDepends = [ criterion ... ]; # ... # } # ... # ] cabalDepsForSelected = map (p: p.getCabalDeps) selected;
# A predicate that takes a derivation as input, and tests whether it is # the same as any of the `selected` packages. # # Returns true if the input derivation is not in the list of `selected` # packages. # # isNotSelected :: Derivation -> Bool # # Example: # # isNotSelected common [ frontend backend common ] # => false # # isNotSelected lens [ frontend backend common ] # => true isNotSelected = input: pkgs.lib.all (p: input.outPath or null != p.outPath) selected;
# A function that takes a list of list of derivations, filters out all # the `selected` packages from each list, and concats the results. # # zipperCombinedPkgs :: [[Derivation]] -> [Derivation] # # Example: # zipperCombinedPkgs [ [ lens conduit ] [ aeson frontend ] ] # => [ lens conduit aeson ] # # Note: The reason this isn't just the function `pkgs.lib.concat` is # that we need to be careful to remove dependencies that are in the # `selected` packages. # # For instance, in the above example, if `common` is a dependency of # `backend`, then zipperCombinedPkgs needs to be careful to filter out # `common`, because cabal will end up ignoring that built version, # assuming new-style commands. zipperCombinedPkgs = vals: pkgs.lib.concatMap (drvList: pkgs.lib.filter isNotSelected drvList) vals;
# Zip `cabalDepsForSelected` into a single attribute list, combining # the derivations in all the individual attributes. # # Example: # packageInputs # => # Assuming the value of cabalDepsForSelected is the same as # # the example in cabalDepsForSelected: # { buildDepends = [ gcc ... ]; # libraryHaskellDepends = [ lens conduit aeson ... ]; # testHaskellDepends = [ tasty hspec ... ]; # benchmarkHaskellDepends = [ criterion ... ]; # ... # } # # See the Note in `zipperCombinedPkgs` for what gets filtered out from # each of these dependency lists. packageInputs = pkgs.lib.zipAttrsWith (_name: zipperCombinedPkgs) ( cabalDepsForSelected ++ [ (extraDependencies self) ] );
# A attribute set to pass to `haskellPackages.mkDerivation`. # # The important thing to note here is that all the fields from # packageInputs are set correctly. genericBuilderArgs = { pname = if pkgs.lib.length selected == 1 then (pkgs.lib.head selected).name else "packages"; version = "0"; license = null; } // packageInputs // pkgs.lib.optionalAttrs doBenchmark { # `doBenchmark` needs to explicitly be set here because haskellPackages.mkDerivation defaults it to `false`. If the user wants benchmark dependencies included in their development shell, it has to be explicitly enabled here. doBenchmark = true; };
# This is a pseudo Haskell package derivation that contains all the # dependencies for the packages in `selected`. # # This is a derivation created with `haskellPackages.mkDerivation`. # # pkgWithCombinedDeps :: HaskellDerivation pkgWithCombinedDeps = self.mkDerivation (genericBuilderArgsModifier genericBuilderArgs);
# The derivation returned from `envFunc` for `pkgWithCombinedDeps`. # # This is a derivation that can be run with `nix-shell`. It provides a # GHC with a package database with all the dependencies of our # `selected` packages. # # This is a derivation created with `stdenv.mkDerivation` (not # `haskellPackages.mkDerivation`). # # pkgWithCombinedDepsDevDrv :: Derivation pkgWithCombinedDepsDevDrv = pkgWithCombinedDeps.envFunc { inherit withHoogle; };
mkDerivationArgs = builtins.removeAttrs args [ "genericBuilderArgsModifier" "packages" "withHoogle" "doBenchmark" "extraDependencies" ];
in pkgWithCombinedDepsDevDrv.overrideAttrs ( old: mkDerivationArgs // { nativeBuildInputs = old.nativeBuildInputs ++ mkDerivationArgs.nativeBuildInputs or [ ]; buildInputs = old.buildInputs ++ mkDerivationArgs.buildInputs or [ ]; } );
ghc = ghc // { withPackages = self.ghcWithPackages; withHoogle = self.ghcWithHoogle; };
/* Run `cabal sdist` on a source.
Unlike `haskell.lib.sdistTarball`, this does not require any dependencies to be present, as it uses `cabal-install` instead of building `Setup.hs`. This makes `cabalSdist` faster than `sdistTarball`. */ cabalSdist = { src, name ? if src ? name then "${src.name}-sdist.tar.gz" else "source.tar.gz", }: pkgs.runCommandLocal name { inherit src; nativeBuildInputs = [ buildHaskellPackages.cabal-install
# TODO after https://github.com/haskell/cabal/issues/8352 # remove ghc self.ghc ]; dontUnpack = false; } '' unpackPhase cd "''${sourceRoot:-.}" patchPhase mkdir out HOME=$PWD cabal sdist --output-directory out mv out/*.tar.gz $out '';
/* Like `haskell.lib.buildFromSdist`, but using `cabal sdist` instead of building `./Setup`.
Unlike `haskell.lib.buildFromSdist`, this does not require any dependencies to be present. This makes `buildFromCabalSdist` faster than `haskell.lib.buildFromSdist`. */ buildFromCabalSdist = pkg: haskellLib.overrideSrc { src = self.cabalSdist { inherit (pkg) src; }; version = pkg.version; } pkg;
/* Modify a Haskell package to add shell completion scripts for the given executables produced by it. These completion scripts will be picked up automatically if the resulting derivation is installed, e.g. by `nix-env -i`.
This depends on the `--*-completion` flag `optparse-applicative` provides automatically. Since we need to invoke installed executables, completions are not generated if we are cross-compiling.
commands: names of the executables built by the derivation pkg: Haskell package that builds the executables
Example: generateOptparseApplicativeCompletions [ "exec1" "exec2" ] pkg
Type: [str] -> drv -> drv */ generateOptparseApplicativeCompletions = self.callPackage ( { stdenv }:
commands: pkg:
if stdenv.buildPlatform.canExecute stdenv.hostPlatform then lib.foldr haskellLib.__generateOptparseApplicativeCompletion pkg commands else pkg ) { };
/* Modify given Haskell package to force GHC to employ the LLVM codegen backend when compiling. Useful when working around bugs in a native codegen backend GHC defaults to.
Example: forceLlvmCodegenBackend tls
Type: drv -> drv */ forceLlvmCodegenBackend = overrideCabal (drv: { configureFlags = drv.configureFlags or [ ] ++ [ "--ghc-option=-fllvm" ]; buildTools = drv.buildTools or [ ] ++ [ self.llvmPackages.llvm ]; });}