Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5457a59
refactor(cabal-install,Cabal): move programDbSignature to Cabal
andreabedini Mar 19, 2025
2e33247
refactor(cabal-install): separate GenericReadyPackage from ReadyPackage
andreabedini May 8, 2025
6279d14
refactor(cabal-install): resolve package dbs during planning
andreabedini Apr 8, 2025
d4516ff
refactor(cabal-install): remove workaround for build tools listed as …
andreabedini May 5, 2025
23b082b
refactor(cabal-install): move elabInstantiatedWith and elabLinkedInst…
andreabedini May 5, 2025
de98287
feat(cabal-install-solver): introduce Stage and Toolchain
andreabedini Mar 20, 2025
e7edc74
feat(cabal-install): introduce ProjectConfigToolchain
andreabedini Apr 2, 2025
039160a
cross-compile: make solver stage-aware
andreabedini Mar 21, 2025
e88379f
refactor(cabal-install): don't check for compiler support before usi…
andreabedini Jul 24, 2025
786330d
feat(cabal-install): add build compiler option
andreabedini Mar 20, 2025
ecc7c12
cross-compile: replace flat compiler/platform fields with Toolchains …
andreabedini Mar 21, 2025
d1d2328
feat(cabal-install): add stage to ConstraintScope and UserConstraint
andreabedini Apr 2, 2025
ab21c2d
refactor(cabal-install-solver): improve messages
andreabedini Apr 23, 2025
9ee5204
refactor(cabal-install): use a pretty printer in showDepResolverParams
andreabedini Apr 23, 2025
cdd42cc
feat(cabal-install-solver): add null to ComponentDeps
andreabedini Apr 23, 2025
edd6679
feat(cabal-install-solver): add Pretty instance for SolverId
andreabedini Apr 23, 2025
f644628
refactor(cabal-install): merge two almost identical functions
andreabedini Apr 28, 2025
22eb45e
chore(cabal-install-solver): add comments and improve readability
andreabedini Apr 29, 2025
336f88a
feat(cabal-install, cabal-install-solver): track stage in SolverId
andreabedini Jul 2, 2025
4d1fc99
fix(cabal-install): rewrite dependencyInconsistencies
andreabedini May 1, 2025
567218b
refactor(cabal-install-solver): refactor modularResolver
andreabedini Jun 23, 2025
0f65e87
refactor(cabal-install): generalise GenericInstallPlan to arbitrary n…
andreabedini Aug 7, 2025
b809870
chore(Cabal): update reference to backpack-include field, now called …
andreabedini May 6, 2025
2fd55fa
feat: add a bunch of HasCallStack
andreabedini Jun 25, 2025
2636873
fix: use nodeKey in fromSolverInstallPlanWithProgress
andreabedini May 19, 2025
f6a04f1
propagate stage trough elaborateProjectPlanning
andreabedini May 5, 2025
22812d4
fix(cabal-install): rewrite instantiateInstallPlan
andreabedini Aug 7, 2025
7948671
refactor(cabal-install): reduce scope in ProjectPlanning
andreabedini Jul 14, 2025
a907ffc
refactor(cabal-install): readability improvements
andreabedini May 20, 2025
beeea52
fix(cabal-install): use the correct stage for setup deps
andreabedini May 27, 2025
4c8d003
refactor(cabal-install): rebuildTargets
andreabedini May 27, 2025
e231fcc
feat(cabal-install): more logging in buildAndRegisterUnpackedPackage
andreabedini May 27, 2025
f7d5e2f
fix(cabal-install): use the correct packagedb for setup
andreabedini Jun 25, 2025
ab85b21
fix(cabal-install): fix pkgsToBuildInPlaceOnly
andreabedini May 28, 2025
d8c7381
refactor(cabal-install): seprate build directories and drop -inplace
andreabedini Jul 26, 2025
67139dd
fix(Cabal): do not use GHC to configure LD
angerman May 22, 2025
7371984
feat(cabal-install): add parser for UserQualExe
andreabedini Jul 10, 2025
588e26b
feat(cabal-install): add ScopeAnyExeQualifier and UserAnyExeQualifier
andreabedini Jul 10, 2025
f78f6f6
refactor(cabal-install): refactor InstallPlan.problems
andreabedini Jul 28, 2025
59d259c
refactor(cabal-install): use LogProgress in InstallPlan
andreabedini Aug 1, 2025
92d6b67
feat(cabal-install): implicilty monitor our own executable to burst s…
andreabedini Aug 1, 2025
78ff09d
refactor(Cabal-syntax): Improve Graph.broken
andreabedini Aug 4, 2025
ab2a804
refactor(cabal-install): harmonise various dependency functions
andreabedini Aug 4, 2025
7152349
refactor(cabal-install): rename, format and comment
andreabedini Aug 5, 2025
55fbb4f
refactor(cabal-install): pkgDependsOnSelfLib should not hide failures
andreabedini Aug 5, 2025
dd2faa1
fix(Cabal): do not print finalized package description, it loops
andreabedini Aug 6, 2025
ec8c4f8
feature(cabal-install): improve logging of setup arguments
andreabedini Aug 6, 2025
9487f1f
fix(Cabal): fix abi tag in case ghc's unit-id is the same as the comp…
andreabedini Aug 7, 2025
7829375
fix(Cabal): disable logging of the response file
andreabedini Jul 30, 2025
8d14cf8
fixup! fix(Cabal): do not use GHC to configure LD
angerman Aug 26, 2025
9b3438d
Fix compilation with TH
hasufell Dec 10, 2025
793eef8
feat(testsuite): add --with-build-compiler flag to test runner
andreabedini May 18, 2026
0dd7c97
test: add BuildCompilerSetup integration test verifying build compile…
andreabedini May 18, 2026
de8db60
fix: only apply installedPkgIndex filter to Host stage, not Build
andreabedini May 19, 2026
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
30 changes: 20 additions & 10 deletions Cabal-syntax/src/Distribution/Compat/Graph.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@
import qualified Data.Array as Array
import qualified Data.Foldable as Foldable
import qualified Data.Graph as G
import qualified Data.List.NonEmpty as NE
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Data.Tree as Tree
import qualified Distribution.Compat.Prelude as Prelude
import GHC.Stack (HasCallStack)

-- | A graph of nodes @a@. The nodes are expected to have instance
-- of class 'IsNode'.
Expand All @@ -114,7 +115,7 @@
, graphAdjoint :: G.Graph
, graphVertexToNode :: G.Vertex -> a
, graphKeyToVertex :: Key a -> Maybe G.Vertex
, graphBroken :: [(a, [Key a])]
, graphBroken :: [(a, NonEmpty (Key a))]
}

-- NB: Not a Functor! (or Traversable), because you need
Expand Down Expand Up @@ -284,7 +285,7 @@
-- | /O(1)/. Return a list of nodes paired with their broken
-- neighbors (i.e., neighbor keys which are not in the graph).
-- Requires amortized construction of graph.
broken :: Graph a -> [(a, [Key a])]
broken :: Graph a -> [(a, NonEmpty (Key a))]
broken g = graphBroken g

-- | Lookup the immediate neighbors from a key in the graph.
Expand Down Expand Up @@ -343,7 +344,7 @@
-- if you can't fulfill this invariant use @'fromList' ('Data.Map.elems' m)@
-- instead. The values of the map are assumed to already
-- be in WHNF.
fromMap :: IsNode a => Map (Key a) a -> Graph a
fromMap :: forall a. (IsNode a, Eq (Key a)) => Map (Key a) a -> Graph a
fromMap m =
Graph
{ graphMap = m
Expand All @@ -352,17 +353,26 @@
, graphAdjoint = G.transposeG g
, graphVertexToNode = vertex_to_node
, graphKeyToVertex = key_to_vertex
, graphBroken = broke
, graphBroken =
map (\ns'' -> (fst (NE.head ns''), NE.map snd ns'')) $
NE.groupWith (nodeKey . fst) $

Check warning on line 358 in Cabal-syntax/src/Distribution/Compat/Graph.hs

View workflow job for this annotation

GitHub Actions / hlint

Suggestion in fromMap in module Distribution.Compat.Graph: Redundant $ ▫︎ Found: "NE.groupWith (nodeKey . fst) $ brokenEdges'" ▫︎ Perhaps: "NE.groupWith (nodeKey . fst) brokenEdges'"
brokenEdges'
}
where
try_key_to_vertex k = maybe (Left k) Right (key_to_vertex k)
brokenEdges' :: [(a, Key a)]
brokenEdges' = concat brokenEdges

brokenEdges :: [[(a, Key a)]]
(brokenEdges, edges) =
unzip $
[ partitionEithers (map try_key_to_vertex (nodeNeighbors n))
unzip
[ partitionEithers
[ case key_to_vertex n' of
Just v -> Right v
Nothing -> Left (n, n')
| n' <- nodeNeighbors n
]
| n <- ns
]
broke = filter (not . Prelude.null . snd) (zip ns brokenEdges)

g = Array.listArray bounds edges

Expand All @@ -377,7 +387,7 @@
bounds = (0, Map.size m - 1)

-- | /O(V log V)/. Convert a list of nodes (with distinct keys) into a graph.
fromDistinctList :: (IsNode a, Show (Key a)) => [a] -> Graph a
fromDistinctList :: HasCallStack => (IsNode a, Show (Key a)) => [a] -> Graph a
fromDistinctList =
fromMap
. Map.fromListWith (\_ -> duplicateError)
Expand Down
4 changes: 3 additions & 1 deletion Cabal/src/Distribution/Backpack/ComponentsGraph.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Distribution.Types.ComponentRequestedSpec
import Distribution.Utils.Generic

import Distribution.Pretty (pretty)
import GHC.Stack (HasCallStack)
import Text.PrettyPrint

------------------------------------------------------------------------------
Expand Down Expand Up @@ -50,7 +51,8 @@ dispComponentsWithDeps graph =
-- | Create a 'Graph' of 'Component', or report a cycle if there is a
-- problem.
mkComponentsGraph
:: ComponentRequestedSpec
:: HasCallStack
=> ComponentRequestedSpec
-> PackageDescription
-> Either [ComponentName] ComponentsGraph
mkComponentsGraph enabled pkg_descr =
Expand Down
15 changes: 9 additions & 6 deletions Cabal/src/Distribution/Backpack/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ import Data.Either
import qualified Data.Map as Map
import qualified Data.Set as Set
import Distribution.Pretty
import GHC.Stack (HasCallStack)
import Text.PrettyPrint

------------------------------------------------------------------------------
-- Pipeline
------------------------------------------------------------------------------

configureComponentLocalBuildInfos
:: Verbosity
:: HasCallStack
=> Verbosity
-> Bool -- use_external_internal_deps
-> ComponentRequestedSpec
-> Bool -- deterministic
Expand Down Expand Up @@ -206,7 +208,8 @@ configureComponentLocalBuildInfos
------------------------------------------------------------------------------

toComponentLocalBuildInfos
:: Compiler
:: HasCallStack
=> Compiler
-> InstalledPackageIndex -- FULL set
-> [ConfiguredPromisedComponent]
-> PackageDescription
Expand All @@ -232,12 +235,12 @@ toComponentLocalBuildInfos
-- since we will pay for the ALL installed packages even if
-- they are not related to what we are building. This was true
-- in the old configure code.
external_graph :: Graph (Either InstalledPackageInfo ReadyComponent)
external_graph :: HasCallStack => Graph (Either InstalledPackageInfo ReadyComponent)
external_graph =
Graph.fromDistinctList
. map Left
$ PackageIndex.allPackages installedPackageSet
internal_graph :: Graph (Either InstalledPackageInfo ReadyComponent)
internal_graph :: HasCallStack => Graph (Either InstalledPackageInfo ReadyComponent)
internal_graph =
Graph.fromDistinctList
. map Right
Expand Down Expand Up @@ -280,14 +283,14 @@ toComponentLocalBuildInfos
[ "installed package "
++ prettyShow (packageId pkg)
++ " is broken due to missing package "
++ intercalate ", " (map prettyShow deps)
++ intercalate ", " (map prettyShow $ toList deps)
| (Left pkg, deps) <- broken
]
++ unlines
[ "planned package "
++ prettyShow (packageId pkg)
++ " is broken due to missing package "
++ intercalate ", " (map prettyShow deps)
++ intercalate ", " (map prettyShow $ toList deps)
| (Right pkg, deps) <- broken
]

Expand Down
4 changes: 2 additions & 2 deletions Cabal/src/Distribution/Backpack/ConfiguredComponent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ dispConfiguredComponent cc =

-- | Construct a 'ConfiguredComponent', given that the 'ComponentId'
-- and library/executable dependencies are known. The primary
-- work this does is handling implicit @backpack-include@ fields.
-- work this does is handling implicit @mixin@ fields.
mkConfiguredComponent
:: PackageDescription
-> ComponentId
Expand All @@ -121,7 +121,7 @@ mkConfiguredComponent pkg_descr this_cid lib_deps exe_deps component = do
}

-- Any @build-depends@ which is not explicitly mentioned in
-- @backpack-include@ is converted into an "implicit" include.
-- @mixin@ is converted into an "implicit" include.
let used_explicitly = Set.fromList (map ci_id explicit_includes)
implicit_includes =
map
Expand Down
12 changes: 7 additions & 5 deletions Cabal/src/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ import Distribution.Package
import Distribution.PackageDescription
import Distribution.PackageDescription.Check hiding (doesFileExist, listDirectory)
import Distribution.PackageDescription.Configuration
import Distribution.PackageDescription.PrettyPrint
import Distribution.Simple.BuildTarget
import Distribution.Simple.BuildToolDepends
import Distribution.Simple.BuildWay
Expand Down Expand Up @@ -196,6 +195,7 @@ import Text.PrettyPrint
import qualified Data.Maybe as M
import qualified Data.Set as Set
import qualified Distribution.Compat.NonEmptySet as NES
import GHC.Stack (HasCallStack)

type UseExternalInternalDeps = Bool

Expand Down Expand Up @@ -1146,9 +1146,10 @@ configurePackage verbHandles cfg lbc0 pkg_descr00 flags enabled comp platform pa
, extraCoverageFor = []
}

debug verbosity $
"Finalized package description:\n"
++ showPackageDescription pkg_descr2
-- FIXME: Printing the package description loops indefinitely.
-- debug verbosity $
-- "Finalized package description:\n"
-- ++ showPackageDescription pkg_descr2

return (lbc, pbd)

Expand Down Expand Up @@ -1393,7 +1394,8 @@ finalCheckPackage
CantFindForeignLibraries unsupportedFLibs

configureComponents
:: VerbosityHandles
:: HasCallStack
=> VerbosityHandles
-> LBC.LocalBuildConfig
-> LBC.PackageBuildDescr
-> InstalledPackageIndex
Expand Down
18 changes: 9 additions & 9 deletions Cabal/src/Distribution/Simple/GHC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,13 @@ configureCompiler verbosity hcPath conf0 = do
-- In this example, @AbiTag@ is "inplace".
compilerAbiTag :: AbiTag
compilerAbiTag =
maybe NoAbiTag (AbiTag . dropWhile (== '-') . stripCommonPrefix (prettyShow compilerId)) projectUnitId
case projectUnitId of
Nothing -> NoAbiTag
Just "" -> NoAbiTag
Just unitId ->
case dropWhile (== '-') $ stripCommonPrefix (prettyShow compilerId) unitId of
"" -> NoAbiTag
tag -> AbiTag tag

