Skip to content

Split up ConfigFlags and the Cabal configure function: package-wide vs per-component - #12562

Open
sheaf wants to merge 7 commits into
haskell:masterfrom
sheaf:T12538
Open

sheaf wants to merge 7 commits into
haskell:masterfrom
sheaf:T12538

Conversation

@sheaf

@sheaf sheaf commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator

This PR implements #12538. Apart for some niche edge cases (see the changelog entries), this doesn't change the behaviour of Cabal or cabal-install, although it does change the Cabal API in various small ways.

TODO:

Template Α: This PR modifies behaviour or interface

No new tests or QA notes: for the most part, the behaviour doesn't change (except for some edge cases like not passing --prefix to ./configure for build-type: Configure... all documented in changelog entries).

`cabal-install` used to invoke external `Setup` executables in the package
directory, while also passing them the package directory with `--working-dir`.
Now:

  - Packages with `build-type: Custom` or `Make` are invoked in the package
    directory, and are no longer passed `--working-dir`.
  - Other packages are invoked in the current directory (usually the project
    directory), and are passed a `--working-dir`. This is consistent with the
    in-library method.

The user guide has been updated to properly explain this.

Fixes haskell#12539
The targets of a Setup invocation (e.g. "lib:foo" in "./Setup build lib:foo")
are now stored in the flags specific to each command, moved out from
CommonSetupFlags. This ensures that everything in CommonSetupFlags is
independent of components.
@sheaf
sheaf force-pushed the T12538 branch 2 times, most recently from 2b6aed8 to 8e5a711 Compare November 10, 2026 12:17
This commit splits up ConfigFlags into PackageConfigFlags (for
package-wide configuration) and ComponentConfigFlags (for per-component
configuration).

The existing 'ConfigFlags' API is preserved using a pattern synonym.

Also fixes the hand-written 'Eq' instance for 'ConfigFlags' which had
fallen out of sync (it didn't compare 'configInstantiateWith' nor
'configExtraFrameworkDirs'). Now the 'Eq' instance is derived.

The unused 'configScratchDir' field has also been removed.
This commit splits off the working directory and dist directory fields
of LocalBuildInfo (which were stored in CommonSetupFlags) into a
separate type 'BuildLocation' which is never serialised.

This is because the build location must be passed when deserialising,
e.g. 'getPersistBuildConfig' takes the build location as arguments:

getPersistBuildConfig
  :: Maybe (SymbolicPath CWD (Dir Pkg))
  -> SymbolicPath Pkg (Dir Dist)
  -> IO LocalBuildInfo

so it makes no sense to redundantly store the working directory and the
dist directory in 'LocalBuildInfo'.

As the build location was also stored inside CommonSetupFlags inside
ConfigFlags, to avoid it being serialised we also remove 'configFlags'
from 'LocalBuildInfo', replacing it with separate 'packageConfigFlags'
and 'componentConfigFlags'.
We add a new deprecated function 'configFlags :: LocalBuildInfo -> ConfigFlags'
as a compatibility shim.
This commit moves the information which can differ between components
out of the package-wide 'PackageBuildDescr' into the per-component
'ComponentBuildDescr'.

Fields moved:
  - component-level configure flags
  - enabled components
  - install directories
  - package databases
  - coverage targets

As a consequence, 'build-type: Configure' scripts are no longer passed
the installation directories (--prefix, --libdir, ...), as these are
fundamentally per-component.
The per-component configure hooks overwrote the package-wide package
description stored in PackageBuildDescr.

Instead, the package description is now left alone, and we keep the
diff stored in the per-component ComponentBuildDescr. This cleanly
separates "whole package" vs "per component" information.
Cabal's configure function is finally split up into whole package and
per-component steps. The whole package 'configurePackage' function takes
only package-level inputs, nothing specific to any individual component.
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