nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1# TODO(@Ericson2314): Remove `pkgs` param, which is only used for
2# `buildStackProject`, `justStaticExecutables` and `checkUnusedPackages`
3{ pkgs, lib }:
4
5rec {
6
7 /*
8 This function takes a file like `hackage-packages.nix` and constructs
9 a full package set out of that.
10 */
11 makePackageSet = import ../make-package-set.nix;
12
13 /*
14 The function overrideCabal lets you alter the arguments to the
15 mkDerivation function.
16
17 Example:
18
19 First, note how the aeson package is constructed in hackage-packages.nix:
20
21 "aeson" = callPackage ({ mkDerivation, attoparsec, <snip>
22 }:
23 mkDerivation {
24 pname = "aeson";
25 <snip>
26 homepage = "https://github.com/bos/aeson";
27 })
28
29 The mkDerivation function of haskellPackages will take care of putting
30 the homepage in the right place, in meta.
31
32 > haskellPackages.aeson.meta.homepage
33 "https://github.com/bos/aeson"
34
35 > x = haskell.lib.compose.overrideCabal (old: { homepage = old.homepage + "#readme"; }) haskellPackages.aeson
36 > x.meta.homepage
37 "https://github.com/bos/aeson#readme"
38 */
39 overrideCabal =
40 f: drv:
41 (drv.override (
42 args:
43 args
44 // {
45 mkDerivation = drv: (args.mkDerivation drv).override f;
46 }
47 ))
48 // {
49 overrideScope = scope: overrideCabal f (drv.overrideScope scope);
50 };
51
52 # : Map Name (Either Path VersionNumber) -> HaskellPackageOverrideSet
53 # Given a set whose values are either paths or version strings, produces
54 # a package override set (i.e. (self: super: { etc. })) that sets
55 # the packages named in the input set to the corresponding versions
56 packageSourceOverrides =
57 overrides: self: super:
58 pkgs.lib.mapAttrs (
59 name: src:
60 let
61 isPath = x: builtins.substring 0 1 (toString x) == "/";
62 generateExprs = if isPath src then self.callCabal2nix else self.callHackage;
63 in
64 generateExprs name src { }
65 ) overrides;
66
67 /*
68 doCoverage modifies a haskell package to enable the generation
69 and installation of a coverage report.
70
71 See https://wiki.haskell.org/Haskell_program_coverage
72 */
73 doCoverage = overrideCabal (drv: {
74 doCoverage = true;
75 });
76
77 /*
78 dontCoverage modifies a haskell package to disable the generation
79 and installation of a coverage report.
80 */
81 dontCoverage = overrideCabal (drv: {
82 doCoverage = false;
83 });
84
85 /*
86 doHaddock modifies a haskell package to enable the generation and
87 installation of API documentation from code comments using the
88 haddock tool.
89 */
90 doHaddock = overrideCabal (drv: {
91 doHaddock = true;
92 });
93
94 /*
95 dontHaddock modifies a haskell package to disable the generation and
96 installation of API documentation from code comments using the
97 haddock tool.
98 */
99 dontHaddock = overrideCabal (drv: {
100 doHaddock = false;
101 });
102
103 /*
104 doJailbreak enables the removal of version bounds from the cabal
105 file. You may want to avoid this function.
106
107 This is useful when a package reports that it can not be built
108 due to version mismatches. In some cases, removing the version
109 bounds entirely is an easy way to make a package build, but at
110 the risk of breaking software in non-obvious ways now or in the
111 future.
112
113 Instead of jailbreaking, you can patch the cabal file.
114
115 Note that jailbreaking at this time, doesn't lift bounds on
116 conditional branches.
117 https://github.com/peti/jailbreak-cabal/issues/7 (krank:ignore-line)
118 has further details.
119 */
120 doJailbreak = overrideCabal (drv: {
121 jailbreak = true;
122 });
123
124 /*
125 dontJailbreak restores the use of the version bounds the check
126 the use of dependencies in the package description.
127 */
128 dontJailbreak = overrideCabal (drv: {
129 jailbreak = false;
130 });
131
132 /*
133 doCheck enables dependency checking, compilation and execution
134 of test suites listed in the package description file.
135 */
136 doCheck = overrideCabal (drv: {
137 doCheck = true;
138 });
139 /*
140 dontCheck disables dependency checking, compilation and execution
141 of test suites listed in the package description file.
142 */
143 dontCheck = overrideCabal (drv: {
144 doCheck = false;
145 });
146 /*
147 The dontCheckIf variant sets doCheck = false if the condition
148 applies. In any other case the previously set/default value is used.
149 This prevents accidentally re-enabling tests in a later override.
150 */
151 dontCheckIf = condition: if condition then dontCheck else lib.id;
152
153 /*
154 doBenchmark enables dependency checking and compilation
155 for benchmarks listed in the package description file.
156 Benchmarks are, however, not executed at the moment.
157 */
158 doBenchmark = overrideCabal (drv: {
159 doBenchmark = true;
160 });
161 /*
162 dontBenchmark disables dependency checking, compilation and execution
163 for benchmarks listed in the package description file.
164 */
165 dontBenchmark = overrideCabal (drv: {
166 doBenchmark = false;
167 });
168
169 /*
170 doDistribute enables the distribution of binaries for the package
171 via hydra.
172 */
173 doDistribute = overrideCabal (drv: {
174 # lib.platforms.all is the default value for platforms (since GHC can cross-compile)
175 hydraPlatforms = lib.subtractLists (drv.badPlatforms or [ ]) (drv.platforms or lib.platforms.all);
176 });
177 /*
178 dontDistribute disables the distribution of binaries for the package
179 via hydra.
180 */
181 dontDistribute = overrideCabal (drv: {
182 hydraPlatforms = [ ];
183 });
184
185 /*
186 appendConfigureFlag adds a single argument that will be passed to the
187 cabal configure command, after the arguments that have been defined
188 in the initial declaration or previous overrides.
189
190 Example:
191
192 > haskell.lib.compose.appendConfigureFlag "--profiling-detail=all-functions" haskellPackages.servant
193 */
194 appendConfigureFlag = x: appendConfigureFlags [ x ];
195 appendConfigureFlags =
196 xs:
197 overrideCabal (drv: {
198 configureFlags = (drv.configureFlags or [ ]) ++ xs;
199 });
200
201 appendBuildFlag =
202 x:
203 overrideCabal (drv: {
204 buildFlags = (drv.buildFlags or [ ]) ++ [ x ];
205 });
206 appendBuildFlags =
207 xs:
208 overrideCabal (drv: {
209 buildFlags = (drv.buildFlags or [ ]) ++ xs;
210 });
211
212 /*
213 removeConfigureFlag drv x is a Haskell package like drv, but with
214 all cabal configure arguments that are equal to x removed.
215
216 > haskell.lib.compose.removeConfigureFlag "--verbose" haskellPackages.servant
217 */
218 removeConfigureFlag =
219 x:
220 overrideCabal (drv: {
221 configureFlags = lib.remove x (drv.configureFlags or [ ]);
222 });
223
224 addBuildTool = x: addBuildTools [ x ];
225 addBuildTools =
226 xs:
227 overrideCabal (drv: {
228 buildTools = (drv.buildTools or [ ]) ++ xs;
229 });
230
231 addExtraLibrary = x: addExtraLibraries [ x ];
232 addExtraLibraries =
233 xs:
234 overrideCabal (drv: {
235 extraLibraries = (drv.extraLibraries or [ ]) ++ xs;
236 });
237
238 addBuildDepend = x: addBuildDepends [ x ];
239 addBuildDepends =
240 xs:
241 overrideCabal (drv: {
242 buildDepends = (drv.buildDepends or [ ]) ++ xs;
243 });
244
245 addTestToolDepend = x: addTestToolDepends [ x ];
246 addTestToolDepends =
247 xs:
248 overrideCabal (drv: {
249 testToolDepends = (drv.testToolDepends or [ ]) ++ xs;
250 });
251
252 addPkgconfigDepend = x: addPkgconfigDepends [ x ];
253 addPkgconfigDepends =
254 xs:
255 overrideCabal (drv: {
256 pkg-configDepends = (drv.pkg-configDepends or [ ]) ++ xs;
257 });
258
259 addSetupDepend = x: addSetupDepends [ x ];
260 addSetupDepends =
261 xs:
262 overrideCabal (drv: {
263 setupHaskellDepends = (drv.setupHaskellDepends or [ ]) ++ xs;
264 });
265
266 enableCabalFlag = x: drv: appendConfigureFlag "-f${x}" (removeConfigureFlag "-f-${x}" drv);
267 disableCabalFlag = x: drv: appendConfigureFlag "-f-${x}" (removeConfigureFlag "-f${x}" drv);
268
269 markBroken = overrideCabal (drv: {
270 broken = true;
271 hydraPlatforms = [ ];
272 });
273 unmarkBroken = overrideCabal (drv: {
274 broken = false;
275 });
276 markBrokenVersion =
277 version: drv:
278 assert drv.version == version;
279 markBroken drv;
280 markUnbroken = overrideCabal (drv: {
281 broken = false;
282 });
283
284 /*
285 disableParallelBuilding drops the -j<n> option from the GHC
286 command line for the given package. This can be useful in rare
287 situations where parallel building of a package causes GHC to
288 fail for some reason.
289 */
290 disableParallelBuilding = overrideCabal (drv: {
291 enableParallelBuilding = false;
292 });
293
294 enableLibraryProfiling = overrideCabal (drv: {
295 enableLibraryProfiling = true;
296 });
297 disableLibraryProfiling = overrideCabal (drv: {
298 enableLibraryProfiling = false;
299 });
300
301 enableExecutableProfiling = overrideCabal (drv: {
302 enableExecutableProfiling = true;
303 });
304 disableExecutableProfiling = overrideCabal (drv: {
305 enableExecutableProfiling = false;
306 });
307
308 enableSharedExecutables = overrideCabal (drv: {
309 enableSharedExecutables = true;
310 });
311 disableSharedExecutables = overrideCabal (drv: {
312 enableSharedExecutables = false;
313 });
314
315 enableSharedLibraries = overrideCabal (drv: {
316 enableSharedLibraries = true;
317 });
318 disableSharedLibraries = overrideCabal (drv: {
319 enableSharedLibraries = false;
320 });
321
322 enableDeadCodeElimination = overrideCabal (drv: {
323 enableDeadCodeElimination = true;
324 });
325 disableDeadCodeElimination = overrideCabal (drv: {
326 enableDeadCodeElimination = false;
327 });
328
329 enableStaticLibraries = overrideCabal (drv: {
330 enableStaticLibraries = true;
331 });
332 disableStaticLibraries = overrideCabal (drv: {
333 enableStaticLibraries = false;
334 });
335
336 enableSeparateBinOutput = overrideCabal (drv: {
337 enableSeparateBinOutput = true;
338 });
339
340 appendPatch = x: appendPatches [ x ];
341 appendPatches =
342 xs:
343 overrideCabal (drv: {
344 patches = (drv.patches or [ ]) ++ xs;
345 });
346
347 /*
348 Set a specific build target instead of compiling all targets in the package.
349 For example, imagine we have a .cabal file with a library, and 2 executables "dev" and "server".
350 We can build only "server" and not wait on the compilation of "dev" by using setBuildTarget as follows:
351
352 > setBuildTarget "server" (callCabal2nix "thePackageName" thePackageSrc {})
353 */
354 setBuildTargets =
355 xs:
356 overrideCabal (drv: {
357 buildTarget = lib.concatStringsSep " " xs;
358 });
359 setBuildTarget = x: setBuildTargets [ x ];
360
361 doHyperlinkSource = overrideCabal (drv: {
362 hyperlinkSource = true;
363 });
364 dontHyperlinkSource = overrideCabal (drv: {
365 hyperlinkSource = false;
366 });
367
368 disableHardening =
369 flags:
370 overrideCabal (drv: {
371 hardeningDisable = flags;
372 });
373
374 /*
375 Let Nix strip the binary files.
376 This removes debugging symbols.
377 */
378 doStrip = overrideCabal (drv: {
379 dontStrip = false;
380 });
381
382 /*
383 Stop Nix from stripping the binary files.
384 This keeps debugging symbols.
385 */
386 dontStrip = overrideCabal (drv: {
387 dontStrip = true;
388 });
389
390 /*
391 Useful for debugging segfaults with gdb.
392 This includes dontStrip.
393 */
394 enableDWARFDebugging =
395 drv:
396 # -g: enables debugging symbols
397 # --disable-*-stripping: tell GHC not to strip resulting binaries
398 # dontStrip: see above
399 appendConfigureFlag "--ghc-options=-g --disable-executable-stripping --disable-library-stripping" (
400 dontStrip drv
401 );
402
403 /*
404 Create a source distribution tarball like those found on hackage,
405 instead of building the package.
406 */
407 sdistTarball =
408 pkg:
409 lib.overrideDerivation pkg (drv: {
410 name = "${drv.pname}-source-${drv.version}";
411 # Since we disable the haddock phase, we also need to override the
412 # outputs since the separate doc output will not be produced.
413 outputs = [ "out" ];
414 buildPhase = "./Setup sdist";
415 haddockPhase = ":";
416 checkPhase = ":";
417 installPhase = "install -D dist/${drv.pname}-*.tar.gz $out/${drv.pname}-${drv.version}.tar.gz";
418 fixupPhase = ":";
419 });
420
421 /*
422 Create a documentation tarball suitable for uploading to Hackage instead
423 of building the package.
424 */
425 documentationTarball =
426 pkg:
427 pkgs.lib.overrideDerivation pkg (drv: {
428 name = "${drv.name}-docs";
429 # Like sdistTarball, disable the "doc" output here.
430 outputs = [ "out" ];
431 buildPhase = ''
432 runHook preHaddock
433 ./Setup haddock --for-hackage
434 runHook postHaddock
435 '';
436 haddockPhase = ":";
437 checkPhase = ":";
438 installPhase = ''
439 runHook preInstall
440 mkdir -p "$out"
441 tar --format=ustar \
442 -czf "$out/${drv.name}-docs.tar.gz" \
443 -C dist/doc/html "${drv.name}-docs"
444 runHook postInstall
445 '';
446 });
447
448 /*
449 Use the gold linker. It is a linker for ELF that is designed
450 "to run as fast as possible on modern systems"
451 */
452 linkWithGold = appendConfigureFlag "--ghc-option=-optl-fuse-ld=gold --ld-option=-fuse-ld=gold --with-ld=ld.gold";
453
454 /*
455 link executables statically against haskell libs to reduce
456 closure size
457 */
458 justStaticExecutables = overrideCabal (drv: {
459 enableSharedExecutables = false;
460 enableLibraryProfiling = drv.enableExecutableProfiling or false;
461 isLibrary = false;
462 doHaddock = false;
463 postFixup = drv.postFixup or "" + ''
464
465 # Remove every directory which could have links to other store paths.
466 rm -rf $out/lib $out/nix-support $out/share/doc
467 '';
468 disallowGhcReference = true;
469 });
470
471 /*
472 Build a source distribution tarball instead of using the source files
473 directly. The effect is that the package is built as if it were published
474 on hackage. This can be used as a test for the source distribution,
475 assuming the build fails when packaging mistakes are in the cabal file.
476
477 A faster implementation using `cabal-install` is available as
478 `buildFromCabalSdist` in your Haskell package set.
479 */
480 buildFromSdist =
481 pkg:
482 overrideCabal (drv: {
483 src = "${sdistTarball pkg}/${pkg.pname}-${pkg.version}.tar.gz";
484
485 # Revising, jailbreaking and patches have been handled in sdistTarball
486 revision = null;
487 editedCabalFile = null;
488 jailbreak = false;
489 patches = [ ];
490 }) pkg;
491
492 /*
493 Build the package in a strict way to uncover potential problems.
494 This includes buildFromSdist and failOnAllWarnings.
495 */
496 buildStrictly = pkg: buildFromSdist (failOnAllWarnings pkg);
497
498 # Disable core optimizations, significantly speeds up build time
499 disableOptimization = appendConfigureFlag "--disable-optimization";
500
501 /*
502 Turn on most of the compiler warnings and fail the build if any
503 of them occur.
504 */
505 failOnAllWarnings = appendConfigureFlag "--ghc-option=-Wall --ghc-option=-Werror";
506
507 /*
508 Add a post-build check to verify that dependencies declared in
509 the cabal file are actually used.
510
511 The first attrset argument can be used to configure the strictness
512 of this check and a list of ignored package names that would otherwise
513 cause false alarms.
514 */
515 checkUnusedPackages =
516 {
517 ignoreEmptyImports ? false,
518 ignoreMainModule ? false,
519 ignorePackages ? [ ],
520 }:
521 drv:
522 overrideCabal (_drv: {
523 postBuild =
524 let
525 args = lib.concatStringsSep " " (
526 lib.optional ignoreEmptyImports "--ignore-empty-imports"
527 ++ lib.optional ignoreMainModule "--ignore-main-module"
528 ++ map (pkg: "--ignore-package ${pkg}") ignorePackages
529 );
530 in
531 "${pkgs.haskellPackages.packunused}/bin/packunused" + lib.optionalString (args != "") " ${args}";
532 }) (appendConfigureFlag "--ghc-option=-ddump-minimal-imports" drv);
533
534 buildStackProject = pkgs.callPackage ../generic-stack-builder.nix { };
535
536 /*
537 Add a dummy command to trigger a build despite an equivalent
538 earlier build that is present in the store or cache.
539 */
540 triggerRebuild =
541 i:
542 overrideCabal (drv: {
543 postUnpack = drv.postUnpack or "" + ''
544
545 # trigger rebuild ${toString i}
546 '';
547 });
548
549 /*
550 Override the sources for the package and optionally the version.
551 This also takes of removing editedCabalFile.
552 */
553 overrideSrc =
554 {
555 src,
556 version ? null,
557 }:
558 drv:
559 overrideCabal (_: {
560 inherit src;
561 version = if version == null then drv.version else version;
562 editedCabalFile = null;
563 }) drv;
564
565 # Get all of the build inputs of a haskell package, divided by category.
566 getBuildInputs = p: p.getBuildInputs;
567
568 # Extract the haskell build inputs of a haskell package.
569 # This is useful to build environments for developing on that
570 # package.
571 getHaskellBuildInputs = p: (getBuildInputs p).haskellBuildInputs;
572
573 # Under normal evaluation, simply return the original package. Under
574 # nix-shell evaluation, return a nix-shell optimized environment.
575 shellAware = p: if lib.inNixShell then p.env else p;
576
577 # Utility to convert a directory full of `cabal2nix`-generated files into a
578 # package override set
579 #
580 # packagesFromDirectory : { directory : Directory, ... } -> HaskellPackageOverrideSet
581 packagesFromDirectory =
582 { directory, ... }:
583
584 self: super:
585 let
586 haskellPaths = lib.filter (lib.hasSuffix ".nix") (builtins.attrNames (builtins.readDir directory));
587
588 toKeyVal = file: {
589 name = builtins.replaceStrings [ ".nix" ] [ "" ] file;
590
591 value = self.callPackage (directory + "/${file}") { };
592 };
593
594 in
595 builtins.listToAttrs (map toKeyVal haskellPaths);
596
597 /*
598 INTERNAL function retained for backwards compatibility, use
599 haskell.packages.*.generateOptparseApplicativeCompletions instead!
600 */
601 __generateOptparseApplicativeCompletion =
602 exeName:
603 overrideCabal (drv: {
604 postInstall = (drv.postInstall or "") + ''
605 bashCompDir="''${!outputBin}/share/bash-completion/completions"
606 zshCompDir="''${!outputBin}/share/zsh/vendor-completions"
607 fishCompDir="''${!outputBin}/share/fish/vendor_completions.d"
608 mkdir -p "$bashCompDir" "$zshCompDir" "$fishCompDir"
609 "''${!outputBin}/bin/${exeName}" --bash-completion-script "''${!outputBin}/bin/${exeName}" >"$bashCompDir/${exeName}"
610 "''${!outputBin}/bin/${exeName}" --zsh-completion-script "''${!outputBin}/bin/${exeName}" >"$zshCompDir/_${exeName}"
611 "''${!outputBin}/bin/${exeName}" --fish-completion-script "''${!outputBin}/bin/${exeName}" >"$fishCompDir/${exeName}.fish"
612
613 # Sanity check
614 grep -F ${exeName} <$bashCompDir/${exeName} >/dev/null || {
615 echo 'Could not find ${exeName} in completion script.'
616 exit 1
617 }
618 '';
619 });
620
621 /*
622 Retained for backwards compatibility.
623 Use haskell.packages.*.generateOptparseApplicativeCompletions
624 which is cross aware instead.
625 */
626 generateOptparseApplicativeCompletions =
627 commands: pkg:
628 lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2211)
629 "haskellLib.generateOptparseApplicativeCompletions is deprecated in favor of haskellPackages.generateOptparseApplicativeCompletions. Please change ${pkg.name} to use the latter and make sure it uses its matching haskell.packages set!"
630 (pkgs.lib.foldr __generateOptparseApplicativeCompletion pkg commands);
631
632 /*
633 Retained for backwards compatibility.
634 Use haskell.packages.*.generateOptparseApplicativeCompletions
635 which is cross aware instead.
636 */
637 generateOptparseApplicativeCompletion =
638 command: pkg:
639 lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2211)
640 "haskellLib.generateOptparseApplicativeCompletion is deprecated in favor of haskellPackages.generateOptparseApplicativeCompletions (plural!). Please change ${pkg.name} to use the latter and make sure it uses its matching haskell.packages set!"
641 (__generateOptparseApplicativeCompletion command pkg);
642
643 # Don't fail at configure time if there are multiple versions of the
644 # same package in the (recursive) dependencies of the package being
645 # built. Will delay failures, if any, to compile time.
646 allowInconsistentDependencies = overrideCabal (drv: {
647 allowInconsistentDependencies = true;
648 });
649
650 # Work around a Cabal bug requiring pkg-config --static --libs to work even
651 # when linking dynamically, affecting Cabal 3.8 and 3.9.
652 # https://github.com/haskell/cabal/issues/8455
653 #
654 # For this, we treat the runtime system/pkg-config dependencies of a Haskell
655 # derivation as if they were propagated from their dependencies which allows
656 # pkg-config --static to work in most cases.
657 #
658 # Warning: This function may change or be removed at any time, e.g. if we find
659 # a different workaround, upstream fixes the bug or we patch Cabal.
660 __CabalEagerPkgConfigWorkaround =
661 let
662 # Take list of derivations and return list of the transitive dependency
663 # closure, only taking into account buildInputs. Loosely based on
664 # closePropagationFast.
665 propagatedPlainBuildInputs =
666 drvs:
667 map (i: i.val) (
668 builtins.genericClosure {
669 startSet = map (drv: {
670 key = drv.outPath;
671 val = drv;
672 }) drvs;
673 operator =
674 { val, ... }:
675 if !lib.isDerivation val then
676 [ ]
677 else
678 builtins.concatMap (
679 drv:
680 if !lib.isDerivation drv then
681 [ ]
682 else
683 [
684 {
685 key = drv.outPath;
686 val = drv;
687 }
688 ]
689 ) (val.buildInputs or [ ] ++ val.propagatedBuildInputs or [ ]);
690 }
691 );
692 in
693 overrideCabal (old: {
694 benchmarkPkgconfigDepends = propagatedPlainBuildInputs old.benchmarkPkgconfigDepends or [ ];
695 executablePkgconfigDepends = propagatedPlainBuildInputs old.executablePkgconfigDepends or [ ];
696 libraryPkgconfigDepends = propagatedPlainBuildInputs old.libraryPkgconfigDepends or [ ];
697 testPkgconfigDepends = propagatedPlainBuildInputs old.testPkgconfigDepends or [ ];
698 });
699}