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