nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 765 lines 27 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{ 5 # package-set used for build tools (all of nixpkgs) 6 buildPackages, 7 8 # A haskell package set for Setup.hs, compiler plugins, and similar 9 # build-time uses. 10 buildHaskellPackages, 11 12 # package-set used for non-haskell dependencies (all of nixpkgs) 13 pkgs, 14 15 # stdenv provides our build and host platforms 16 stdenv, 17 18 # this module provides the list of known licenses and maintainers 19 lib, 20 21 # needed for overrideCabal & packageSourceOverrides 22 haskellLib, 23 24 # hashes for downloading Hackage packages 25 # This is either a directory or a .tar.gz containing the cabal files and 26 # hashes of Hackage as exemplified by this repository: 27 # https://github.com/commercialhaskell/all-cabal-hashes/tree/hackage 28 all-cabal-hashes, 29 30 # compiler to use 31 ghc, 32 33 # A function that takes `{ pkgs, lib, callPackage }` as the first arg and 34 # `self` as second, and returns a set of haskell packages 35 package-set, 36 37 # The final, fully overridden package set usable with the nixpkgs fixpoint 38 # overriding functionality 39 extensible-self, 40}: 41 42# return value: a function from self to the package set 43self: 44 45let 46 inherit (stdenv) buildPlatform hostPlatform; 47 48 inherit (lib) fix' extends makeOverridable; 49 inherit (haskellLib) overrideCabal; 50 51 mkDerivationImpl = pkgs.callPackage ./generic-builder.nix { 52 inherit stdenv haskellLib; 53 nodejs = buildPackages.nodejs-slim; 54 inherit (self) 55 buildHaskellPackages 56 ghc 57 ghcWithHoogle 58 ghcWithPackages 59 ; 60 iserv-proxy = { 61 build = buildHaskellPackages.iserv-proxy; 62 host = self.iserv-proxy; 63 }; 64 inherit (self.buildHaskellPackages) jailbreak-cabal; 65 hscolour = overrideCabal (drv: { 66 isLibrary = false; 67 doHaddock = false; 68 hyperlinkSource = false; # Avoid depending on hscolour for this build. 69 postFixup = "rm -rf $out/lib $out/share $out/nix-support"; 70 }) self.buildHaskellPackages.hscolour; 71 cpphs = 72 overrideCabal 73 (drv: { 74 isLibrary = false; 75 postFixup = "rm -rf $out/lib $out/share $out/nix-support"; 76 }) 77 ( 78 self.cpphs.overrideScope ( 79 self: super: { 80 mkDerivation = 81 drv: 82 super.mkDerivation ( 83 drv 84 // { 85 enableSharedExecutables = false; 86 enableSharedLibraries = false; 87 doHaddock = false; 88 useCpphs = false; 89 } 90 ); 91 } 92 ) 93 ); 94 }; 95 96 mkDerivation = makeOverridable mkDerivationImpl; 97 98 # manualArgs are the arguments that were explicitly passed to `callPackage`, like: 99 # 100 # callPackage foo { bar = null; }; 101 # 102 # here `bar` is a manual argument. 103 callPackageWithScope = 104 scope: fn: manualArgs: 105 let 106 # this code is copied from callPackage in lib/customisation.nix 107 # 108 # we cannot use `callPackage` here because we want to call `makeOverridable` 109 # on `drvScope` (we cannot add `overrideScope` after calling `callPackage` because then it is 110 # lost on `.override`) but determine the auto-args based on `drv` (the problem here 111 # is that nix has no way to "passthrough" args while preserving the reflection 112 # info that callPackage uses to determine the arguments). 113 drv = if lib.isFunction fn then fn else import fn; 114 drvFunctionArgs = lib.functionArgs drv; 115 auto = builtins.intersectAttrs drvFunctionArgs scope; 116 117 # Converts a returned function to a functor attribute set if necessary 118 ensureAttrs = v: if builtins.isFunction v then { __functor = _: v; } else v; 119 120 # this wraps the `drv` function to add `scope` and `overrideScope` to the result. 121 # it's a functor, so that we can pass through `functionArgs` 122 drvScope = { 123 __functor = 124 _: allArgs: 125 ensureAttrs (drv allArgs) 126 // { 127 inherit scope; 128 overrideScope = 129 f: 130 let 131 newScope = mkScope (fix' (extends f scope.__unfix__)); 132 in 133 # note that we have to be careful here: `allArgs` includes the auto-arguments that 134 # weren't manually specified. If we would just pass `allArgs` to the recursive call here, 135 # then we wouldn't look up any packages in the scope in the next interation, because it 136 # appears as if all arguments were already manually passed, so the scope change would do 137 # nothing. 138 callPackageWithScope newScope drv manualArgs; 139 }; 140 # `drvScope` accepts the same arguments as `drv` 141 __functionArgs = drvFunctionArgs; 142 }; 143 in 144 lib.makeOverridable drvScope (auto // manualArgs); 145 146 mkScope = 147 scope: 148 let 149 ps = pkgs.__splicedPackages; 150 scopeSpliced = 151 pkgs.splicePackages { 152 pkgsBuildBuild = scope.buildHaskellPackages.buildHaskellPackages; 153 pkgsBuildHost = scope.buildHaskellPackages; 154 pkgsBuildTarget = { }; 155 pkgsHostHost = { }; 156 pkgsHostTarget = scope; 157 pkgsTargetTarget = { }; 158 } 159 // { 160 # Don't splice these 161 inherit (scope) ghc buildHaskellPackages; 162 }; 163 in 164 ps // ps.xorg // ps.gnome2 // { inherit stdenv; } // scopeSpliced; 165 defaultScope = mkScope self; 166 callPackage = drv: args: callPackageWithScope defaultScope drv args; 167 168 # Use cabal2nix to create a default.nix for the package sources found at 'src'. 169 haskellSrc2nix = 170 { 171 name, 172 src, 173 sha256 ? null, 174 extraCabal2nixOptions ? "", 175 }: 176 let 177 sha256Arg = if sha256 == null then "--sha256=" else ''--sha256="${sha256}"''; 178 in 179 buildPackages.runCommand "cabal2nix-${name}" 180 { 181 nativeBuildInputs = [ buildPackages.cabal2nix-unwrapped ]; 182 preferLocalBuild = true; 183 allowSubstitutes = false; 184 LANG = "en_US.UTF-8"; 185 LOCALE_ARCHIVE = pkgs.lib.optionalString ( 186 buildPlatform.libc == "glibc" 187 ) "${buildPackages.glibcLocales}/lib/locale/locale-archive"; 188 } 189 '' 190 export HOME="$TMP" 191 mkdir -p "$out" 192 cabal2nix --compiler=${self.ghc.haskellCompilerName} --system=${hostPlatform.config} ${sha256Arg} "${src}" ${extraCabal2nixOptions} > "$out/default.nix" 193 ''; 194 195 # Given a package name and version, e.g. name = "async", version = "2.2.4", 196 # gives its cabal file and hashes (JSON file) as discovered from the 197 # all-cabal-hashes value. If that's a directory, it will copy the relevant 198 # files to $out; if it's a tarball, it will extract and move them to $out. 199 all-cabal-hashes-component = 200 name: version: 201 buildPackages.runCommand "all-cabal-hashes-component-${name}-${version}" { } '' 202 mkdir -p $out 203 if [ -d ${all-cabal-hashes} ] 204 then 205 cp ${all-cabal-hashes}/${name}/${version}/${name}.json $out 206 cp ${all-cabal-hashes}/${name}/${version}/${name}.cabal $out 207 else 208 tar --wildcards -xzvf ${all-cabal-hashes} \*/${name}/${version}/${name}.{json,cabal} 209 mv */${name}/${version}/${name}.{json,cabal} $out 210 fi 211 ''; 212 213 hackage2nix = 214 name: version: 215 let 216 component = all-cabal-hashes-component name version; 217 in 218 self.haskellSrc2nix { 219 name = "${name}-${version}"; 220 sha256 = ''$(sed -e 's/.*"SHA256":"//' -e 's/".*$//' "${component}/${name}.json")''; 221 src = "${component}/${name}.cabal"; 222 }; 223 224 # Adds a nix file derived from cabal2nix in the passthru of the derivation it 225 # produces. This is useful to debug callHackage / callCabal2nix by looking at 226 # the content of the nix file pointed by `cabal2nixDeriver`. 227 # However, it does not keep a reference to that file, which may be garbage 228 # collected, which may be an annoyance. 229 callPackageKeepDeriver = 230 src: args: 231 overrideCabal (orig: { 232 passthru = orig.passthru or { } // { 233 # When using callCabal2nix or callHackage, it is often useful 234 # to debug a failure by inspecting the Nix expression 235 # generated by cabal2nix. This can be accessed via this 236 # cabal2nixDeriver field. 237 cabal2nixDeriver = src; 238 }; 239 }) (self.callPackage src args); 240 241in 242package-set { inherit pkgs lib callPackage; } self 243// { 244 245 inherit 246 mkDerivation 247 callPackage 248 haskellSrc2nix 249 hackage2nix 250 buildHaskellPackages 251 ; 252 253 inherit (haskellLib) packageSourceOverrides; 254 255 # callHackage :: Text -> Text -> AttrSet -> HaskellPackage 256 # 257 # e.g., while overriding a package set: 258 # '... foo = self.callHackage "foo" "1.5.3" {}; ...' 259 callHackage = name: version: callPackageKeepDeriver (self.hackage2nix name version); 260 261 # callHackageDirect 262 # :: { pkg :: Text, ver :: Text, sha256 :: Text } 263 # -> AttrSet 264 # -> HaskellPackage 265 # 266 # This function does not depend on all-cabal-hashes and therefore will work 267 # for any version that has been released on hackage as opposed to only 268 # versions released before whatever version of all-cabal-hashes you happen 269 # to be currently using. 270 callHackageDirect = 271 { 272 pkg, 273 ver, 274 sha256, 275 candidate ? false, 276 rev ? { 277 revision = null; 278 sha256 = null; 279 }, 280 }: 281 args: 282 let 283 pkgver = "${pkg}-${ver}"; 284 firstRevision = self.callCabal2nix pkg (pkgs.fetchzip { 285 url = 286 if candidate then 287 "mirror://hackage/${pkgver}/candidate/${pkgver}.tar.gz" 288 else 289 "mirror://hackage/${pkgver}/${pkgver}.tar.gz"; 290 inherit sha256; 291 }) args; 292 in 293 overrideCabal (orig: { 294 revision = rev.revision; 295 editedCabalFile = rev.sha256; 296 }) firstRevision; 297 298 # Creates a Haskell package from a source package by calling cabal2nix on the source. 299 callCabal2nixWithOptions = 300 name: src: opts: args: 301 let 302 extraCabal2nixOptions = if builtins.isString opts then opts else opts.extraCabal2nixOptions or ""; 303 srcModifier = opts.srcModifier or null; 304 defaultFilter = path: type: pkgs.lib.hasSuffix ".cabal" path || baseNameOf path == "package.yaml"; 305 expr = self.haskellSrc2nix { 306 inherit name extraCabal2nixOptions; 307 src = 308 if srcModifier != null then 309 srcModifier src 310 else if pkgs.lib.canCleanSource src then 311 pkgs.lib.cleanSourceWith { 312 inherit src; 313 filter = defaultFilter; 314 } 315 else 316 src; 317 }; 318 in 319 overrideCabal (orig: { 320 inherit src; 321 }) (callPackageKeepDeriver expr args); 322 323 callCabal2nix = 324 name: src: args: 325 self.callCabal2nixWithOptions name src "" args; 326 327 # : { root : Path 328 # , name : Defaulted String 329 # , source-overrides : Defaulted (Either Path VersionNumber) 330 # , overrides : Defaulted (HaskellPackageOverrideSet) 331 # , modifier : Defaulted 332 # , returnShellEnv : Defaulted 333 # , withHoogle : Defaulted 334 # , cabal2nixOptions : Defaulted 335 # } -> NixShellAwareDerivation 336 # 337 # Given a path to a haskell package directory, an optional package name 338 # which defaults to the base name of the path, an optional set of source 339 # overrides as appropriate for the 'packageSourceOverrides' function, an 340 # optional set of arbitrary overrides, and an optional haskell package 341 # modifier, return a derivation appropriate for nix-build or nix-shell to 342 # build that package. 343 # 344 # If 'returnShellEnv' is true this returns a derivation which will give you 345 # an environment suitable for developing the listed packages with an 346 # incremental tool like cabal-install. 347 # 348 # If 'withHoogle' is true (the default if a shell environment is requested) 349 # then 'ghcWithHoogle' is used to generate the derivation (instead of 350 # 'ghcWithPackages'), see the documentation there for more information. 351 # 352 # 'cabal2nixOptions' can contain extra command line arguments to pass to 353 # 'cabal2nix' when generating the package derivation, for example setting 354 # a cabal flag with '--flag=myflag'. 355 developPackage = 356 { 357 root, 358 name ? lib.optionalString (builtins.typeOf root == "path") (baseNameOf root), 359 source-overrides ? { }, 360 overrides ? self: super: { }, 361 modifier ? drv: drv, 362 returnShellEnv ? pkgs.lib.inNixShell, 363 withHoogle ? returnShellEnv, 364 cabal2nixOptions ? "", 365 }: 366 let 367 drv = 368 (extensible-self.extend ( 369 pkgs.lib.composeExtensions (self.packageSourceOverrides source-overrides) overrides 370 )).callCabal2nixWithOptions 371 name 372 root 373 cabal2nixOptions 374 { }; 375 in 376 if returnShellEnv then (modifier drv).envFunc { inherit withHoogle; } else modifier drv; 377 378 # This can be used to easily create a derivation containing GHC and the specified set of Haskell packages. 379 # 380 # Example: 381 # $ nix-shell -p 'haskellPackages.ghcWithPackages (hpkgs: [ hpkgs.mtl hpkgs.lens ])' 382 # $ ghci # in the nix-shell 383 # Prelude > import Control.Lens 384 # 385 # GHC is setup with a package database with all the specified Haskell packages. 386 # 387 # ghcWithPackages :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation 388 ghcWithPackages = buildHaskellPackages.callPackage ./with-packages-wrapper.nix { 389 haskellPackages = self; 390 inherit (self) hoogleWithPackages; 391 }; 392 393 # Put 'hoogle' into the derivation's PATH with a database containing all 394 # the package's dependencies; run 'hoogle server --local' in a shell to 395 # host a search engine for the dependencies. 396 # 397 # Example usage: 398 # $ nix-shell -p 'haskellPackages.hoogleWithPackages (p: [ p.mtl p.lens ])' 399 # [nix-shell] $ hoogle server 400 # 401 # hoogleWithPackages :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation 402 # 403 # To reload the Hoogle server automatically on .cabal file changes try 404 # this: 405 # echo *.cabal | entr -r -- nix-shell --run 'hoogle server --local' 406 hoogleWithPackages = self.callPackage ./hoogle.nix { 407 haskellPackages = self; 408 }; 409 hoogleLocal = 410 { 411 packages ? [ ], 412 }: 413 lib.warn "hoogleLocal is deprecated, use hoogleWithPackages instead" ( 414 self.hoogleWithPackages (_: packages) 415 ); 416 # This is like a combination of ghcWithPackages and hoogleWithPackages. 417 # It provides a derivation containing both GHC and Hoogle with an index of 418 # the given Haskell package database. 419 # 420 # Example: 421 # $ nix-shell -p 'haskellPackages.ghcWithHoogle (hpkgs: [ hpkgs.conduit hpkgs.lens ])' 422 # 423 # ghcWithHoogle :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation 424 ghcWithHoogle = self.ghcWithPackages.override { 425 withHoogle = true; 426 }; 427 428 # Returns a derivation whose environment contains a GHC with only 429 # the dependencies of packages listed in `packages`, not the 430 # packages themselves. Using nix-shell on this derivation will 431 # give you an environment suitable for developing the listed 432 # packages with an incremental tool like cabal-install. 433 # 434 # In addition to the "packages" arg and "withHoogle" arg, anything that 435 # can be passed into stdenv.mkDerivation can be included in the input attrset 436 # 437 # # default.nix 438 # with import <nixpkgs> {}; 439 # haskellPackages.extend (haskell.lib.compose.packageSourceOverrides { 440 # frontend = ./frontend; 441 # backend = ./backend; 442 # common = ./common; 443 # }) 444 # 445 # # shell.nix 446 # let pkgs = import <nixpkgs> {} in 447 # (import ./.).shellFor { 448 # packages = p: [p.frontend p.backend p.common]; 449 # withHoogle = true; 450 # buildInputs = [ pkgs.python pkgs.cabal-install ]; 451 # } 452 # 453 # -- cabal.project 454 # packages: 455 # frontend/ 456 # backend/ 457 # common/ 458 # 459 # bash$ nix-shell --run "cabal new-build all" 460 # bash$ nix-shell --run "python" 461 shellFor = 462 { 463 # Packages to create this development shell for. These are usually 464 # your local packages. 465 packages, 466 # Whether or not to generate a Hoogle database for all the 467 # dependencies. 468 withHoogle ? false, 469 # Whether or not to include benchmark dependencies of your local 470 # packages. You should set this to true if you have benchmarks defined 471 # in your local packages that you want to be able to run with cabal benchmark 472 doBenchmark ? false, 473 # An optional function that can modify the generic builder arguments 474 # for the fake package that shellFor uses to construct its environment. 475 # 476 # Example: 477 # let 478 # # elided... 479 # haskellPkgs = pkgs.haskell.packages.ghc884.override (hpArgs: { 480 # overrides = pkgs.lib.composeExtensions (hpArgs.overrides or (_: _: { })) ( 481 # _hfinal: hprev: { 482 # mkDerivation = args: hprev.mkDerivation ({ 483 # doCheck = false; 484 # doBenchmark = false; 485 # doHoogle = true; 486 # doHaddock = true; 487 # enableLibraryProfiling = false; 488 # enableExecutableProfiling = false; 489 # } // args); 490 # } 491 # ); 492 # }); 493 # in 494 # haskellPkgs.shellFor { 495 # packages = p: [ p.foo ]; 496 # genericBuilderArgsModifier = args: args // { doCheck = true; doBenchmark = true }; 497 # } 498 # 499 # This will disable tests and benchmarks for everything in "haskellPkgs" 500 # (which will invalidate the binary cache), and then re-enable them 501 # for the "shellFor" environment (ensuring that any test/benchmark 502 # dependencies for "foo" will be available within the nix-shell). 503 genericBuilderArgsModifier ? (args: args), 504 505 # Extra dependencies, in the form of cabal2nix build attributes. 506 # 507 # An example use case is when you have Haskell scripts that use 508 # libraries that don't occur in your packages' dependencies. 509 # 510 # Example: 511 # 512 # extraDependencies = p: { 513 # libraryHaskellDepends = [ p.releaser ]; 514 # }; 515 extraDependencies ? p: { }, 516 ... 517 }@args: 518 let 519 # A list of the packages we want to build a development shell for. 520 # This is a list of Haskell package derivations. 521 selected = packages self; 522 523 # This is a list of attribute sets, where each attribute set 524 # corresponds to the build inputs of one of the packages input to shellFor. 525 # 526 # Each attribute has keys like buildDepends, executableHaskellDepends, 527 # testPkgconfigDepends, etc. The values for the keys of the attribute 528 # set are lists of dependencies. 529 # 530 # Example: 531 # cabalDepsForSelected 532 # => [ 533 # # This may be the attribute set corresponding to the `backend` 534 # # package in the example above. 535 # { buildDepends = [ gcc ... ]; 536 # libraryHaskellDepends = [ lens conduit ... ]; 537 # ... 538 # } 539 # # This may be the attribute set corresponding to the `common` 540 # # package in the example above. 541 # { testHaskellDepends = [ tasty hspec ... ]; 542 # libraryHaskellDepends = [ lens aeson ]; 543 # benchmarkHaskellDepends = [ criterion ... ]; 544 # ... 545 # } 546 # ... 547 # ] 548 cabalDepsForSelected = map (p: p.getCabalDeps) selected; 549 550 # A predicate that takes a derivation as input, and tests whether it is 551 # the same as any of the `selected` packages. 552 # 553 # Returns true if the input derivation is not in the list of `selected` 554 # packages. 555 # 556 # isNotSelected :: Derivation -> Bool 557 # 558 # Example: 559 # 560 # isNotSelected common [ frontend backend common ] 561 # => false 562 # 563 # isNotSelected lens [ frontend backend common ] 564 # => true 565 isNotSelected = input: pkgs.lib.all (p: input.outPath or null != p.outPath) selected; 566 567 # A function that takes a list of list of derivations, filters out all 568 # the `selected` packages from each list, and concats the results. 569 # 570 # zipperCombinedPkgs :: [[Derivation]] -> [Derivation] 571 # 572 # Example: 573 # zipperCombinedPkgs [ [ lens conduit ] [ aeson frontend ] ] 574 # => [ lens conduit aeson ] 575 # 576 # Note: The reason this isn't just the function `pkgs.lib.concat` is 577 # that we need to be careful to remove dependencies that are in the 578 # `selected` packages. 579 # 580 # For instance, in the above example, if `common` is a dependency of 581 # `backend`, then zipperCombinedPkgs needs to be careful to filter out 582 # `common`, because cabal will end up ignoring that built version, 583 # assuming new-style commands. 584 zipperCombinedPkgs = vals: pkgs.lib.concatMap (drvList: pkgs.lib.filter isNotSelected drvList) vals; 585 586 # Zip `cabalDepsForSelected` into a single attribute list, combining 587 # the derivations in all the individual attributes. 588 # 589 # Example: 590 # packageInputs 591 # => # Assuming the value of cabalDepsForSelected is the same as 592 # # the example in cabalDepsForSelected: 593 # { buildDepends = [ gcc ... ]; 594 # libraryHaskellDepends = [ lens conduit aeson ... ]; 595 # testHaskellDepends = [ tasty hspec ... ]; 596 # benchmarkHaskellDepends = [ criterion ... ]; 597 # ... 598 # } 599 # 600 # See the Note in `zipperCombinedPkgs` for what gets filtered out from 601 # each of these dependency lists. 602 packageInputs = pkgs.lib.zipAttrsWith (_name: zipperCombinedPkgs) ( 603 cabalDepsForSelected ++ [ (extraDependencies self) ] 604 ); 605 606 # A attribute set to pass to `haskellPackages.mkDerivation`. 607 # 608 # The important thing to note here is that all the fields from 609 # packageInputs are set correctly. 610 genericBuilderArgs = { 611 pname = if pkgs.lib.length selected == 1 then (pkgs.lib.head selected).name else "packages"; 612 version = "0"; 613 license = null; 614 } 615 // packageInputs 616 // pkgs.lib.optionalAttrs doBenchmark { 617 # `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. 618 doBenchmark = true; 619 }; 620 621 # This is a pseudo Haskell package derivation that contains all the 622 # dependencies for the packages in `selected`. 623 # 624 # This is a derivation created with `haskellPackages.mkDerivation`. 625 # 626 # pkgWithCombinedDeps :: HaskellDerivation 627 pkgWithCombinedDeps = self.mkDerivation (genericBuilderArgsModifier genericBuilderArgs); 628 629 # The derivation returned from `envFunc` for `pkgWithCombinedDeps`. 630 # 631 # This is a derivation that can be run with `nix-shell`. It provides a 632 # GHC with a package database with all the dependencies of our 633 # `selected` packages. 634 # 635 # This is a derivation created with `stdenv.mkDerivation` (not 636 # `haskellPackages.mkDerivation`). 637 # 638 # pkgWithCombinedDepsDevDrv :: Derivation 639 pkgWithCombinedDepsDevDrv = pkgWithCombinedDeps.envFunc { inherit withHoogle; }; 640 641 mkDerivationArgs = removeAttrs args [ 642 "genericBuilderArgsModifier" 643 "packages" 644 "withHoogle" 645 "doBenchmark" 646 "extraDependencies" 647 ]; 648 649 in 650 pkgWithCombinedDepsDevDrv.overrideAttrs ( 651 old: 652 mkDerivationArgs 653 // { 654 nativeBuildInputs = old.nativeBuildInputs ++ mkDerivationArgs.nativeBuildInputs or [ ]; 655 buildInputs = old.buildInputs ++ mkDerivationArgs.buildInputs or [ ]; 656 } 657 ); 658 659 ghc = ghc // { 660 withPackages = self.ghcWithPackages; 661 withHoogle = self.ghcWithHoogle; 662 }; 663 664 /* 665 Run `cabal sdist` on a source. 666 667 Unlike `haskell.lib.sdistTarball`, this does not require any dependencies 668 to be present, as it uses `cabal-install` instead of building `Setup.hs`. 669 This makes `cabalSdist` faster than `sdistTarball`. 670 */ 671 cabalSdist = 672 { 673 src, 674 name ? if src ? name then "${src.name}-sdist.tar.gz" else "source.tar.gz", 675 }: 676 pkgs.runCommandLocal name 677 { 678 inherit src; 679 nativeBuildInputs = [ 680 buildHaskellPackages.cabal-install 681 ]; 682 dontUnpack = false; 683 } 684 '' 685 unpackPhase 686 cd "''${sourceRoot:-.}" 687 patchPhase 688 mkdir out 689 HOME=$PWD cabal sdist --output-directory out 690 mv out/*.tar.gz $out 691 ''; 692 693 /* 694 Like `haskell.lib.buildFromSdist`, but using `cabal sdist` instead of 695 building `./Setup`. 696 697 Unlike `haskell.lib.buildFromSdist`, this does not require any dependencies 698 to be present. This makes `buildFromCabalSdist` faster than `haskell.lib.buildFromSdist`. 699 */ 700 buildFromCabalSdist = 701 pkg: 702 haskellLib.overrideCabal 703 (_: { 704 # Patches are already applied by srcOnly above, so clear them 705 # to avoid double-application. 706 patches = [ ]; 707 }) 708 ( 709 haskellLib.overrideSrc { 710 src = self.cabalSdist { src = pkgs.srcOnly pkg; }; 711 version = pkg.version; 712 } pkg 713 ); 714 715 /* 716 Modify a Haskell package to add shell completion scripts for the 717 given executables produced by it. These completion scripts will be 718 picked up automatically if the resulting derivation is installed, 719 e.g. by `nix-env -i`. 720 721 This depends on the `--*-completion` flag `optparse-applicative` provides 722 automatically. Since we need to invoke installed executables, completions 723 are not generated if we are cross-compiling. 724 725 commands: names of the executables built by the derivation 726 pkg: Haskell package that builds the executables 727 728 Example: 729 generateOptparseApplicativeCompletions [ "exec1" "exec2" ] pkg 730 731 Type: [str] -> drv -> drv 732 */ 733 generateOptparseApplicativeCompletions = self.callPackage ( 734 { stdenv }: 735 736 commands: pkg: 737 738 if stdenv.buildPlatform.canExecute stdenv.hostPlatform then 739 lib.foldr haskellLib.__generateOptparseApplicativeCompletion pkg commands 740 else 741 pkg 742 ) { }; 743 744 /* 745 Modify given Haskell package to force GHC to employ the LLVM 746 codegen backend when compiling. Useful when working around bugs 747 in a native codegen backend GHC defaults to. 748 749 Example: 750 forceLlvmCodegenBackend tls 751 752 Type: drv -> drv 753 */ 754 forceLlvmCodegenBackend = overrideCabal (drv: { 755 configureFlags = drv.configureFlags or [ ] ++ [ "--ghc-option=-fllvm" ]; 756 buildTools = 757 drv.buildTools or [ ] 758 ++ [ self.ghc.llvmPackages.llvm ] 759 # GHC >= 9.10 needs LLVM specific assembler, i.e. clang 760 # On Darwin clang is always required 761 ++ lib.optionals (lib.versionAtLeast self.ghc.version "9.10" || stdenv.hostPlatform.isDarwin) [ 762 self.ghc.llvmPackages.clang 763 ]; 764 }); 765}