Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/languages-frameworks/dhall.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,12 +307,12 @@ $ nix-env --install --attr haskellPackages.dhall-nixpkgs

$ nix-env --install --attr nix-prefetch-git # Used by dhall-to-nixpkgs

$ dhall-to-nixpkgs github https://github.com/Gabriel439/dhall-semver.git
$ dhall-to-nixpkgs github https://github.com/Gabriella439/dhall-semver.git
{ buildDhallGitHubPackage, Prelude }:
buildDhallGitHubPackage {
name = "dhall-semver";
githubBase = "github.com";
owner = "Gabriel439";
owner = "Gabriella439";
repo = "dhall-semver";
rev = "2d44ae605302ce5dc6c657a1216887fbb96392a4";
fetchSubmodules = false;
Expand Down
71 changes: 71 additions & 0 deletions doc/languages-frameworks/haskell.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,15 @@ Defaults to `true`.
: Whether to generate an index for interactive navigation of the HTML documentation.
Defaults to `true` if supported.

`doInstallIntermediates`
: Whether to install intermediate build products (files written to `dist/build`
by GHC during the build process). With `enableSeparateIntermediatesOutput`,
these files are instead installed to [a separate `intermediates`
output.][multiple-outputs] The output can then be passed into a future build of
the same package with the `previousIntermediates` argument to support
incremental builds. See [“Incremental builds”](#haskell-incremental-builds) for
more information. Defaults to `false`.

`enableLibraryProfiling`
: Whether to enable [profiling][profiling] for libraries contained in the
package. Enabled by default if supported.
Expand Down Expand Up @@ -371,6 +380,12 @@ Defaults to `false`.
: Whether to install documentation to a separate `doc` output.
Is automatically enabled if `doHaddock` is `true`.

`enableSeparateIntermediatesOutput`
: When `doInstallIntermediates` is true, whether to install intermediate build
products to a separate `intermediates` output. See [“Incremental
builds”](#haskell-incremental-builds) for more information. Defaults to
`false`.

`allowInconsistentDependencies`
: If enabled, allow multiple versions of the same Haskell package in the
dependency tree at configure time. Often in such a situation compilation would
Expand All @@ -381,6 +396,11 @@ later fail because of type mismatches. Defaults to `false`.
when loading the library in the REPL, but requires extra build time and
disk space. Defaults to `false`.

`previousIntermediates`
: If non-null, intermediate build artifacts are copied from this input to
`dist/build` before performing compiling. See [“Incremental
builds”](#haskell-incremental-builds) for more information. Defaults to `null`.

`buildTarget`
: Name of the executable or library to build and install.
If unset, all available targets are built and installed.
Expand Down Expand Up @@ -496,6 +516,54 @@ the [Meta-attributes section](#chap-meta) for their documentation.
* `broken`
* `hydraPlatforms`

### Incremental builds {#haskell-incremental-builds}

`haskellPackages.mkDerivation` supports incremental builds for GHC 9.4 and
newer with the `doInstallIntermediates`, `enableSeparateIntermediatesOutput`,
and `previousIntermediates` arguments.

The basic idea is to first perform a full build of the package in question,
save its intermediate build products for later, and then copy those build
products into the build directory of an incremental build performed later.
Then, GHC will use those build artifacts to avoid recompiling unchanged
modules.

For more detail on how to store and use incremental build products, see
[Gabriella Gonzalez’ blog post “Nixpkgs support for incremental Haskell
builds”.][incremental-builds] motivation behind this feature.

An incremental build for [the `turtle` package][turtle] can be performed like
so:

```nix
let
pkgs = import <nixpkgs> {};
inherit (pkgs) haskell;
inherit (haskell.lib.compose) overrideCabal;

# Incremental builds work with GHC >=9.4.
turtle = haskell.packages.ghc944.turtle;

# This will do a full build of `turtle`, while writing the intermediate build products
# (compiled modules, etc.) to the `intermediates` output.
turtle-full-build-with-incremental-output = overrideCabal (drv: {
doInstallIntermediates = true;
enableSeparateIntermediatesOutput = true;
}) turtle;

# This will do an incremental build of `turtle` by copying the previously
# compiled modules and intermediate build products into the source tree
# before running the build.
#
# GHC will then naturally pick up and reuse these products, making this build
# complete much more quickly than the previous one.
turtle-incremental-build = overrideCabal (drv: {
previousIntermediates = turtle-full-build-with-incremental-output.intermediates;
}) turtle;
in
turtle-incremental-build
```

## Development environments {#haskell-development-environments}

In addition to building and installing Haskell software, nixpkgs can also
Expand Down Expand Up @@ -1083,8 +1151,11 @@ on the issue linked above.
[haskell.nix]: https://input-output-hk.github.io/haskell.nix/index.html
[HLS user guide]: https://haskell-language-server.readthedocs.io/en/latest/configuration.html#configuring-your-editor
[hoogle]: https://wiki.haskell.org/Hoogle
[incremental-builds]: https://www.haskellforall.com/2022/12/nixpkgs-support-for-incremental-haskell.html
[jailbreak-cabal]: https://github.com/NixOS/jailbreak-cabal/
[multiple-outputs]: https://nixos.org/manual/nixpkgs/stable/#chap-multiple-output
[optparse-applicative-completions]: https://github.com/pcapriotti/optparse-applicative/blob/7726b63796aa5d0df82e926d467f039b78ca09e2/README.md#bash-zsh-and-fish-completions
[profiling-detail]: https://cabal.readthedocs.io/en/latest/cabal-project.html#cfg-field-profiling-detail
[profiling]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html
[search.nixos.org]: https://search.nixos.org
[turtle]: https://hackage.haskell.org/package/turtle
12 changes: 6 additions & 6 deletions maintainers/maintainer-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5524,18 +5524,18 @@
githubId = 606000;
name = "Gabriel Adomnicai";
};
Gabriel439 = {
email = "Gabriel439@gmail.com";
github = "Gabriella439";
githubId = 1313787;
name = "Gabriel Gonzalez";
};
GabrielDougherty = {
email = "contact@gabrieldougherty.com";
github = "GabrielDougherty";
githubId = 10541219;
name = "Gabriel Dougherty";
};
Gabriella439 = {
email = "GenuineGabriella@gmail.com";
github = "Gabriella439";
githubId = 1313787;
name = "Gabriella Gonzalez";
};
gador = {
email = "florian.brandes@posteo.de";
github = "gador";
Expand Down
11 changes: 10 additions & 1 deletion maintainers/team-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ with lib.maintainers; {

dhall = {
members = [
Gabriel439
Gabriella439
ehmry
];
scope = "Maintain Dhall and related packages.";
Expand Down Expand Up @@ -556,6 +556,15 @@ with lib.maintainers; {
shortName = "Minimal Bootstrap";
};

mercury = {
members = [
_9999years
Gabriella439
];
scope = "Group registry for packages maintained by Mercury";
shortName = "Mercury Employees";
};

mobile = {
members = [
samueldr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ package-maintainers:
- vulkan-utils
erictapen:
- hakyll
Gabriel439:
Gabriella439:
- annah
- bench
- break
Expand Down
53 changes: 46 additions & 7 deletions pkgs/development/haskell-modules/generic-builder.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ in
, doBenchmark ? false
, doHoogle ? true
, doHaddockQuickjump ? doHoogle && lib.versionAtLeast ghc.version "8.6"
, doInstallIntermediates ? false
, editedCabalFile ? null
# aarch64 outputs otherwise exceed 2GB limit
, enableLibraryProfiling ? !(ghc.isGhcjs or stdenv.targetPlatform.isAarch64 or false)
Expand Down Expand Up @@ -84,6 +85,7 @@ in
, enableSeparateBinOutput ? false
, enableSeparateDataOutput ? false
, enableSeparateDocOutput ? doHaddock
, enableSeparateIntermediatesOutput ? false
, # 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.
Expand All @@ -93,6 +95,10 @@ in
# This can make it slightly faster to load this library into GHCi, but takes
# extra disk space and compile time.
enableLibraryForGhci ? false
# Set this to a previous build of this same package to reuse the intermediate
# build products from that prior build as a starting point for accelerating
# this build
, previousIntermediates ? null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New arguments should also be documented in the nixpkgs manual.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

} @ args:

assert editedCabalFile != null -> revision != null;
Expand Down Expand Up @@ -240,6 +246,8 @@ let
"--ghc-options=-haddock"
];

postPhases = optional doInstallIntermediates [ "installIntermediatesPhase" ];

setupCompileFlags = [
(optionalString (!coreSetup) "-${nativePackageDbFlag}=$setupPackageConfDir")
(optionalString enableParallelBuilding (parallelBuildingFlags))
Expand Down Expand Up @@ -306,6 +314,8 @@ let
continue
fi
'';

intermediatesDir = "share/haskell/${ghc.version}/${pname}-${version}/dist";
in lib.fix (drv:

assert allPkgconfigDepends != [] -> pkg-config != null;
Expand All @@ -316,7 +326,9 @@ stdenv.mkDerivation ({
outputs = [ "out" ]
++ (optional enableSeparateDataOutput "data")
++ (optional enableSeparateDocOutput "doc")
++ (optional enableSeparateBinOutput "bin");
++ (optional enableSeparateBinOutput "bin")
++ (optional enableSeparateIntermediatesOutput "intermediates");

setOutputFlags = false;

pos = builtins.unsafeGetAttrPos "pname" args;
Expand Down Expand Up @@ -393,7 +405,13 @@ stdenv.mkDerivation ({
# only use the links hack if we're actually building dylibs. otherwise, the
# "dynamic-library-dirs" point to nonexistent paths, and the ln command becomes
# "ln -s $out/lib/links", which tries to recreate the links dir and fails
+ (optionalString (stdenv.isDarwin && (enableSharedLibraries || enableSharedExecutables)) ''
#
# Note: We need to disable this work-around when using intermediate build
# products from a prior build because otherwise Nix will change permissions on
# the `$out/lib/links` directory to read-only when the build is done after the
# dist directory has already been exported, which triggers an unnecessary
# rebuild of modules included in the exported dist directory.
+ (optionalString (stdenv.isDarwin && (enableSharedLibraries || enableSharedExecutables) && !enableSeparateIntermediatesOutput) ''
# Work around a limit in the macOS Sierra linker on the number of paths
# referenced by any one dynamic library:
#
Expand Down Expand Up @@ -471,11 +489,22 @@ stdenv.mkDerivation ({
runHook postConfigure
'';

buildPhase = ''
runHook preBuild
${setupCommand} build ${buildTarget}${crossCabalFlagsString}${buildFlagsString}
runHook postBuild
'';
buildPhase =
''
runHook preBuild
''
+ lib.optionalString (previousIntermediates != null)
''
mkdir -p dist;
rm -r dist/build
cp -r ${previousIntermediates}/${intermediatesDir}/build dist/build
find dist/build -exec chmod u+w {} +
find dist/build -exec touch -d '1970-01-01T00:00:00Z' {} +
''
+ ''
${setupCommand} build ${buildTarget}${crossCabalFlagsString}${buildFlagsString}
runHook postBuild
'';

inherit doCheck;

Expand Down Expand Up @@ -558,6 +587,15 @@ stdenv.mkDerivation ({
runHook postInstall
'';

${if doInstallIntermediates then "installIntermediatesPhase" else null} = ''
runHook preInstallIntermediates
intermediatesOutput=${if enableSeparateIntermediatesOutput then "$intermediates" else "$out"}
installIntermediatesDir="$intermediatesOutput/${intermediatesDir}"
mkdir -p "$installIntermediatesDir"
cp -r dist/build "$installIntermediatesDir"
runHook postInstallIntermediates
'';

passthru = passthru // rec {

inherit pname version;
Expand Down Expand Up @@ -719,6 +757,7 @@ stdenv.mkDerivation ({
// optionalAttrs (args ? preFixup) { inherit preFixup; }
// optionalAttrs (args ? postFixup) { inherit postFixup; }
// optionalAttrs (args ? dontStrip) { inherit dontStrip; }
// optionalAttrs (postPhases != []) { inherit postPhases; }
// optionalAttrs (stdenv.buildPlatform.libc == "glibc"){ LOCALE_ARCHIVE = "${glibcLocales}/lib/locale/locale-archive"; }
)
)
Loading