wiredInUnitIds = do
ghcInternalUnitId <- Map.lookup "ghc-internal Unit Id" ghcInfoMap
Expand Down Expand Up @@ -312,14 +318,8 @@ compilerProgramDb verbosity comp progdb1 hcPkgPath = do
ghcProg = fromJust $ lookupProgram ghcProgram progdb1
ghcVersion = compilerVersion comp

-- configure gcc, ld, ar etc... based on the paths stored
-- in the GHC settings file
progdb3 =
Internal.configureToolchain
(ghcVersionImplInfo ghcVersion)
ghcProg
(compilerProperties comp)
progdb2
-- configure gcc, ld, ar etc... based on the paths stored in the GHC settings file
progdb3 <- Internal.configureToolchain verbosity (ghcVersionImplInfo ghcVersion) ghcProg (compilerProperties comp) progdb2

-- This is slightly tricky, we have to configure ghc first, then we use the
-- location of ghc to help find ghc-pkg in the case that the user did not
Expand Down
81 changes: 45 additions & 36 deletions Cabal/src/Distribution/Simple/GHC/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,37 +100,47 @@

-- | Adjust the way we find and configure gcc and ld
configureToolchain
:: GhcImplInfo
:: Verbosity
-> GhcImplInfo
-> ConfiguredProgram
-> Map String String
-> ProgramDb
-> ProgramDb
configureToolchain _implInfo ghcProg ghcInfo =
addKnownProgram
gccProgram
{ programFindLocation = findProg gccProgramName extraGccPath
, programPostConf = configureGcc
}
. addKnownProgram
gppProgram
{ programFindLocation = findProg gppProgramName extraGppPath
, programPostConf = configureGpp
}
. addKnownProgram
ldProgram
{ programFindLocation = findProg ldProgramName extraLdPath
, programPostConf = \v cp ->
-- Call any existing configuration first and then add any new configuration
configureLd v =<< programPostConf ldProgram v cp
}
. addKnownProgram
arProgram
{ programFindLocation = findProg arProgramName extraArPath
}
. addKnownProgram
stripProgram
{ programFindLocation = findProg stripProgramName extraStripPath
-> IO ProgramDb
configureToolchain verbosity _implInfo ghcProg ghcInfo db = do
-- this is a bit of a hack. We have a dependency of ld on gcc.
-- ld needs to compiler a c program, to check an ld feature.
-- we _could_ use ghc as a c frontend, but we do not pass all
-- db stack appropriately, and thus we can run into situations
-- where GHC will fail if it's stricter in it's wired-in-unit
-- selction and has the wrong db stack. However we don't need
-- ghc to compile a _test_ c program. So we configure `gcc`
-- first and then use `gcc` (the generic c compiler in cabal
-- terminology) to compile the test program.
let gccProgram' = gccProgram
{ programFindLocation = findProg gccProgramName extraGccPath
, programPostConf = configureGcc
}
let db' = flip addKnownProgram db $ gccProgram'

Check warning on line 123 in Cabal/src/Distribution/Simple/GHC/Internal.hs

View workflow job for this annotation

GitHub Actions / hlint

Suggestion in configureToolchain in module Distribution.Simple.GHC.Internal: Redundant $ ▫︎ Found: "flip addKnownProgram db $ gccProgram'" ▫︎ Perhaps: "flip addKnownProgram db gccProgram'"
(gccProg, db'') <- requireProgram verbosity gccProgram' db'
return $
flip addKnownPrograms db'' $

Check warning on line 126 in Cabal/src/Distribution/Simple/GHC/Internal.hs

View workflow job for this annotation

GitHub Actions / hlint

Suggestion in configureToolchain in module Distribution.Simple.GHC.Internal: Redundant $ ▫︎ Found: "flip addKnownPrograms db''\n $ [gppProgram\n {programFindLocation = findProg gppProgramName extraGppPath,\n programPostConf = configureGpp},\n ldProgram\n {programFindLocation = findProg ldProgramName extraLdPath,\n programPostConf = \\ v cp\n -> configureLd gccProg v =<< programPostConf ldProgram v cp},\n arProgram\n {programFindLocation = findProg arProgramName extraArPath},\n stripProgram\n {programFindLocation = findProg stripProgramName extraStripPath}]" ▫︎ Perhaps: "flip\n addKnownPrograms db''\n [gppProgram\n {programFindLocation = findProg gppProgramName extraGppPath,\n programPostConf = configureGpp},\n ldProgram\n {programFindLocation = findProg ldProgramName extraLdPath,\n programPostConf = \\ v cp\n -> configureLd gccProg v =<< programPostConf ldProgram v cp},\n arProgram\n {programFindLocation = findProg arProgramName extraArPath},\n stripProgram\n {programFindLocation = findProg stripProgramName extraStripPath}]"
[ gppProgram
{ programFindLocation = findProg gppProgramName extraGppPath
, programPostConf = configureGpp
}
, ldProgram
{ programFindLocation = findProg ldProgramName extraLdPath
, programPostConf = \v cp ->
-- Call any existing configuration first and then add any new configuration
configureLd gccProg v =<< programPostConf ldProgram v cp
}
, arProgram
{ programFindLocation = findProg arProgramName extraArPath
}
, stripProgram
{ programFindLocation = findProg stripProgramName extraStripPath
}
]
where
compilerDir, base_dir, mingwBinDir :: FilePath
compilerDir = takeDirectory (programPath ghcProg)
Expand Down Expand Up @@ -228,27 +238,26 @@
++ cxxFlags
}

configureLd :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
configureLd v ldProg = do
ldProg' <- configureLd' v ldProg
configureLd :: ConfiguredProgram -> Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
configureLd gccProg v ldProg = do
ldProg' <- configureLd' gccProg v ldProg
return
ldProg'
{ programDefaultArgs = programDefaultArgs ldProg' ++ ldLinkerFlags
}

-- we need to find out if ld supports the -x flag
configureLd' :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
configureLd' verbosity ldProg = do
configureLd' :: ConfiguredProgram -> Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
configureLd' gccProg v ldProg = do
ldx <- withTempFile ".c" $ \testcfile testchnd ->
withTempFile ".o" $ \testofile testohnd -> do
hPutStrLn testchnd "int foo() { return 0; }"
hClose testchnd
hClose testohnd
runProgram
verbosity
ghcProg
[ "-hide-all-packages"
, "-c"
v
gccProg
[ "-c"
, testcfile
, "-o"
, testofile
Expand Down
15 changes: 15 additions & 0 deletions Cabal/src/Distribution/Simple/Program/Db.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ module Distribution.Simple.Program.Db
, updateUnconfiguredProgs
, updateConfiguredProgs
, updatePathProgDb
, programDbSignature
) where

import Distribution.Compat.Prelude
Expand Down Expand Up @@ -604,3 +605,17 @@ requireProgramVersion verbosity prog range programDb =
join $
either (dieWithException verbosity) return
`fmap` lookupProgramVersion verbosity prog range programDb

-- | Select the bits of a 'ProgramDb' to monitor for value changes.
-- Use 'programsMonitorFiles' for the files to monitor.
programDbSignature :: ProgramDb -> [ConfiguredProgram]
programDbSignature progdb =
[ prog
{ programMonitorFiles = []
, programOverrideEnv =
filter
((/= "PATH") . fst)
(programOverrideEnv prog)
}
| prog <- configuredPrograms progdb
]
Loading
Loading