haskell.lib.compose: init
No changes in derivations for pkgs.haskellPackages
This commit is contained in:
parent
8b7c314eae
commit
518f09f2d0
2 changed files with 557 additions and 201 deletions
|
@ -3,10 +3,18 @@
|
||||||
{ pkgs, lib }:
|
{ pkgs, lib }:
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
/* The same functionality as this haskell.lib, except that the derivation
|
||||||
|
being overridden is always the last parameter. This permits more natural
|
||||||
|
composition of several overrides, i.e. without having to nestle one call
|
||||||
|
between the function name and argument of another. haskell.lib.compose is
|
||||||
|
preferred for any new code.
|
||||||
|
*/
|
||||||
|
compose = import ./lib/compose.nix { inherit pkgs lib; };
|
||||||
|
|
||||||
/* This function takes a file like `hackage-packages.nix` and constructs
|
/* This function takes a file like `hackage-packages.nix` and constructs
|
||||||
a full package set out of that.
|
a full package set out of that.
|
||||||
*/
|
*/
|
||||||
makePackageSet = import ./make-package-set.nix;
|
makePackageSet = compose.makePackageSet;
|
||||||
|
|
||||||
/* The function overrideCabal lets you alter the arguments to the
|
/* The function overrideCabal lets you alter the arguments to the
|
||||||
mkDerivation function.
|
mkDerivation function.
|
||||||
|
@ -34,47 +42,37 @@ rec {
|
||||||
"https://github.com/bos/aeson#readme"
|
"https://github.com/bos/aeson#readme"
|
||||||
|
|
||||||
*/
|
*/
|
||||||
overrideCabal = drv: f: (drv.override (args: args // {
|
overrideCabal = drv: f: compose.overrideCabal f drv;
|
||||||
mkDerivation = drv: (args.mkDerivation drv).override f;
|
|
||||||
})) // {
|
|
||||||
overrideScope = scope: overrideCabal (drv.overrideScope scope) f;
|
|
||||||
};
|
|
||||||
|
|
||||||
# : Map Name (Either Path VersionNumber) -> HaskellPackageOverrideSet
|
# : Map Name (Either Path VersionNumber) -> HaskellPackageOverrideSet
|
||||||
# Given a set whose values are either paths or version strings, produces
|
# Given a set whose values are either paths or version strings, produces
|
||||||
# a package override set (i.e. (self: super: { etc. })) that sets
|
# a package override set (i.e. (self: super: { etc. })) that sets
|
||||||
# the packages named in the input set to the corresponding versions
|
# the packages named in the input set to the corresponding versions
|
||||||
packageSourceOverrides =
|
packageSourceOverrides = compose.packageSourceOverrides;
|
||||||
overrides: self: super: pkgs.lib.mapAttrs (name: src:
|
|
||||||
let isPath = x: builtins.substring 0 1 (toString x) == "/";
|
|
||||||
generateExprs = if isPath src
|
|
||||||
then self.callCabal2nix
|
|
||||||
else self.callHackage;
|
|
||||||
in generateExprs name src {}) overrides;
|
|
||||||
|
|
||||||
/* doCoverage modifies a haskell package to enable the generation
|
/* doCoverage modifies a haskell package to enable the generation
|
||||||
and installation of a coverage report.
|
and installation of a coverage report.
|
||||||
|
|
||||||
See https://wiki.haskell.org/Haskell_program_coverage
|
See https://wiki.haskell.org/Haskell_program_coverage
|
||||||
*/
|
*/
|
||||||
doCoverage = drv: overrideCabal drv (drv: { doCoverage = true; });
|
doCoverage = compose.doCoverage;
|
||||||
|
|
||||||
/* dontCoverage modifies a haskell package to disable the generation
|
/* dontCoverage modifies a haskell package to disable the generation
|
||||||
and installation of a coverage report.
|
and installation of a coverage report.
|
||||||
*/
|
*/
|
||||||
dontCoverage = drv: overrideCabal drv (drv: { doCoverage = false; });
|
dontCoverage = compose.dontCoverage;
|
||||||
|
|
||||||
/* doHaddock modifies a haskell package to enable the generation and
|
/* doHaddock modifies a haskell package to enable the generation and
|
||||||
installation of API documentation from code comments using the
|
installation of API documentation from code comments using the
|
||||||
haddock tool.
|
haddock tool.
|
||||||
*/
|
*/
|
||||||
doHaddock = drv: overrideCabal drv (drv: { doHaddock = true; });
|
doHaddock = compose.doHaddock;
|
||||||
|
|
||||||
/* dontHaddock modifies a haskell package to disable the generation and
|
/* dontHaddock modifies a haskell package to disable the generation and
|
||||||
installation of API documentation from code comments using the
|
installation of API documentation from code comments using the
|
||||||
haddock tool.
|
haddock tool.
|
||||||
*/
|
*/
|
||||||
dontHaddock = drv: overrideCabal drv (drv: { doHaddock = false; });
|
dontHaddock = compose.dontHaddock;
|
||||||
|
|
||||||
/* doJailbreak enables the removal of version bounds from the cabal
|
/* doJailbreak enables the removal of version bounds from the cabal
|
||||||
file. You may want to avoid this function.
|
file. You may want to avoid this function.
|
||||||
|
@ -92,39 +90,39 @@ rec {
|
||||||
https://github.com/peti/jailbreak-cabal/issues/7 has further details.
|
https://github.com/peti/jailbreak-cabal/issues/7 has further details.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
doJailbreak = drv: overrideCabal drv (drv: { jailbreak = true; });
|
doJailbreak = compose.doJailbreak;
|
||||||
|
|
||||||
/* dontJailbreak restores the use of the version bounds the check
|
/* dontJailbreak restores the use of the version bounds the check
|
||||||
the use of dependencies in the package description.
|
the use of dependencies in the package description.
|
||||||
*/
|
*/
|
||||||
dontJailbreak = drv: overrideCabal drv (drv: { jailbreak = false; });
|
dontJailbreak = compose.dontJailbreak;
|
||||||
|
|
||||||
/* doCheck enables dependency checking, compilation and execution
|
/* doCheck enables dependency checking, compilation and execution
|
||||||
of test suites listed in the package description file.
|
of test suites listed in the package description file.
|
||||||
*/
|
*/
|
||||||
doCheck = drv: overrideCabal drv (drv: { doCheck = true; });
|
doCheck = compose.doCheck;
|
||||||
/* dontCheck disables dependency checking, compilation and execution
|
/* dontCheck disables dependency checking, compilation and execution
|
||||||
of test suites listed in the package description file.
|
of test suites listed in the package description file.
|
||||||
*/
|
*/
|
||||||
dontCheck = drv: overrideCabal drv (drv: { doCheck = false; });
|
dontCheck = compose.dontCheck;
|
||||||
|
|
||||||
/* doBenchmark enables dependency checking, compilation and execution
|
/* doBenchmark enables dependency checking, compilation and execution
|
||||||
for benchmarks listed in the package description file.
|
for benchmarks listed in the package description file.
|
||||||
*/
|
*/
|
||||||
doBenchmark = drv: overrideCabal drv (drv: { doBenchmark = true; });
|
doBenchmark = compose.doBenchmark;
|
||||||
/* dontBenchmark disables dependency checking, compilation and execution
|
/* dontBenchmark disables dependency checking, compilation and execution
|
||||||
for benchmarks listed in the package description file.
|
for benchmarks listed in the package description file.
|
||||||
*/
|
*/
|
||||||
dontBenchmark = drv: overrideCabal drv (drv: { doBenchmark = false; });
|
dontBenchmark = compose.dontBenchmark;
|
||||||
|
|
||||||
/* doDistribute enables the distribution of binaries for the package
|
/* doDistribute enables the distribution of binaries for the package
|
||||||
via hydra.
|
via hydra.
|
||||||
*/
|
*/
|
||||||
doDistribute = drv: overrideCabal drv (drv: { hydraPlatforms = drv.platforms or ["i686-linux" "x86_64-linux" "x86_64-darwin"]; });
|
doDistribute = compose.doDistribute;
|
||||||
/* dontDistribute disables the distribution of binaries for the package
|
/* dontDistribute disables the distribution of binaries for the package
|
||||||
via hydra.
|
via hydra.
|
||||||
*/
|
*/
|
||||||
dontDistribute = drv: overrideCabal drv (drv: { hydraPlatforms = []; });
|
dontDistribute = compose.dontDistribute;
|
||||||
|
|
||||||
/* appendConfigureFlag adds a single argument that will be passed to the
|
/* appendConfigureFlag adds a single argument that will be passed to the
|
||||||
cabal configure command, after the arguments that have been defined
|
cabal configure command, after the arguments that have been defined
|
||||||
|
@ -134,67 +132,67 @@ rec {
|
||||||
|
|
||||||
> haskell.lib.appendConfigureFlag haskellPackages.servant "--profiling-detail=all-functions"
|
> haskell.lib.appendConfigureFlag haskellPackages.servant "--profiling-detail=all-functions"
|
||||||
*/
|
*/
|
||||||
appendConfigureFlag = drv: x: appendConfigureFlags drv [x];
|
appendConfigureFlag = drv: x: compose.appendConfigureFlag x drv;
|
||||||
appendConfigureFlags = drv: xs: overrideCabal drv (drv: { configureFlags = (drv.configureFlags or []) ++ xs; });
|
appendConfigureFlags = drv: xs: compose.appendConfigureFlags xs drv;
|
||||||
|
|
||||||
appendBuildFlag = drv: x: overrideCabal drv (drv: { buildFlags = (drv.buildFlags or []) ++ [x]; });
|
appendBuildFlag = drv: x: compose.appendBuildFlag x drv;
|
||||||
appendBuildFlags = drv: xs: overrideCabal drv (drv: { buildFlags = (drv.buildFlags or []) ++ xs; });
|
appendBuildFlags = drv: xs: compose.appendBuildFlags xs drv;
|
||||||
|
|
||||||
/* removeConfigureFlag drv x is a Haskell package like drv, but with
|
/* removeConfigureFlag drv x is a Haskell package like drv, but with
|
||||||
all cabal configure arguments that are equal to x removed.
|
all cabal configure arguments that are equal to x removed.
|
||||||
|
|
||||||
> haskell.lib.removeConfigureFlag haskellPackages.servant "--verbose"
|
> haskell.lib.removeConfigureFlag haskellPackages.servant "--verbose"
|
||||||
*/
|
*/
|
||||||
removeConfigureFlag = drv: x: overrideCabal drv (drv: { configureFlags = lib.remove x (drv.configureFlags or []); });
|
removeConfigureFlag = drv: x: compose.removeConfigureFlag x drv;
|
||||||
|
|
||||||
addBuildTool = drv: x: addBuildTools drv [x];
|
addBuildTool = drv: x: compose.addBuildTool x drv;
|
||||||
addBuildTools = drv: xs: overrideCabal drv (drv: { buildTools = (drv.buildTools or []) ++ xs; });
|
addBuildTools = drv: xs: compose.addBuildTools xs drv;
|
||||||
|
|
||||||
addExtraLibrary = drv: x: addExtraLibraries drv [x];
|
addExtraLibrary = drv: x: compose.addExtraLibrary x drv;
|
||||||
addExtraLibraries = drv: xs: overrideCabal drv (drv: { extraLibraries = (drv.extraLibraries or []) ++ xs; });
|
addExtraLibraries = drv: xs: compose.addExtraLibraries xs drv;
|
||||||
|
|
||||||
addBuildDepend = drv: x: addBuildDepends drv [x];
|
addBuildDepend = drv: x: compose.addBuildDepend x drv;
|
||||||
addBuildDepends = drv: xs: overrideCabal drv (drv: { buildDepends = (drv.buildDepends or []) ++ xs; });
|
addBuildDepends = drv: xs: compose.addBuildDepends xs drv;
|
||||||
|
|
||||||
addTestToolDepend = drv: x: addTestToolDepends drv [x];
|
addTestToolDepend = drv: x: compose.addTestToolDepend x drv;
|
||||||
addTestToolDepends = drv: xs: overrideCabal drv (drv: { testToolDepends = (drv.testToolDepends or []) ++ xs; });
|
addTestToolDepends = drv: xs: compose.addTestToolDepends xs drv;
|
||||||
|
|
||||||
addPkgconfigDepend = drv: x: addPkgconfigDepends drv [x];
|
addPkgconfigDepend = drv: x: compose.addPkgconfigDepend x drv;
|
||||||
addPkgconfigDepends = drv: xs: overrideCabal drv (drv: { pkg-configDepends = (drv.pkg-configDepends or []) ++ xs; });
|
addPkgconfigDepends = drv: xs: compose.addPkgconfigDepends xs drv;
|
||||||
|
|
||||||
addSetupDepend = drv: x: addSetupDepends drv [x];
|
addSetupDepend = drv: x: compose.addSetupDepend x drv;
|
||||||
addSetupDepends = drv: xs: overrideCabal drv (drv: { setupHaskellDepends = (drv.setupHaskellDepends or []) ++ xs; });
|
addSetupDepends = drv: xs: compose.addSetupDepends xs drv;
|
||||||
|
|
||||||
enableCabalFlag = drv: x: appendConfigureFlag (removeConfigureFlag drv "-f-${x}") "-f${x}";
|
enableCabalFlag = drv: x: compose.enableCabalFlag x drv;
|
||||||
disableCabalFlag = drv: x: appendConfigureFlag (removeConfigureFlag drv "-f${x}") "-f-${x}";
|
disableCabalFlag = drv: x: compose.disableCabalFlag x drv;
|
||||||
|
|
||||||
markBroken = drv: overrideCabal drv (drv: { broken = true; hydraPlatforms = []; });
|
markBroken = compose.markBroken;
|
||||||
unmarkBroken = drv: overrideCabal drv (drv: { broken = false; });
|
unmarkBroken = compose.unmarkBroken;
|
||||||
markBrokenVersion = version: drv: assert drv.version == version; markBroken drv;
|
markBrokenVersion = compose.markBrokenVersion;
|
||||||
markUnbroken = drv: overrideCabal drv (drv: { broken = false; });
|
markUnbroken = compose.markUnbroken;
|
||||||
|
|
||||||
enableLibraryProfiling = drv: overrideCabal drv (drv: { enableLibraryProfiling = true; });
|
enableLibraryProfiling = compose.enableLibraryProfiling;
|
||||||
disableLibraryProfiling = drv: overrideCabal drv (drv: { enableLibraryProfiling = false; });
|
disableLibraryProfiling = compose.disableLibraryProfiling;
|
||||||
|
|
||||||
enableExecutableProfiling = drv: overrideCabal drv (drv: { enableExecutableProfiling = true; });
|
enableExecutableProfiling = compose.enableExecutableProfiling;
|
||||||
disableExecutableProfiling = drv: overrideCabal drv (drv: { enableExecutableProfiling = false; });
|
disableExecutableProfiling = compose.disableExecutableProfiling;
|
||||||
|
|
||||||
enableSharedExecutables = drv: overrideCabal drv (drv: { enableSharedExecutables = true; });
|
enableSharedExecutables = compose.enableSharedExecutables;
|
||||||
disableSharedExecutables = drv: overrideCabal drv (drv: { enableSharedExecutables = false; });
|
disableSharedExecutables = compose.disableSharedExecutables;
|
||||||
|
|
||||||
enableSharedLibraries = drv: overrideCabal drv (drv: { enableSharedLibraries = true; });
|
enableSharedLibraries = compose.enableSharedLibraries;
|
||||||
disableSharedLibraries = drv: overrideCabal drv (drv: { enableSharedLibraries = false; });
|
disableSharedLibraries = compose.disableSharedLibraries;
|
||||||
|
|
||||||
enableDeadCodeElimination = drv: overrideCabal drv (drv: { enableDeadCodeElimination = true; });
|
enableDeadCodeElimination = compose.enableDeadCodeElimination;
|
||||||
disableDeadCodeElimination = drv: overrideCabal drv (drv: { enableDeadCodeElimination = false; });
|
disableDeadCodeElimination = compose.disableDeadCodeElimination;
|
||||||
|
|
||||||
enableStaticLibraries = drv: overrideCabal drv (drv: { enableStaticLibraries = true; });
|
enableStaticLibraries = compose.enableStaticLibraries;
|
||||||
disableStaticLibraries = drv: overrideCabal drv (drv: { enableStaticLibraries = false; });
|
disableStaticLibraries = compose.disableStaticLibraries;
|
||||||
|
|
||||||
enableSeparateBinOutput = drv: overrideCabal drv (drv: { enableSeparateBinOutput = true; });
|
enableSeparateBinOutput = compose.enableSeparateBinOutput;
|
||||||
|
|
||||||
appendPatch = drv: x: appendPatches drv [x];
|
appendPatch = drv: x: compose.appendPatch x drv;
|
||||||
appendPatches = drv: xs: overrideCabal drv (drv: { patches = (drv.patches or []) ++ xs; });
|
appendPatches = drv: xs: compose.appendPatches xs drv;
|
||||||
|
|
||||||
/* Set a specific build target instead of compiling all targets in the package.
|
/* Set a specific build target instead of compiling all targets in the package.
|
||||||
* For example, imagine we have a .cabal file with a library, and 2 executables "dev" and "server".
|
* For example, imagine we have a .cabal file with a library, and 2 executables "dev" and "server".
|
||||||
|
@ -203,115 +201,67 @@ rec {
|
||||||
* setBuildTarget (callCabal2nix "thePackageName" thePackageSrc {}) "server"
|
* setBuildTarget (callCabal2nix "thePackageName" thePackageSrc {}) "server"
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
setBuildTargets = drv: xs: overrideCabal drv (drv: { buildTarget = lib.concatStringsSep " " xs; });
|
setBuildTargets = drv: xs: compose.setBuildTargets xs drv;
|
||||||
setBuildTarget = drv: x: setBuildTargets drv [x];
|
setBuildTarget = drv: x: compose.setBuildTarget x drv;
|
||||||
|
|
||||||
doHyperlinkSource = drv: overrideCabal drv (drv: { hyperlinkSource = true; });
|
doHyperlinkSource = compose.doHyperlinkSource;
|
||||||
dontHyperlinkSource = drv: overrideCabal drv (drv: { hyperlinkSource = false; });
|
dontHyperlinkSource = compose.dontHyperlinkSource;
|
||||||
|
|
||||||
disableHardening = drv: flags: overrideCabal drv (drv: { hardeningDisable = flags; });
|
disableHardening = drv: flags: compose.disableHardening flags drv;
|
||||||
|
|
||||||
/* Let Nix strip the binary files.
|
/* Let Nix strip the binary files.
|
||||||
* This removes debugging symbols.
|
* This removes debugging symbols.
|
||||||
*/
|
*/
|
||||||
doStrip = drv: overrideCabal drv (drv: { dontStrip = false; });
|
doStrip = compose.doStrip;
|
||||||
|
|
||||||
/* Stop Nix from stripping the binary files.
|
/* Stop Nix from stripping the binary files.
|
||||||
* This keeps debugging symbols.
|
* This keeps debugging symbols.
|
||||||
*/
|
*/
|
||||||
dontStrip = drv: overrideCabal drv (drv: { dontStrip = true; });
|
dontStrip = compose.dontStrip;
|
||||||
|
|
||||||
/* Useful for debugging segfaults with gdb.
|
/* Useful for debugging segfaults with gdb.
|
||||||
* This includes dontStrip.
|
* This includes dontStrip.
|
||||||
*/
|
*/
|
||||||
enableDWARFDebugging = drv:
|
enableDWARFDebugging = compose.enableDWARFDebugging;
|
||||||
# -g: enables debugging symbols
|
|
||||||
# --disable-*-stripping: tell GHC not to strip resulting binaries
|
|
||||||
# dontStrip: see above
|
|
||||||
appendConfigureFlag (dontStrip drv) "--ghc-options=-g --disable-executable-stripping --disable-library-stripping";
|
|
||||||
|
|
||||||
/* Create a source distribution tarball like those found on hackage,
|
/* Create a source distribution tarball like those found on hackage,
|
||||||
instead of building the package.
|
instead of building the package.
|
||||||
*/
|
*/
|
||||||
sdistTarball = pkg: lib.overrideDerivation pkg (drv: {
|
sdistTarball = compose.sdistTarball;
|
||||||
name = "${drv.pname}-source-${drv.version}";
|
|
||||||
# Since we disable the haddock phase, we also need to override the
|
|
||||||
# outputs since the separate doc output will not be produced.
|
|
||||||
outputs = ["out"];
|
|
||||||
buildPhase = "./Setup sdist";
|
|
||||||
haddockPhase = ":";
|
|
||||||
checkPhase = ":";
|
|
||||||
installPhase = "install -D dist/${drv.pname}-*.tar.gz $out/${drv.pname}-${drv.version}.tar.gz";
|
|
||||||
fixupPhase = ":";
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Create a documentation tarball suitable for uploading to Hackage instead
|
/* Create a documentation tarball suitable for uploading to Hackage instead
|
||||||
of building the package.
|
of building the package.
|
||||||
*/
|
*/
|
||||||
documentationTarball = pkg:
|
documentationTarball = compose.documentationTarball;
|
||||||
pkgs.lib.overrideDerivation pkg (drv: {
|
|
||||||
name = "${drv.name}-docs";
|
|
||||||
# Like sdistTarball, disable the "doc" output here.
|
|
||||||
outputs = [ "out" ];
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preHaddock
|
|
||||||
./Setup haddock --for-hackage
|
|
||||||
runHook postHaddock
|
|
||||||
'';
|
|
||||||
haddockPhase = ":";
|
|
||||||
checkPhase = ":";
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
mkdir -p "$out"
|
|
||||||
tar --format=ustar \
|
|
||||||
-czf "$out/${drv.name}-docs.tar.gz" \
|
|
||||||
-C dist/doc/html "${drv.name}-docs"
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Use the gold linker. It is a linker for ELF that is designed
|
/* Use the gold linker. It is a linker for ELF that is designed
|
||||||
"to run as fast as possible on modern systems"
|
"to run as fast as possible on modern systems"
|
||||||
*/
|
*/
|
||||||
linkWithGold = drv : appendConfigureFlag drv
|
linkWithGold = compose.linkWithGold;
|
||||||
"--ghc-option=-optl-fuse-ld=gold --ld-option=-fuse-ld=gold --with-ld=ld.gold";
|
|
||||||
|
|
||||||
/* link executables statically against haskell libs to reduce
|
/* link executables statically against haskell libs to reduce
|
||||||
closure size
|
closure size
|
||||||
*/
|
*/
|
||||||
justStaticExecutables = drv: overrideCabal drv (drv: {
|
justStaticExecutables = compose.justStaticExecutables;
|
||||||
enableSharedExecutables = false;
|
|
||||||
enableLibraryProfiling = false;
|
|
||||||
isLibrary = false;
|
|
||||||
doHaddock = false;
|
|
||||||
postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc";
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Build a source distribution tarball instead of using the source files
|
/* Build a source distribution tarball instead of using the source files
|
||||||
directly. The effect is that the package is built as if it were published
|
directly. The effect is that the package is built as if it were published
|
||||||
on hackage. This can be used as a test for the source distribution,
|
on hackage. This can be used as a test for the source distribution,
|
||||||
assuming the build fails when packaging mistakes are in the cabal file.
|
assuming the build fails when packaging mistakes are in the cabal file.
|
||||||
*/
|
*/
|
||||||
buildFromSdist = pkg: overrideCabal pkg (drv: {
|
buildFromSdist = compose.buildFromSdist;
|
||||||
src = "${sdistTarball pkg}/${pkg.pname}-${pkg.version}.tar.gz";
|
|
||||||
|
|
||||||
# Revising and jailbreaking the cabal file has been handled in sdistTarball
|
|
||||||
revision = null;
|
|
||||||
editedCabalFile = null;
|
|
||||||
jailbreak = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Build the package in a strict way to uncover potential problems.
|
/* Build the package in a strict way to uncover potential problems.
|
||||||
This includes buildFromSdist and failOnAllWarnings.
|
This includes buildFromSdist and failOnAllWarnings.
|
||||||
*/
|
*/
|
||||||
buildStrictly = pkg: buildFromSdist (failOnAllWarnings pkg);
|
buildStrictly = compose.buildStrictly;
|
||||||
|
|
||||||
/* Disable core optimizations, significantly speeds up build time */
|
/* Disable core optimizations, significantly speeds up build time */
|
||||||
disableOptimization = pkg: appendConfigureFlag pkg "--disable-optimization";
|
disableOptimization = compose.disableOptimization;
|
||||||
|
|
||||||
/* Turn on most of the compiler warnings and fail the build if any
|
/* Turn on most of the compiler warnings and fail the build if any
|
||||||
of them occur. */
|
of them occur. */
|
||||||
failOnAllWarnings = drv: appendConfigureFlag drv "--ghc-option=-Wall --ghc-option=-Werror";
|
failOnAllWarnings = compose.failOnAllWarnings;
|
||||||
|
|
||||||
/* Add a post-build check to verify that dependencies declared in
|
/* Add a post-build check to verify that dependencies declared in
|
||||||
the cabal file are actually used.
|
the cabal file are actually used.
|
||||||
|
@ -320,54 +270,33 @@ rec {
|
||||||
of this check and a list of ignored package names that would otherwise
|
of this check and a list of ignored package names that would otherwise
|
||||||
cause false alarms.
|
cause false alarms.
|
||||||
*/
|
*/
|
||||||
checkUnusedPackages =
|
checkUnusedPackages = compose.checkUnusedPackages;
|
||||||
{ ignoreEmptyImports ? false
|
|
||||||
, ignoreMainModule ? false
|
|
||||||
, ignorePackages ? []
|
|
||||||
} : drv :
|
|
||||||
overrideCabal (appendConfigureFlag drv "--ghc-option=-ddump-minimal-imports") (_drv: {
|
|
||||||
postBuild = with lib;
|
|
||||||
let args = concatStringsSep " " (
|
|
||||||
optional ignoreEmptyImports "--ignore-empty-imports" ++
|
|
||||||
optional ignoreMainModule "--ignore-main-module" ++
|
|
||||||
map (pkg: "--ignore-package ${pkg}") ignorePackages
|
|
||||||
);
|
|
||||||
in "${pkgs.haskellPackages.packunused}/bin/packunused" +
|
|
||||||
optionalString (args != "") " ${args}";
|
|
||||||
});
|
|
||||||
|
|
||||||
buildStackProject = pkgs.callPackage ./generic-stack-builder.nix { };
|
buildStackProject = compose.buildStackProject;
|
||||||
|
|
||||||
/* Add a dummy command to trigger a build despite an equivalent
|
/* Add a dummy command to trigger a build despite an equivalent
|
||||||
earlier build that is present in the store or cache.
|
earlier build that is present in the store or cache.
|
||||||
*/
|
*/
|
||||||
triggerRebuild = drv: i: overrideCabal drv (drv: { postUnpack = ": trigger rebuild ${toString i}"; });
|
triggerRebuild = drv: i: compose.triggerRebuild i drv;
|
||||||
|
|
||||||
/* Override the sources for the package and optionaly the version.
|
/* Override the sources for the package and optionaly the version.
|
||||||
This also takes of removing editedCabalFile.
|
This also takes of removing editedCabalFile.
|
||||||
*/
|
*/
|
||||||
overrideSrc = drv: { src, version ? drv.version }:
|
overrideSrc = drv: src: compose.overrideSrc src drv;
|
||||||
overrideCabal drv (_: { inherit src version; editedCabalFile = null; });
|
|
||||||
|
|
||||||
# Get all of the build inputs of a haskell package, divided by category.
|
# Get all of the build inputs of a haskell package, divided by category.
|
||||||
getBuildInputs = p: p.getBuildInputs;
|
getBuildInputs = compose.getBuildInputs;
|
||||||
|
|
||||||
# Extract the haskell build inputs of a haskell package.
|
# Extract the haskell build inputs of a haskell package.
|
||||||
# This is useful to build environments for developing on that
|
# This is useful to build environments for developing on that
|
||||||
# package.
|
# package.
|
||||||
getHaskellBuildInputs = p: (getBuildInputs p).haskellBuildInputs;
|
getHaskellBuildInputs = compose.getHaskellBuildInputs;
|
||||||
|
|
||||||
# Under normal evaluation, simply return the original package. Under
|
# Under normal evaluation, simply return the original package. Under
|
||||||
# nix-shell evaluation, return a nix-shell optimized environment.
|
# nix-shell evaluation, return a nix-shell optimized environment.
|
||||||
shellAware = p: if lib.inNixShell then p.env else p;
|
shellAware = compose.shellAware;
|
||||||
|
|
||||||
ghcInfo = ghc:
|
ghcInfo = compose.ghcInfo;
|
||||||
rec { isCross = (ghc.cross or null) != null;
|
|
||||||
isGhcjs = ghc.isGhcjs or false;
|
|
||||||
nativeGhc = if isCross || isGhcjs
|
|
||||||
then ghc.bootPkgs.ghc
|
|
||||||
else ghc;
|
|
||||||
};
|
|
||||||
|
|
||||||
### mkDerivation helpers
|
### mkDerivation helpers
|
||||||
# These allow external users of a haskell package to extract
|
# These allow external users of a haskell package to extract
|
||||||
|
@ -379,35 +308,15 @@ rec {
|
||||||
# an example of this.
|
# an example of this.
|
||||||
|
|
||||||
# Some information about which phases should be run.
|
# Some information about which phases should be run.
|
||||||
controlPhases = ghc: let inherit (ghcInfo ghc) isCross; in
|
controlPhases = compose.controlPhases;
|
||||||
{ doCheck ? !isCross && (lib.versionOlder "7.4" ghc.version)
|
|
||||||
, doBenchmark ? false
|
|
||||||
, ...
|
|
||||||
}: { inherit doCheck doBenchmark; };
|
|
||||||
|
|
||||||
# Utility to convert a directory full of `cabal2nix`-generated files into a
|
# Utility to convert a directory full of `cabal2nix`-generated files into a
|
||||||
# package override set
|
# package override set
|
||||||
#
|
#
|
||||||
# packagesFromDirectory : { directory : Directory, ... } -> HaskellPackageOverrideSet
|
# packagesFromDirectory : { directory : Directory, ... } -> HaskellPackageOverrideSet
|
||||||
packagesFromDirectory =
|
packagesFromDirectory = compose.packagesFromDirectory;
|
||||||
{ directory, ... }:
|
|
||||||
|
|
||||||
self: super:
|
addOptparseApplicativeCompletionScripts = compose.addOptparseApplicativeCompletionScripts;
|
||||||
let
|
|
||||||
haskellPaths = builtins.attrNames (builtins.readDir directory);
|
|
||||||
|
|
||||||
toKeyVal = file: {
|
|
||||||
name = builtins.replaceStrings [ ".nix" ] [ "" ] file;
|
|
||||||
|
|
||||||
value = self.callPackage (directory + "/${file}") { };
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
builtins.listToAttrs (map toKeyVal haskellPaths);
|
|
||||||
|
|
||||||
addOptparseApplicativeCompletionScripts = exeName: pkg:
|
|
||||||
builtins.trace "addOptparseApplicativeCompletionScripts is deprecated in favor of generateOptparseApplicativeCompletion. Please change ${pkg.name} to use the latter or its plural form."
|
|
||||||
(generateOptparseApplicativeCompletion exeName pkg);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Modify a Haskell package to add shell completion scripts for the
|
Modify a Haskell package to add shell completion scripts for the
|
||||||
|
@ -422,23 +331,7 @@ rec {
|
||||||
command: name of an executable
|
command: name of an executable
|
||||||
pkg: Haskell package that builds the executables
|
pkg: Haskell package that builds the executables
|
||||||
*/
|
*/
|
||||||
generateOptparseApplicativeCompletion = exeName: pkg: overrideCabal pkg (drv: {
|
generateOptparseApplicativeCompletion = compose.generateOptparseApplicativeCompletion;
|
||||||
postInstall = (drv.postInstall or "") + ''
|
|
||||||
bashCompDir="''${!outputBin}/share/bash-completion/completions"
|
|
||||||
zshCompDir="''${!outputBin}/share/zsh/vendor-completions"
|
|
||||||
fishCompDir="''${!outputBin}/share/fish/vendor_completions.d"
|
|
||||||
mkdir -p "$bashCompDir" "$zshCompDir" "$fishCompDir"
|
|
||||||
"''${!outputBin}/bin/${exeName}" --bash-completion-script "''${!outputBin}/bin/${exeName}" >"$bashCompDir/${exeName}"
|
|
||||||
"''${!outputBin}/bin/${exeName}" --zsh-completion-script "''${!outputBin}/bin/${exeName}" >"$zshCompDir/_${exeName}"
|
|
||||||
"''${!outputBin}/bin/${exeName}" --fish-completion-script "''${!outputBin}/bin/${exeName}" >"$fishCompDir/${exeName}.fish"
|
|
||||||
|
|
||||||
# Sanity check
|
|
||||||
grep -F ${exeName} <$bashCompDir/${exeName} >/dev/null || {
|
|
||||||
echo 'Could not find ${exeName} in completion script.'
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Modify a Haskell package to add shell completion scripts for the
|
Modify a Haskell package to add shell completion scripts for the
|
||||||
|
@ -453,13 +346,10 @@ rec {
|
||||||
commands: name of an executable
|
commands: name of an executable
|
||||||
pkg: Haskell package that builds the executables
|
pkg: Haskell package that builds the executables
|
||||||
*/
|
*/
|
||||||
generateOptparseApplicativeCompletions = commands: pkg:
|
generateOptparseApplicativeCompletions = compose.generateOptparseApplicativeCompletions;
|
||||||
pkgs.lib.foldr generateOptparseApplicativeCompletion pkg commands;
|
|
||||||
|
|
||||||
# Don't fail at configure time if there are multiple versions of the
|
# Don't fail at configure time if there are multiple versions of the
|
||||||
# same package in the (recursive) dependencies of the package being
|
# same package in the (recursive) dependencies of the package being
|
||||||
# built. Will delay failures, if any, to compile time.
|
# built. Will delay failures, if any, to compile time.
|
||||||
allowInconsistentDependencies = drv: overrideCabal drv (drv: {
|
allowInconsistentDependencies = compose.allowInconsistentDependencies;
|
||||||
allowInconsistentDependencies = true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
466
pkgs/development/haskell-modules/lib/compose.nix
Normal file
466
pkgs/development/haskell-modules/lib/compose.nix
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
# TODO(@Ericson2314): Remove `pkgs` param, which is only used for
|
||||||
|
# `buildStackProject`, `justStaticExecutables` and `checkUnusedPackages`
|
||||||
|
{ pkgs, lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
|
||||||
|
/* This function takes a file like `hackage-packages.nix` and constructs
|
||||||
|
a full package set out of that.
|
||||||
|
*/
|
||||||
|
makePackageSet = import ../make-package-set.nix;
|
||||||
|
|
||||||
|
/* The function overrideCabal lets you alter the arguments to the
|
||||||
|
mkDerivation function.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
First, note how the aeson package is constructed in hackage-packages.nix:
|
||||||
|
|
||||||
|
"aeson" = callPackage ({ mkDerivation, attoparsec, <snip>
|
||||||
|
}:
|
||||||
|
mkDerivation {
|
||||||
|
pname = "aeson";
|
||||||
|
<snip>
|
||||||
|
homepage = "https://github.com/bos/aeson";
|
||||||
|
})
|
||||||
|
|
||||||
|
The mkDerivation function of haskellPackages will take care of putting
|
||||||
|
the homepage in the right place, in meta.
|
||||||
|
|
||||||
|
> haskellPackages.aeson.meta.homepage
|
||||||
|
"https://github.com/bos/aeson"
|
||||||
|
|
||||||
|
> x = haskell.lib.composable.overrideCabal (old: { homepage = old.homepage + "#readme"; }) haskellPackages.aeson
|
||||||
|
> x.meta.homepage
|
||||||
|
"https://github.com/bos/aeson#readme"
|
||||||
|
|
||||||
|
*/
|
||||||
|
overrideCabal = f: drv: (drv.override (args: args // {
|
||||||
|
mkDerivation = drv: (args.mkDerivation drv).override f;
|
||||||
|
})) // {
|
||||||
|
overrideScope = scope: overrideCabal f (drv.overrideScope scope);
|
||||||
|
};
|
||||||
|
|
||||||
|
# : Map Name (Either Path VersionNumber) -> HaskellPackageOverrideSet
|
||||||
|
# Given a set whose values are either paths or version strings, produces
|
||||||
|
# a package override set (i.e. (self: super: { etc. })) that sets
|
||||||
|
# the packages named in the input set to the corresponding versions
|
||||||
|
packageSourceOverrides =
|
||||||
|
overrides: self: super: pkgs.lib.mapAttrs (name: src:
|
||||||
|
let isPath = x: builtins.substring 0 1 (toString x) == "/";
|
||||||
|
generateExprs = if isPath src
|
||||||
|
then self.callCabal2nix
|
||||||
|
else self.callHackage;
|
||||||
|
in generateExprs name src {}) overrides;
|
||||||
|
|
||||||
|
/* doCoverage modifies a haskell package to enable the generation
|
||||||
|
and installation of a coverage report.
|
||||||
|
|
||||||
|
See https://wiki.haskell.org/Haskell_program_coverage
|
||||||
|
*/
|
||||||
|
doCoverage = overrideCabal (drv: { doCoverage = true; });
|
||||||
|
|
||||||
|
/* dontCoverage modifies a haskell package to disable the generation
|
||||||
|
and installation of a coverage report.
|
||||||
|
*/
|
||||||
|
dontCoverage = overrideCabal (drv: { doCoverage = false; });
|
||||||
|
|
||||||
|
/* doHaddock modifies a haskell package to enable the generation and
|
||||||
|
installation of API documentation from code comments using the
|
||||||
|
haddock tool.
|
||||||
|
*/
|
||||||
|
doHaddock = overrideCabal (drv: { doHaddock = true; });
|
||||||
|
|
||||||
|
/* dontHaddock modifies a haskell package to disable the generation and
|
||||||
|
installation of API documentation from code comments using the
|
||||||
|
haddock tool.
|
||||||
|
*/
|
||||||
|
dontHaddock = overrideCabal (drv: { doHaddock = false; });
|
||||||
|
|
||||||
|
/* doJailbreak enables the removal of version bounds from the cabal
|
||||||
|
file. You may want to avoid this function.
|
||||||
|
|
||||||
|
This is useful when a package reports that it can not be built
|
||||||
|
due to version mismatches. In some cases, removing the version
|
||||||
|
bounds entirely is an easy way to make a package build, but at
|
||||||
|
the risk of breaking software in non-obvious ways now or in the
|
||||||
|
future.
|
||||||
|
|
||||||
|
Instead of jailbreaking, you can patch the cabal file.
|
||||||
|
|
||||||
|
Note that jailbreaking at this time, doesn't lift bounds on
|
||||||
|
conditional branches.
|
||||||
|
https://github.com/peti/jailbreak-cabal/issues/7 has further details.
|
||||||
|
|
||||||
|
*/
|
||||||
|
doJailbreak = overrideCabal (drv: { jailbreak = true; });
|
||||||
|
|
||||||
|
/* dontJailbreak restores the use of the version bounds the check
|
||||||
|
the use of dependencies in the package description.
|
||||||
|
*/
|
||||||
|
dontJailbreak = overrideCabal (drv: { jailbreak = false; });
|
||||||
|
|
||||||
|
/* doCheck enables dependency checking, compilation and execution
|
||||||
|
of test suites listed in the package description file.
|
||||||
|
*/
|
||||||
|
doCheck = overrideCabal (drv: { doCheck = true; });
|
||||||
|
/* dontCheck disables dependency checking, compilation and execution
|
||||||
|
of test suites listed in the package description file.
|
||||||
|
*/
|
||||||
|
dontCheck = overrideCabal (drv: { doCheck = false; });
|
||||||
|
|
||||||
|
/* doBenchmark enables dependency checking, compilation and execution
|
||||||
|
for benchmarks listed in the package description file.
|
||||||
|
*/
|
||||||
|
doBenchmark = overrideCabal (drv: { doBenchmark = true; });
|
||||||
|
/* dontBenchmark disables dependency checking, compilation and execution
|
||||||
|
for benchmarks listed in the package description file.
|
||||||
|
*/
|
||||||
|
dontBenchmark = overrideCabal (drv: { doBenchmark = false; });
|
||||||
|
|
||||||
|
/* doDistribute enables the distribution of binaries for the package
|
||||||
|
via hydra.
|
||||||
|
*/
|
||||||
|
doDistribute = overrideCabal (drv: { hydraPlatforms = drv.platforms or ["i686-linux" "x86_64-linux" "x86_64-darwin"]; });
|
||||||
|
/* dontDistribute disables the distribution of binaries for the package
|
||||||
|
via hydra.
|
||||||
|
*/
|
||||||
|
dontDistribute = overrideCabal (drv: { hydraPlatforms = []; });
|
||||||
|
|
||||||
|
/* appendConfigureFlag adds a single argument that will be passed to the
|
||||||
|
cabal configure command, after the arguments that have been defined
|
||||||
|
in the initial declaration or previous overrides.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
> haskell.lib.composable.appendConfigureFlag "--profiling-detail=all-functions" haskellPackages.servant
|
||||||
|
*/
|
||||||
|
appendConfigureFlag = x: appendConfigureFlags [x];
|
||||||
|
appendConfigureFlags = xs: overrideCabal (drv: { configureFlags = (drv.configureFlags or []) ++ xs; });
|
||||||
|
|
||||||
|
appendBuildFlag = x: overrideCabal (drv: { buildFlags = (drv.buildFlags or []) ++ [x]; });
|
||||||
|
appendBuildFlags = xs: overrideCabal (drv: { buildFlags = (drv.buildFlags or []) ++ xs; });
|
||||||
|
|
||||||
|
/* removeConfigureFlag drv x is a Haskell package like drv, but with
|
||||||
|
all cabal configure arguments that are equal to x removed.
|
||||||
|
|
||||||
|
> haskell.lib.composable.removeConfigureFlag "--verbose" haskellPackages.servant
|
||||||
|
*/
|
||||||
|
removeConfigureFlag = x: overrideCabal (drv: { configureFlags = lib.remove x (drv.configureFlags or []); });
|
||||||
|
|
||||||
|
addBuildTool = x: addBuildTools [x];
|
||||||
|
addBuildTools = xs: overrideCabal (drv: { buildTools = (drv.buildTools or []) ++ xs; });
|
||||||
|
|
||||||
|
addExtraLibrary = x: addExtraLibraries [x];
|
||||||
|
addExtraLibraries = xs: overrideCabal (drv: { extraLibraries = (drv.extraLibraries or []) ++ xs; });
|
||||||
|
|
||||||
|
addBuildDepend = x: addBuildDepends [x];
|
||||||
|
addBuildDepends = xs: overrideCabal (drv: { buildDepends = (drv.buildDepends or []) ++ xs; });
|
||||||
|
|
||||||
|
addTestToolDepend = x: addTestToolDepends [x];
|
||||||
|
addTestToolDepends = xs: overrideCabal (drv: { testToolDepends = (drv.testToolDepends or []) ++ xs; });
|
||||||
|
|
||||||
|
addPkgconfigDepend = x: addPkgconfigDepends [x];
|
||||||
|
addPkgconfigDepends = xs: overrideCabal (drv: { pkg-configDepends = (drv.pkg-configDepends or []) ++ xs; });
|
||||||
|
|
||||||
|
addSetupDepend = x: addSetupDepends [x];
|
||||||
|
addSetupDepends = xs: overrideCabal (drv: { setupHaskellDepends = (drv.setupHaskellDepends or []) ++ xs; });
|
||||||
|
|
||||||
|
enableCabalFlag = x: drv: appendConfigureFlag "-f${x}" (removeConfigureFlag "-f-${x}" drv);
|
||||||
|
disableCabalFlag = x: drv: appendConfigureFlag "-f-${x}" (removeConfigureFlag "-f${x}" drv);
|
||||||
|
|
||||||
|
markBroken = overrideCabal (drv: { broken = true; hydraPlatforms = []; });
|
||||||
|
unmarkBroken = overrideCabal (drv: { broken = false; });
|
||||||
|
markBrokenVersion = version: drv: assert drv.version == version; markBroken drv;
|
||||||
|
markUnbroken = overrideCabal (drv: { broken = false; });
|
||||||
|
|
||||||
|
enableLibraryProfiling = overrideCabal (drv: { enableLibraryProfiling = true; });
|
||||||
|
disableLibraryProfiling = overrideCabal (drv: { enableLibraryProfiling = false; });
|
||||||
|
|
||||||
|
enableExecutableProfiling = overrideCabal (drv: { enableExecutableProfiling = true; });
|
||||||
|
disableExecutableProfiling = overrideCabal (drv: { enableExecutableProfiling = false; });
|
||||||
|
|
||||||
|
enableSharedExecutables = overrideCabal (drv: { enableSharedExecutables = true; });
|
||||||
|
disableSharedExecutables = overrideCabal (drv: { enableSharedExecutables = false; });
|
||||||
|
|
||||||
|
enableSharedLibraries = overrideCabal (drv: { enableSharedLibraries = true; });
|
||||||
|
disableSharedLibraries = overrideCabal (drv: { enableSharedLibraries = false; });
|
||||||
|
|
||||||
|
enableDeadCodeElimination = overrideCabal (drv: { enableDeadCodeElimination = true; });
|
||||||
|
disableDeadCodeElimination = overrideCabal (drv: { enableDeadCodeElimination = false; });
|
||||||
|
|
||||||
|
enableStaticLibraries = overrideCabal (drv: { enableStaticLibraries = true; });
|
||||||
|
disableStaticLibraries = overrideCabal (drv: { enableStaticLibraries = false; });
|
||||||
|
|
||||||
|
enableSeparateBinOutput = overrideCabal (drv: { enableSeparateBinOutput = true; });
|
||||||
|
|
||||||
|
appendPatch = x: appendPatches [x];
|
||||||
|
appendPatches = xs: overrideCabal (drv: { patches = (drv.patches or []) ++ xs; });
|
||||||
|
|
||||||
|
/* Set a specific build target instead of compiling all targets in the package.
|
||||||
|
* For example, imagine we have a .cabal file with a library, and 2 executables "dev" and "server".
|
||||||
|
* We can build only "server" and not wait on the compilation of "dev" by using setBuildTarget as follows:
|
||||||
|
*
|
||||||
|
* > setBuildTarget "server" (callCabal2nix "thePackageName" thePackageSrc {})
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
setBuildTargets = xs: overrideCabal (drv: { buildTarget = lib.concatStringsSep " " xs; });
|
||||||
|
setBuildTarget = x: setBuildTargets [x];
|
||||||
|
|
||||||
|
doHyperlinkSource = overrideCabal (drv: { hyperlinkSource = true; });
|
||||||
|
dontHyperlinkSource = overrideCabal (drv: { hyperlinkSource = false; });
|
||||||
|
|
||||||
|
disableHardening = flags: overrideCabal (drv: { hardeningDisable = flags; });
|
||||||
|
|
||||||
|
/* Let Nix strip the binary files.
|
||||||
|
* This removes debugging symbols.
|
||||||
|
*/
|
||||||
|
doStrip = overrideCabal (drv: { dontStrip = false; });
|
||||||
|
|
||||||
|
/* Stop Nix from stripping the binary files.
|
||||||
|
* This keeps debugging symbols.
|
||||||
|
*/
|
||||||
|
dontStrip = overrideCabal (drv: { dontStrip = true; });
|
||||||
|
|
||||||
|
/* Useful for debugging segfaults with gdb.
|
||||||
|
* This includes dontStrip.
|
||||||
|
*/
|
||||||
|
enableDWARFDebugging = drv:
|
||||||
|
# -g: enables debugging symbols
|
||||||
|
# --disable-*-stripping: tell GHC not to strip resulting binaries
|
||||||
|
# dontStrip: see above
|
||||||
|
appendConfigureFlag "--ghc-options=-g --disable-executable-stripping --disable-library-stripping" (dontStrip drv);
|
||||||
|
|
||||||
|
/* Create a source distribution tarball like those found on hackage,
|
||||||
|
instead of building the package.
|
||||||
|
*/
|
||||||
|
sdistTarball = pkg: lib.overrideDerivation pkg (drv: {
|
||||||
|
name = "${drv.pname}-source-${drv.version}";
|
||||||
|
# Since we disable the haddock phase, we also need to override the
|
||||||
|
# outputs since the separate doc output will not be produced.
|
||||||
|
outputs = ["out"];
|
||||||
|
buildPhase = "./Setup sdist";
|
||||||
|
haddockPhase = ":";
|
||||||
|
checkPhase = ":";
|
||||||
|
installPhase = "install -D dist/${drv.pname}-*.tar.gz $out/${drv.pname}-${drv.version}.tar.gz";
|
||||||
|
fixupPhase = ":";
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Create a documentation tarball suitable for uploading to Hackage instead
|
||||||
|
of building the package.
|
||||||
|
*/
|
||||||
|
documentationTarball = pkg:
|
||||||
|
pkgs.lib.overrideDerivation pkg (drv: {
|
||||||
|
name = "${drv.name}-docs";
|
||||||
|
# Like sdistTarball, disable the "doc" output here.
|
||||||
|
outputs = [ "out" ];
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preHaddock
|
||||||
|
./Setup haddock --for-hackage
|
||||||
|
runHook postHaddock
|
||||||
|
'';
|
||||||
|
haddockPhase = ":";
|
||||||
|
checkPhase = ":";
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
mkdir -p "$out"
|
||||||
|
tar --format=ustar \
|
||||||
|
-czf "$out/${drv.name}-docs.tar.gz" \
|
||||||
|
-C dist/doc/html "${drv.name}-docs"
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Use the gold linker. It is a linker for ELF that is designed
|
||||||
|
"to run as fast as possible on modern systems"
|
||||||
|
*/
|
||||||
|
linkWithGold = appendConfigureFlag
|
||||||
|
"--ghc-option=-optl-fuse-ld=gold --ld-option=-fuse-ld=gold --with-ld=ld.gold";
|
||||||
|
|
||||||
|
/* link executables statically against haskell libs to reduce
|
||||||
|
closure size
|
||||||
|
*/
|
||||||
|
justStaticExecutables = overrideCabal (drv: {
|
||||||
|
enableSharedExecutables = false;
|
||||||
|
enableLibraryProfiling = false;
|
||||||
|
isLibrary = false;
|
||||||
|
doHaddock = false;
|
||||||
|
postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc";
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Build a source distribution tarball instead of using the source files
|
||||||
|
directly. The effect is that the package is built as if it were published
|
||||||
|
on hackage. This can be used as a test for the source distribution,
|
||||||
|
assuming the build fails when packaging mistakes are in the cabal file.
|
||||||
|
*/
|
||||||
|
buildFromSdist = pkg: overrideCabal (drv: {
|
||||||
|
src = "${sdistTarball pkg}/${pkg.pname}-${pkg.version}.tar.gz";
|
||||||
|
|
||||||
|
# Revising and jailbreaking the cabal file has been handled in sdistTarball
|
||||||
|
revision = null;
|
||||||
|
editedCabalFile = null;
|
||||||
|
jailbreak = false;
|
||||||
|
}) pkg;
|
||||||
|
|
||||||
|
/* Build the package in a strict way to uncover potential problems.
|
||||||
|
This includes buildFromSdist and failOnAllWarnings.
|
||||||
|
*/
|
||||||
|
buildStrictly = pkg: buildFromSdist (failOnAllWarnings pkg);
|
||||||
|
|
||||||
|
/* Disable core optimizations, significantly speeds up build time */
|
||||||
|
disableOptimization = appendConfigureFlag "--disable-optimization";
|
||||||
|
|
||||||
|
/* Turn on most of the compiler warnings and fail the build if any
|
||||||
|
of them occur. */
|
||||||
|
failOnAllWarnings = appendConfigureFlag "--ghc-option=-Wall --ghc-option=-Werror";
|
||||||
|
|
||||||
|
/* Add a post-build check to verify that dependencies declared in
|
||||||
|
the cabal file are actually used.
|
||||||
|
|
||||||
|
The first attrset argument can be used to configure the strictness
|
||||||
|
of this check and a list of ignored package names that would otherwise
|
||||||
|
cause false alarms.
|
||||||
|
*/
|
||||||
|
checkUnusedPackages =
|
||||||
|
{ ignoreEmptyImports ? false
|
||||||
|
, ignoreMainModule ? false
|
||||||
|
, ignorePackages ? []
|
||||||
|
} : drv :
|
||||||
|
overrideCabal (_drv: {
|
||||||
|
postBuild = with lib;
|
||||||
|
let args = concatStringsSep " " (
|
||||||
|
optional ignoreEmptyImports "--ignore-empty-imports" ++
|
||||||
|
optional ignoreMainModule "--ignore-main-module" ++
|
||||||
|
map (pkg: "--ignore-package ${pkg}") ignorePackages
|
||||||
|
);
|
||||||
|
in "${pkgs.haskellPackages.packunused}/bin/packunused" +
|
||||||
|
optionalString (args != "") " ${args}";
|
||||||
|
}) (appendConfigureFlag "--ghc-option=-ddump-minimal-imports" drv);
|
||||||
|
|
||||||
|
buildStackProject = pkgs.callPackage ../generic-stack-builder.nix { };
|
||||||
|
|
||||||
|
/* Add a dummy command to trigger a build despite an equivalent
|
||||||
|
earlier build that is present in the store or cache.
|
||||||
|
*/
|
||||||
|
triggerRebuild = i: overrideCabal (drv: { postUnpack = ": trigger rebuild ${toString i}"; });
|
||||||
|
|
||||||
|
/* Override the sources for the package and optionaly the version.
|
||||||
|
This also takes of removing editedCabalFile.
|
||||||
|
*/
|
||||||
|
overrideSrc = { src, version ? null }: drv:
|
||||||
|
overrideCabal (_: { inherit src; version = if version == null then drv.version else version; editedCabalFile = null; }) drv;
|
||||||
|
|
||||||
|
# Get all of the build inputs of a haskell package, divided by category.
|
||||||
|
getBuildInputs = p: p.getBuildInputs;
|
||||||
|
|
||||||
|
# Extract the haskell build inputs of a haskell package.
|
||||||
|
# This is useful to build environments for developing on that
|
||||||
|
# package.
|
||||||
|
getHaskellBuildInputs = p: (getBuildInputs p).haskellBuildInputs;
|
||||||
|
|
||||||
|
# Under normal evaluation, simply return the original package. Under
|
||||||
|
# nix-shell evaluation, return a nix-shell optimized environment.
|
||||||
|
shellAware = p: if lib.inNixShell then p.env else p;
|
||||||
|
|
||||||
|
ghcInfo = ghc:
|
||||||
|
rec { isCross = (ghc.cross or null) != null;
|
||||||
|
isGhcjs = ghc.isGhcjs or false;
|
||||||
|
nativeGhc = if isCross || isGhcjs
|
||||||
|
then ghc.bootPkgs.ghc
|
||||||
|
else ghc;
|
||||||
|
};
|
||||||
|
|
||||||
|
### mkDerivation helpers
|
||||||
|
# These allow external users of a haskell package to extract
|
||||||
|
# information about how it is built in the same way that the
|
||||||
|
# generic haskell builder does, by reusing the same functions.
|
||||||
|
# Each function here has the same interface as mkDerivation and thus
|
||||||
|
# can be called for a given package simply by overriding the
|
||||||
|
# mkDerivation argument it used. See getHaskellBuildInputs above for
|
||||||
|
# an example of this.
|
||||||
|
|
||||||
|
# Some information about which phases should be run.
|
||||||
|
controlPhases = ghc: let inherit (ghcInfo ghc) isCross; in
|
||||||
|
{ doCheck ? !isCross && (lib.versionOlder "7.4" ghc.version)
|
||||||
|
, doBenchmark ? false
|
||||||
|
, ...
|
||||||
|
}: { inherit doCheck doBenchmark; };
|
||||||
|
|
||||||
|
# Utility to convert a directory full of `cabal2nix`-generated files into a
|
||||||
|
# package override set
|
||||||
|
#
|
||||||
|
# packagesFromDirectory : { directory : Directory, ... } -> HaskellPackageOverrideSet
|
||||||
|
packagesFromDirectory =
|
||||||
|
{ directory, ... }:
|
||||||
|
|
||||||
|
self: super:
|
||||||
|
let
|
||||||
|
haskellPaths = builtins.attrNames (builtins.readDir directory);
|
||||||
|
|
||||||
|
toKeyVal = file: {
|
||||||
|
name = builtins.replaceStrings [ ".nix" ] [ "" ] file;
|
||||||
|
|
||||||
|
value = self.callPackage (directory + "/${file}") { };
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
builtins.listToAttrs (map toKeyVal haskellPaths);
|
||||||
|
|
||||||
|
addOptparseApplicativeCompletionScripts = exeName: pkg:
|
||||||
|
builtins.trace "addOptparseApplicativeCompletionScripts is deprecated in favor of generateOptparseApplicativeCompletion. Please change ${pkg.name} to use the latter or its plural form."
|
||||||
|
(generateOptparseApplicativeCompletion exeName pkg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Modify a Haskell package to add shell completion scripts for the
|
||||||
|
given executable produced by it. These completion scripts will be
|
||||||
|
picked up automatically if the resulting derivation is installed,
|
||||||
|
e.g. by `nix-env -i`.
|
||||||
|
|
||||||
|
Invocation:
|
||||||
|
generateOptparseApplicativeCompletion command pkg
|
||||||
|
|
||||||
|
|
||||||
|
command: name of an executable
|
||||||
|
pkg: Haskell package that builds the executables
|
||||||
|
*/
|
||||||
|
generateOptparseApplicativeCompletion = exeName: overrideCabal (drv: {
|
||||||
|
postInstall = (drv.postInstall or "") + ''
|
||||||
|
bashCompDir="''${!outputBin}/share/bash-completion/completions"
|
||||||
|
zshCompDir="''${!outputBin}/share/zsh/vendor-completions"
|
||||||
|
fishCompDir="''${!outputBin}/share/fish/vendor_completions.d"
|
||||||
|
mkdir -p "$bashCompDir" "$zshCompDir" "$fishCompDir"
|
||||||
|
"''${!outputBin}/bin/${exeName}" --bash-completion-script "''${!outputBin}/bin/${exeName}" >"$bashCompDir/${exeName}"
|
||||||
|
"''${!outputBin}/bin/${exeName}" --zsh-completion-script "''${!outputBin}/bin/${exeName}" >"$zshCompDir/_${exeName}"
|
||||||
|
"''${!outputBin}/bin/${exeName}" --fish-completion-script "''${!outputBin}/bin/${exeName}" >"$fishCompDir/${exeName}.fish"
|
||||||
|
|
||||||
|
# Sanity check
|
||||||
|
grep -F ${exeName} <$bashCompDir/${exeName} >/dev/null || {
|
||||||
|
echo 'Could not find ${exeName} in completion script.'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
Modify a Haskell package to add shell completion scripts for the
|
||||||
|
given executables produced by it. These completion scripts will be
|
||||||
|
picked up automatically if the resulting derivation is installed,
|
||||||
|
e.g. by `nix-env -i`.
|
||||||
|
|
||||||
|
Invocation:
|
||||||
|
generateOptparseApplicativeCompletions commands pkg
|
||||||
|
|
||||||
|
|
||||||
|
commands: name of an executable
|
||||||
|
pkg: Haskell package that builds the executables
|
||||||
|
*/
|
||||||
|
generateOptparseApplicativeCompletions = commands: pkg:
|
||||||
|
pkgs.lib.foldr generateOptparseApplicativeCompletion pkg commands;
|
||||||
|
|
||||||
|
# Don't fail at configure time if there are multiple versions of the
|
||||||
|
# same package in the (recursive) dependencies of the package being
|
||||||
|
# built. Will delay failures, if any, to compile time.
|
||||||
|
allowInconsistentDependencies = overrideCabal (drv: {
|
||||||
|
allowInconsistentDependencies = true;
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue