Skip to content

Faster cabal builds by caching the build directory #2365

Closed
@nh2

Description

@nh2

Imported from reddit:

I got annoyed that every time I build something in a new cabal sandbox I have to wait for the same versions of lens or haskell-src-exts to compile forever.

Couldn't we just cache the build directory from which we installed a package instead of throwing it away after every build?

Cabal tries to guarantee that running cabal install in a source directory always produces the correct result without us having to run cabal clean first (so no matter what the state of the dist/ directory is). Cabal does this by using ghc --make for building, which has very good recompilation avoidance and flag change detection.

This means that this kind of cache introduces no additional correctness guarantees we would have to provide, it is only relying on guarantees that cabal already tries to provide.

The cache does take some space in my home directory, but I accept that for the 20x faster build it allows.

For example, a no-op rebuild of for haskell-src-exts is 7 seconds on my computer vs. a full build that takes 132 seconds.

This method will pick up changed dependencies (e.g. it will build correctly when the version of haskell-src-exts's dependency pretty changes between two builds) because ghc --make notices that.

This method will also provide for cases where other approaches cannot. For example, as mentioned here and here, it can cache more than a nix-like approach can: With nix caching ends completely at the first dependency that has changed, while ghc --make caches on the module level, recompiling only those modules that depend on changed code, not packages. Nevertheless, the biggest speedup to be expected is for CI systems like TravisCI, CircleCI etc., and sandboxes, as those compile share huge parts of the dependency graph where all code is exactly the same.

Here's a proof of concept patch: nh2/cabal@nh2:before-buildcache...buildcache

What do you think?


Some things we would need:

  • Are you aware of any recent or past cabal bugs mentioning that cabal clean was necessary in order to build correctly?
  • Also I think that if we want to try this out, the best might be to hide it behind a cabal install --cached option defaulting to False, and if it works out well, make it the default at some point in the future. Do you agree?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions