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 /* This function takes a file like `hackage-packages.nix` and constructs
8 a full package set out of that.
9 */
10 makePackageSet = import ../make-package-set.nix;
11
12 /* The function overrideCabal lets you alter the arguments to the
13 mkDerivation function.
14
15 Example:
16
17 First, note how the aeson package is constructed in hackage-packages.nix:
18
19 "aeson" = callPackage ({ mkDerivation, attoparsec, <snip>
20 }:
21 mkDerivation {
22 pname = "aeson";
23 <snip>
24 homepage = "https://github.com/bos/aeson";
25 })
26
27 The mkDerivation function of haskellPackages will take care of putting
28 the homepage in the right place, in meta.
29
30 > haskellPackages.aeson.meta.homepage
31 "https://github.com/bos/aeson"
32
33 > x = haskell.lib.compose.overrideCabal (old: { homepage = old.homepage + "#readme"; }) haskellPackages.aeson
34 > x.meta.homepage
35 "https://github.com/bos/aeson#readme"
36
37 */
38 overrideCabal = f: drv: (drv.override (args: args // {
39 mkDerivation = drv: (args.mkDerivation drv).override f;
40 })) // {
41 overrideScope = scope: overrideCabal f (drv.overrideScope scope);
42 };
43
44 # : Map Name (Either Path VersionNumber) -> HaskellPackageOverrideSet
45 # Given a set whose values are either paths or version strings, produces
46 # a package override set (i.e. (self: super: { etc. })) that sets
47 # the packages named in the input set to the corresponding versions
48 packageSourceOverrides =
49 overrides: self: super: pkgs.lib.mapAttrs (name: src:
50 let isPath = x: builtins.substring 0 1 (toString x) == "/";
51 generateExprs = if isPath src
52 then self.callCabal2nix
53 else self.callHackage;
54 in generateExprs name src {}) overrides;
55
56 /* doCoverage modifies a haskell package to enable the generation
57 and installation of a coverage report.
58
59 See https://wiki.haskell.org/Haskell_program_coverage
60 */
61 doCoverage = overrideCabal (drv: { doCoverage = true; });
62
63 /* dontCoverage modifies a haskell package to disable the generation
64 and installation of a coverage report.
65 */
66 dontCoverage = overrideCabal (drv: { doCoverage = false; });
67
68 /* doHaddock modifies a haskell package to enable the generation and
69 installation of API documentation from code comments using the
70 haddock tool.
71 */
72 doHaddock = overrideCabal (drv: { doHaddock = true; });
73
74 /* dontHaddock modifies a haskell package to disable the generation and
75 installation of API documentation from code comments using the
76 haddock tool.
77 */
78 dontHaddock = overrideCabal (drv: { doHaddock = false; });
79
80 /* doJailbreak enables the removal of version bounds from the cabal
81 file. You may want to avoid this function.
82
83 This is useful when a package reports that it can not be built
84 due to version mismatches. In some cases, removing the version
85 bounds entirely is an easy way to make a package build, but at
86 the risk of breaking software in non-obvious ways now or in the
87 future.
88
89 Instead of jailbreaking, you can patch the cabal file.
90
91 Note that jailbreaking at this time, doesn't lift bounds on
92 conditional branches.
93 https://github.com/peti/jailbreak-cabal/issues/7 has further details.
94
95 */
96 doJailbreak = overrideCabal (drv: { jailbreak = true; });
97
98 /* dontJailbreak restores the use of the version bounds the check
99 the use of dependencies in the package description.
100 */
101 dontJailbreak = overrideCabal (drv: { jailbreak = false; });
102
103 /* doCheck enables dependency checking, compilation and execution
104 of test suites listed in the package description file.
105 */
106 doCheck = overrideCabal (drv: { doCheck = true; });
107 /* dontCheck disables dependency checking, compilation and execution
108 of test suites listed in the package description file.
109 */
110 dontCheck = overrideCabal (drv: { doCheck = false; });
111
112 /* doBenchmark enables dependency checking, compilation and execution
113 for benchmarks listed in the package description file.
114 */
115 doBenchmark = overrideCabal (drv: { doBenchmark = true; });
116 /* dontBenchmark disables dependency checking, compilation and execution
117 for benchmarks listed in the package description file.
118 */
119 dontBenchmark = overrideCabal (drv: { doBenchmark = false; });
120
121 /* doDistribute enables the distribution of binaries for the package
122 via hydra.
123 */
124 doDistribute = overrideCabal (drv: { hydraPlatforms = drv.platforms or ["i686-linux" "x86_64-linux" "x86_64-darwin"]; });
125 /* dontDistribute disables the distribution of binaries for the package
126 via hydra.
127 */
128 dontDistribute = overrideCabal (drv: { hydraPlatforms = []; });
129
130 /* appendConfigureFlag adds a single argument that will be passed to the
131 cabal configure command, after the arguments that have been defined
132 in the initial declaration or previous overrides.
133
134 Example:
135
136 > haskell.lib.compose.appendConfigureFlag "--profiling-detail=all-functions" haskellPackages.servant
137 */
138 appendConfigureFlag = x: appendConfigureFlags [x];
139 appendConfigureFlags = xs: overrideCabal (drv: { configureFlags = (drv.configureFlags or []) ++ xs; });
140
141 appendBuildFlag = x: overrideCabal (drv: { buildFlags = (drv.buildFlags or []) ++ [x]; });
142 appendBuildFlags = xs: overrideCabal (drv: { buildFlags = (drv.buildFlags or []) ++ xs; });
143
144 /* removeConfigureFlag drv x is a Haskell package like drv, but with
145 all cabal configure arguments that are equal to x removed.
146
147 > haskell.lib.compose.removeConfigureFlag "--verbose" haskellPackages.servant
148 */
149 removeConfigureFlag = x: overrideCabal (drv: { configureFlags = lib.remove x (drv.configureFlags or []); });
150
151 addBuildTool = x: addBuildTools [x];
152 addBuildTools = xs: overrideCabal (drv: { buildTools = (drv.buildTools or []) ++ xs; });
153
154 addExtraLibrary = x: addExtraLibraries [x];
155 addExtraLibraries = xs: overrideCabal (drv: { extraLibraries = (drv.extraLibraries or []) ++ xs; });
156
157 addBuildDepend = x: addBuildDepends [x];
158 addBuildDepends = xs: overrideCabal (drv: { buildDepends = (drv.buildDepends or []) ++ xs; });
159
160 addTestToolDepend = x: addTestToolDepends [x];
161 addTestToolDepends = xs: overrideCabal (drv: { testToolDepends = (drv.testToolDepends or []) ++ xs; });
162
163 addPkgconfigDepend = x: addPkgconfigDepends [x];
164 addPkgconfigDepends = xs: overrideCabal (drv: { pkg-configDepends = (drv.pkg-configDepends or []) ++ xs; });
165
166 addSetupDepend = x: addSetupDepends [x];
167 addSetupDepends = xs: overrideCabal (drv: { setupHaskellDepends = (drv.setupHaskellDepends or []) ++ xs; });
168
169 enableCabalFlag = x: drv: appendConfigureFlag "-f${x}" (removeConfigureFlag "-f-${x}" drv);
170 disableCabalFlag = x: drv: appendConfigureFlag "-f-${x}" (removeConfigureFlag "-f${x}" drv);
171
172 markBroken = overrideCabal (drv: { broken = true; hydraPlatforms = []; });
173 unmarkBroken = overrideCabal (drv: { broken = false; });
174 markBrokenVersion = version: drv: assert drv.version == version; markBroken drv;
175 markUnbroken = overrideCabal (drv: { broken = false; });
176
177 enableLibraryProfiling = overrideCabal (drv: { enableLibraryProfiling = true; });
178 disableLibraryProfiling = overrideCabal (drv: { enableLibraryProfiling = false; });
179
180 enableExecutableProfiling = overrideCabal (drv: { enableExecutableProfiling = true; });
181 disableExecutableProfiling = overrideCabal (drv: { enableExecutableProfiling = false; });
182
183 enableSharedExecutables = overrideCabal (drv: { enableSharedExecutables = true; });
184 disableSharedExecutables = overrideCabal (drv: { enableSharedExecutables = false; });
185
186 enableSharedLibraries = overrideCabal (drv: { enableSharedLibraries = true; });
187 disableSharedLibraries = overrideCabal (drv: { enableSharedLibraries = false; });
188
189 enableDeadCodeElimination = overrideCabal (drv: { enableDeadCodeElimination = true; });
190 disableDeadCodeElimination = overrideCabal (drv: { enableDeadCodeElimination = false; });
191
192 enableStaticLibraries = overrideCabal (drv: { enableStaticLibraries = true; });
193 disableStaticLibraries = overrideCabal (drv: { enableStaticLibraries = false; });
194
195 enableSeparateBinOutput = overrideCabal (drv: { enableSeparateBinOutput = true; });
196
197 appendPatch = x: appendPatches [x];
198 appendPatches = xs: overrideCabal (drv: { patches = (drv.patches or []) ++ xs; });
199
200 /* Set a specific build target instead of compiling all targets in the package.
201 * For example, imagine we have a .cabal file with a library, and 2 executables "dev" and "server".
202 * We can build only "server" and not wait on the compilation of "dev" by using setBuildTarget as follows:
203 *
204 * > setBuildTarget "server" (callCabal2nix "thePackageName" thePackageSrc {})
205 *
206 */
207 setBuildTargets = xs: overrideCabal (drv: { buildTarget = lib.concatStringsSep " " xs; });
208 setBuildTarget = x: setBuildTargets [x];
209
210 doHyperlinkSource = overrideCabal (drv: { hyperlinkSource = true; });
211 dontHyperlinkSource = overrideCabal (drv: { hyperlinkSource = false; });
212
213 disableHardening = flags: overrideCabal (drv: { hardeningDisable = flags; });
214
215 /* Let Nix strip the binary files.
216 * This removes debugging symbols.
217 */
218 doStrip = overrideCabal (drv: { dontStrip = false; });
219
220 /* Stop Nix from stripping the binary files.
221 * This keeps debugging symbols.
222 */
223 dontStrip = overrideCabal (drv: { dontStrip = true; });
224
225 /* Useful for debugging segfaults with gdb.
226 * This includes dontStrip.
227 */
228 enableDWARFDebugging = drv:
229 # -g: enables debugging symbols
230 # --disable-*-stripping: tell GHC not to strip resulting binaries
231 # dontStrip: see above
232 appendConfigureFlag "--ghc-options=-g --disable-executable-stripping --disable-library-stripping" (dontStrip drv);
233
234 /* Create a source distribution tarball like those found on hackage,
235 instead of building the package.
236 */
237 sdistTarball = pkg: lib.overrideDerivation pkg (drv: {
238 name = "${drv.pname}-source-${drv.version}";
239 # Since we disable the haddock phase, we also need to override the
240 # outputs since the separate doc output will not be produced.
241 outputs = ["out"];
242 buildPhase = "./Setup sdist";
243 haddockPhase = ":";
244 checkPhase = ":";
245 installPhase = "install -D dist/${drv.pname}-*.tar.gz $out/${drv.pname}-${drv.version}.tar.gz";
246 fixupPhase = ":";
247 });
248
249 /* Create a documentation tarball suitable for uploading to Hackage instead
250 of building the package.
251 */
252 documentationTarball = pkg:
253 pkgs.lib.overrideDerivation pkg (drv: {
254 name = "${drv.name}-docs";
255 # Like sdistTarball, disable the "doc" output here.
256 outputs = [ "out" ];
257 buildPhase = ''
258 runHook preHaddock
259 ./Setup haddock --for-hackage
260 runHook postHaddock
261 '';
262 haddockPhase = ":";
263 checkPhase = ":";
264 installPhase = ''
265 runHook preInstall
266 mkdir -p "$out"
267 tar --format=ustar \
268 -czf "$out/${drv.name}-docs.tar.gz" \
269 -C dist/doc/html "${drv.name}-docs"
270 runHook postInstall
271 '';
272 });
273
274 /* Use the gold linker. It is a linker for ELF that is designed
275 "to run as fast as possible on modern systems"
276 */
277 linkWithGold = appendConfigureFlag
278 "--ghc-option=-optl-fuse-ld=gold --ld-option=-fuse-ld=gold --with-ld=ld.gold";
279
280 /* link executables statically against haskell libs to reduce
281 closure size
282 */
283 justStaticExecutables = overrideCabal (drv: {
284 enableSharedExecutables = false;
285 enableLibraryProfiling = false;
286 isLibrary = false;
287 doHaddock = false;
288 postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc";
289 });
290
291 /* Build a source distribution tarball instead of using the source files
292 directly. The effect is that the package is built as if it were published
293 on hackage. This can be used as a test for the source distribution,
294 assuming the build fails when packaging mistakes are in the cabal file.
295 */
296 buildFromSdist = pkg: overrideCabal (drv: {
297 src = "${sdistTarball pkg}/${pkg.pname}-${pkg.version}.tar.gz";
298
299 # Revising and jailbreaking the cabal file has been handled in sdistTarball
300 revision = null;
301 editedCabalFile = null;
302 jailbreak = false;
303 }) pkg;
304
305 /* Build the package in a strict way to uncover potential problems.
306 This includes buildFromSdist and failOnAllWarnings.
307 */
308 buildStrictly = pkg: buildFromSdist (failOnAllWarnings pkg);
309
310 /* Disable core optimizations, significantly speeds up build time */
311 disableOptimization = appendConfigureFlag "--disable-optimization";
312
313 /* Turn on most of the compiler warnings and fail the build if any
314 of them occur. */
315 failOnAllWarnings = appendConfigureFlag "--ghc-option=-Wall --ghc-option=-Werror";
316
317 /* Add a post-build check to verify that dependencies declared in
318 the cabal file are actually used.
319
320 The first attrset argument can be used to configure the strictness
321 of this check and a list of ignored package names that would otherwise
322 cause false alarms.
323 */
324 checkUnusedPackages =
325 { ignoreEmptyImports ? false
326 , ignoreMainModule ? false
327 , ignorePackages ? []
328 } : drv :
329 overrideCabal (_drv: {
330 postBuild = with lib;
331 let args = concatStringsSep " " (
332 optional ignoreEmptyImports "--ignore-empty-imports" ++
333 optional ignoreMainModule "--ignore-main-module" ++
334 map (pkg: "--ignore-package ${pkg}") ignorePackages
335 );
336 in "${pkgs.haskellPackages.packunused}/bin/packunused" +
337 optionalString (args != "") " ${args}";
338 }) (appendConfigureFlag "--ghc-option=-ddump-minimal-imports" drv);
339
340 buildStackProject = pkgs.callPackage ../generic-stack-builder.nix { };
341
342 /* Add a dummy command to trigger a build despite an equivalent
343 earlier build that is present in the store or cache.
344 */
345 triggerRebuild = i: overrideCabal (drv: { postUnpack = ": trigger rebuild ${toString i}"; });
346
347 /* Override the sources for the package and optionaly the version.
348 This also takes of removing editedCabalFile.
349 */
350 overrideSrc = { src, version ? null }: drv:
351 overrideCabal (_: { inherit src; version = if version == null then drv.version else version; editedCabalFile = null; }) drv;
352
353 # Get all of the build inputs of a haskell package, divided by category.
354 getBuildInputs = p: p.getBuildInputs;
355
356 # Extract the haskell build inputs of a haskell package.
357 # This is useful to build environments for developing on that
358 # package.
359 getHaskellBuildInputs = p: (getBuildInputs p).haskellBuildInputs;
360
361 # Under normal evaluation, simply return the original package. Under
362 # nix-shell evaluation, return a nix-shell optimized environment.
363 shellAware = p: if lib.inNixShell then p.env else p;
364
365 ghcInfo = ghc:
366 rec { isCross = (ghc.cross or null) != null;
367 isGhcjs = ghc.isGhcjs or false;
368 nativeGhc = if isCross || isGhcjs
369 then ghc.bootPkgs.ghc
370 else ghc;
371 };
372
373 ### mkDerivation helpers
374 # These allow external users of a haskell package to extract
375 # information about how it is built in the same way that the
376 # generic haskell builder does, by reusing the same functions.
377 # Each function here has the same interface as mkDerivation and thus
378 # can be called for a given package simply by overriding the
379 # mkDerivation argument it used. See getHaskellBuildInputs above for
380 # an example of this.
381
382 # Some information about which phases should be run.
383 controlPhases = ghc: let inherit (ghcInfo ghc) isCross; in
384 { doCheck ? !isCross && (lib.versionOlder "7.4" ghc.version)
385 , doBenchmark ? false
386 , ...
387 }: { inherit doCheck doBenchmark; };
388
389 # Utility to convert a directory full of `cabal2nix`-generated files into a
390 # package override set
391 #
392 # packagesFromDirectory : { directory : Directory, ... } -> HaskellPackageOverrideSet
393 packagesFromDirectory =
394 { directory, ... }:
395
396 self: super:
397 let
398 haskellPaths = builtins.attrNames (builtins.readDir directory);
399
400 toKeyVal = file: {
401 name = builtins.replaceStrings [ ".nix" ] [ "" ] file;
402
403 value = self.callPackage (directory + "/${file}") { };
404 };
405
406 in
407 builtins.listToAttrs (map toKeyVal haskellPaths);
408
409 addOptparseApplicativeCompletionScripts = exeName: pkg:
410 builtins.trace "addOptparseApplicativeCompletionScripts is deprecated in favor of generateOptparseApplicativeCompletion. Please change ${pkg.name} to use the latter or its plural form."
411 (generateOptparseApplicativeCompletion exeName pkg);
412
413 /*
414 Modify a Haskell package to add shell completion scripts for the
415 given executable produced by it. These completion scripts will be
416 picked up automatically if the resulting derivation is installed,
417 e.g. by `nix-env -i`.
418
419 Invocation:
420 generateOptparseApplicativeCompletion command pkg
421
422
423 command: name of an executable
424 pkg: Haskell package that builds the executables
425 */
426 generateOptparseApplicativeCompletion = exeName: overrideCabal (drv: {
427 postInstall = (drv.postInstall or "") + ''
428 bashCompDir="''${!outputBin}/share/bash-completion/completions"
429 zshCompDir="''${!outputBin}/share/zsh/vendor-completions"
430 fishCompDir="''${!outputBin}/share/fish/vendor_completions.d"
431 mkdir -p "$bashCompDir" "$zshCompDir" "$fishCompDir"
432 "''${!outputBin}/bin/${exeName}" --bash-completion-script "''${!outputBin}/bin/${exeName}" >"$bashCompDir/${exeName}"
433 "''${!outputBin}/bin/${exeName}" --zsh-completion-script "''${!outputBin}/bin/${exeName}" >"$zshCompDir/_${exeName}"
434 "''${!outputBin}/bin/${exeName}" --fish-completion-script "''${!outputBin}/bin/${exeName}" >"$fishCompDir/${exeName}.fish"
435
436 # Sanity check
437 grep -F ${exeName} <$bashCompDir/${exeName} >/dev/null || {
438 echo 'Could not find ${exeName} in completion script.'
439 exit 1
440 }
441 '';
442 });
443
444 /*
445 Modify a Haskell package to add shell completion scripts for the
446 given executables produced by it. These completion scripts will be
447 picked up automatically if the resulting derivation is installed,
448 e.g. by `nix-env -i`.
449
450 Invocation:
451 generateOptparseApplicativeCompletions commands pkg
452
453
454 commands: name of an executable
455 pkg: Haskell package that builds the executables
456 */
457 generateOptparseApplicativeCompletions = commands: pkg:
458 pkgs.lib.foldr generateOptparseApplicativeCompletion pkg commands;
459
460 # Don't fail at configure time if there are multiple versions of the
461 # same package in the (recursive) dependencies of the package being
462 # built. Will delay failures, if any, to compile time.
463 allowInconsistentDependencies = overrideCabal (drv: {
464 allowInconsistentDependencies = true;
465 });
466}