1# TODO(@Ericson2314): Remove `pkgs` param, which is only used for
2# `buildStackProject`, `justStaticExecutables` and `checkUnusedPackages`
3{ pkgs, lib }:
4
5rec {
6 makePackageSet = import ./make-package-set.nix;
7
8 overrideCabal = drv: f: (drv.override (args: args // {
9 mkDerivation = drv: (args.mkDerivation drv).override f;
10 })) // {
11 overrideScope = scope: overrideCabal (drv.overrideScope scope) f;
12 };
13
14 doCoverage = drv: overrideCabal drv (drv: { doCoverage = true; });
15 dontCoverage = drv: overrideCabal drv (drv: { doCoverage = false; });
16
17 doHaddock = drv: overrideCabal drv (drv: { doHaddock = true; });
18 dontHaddock = drv: overrideCabal drv (drv: { doHaddock = false; });
19
20 doJailbreak = drv: overrideCabal drv (drv: { jailbreak = true; });
21 dontJailbreak = drv: overrideCabal drv (drv: { jailbreak = false; });
22
23 doCheck = drv: overrideCabal drv (drv: { doCheck = true; });
24 dontCheck = drv: overrideCabal drv (drv: { doCheck = false; });
25
26 doDistribute = drv: overrideCabal drv (drv: { hydraPlatforms = drv.platforms or ["i686-linux" "x86_64-linux" "x86_64-darwin"]; });
27 dontDistribute = drv: overrideCabal drv (drv: { hydraPlatforms = []; });
28
29 appendConfigureFlag = drv: x: overrideCabal drv (drv: { configureFlags = (drv.configureFlags or []) ++ [x]; });
30 removeConfigureFlag = drv: x: overrideCabal drv (drv: { configureFlags = lib.remove x (drv.configureFlags or []); });
31
32 addBuildTool = drv: x: addBuildTools drv [x];
33 addBuildTools = drv: xs: overrideCabal drv (drv: { buildTools = (drv.buildTools or []) ++ xs; });
34
35 addExtraLibrary = drv: x: addExtraLibraries drv [x];
36 addExtraLibraries = drv: xs: overrideCabal drv (drv: { extraLibraries = (drv.extraLibraries or []) ++ xs; });
37
38 addBuildDepend = drv: x: addBuildDepends drv [x];
39 addBuildDepends = drv: xs: overrideCabal drv (drv: { buildDepends = (drv.buildDepends or []) ++ xs; });
40
41 addPkgconfigDepend = drv: x: addPkgconfigDepends drv [x];
42 addPkgconfigDepends = drv: xs: overrideCabal drv (drv: { pkgconfigDepends = (drv.pkgconfigDepends or []) ++ xs; });
43
44 addSetupDepend = drv: x: addSetupDepends drv [x];
45 addSetupDepends = drv: xs: overrideCabal drv (drv: { setupHaskellDepends = (drv.setupHaskellDepends or []) ++ xs; });
46
47 enableCabalFlag = drv: x: appendConfigureFlag (removeConfigureFlag drv "-f-${x}") "-f${x}";
48 disableCabalFlag = drv: x: appendConfigureFlag (removeConfigureFlag drv "-f${x}") "-f-${x}";
49
50 markBroken = drv: overrideCabal drv (drv: { broken = true; });
51 markBrokenVersion = version: drv: assert drv.version == version; markBroken drv;
52
53 enableLibraryProfiling = drv: overrideCabal drv (drv: { enableLibraryProfiling = true; });
54 disableLibraryProfiling = drv: overrideCabal drv (drv: { enableLibraryProfiling = false; });
55
56 enableSharedExecutables = drv: overrideCabal drv (drv: { enableSharedExecutables = true; });
57 disableSharedExecutables = drv: overrideCabal drv (drv: { enableSharedExecutables = false; });
58
59 enableSharedLibraries = drv: overrideCabal drv (drv: { enableSharedLibraries = true; });
60 disableSharedLibraries = drv: overrideCabal drv (drv: { enableSharedLibraries = false; });
61
62 enableDeadCodeElimination = drv: overrideCabal drv (drv: { enableDeadCodeElimination = true; });
63 disableDeadCodeElimination = drv: overrideCabal drv (drv: { enableDeadCodeElimination = false; });
64
65 enableStaticLibraries = drv: overrideCabal drv (drv: { enableStaticLibraries = true; });
66 disableStaticLibraries = drv: overrideCabal drv (drv: { enableStaticLibraries = false; });
67
68 appendPatch = drv: x: appendPatches drv [x];
69 appendPatches = drv: xs: overrideCabal drv (drv: { patches = (drv.patches or []) ++ xs; });
70
71 doHyperlinkSource = drv: overrideCabal drv (drv: { hyperlinkSource = true; });
72 dontHyperlinkSource = drv: overrideCabal drv (drv: { hyperlinkSource = false; });
73
74 disableHardening = drv: flags: overrideCabal drv (drv: { hardeningDisable = flags; });
75
76 sdistTarball = pkg: lib.overrideDerivation pkg (drv: {
77 name = "${drv.pname}-source-${drv.version}";
78 # Since we disable the haddock phase, we also need to override the
79 # outputs since the separate doc output will not be produced.
80 outputs = ["out"];
81 buildPhase = "./Setup sdist";
82 haddockPhase = ":";
83 checkPhase = ":";
84 installPhase = "install -D dist/${drv.pname}-*.tar.gz $out/${drv.pname}-${drv.version}.tar.gz";
85 fixupPhase = ":";
86 });
87
88 linkWithGold = drv : appendConfigureFlag drv
89 "--ghc-option=-optl-fuse-ld=gold --ld-option=-fuse-ld=gold --with-ld=ld.gold";
90
91 # link executables statically against haskell libs to reduce closure size
92 justStaticExecutables = drv: overrideCabal drv (drv: {
93 enableSharedExecutables = false;
94 isLibrary = false;
95 doHaddock = false;
96 postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc";
97 } // lib.optionalAttrs (pkgs.hostPlatform.isDarwin) {
98 configureFlags = (drv.configureFlags or []) ++ ["--ghc-option=-optl=-dead_strip"];
99 });
100
101 buildFromSdist = pkg: lib.overrideDerivation pkg (drv: {
102 unpackPhase = let src = sdistTarball pkg; tarname = "${pkg.pname}-${pkg.version}"; in ''
103 echo "Source tarball is at ${src}/${tarname}.tar.gz"
104 tar xf ${src}/${tarname}.tar.gz
105 cd ${pkg.pname}-*
106 '';
107 });
108
109 buildStrictly = pkg: buildFromSdist (appendConfigureFlag pkg "--ghc-option=-Wall --ghc-option=-Werror");
110
111 checkUnusedPackages =
112 { ignoreEmptyImports ? false
113 , ignoreMainModule ? false
114 , ignorePackages ? []
115 } : drv :
116 overrideCabal (appendConfigureFlag drv "--ghc-option=-ddump-minimal-imports") (_drv: {
117 postBuild = with lib;
118 let args = concatStringsSep " " (
119 optional ignoreEmptyImports "--ignore-empty-imports" ++
120 optional ignoreMainModule "--ignore-main-module" ++
121 map (pkg: "--ignore-package ${pkg}") ignorePackages
122 );
123 in "${pkgs.haskellPackages.packunused}/bin/packunused" +
124 optionalString (args != "") " ${args}";
125 });
126
127 buildStackProject = pkgs.callPackage ./generic-stack-builder.nix { };
128
129 triggerRebuild = drv: i: overrideCabal drv (drv: { postUnpack = ": trigger rebuild ${toString i}"; });
130
131 overrideSrc = drv: { src, version ? drv.version }:
132 overrideCabal drv (_: { inherit src version; editedCabalFile = null; });
133
134}