nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at 21.11 466 lines 19 kB view raw
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}