Skip to content

Directly call in-library functions to build packages#11703

Draft
sheaf wants to merge 1 commit intohaskell:masterfrom
sheaf:wip/cabal-install-hooks
Draft

Directly call in-library functions to build packages#11703
sheaf wants to merge 1 commit intohaskell:masterfrom
sheaf:wip/cabal-install-hooks

Conversation

@sheaf
Copy link
Copy Markdown
Collaborator

@sheaf sheaf commented Apr 3, 2026

This is a rebase of #9871. I had to create a new PR as Matthew is no longer active (and that PR was made from his personal fork).


Template B: This PR does not modify behaviour or interface.

This is a major refactoring in how cabal-install works, with a few knock-on internal changes to some Cabal library functionality.
It should not cause any breakage for users (I tested clc-stackage against previous versions of this PR, and it all builds unchanged with this branch).


This PR modifies cabal-install to directly go through the Cabal library when building packages, instead of the Setup interface (except of course for build-type: Custom packages).

In particular, to build a package with build-type: Hooks, cabal-install will compile the package's SetupHooks file into an external hooks executable using the new hooks-exe package. All hooked operations are then performed by communicating with this external executable, instead of going through an opaque Setup executable. The hooks-exe package provides both functionality for compiling an external hooks executable and for interfacing with it. This makes use of the CommunicationHandle API that I added to process.

The main change is to SetupWrapper: the old InternalMethod becomes LibraryMethod, which builds the package by calling Cabal library functions. This is used to build all packages unless build-type: Custom or there is a Cabal library version mismatch which requires us to fall back to compiling Setup.hs and running that. The SelfExec method as well as forceExternalSetupMethod are removed: they no longer have any purpose, as builds can now be carried out concurrently thanks to 7b90583 and edb808a.

The new Distribution.Client.InLibrary module contains all the necessary framework for taking information that cabal-install has and invoking Cabal library functions to perform the appropriate action (configure, build, test, bench, ...). Most of these are pretty simple; the main difficulty is with configure as we need to jump to the part of the Cabal configure code that continues after figuring out information about the system (e.g. compiler information), to avoid wasting work with Cabal rediscovering things that cabal-install already knows. This required a bit of refactoring in Distribution.Simple.Configure.

TODO:

  • Update bootstrap plans.
  • Validate this version of the patch against clc-stackage and update the PR description accordingly.

@sheaf sheaf force-pushed the wip/cabal-install-hooks branch 3 times, most recently from 0ba5efe to cff8372 Compare April 3, 2026 18:45
This commit modifies the SetupWrapper mechanism, adding a new way of
building a package: directly calling Cabal library functions (e.g.
'build', 'configure' etc).

This currently requires a bit of GADT trickery to accomodate the fact
that configure returns a LocalBuildInfo which must then be passed to
subsequent phases, while with the old Setup interface everything returns
IO () and communication is done through the filesystem
(the local build info file).

To handle 'build-type: Hooks', this commit introduces the hooks-exe
package, which contains:

  - the hooks-exe library, used to compile a set of SetupHooks into an
    external executable,
  - the hooks-cli library, which is used by cabal-install to communicate
    with an external hooks executable.

This package depends on the new `CommunicationHandle` functionality from
haskell/process#308.
@sheaf sheaf force-pushed the wip/cabal-install-hooks branch from cff8372 to 0a2b46e Compare April 3, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant