From f03ad8d09cfbe3b64a17cb144bc191c8d0f61632 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Thu, 6 Mar 2025 17:54:46 +0800 Subject: [PATCH 01/82] feat: add per-file options to extra source files --- Cabal-syntax/Cabal-syntax.cabal | 1 + .../src/Distribution/PackageDescription.hs | 4 + .../PackageDescription/FieldGrammar.hs | 19 +++-- .../src/Distribution/Types/BuildInfo.hs | 20 +++-- .../src/Distribution/Types/BuildInfo/Lens.hs | 13 +-- .../src/Distribution/Types/ExtraSource.hs | 48 +++++++++++ Cabal-tests/tests/NoThunks.hs | 2 + .../Distribution/Utils/Structured.hs | 4 +- .../src/Data/TreeDiff/Instances/Cabal.hs | 2 + .../PackageDescription/Check/Target.hs | 14 ++-- Cabal/src/Distribution/Simple/Build.hs | 20 ++--- Cabal/src/Distribution/Simple/BuildTarget.hs | 10 +-- .../Simple/GHC/Build/ExtraSources.hs | 63 ++++++++------- Cabal/src/Distribution/Simple/GHC/Internal.hs | 79 +++++++------------ Cabal/src/Distribution/Simple/GHCJS.hs | 32 ++++---- Cabal/src/Distribution/Simple/SrcDist.hs | 10 +-- .../src/Distribution/Client/SourceFiles.hs | 11 +-- .../src/Distribution/Client/TargetSelector.hs | 5 +- cabal-install/tests/IntegrationTests2.hs | 4 +- .../PackageTests/ExtraSources/cbits/test.c | 3 + .../ExtraSources/extra-sources.cabal | 10 +++ .../PackageTests/ExtraSources/setup.out | 5 ++ .../PackageTests/ExtraSources/setup.test.hs | 5 ++ .../PackageTests/ExtraSources/src/MyLib.hs | 4 + 24 files changed, 235 insertions(+), 153 deletions(-) create mode 100644 Cabal-syntax/src/Distribution/Types/ExtraSource.hs create mode 100644 cabal-testsuite/PackageTests/ExtraSources/cbits/test.c create mode 100644 cabal-testsuite/PackageTests/ExtraSources/extra-sources.cabal create mode 100644 cabal-testsuite/PackageTests/ExtraSources/setup.out create mode 100644 cabal-testsuite/PackageTests/ExtraSources/setup.test.hs create mode 100644 cabal-testsuite/PackageTests/ExtraSources/src/MyLib.hs diff --git a/Cabal-syntax/Cabal-syntax.cabal b/Cabal-syntax/Cabal-syntax.cabal index 997b91363ce..64aee5d23a4 100644 --- a/Cabal-syntax/Cabal-syntax.cabal +++ b/Cabal-syntax/Cabal-syntax.cabal @@ -140,6 +140,7 @@ library Distribution.Types.Executable Distribution.Types.Executable.Lens Distribution.Types.ExecutableScope + Distribution.Types.ExtraSource Distribution.Types.ExposedModule Distribution.Types.Flag Distribution.Types.ForeignLib diff --git a/Cabal-syntax/src/Distribution/PackageDescription.hs b/Cabal-syntax/src/Distribution/PackageDescription.hs index 47d46673e5f..71078654e68 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription.hs @@ -48,6 +48,9 @@ module Distribution.PackageDescription , module Distribution.Types.HookedBuildInfo , module Distribution.Types.SetupBuildInfo + -- * Extra sources + , module Distribution.Types.ExtraSource + -- * Flags , module Distribution.Types.Flag @@ -95,6 +98,7 @@ import Distribution.Types.ComponentName import Distribution.Types.CondTree import Distribution.Types.Condition import Distribution.Types.ConfVar +import Distribution.Types.ExtraSource import Distribution.Types.Dependency import Distribution.Types.ExeDependency import Distribution.Types.Executable diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index 49db03ee3c1..bb6f3f25eee 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -174,6 +174,7 @@ libraryFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) + , c (List VCat (Identity ExtraSource) ExtraSource) , c (List CommaVCat (Identity ModuleReexport) ModuleReexport) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -224,6 +225,7 @@ foreignLibFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) + , c (List VCat (Identity ExtraSource) ExtraSource) , c (List FSep (Identity ForeignLibOption) ForeignLibOption) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -263,6 +265,7 @@ executableFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) + , c (List VCat (Identity ExtraSource) ExtraSource) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -339,6 +342,7 @@ testSuiteFieldGrammar , c (List CommaFSep Token String) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) + , c (List VCat (Identity ExtraSource) ExtraSource) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -483,6 +487,7 @@ benchmarkFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) + , c (List VCat (Identity ExtraSource) ExtraSource) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -585,6 +590,7 @@ buildInfoFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) + , c (List VCat (Identity ExtraSource) ExtraSource) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -627,14 +633,14 @@ buildInfoFieldGrammar = <*> monoidalFieldAla "pkgconfig-depends" (alaList CommaFSep) L.pkgconfigDepends <*> monoidalFieldAla "frameworks" (alaList' FSep RelativePathNT) L.frameworks <*> monoidalFieldAla "extra-framework-dirs" (alaList' FSep SymbolicPathNT) L.extraFrameworkDirs - <*> monoidalFieldAla "asm-sources" (alaList' VCat SymbolicPathNT) L.asmSources + <*> monoidalFieldAla "asm-sources" formatExtraSources L.asmSources ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "cmm-sources" (alaList' VCat SymbolicPathNT) L.cmmSources + <*> monoidalFieldAla "cmm-sources" formatExtraSources L.cmmSources ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "c-sources" (alaList' VCat SymbolicPathNT) L.cSources - <*> monoidalFieldAla "cxx-sources" (alaList' VCat SymbolicPathNT) L.cxxSources + <*> monoidalFieldAla "c-sources" formatExtraSources L.cSources + <*> monoidalFieldAla "cxx-sources" formatExtraSources L.cxxSources ^^^ availableSince CabalSpecV2_2 [] - <*> monoidalFieldAla "js-sources" (alaList' VCat SymbolicPathNT) L.jsSources + <*> monoidalFieldAla "js-sources" formatExtraSources L.jsSources <*> hsSourceDirsGrammar <*> monoidalFieldAla "other-modules" formatOtherModules L.otherModules <*> monoidalFieldAla "virtual-modules" (alaList' VCat MQuoted) L.virtualModules @@ -834,6 +840,9 @@ formatOtherExtensions = alaList' FSep MQuoted formatOtherModules :: [ModuleName] -> List VCat (MQuoted ModuleName) ModuleName formatOtherModules = alaList' VCat MQuoted +formatExtraSources :: [ExtraSource] -> List VCat (Identity ExtraSource) ExtraSource +formatExtraSources = alaList' VCat Identity + ------------------------------------------------------------------------------- -- newtypes ------------------------------------------------------------------------------- diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs index 2d7a5edeae1..a4a68546b92 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs @@ -21,6 +21,7 @@ import Prelude () import Distribution.Types.Dependency import Distribution.Types.ExeDependency +import Distribution.Types.ExtraSource import Distribution.Types.LegacyExeDependency import Distribution.Types.Mixin import Distribution.Types.PkgconfigDependency @@ -70,14 +71,17 @@ data BuildInfo = BuildInfo , frameworks :: [RelativePath Framework File] -- ^ support frameworks for Mac OS X , extraFrameworkDirs :: [SymbolicPath Pkg (Dir Framework)] - -- ^ extra locations to find frameworks. - , asmSources :: [SymbolicPath Pkg File] - -- ^ Assembly files. - , cmmSources :: [SymbolicPath Pkg File] - -- ^ C-- files. - , cSources :: [SymbolicPath Pkg File] - , cxxSources :: [SymbolicPath Pkg File] - , jsSources :: [SymbolicPath Pkg File] + -- ^ extra locations to find frameworks + , asmSources :: [ExtraSource] + -- ^ Assembly source files + , cmmSources :: [ExtraSource] + -- ^ C-- source files + , cSources :: [ExtraSource] + -- ^ C source files + , cxxSources :: [ExtraSource] + -- ^ C++ source files + , jsSources :: [ExtraSource] + -- ^ JavaScript source file , hsSourceDirs :: [SymbolicPath Pkg (Dir Source)] -- ^ where to look for the Haskell module hierarchy , -- NB: these are symbolic paths are not relative paths, diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs index ac99f3c65a5..e50b41485a8 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs @@ -13,6 +13,7 @@ import Prelude () import Distribution.Compiler (PerCompilerFlavor) import Distribution.ModuleName (ModuleName) import Distribution.Types.BuildInfo (BuildInfo) +import Distribution.Types.ExtraSource (ExtraSource) import Distribution.Types.Dependency (Dependency) import Distribution.Types.ExeDependency (ExeDependency) import Distribution.Types.LegacyExeDependency (LegacyExeDependency) @@ -79,23 +80,23 @@ class HasBuildInfo a where extraFrameworkDirs = buildInfo . extraFrameworkDirs {-# INLINE extraFrameworkDirs #-} - asmSources :: Lens' a [SymbolicPath Pkg File] + asmSources :: Lens' a [ExtraSource] asmSources = buildInfo . asmSources {-# INLINE asmSources #-} - cmmSources :: Lens' a [SymbolicPath Pkg File] + cmmSources :: Lens' a [ExtraSource] cmmSources = buildInfo . cmmSources {-# INLINE cmmSources #-} - cSources :: Lens' a [SymbolicPath Pkg File] + cSources :: Lens' a [ExtraSource] cSources = buildInfo . cSources {-# INLINE cSources #-} - cxxSources :: Lens' a [SymbolicPath Pkg File] + cxxSources :: Lens' a [ExtraSource] cxxSources = buildInfo . cxxSources {-# INLINE cxxSources #-} - jsSources :: Lens' a [SymbolicPath Pkg File] + jsSources :: Lens' a [ExtraSource] jsSources = buildInfo . jsSources {-# INLINE jsSources #-} @@ -267,7 +268,7 @@ instance HasBuildInfo BuildInfo where cSources f s = fmap (\x -> s{T.cSources = x}) (f (T.cSources s)) {-# INLINE cSources #-} - cxxSources f s = fmap (\x -> s{T.cSources = x}) (f (T.cxxSources s)) + cxxSources f s = fmap (\x -> s{T.cxxSources = x}) (f (T.cxxSources s)) {-# INLINE cxxSources #-} jsSources f s = fmap (\x -> s{T.jsSources = x}) (f (T.jsSources s)) diff --git a/Cabal-syntax/src/Distribution/Types/ExtraSource.hs b/Cabal-syntax/src/Distribution/Types/ExtraSource.hs new file mode 100644 index 00000000000..f9ba481502c --- /dev/null +++ b/Cabal-syntax/src/Distribution/Types/ExtraSource.hs @@ -0,0 +1,48 @@ +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DataKinds #-} + +module Distribution.Types.ExtraSource + ( ExtraSource (..) + , extraSourceFromPath + ) where + +import Distribution.Compat.Prelude +import Prelude () + +import Distribution.Parsec +import Distribution.Pretty +import Distribution.Utils.Path (SymbolicPath, FileOrDir(..), Pkg) + +import qualified Distribution.Compat.CharParsing as P +import qualified Text.PrettyPrint as PP +import Distribution.FieldGrammar.Newtypes (SymbolicPathNT(..)) + +data ExtraSource = ExtraSource + { extraSourceFile :: SymbolicPath Pkg File + , extraSourceOpts :: [String] + } + deriving (Generic, Show, Read, Eq, Ord, Typeable, Data) + +instance Binary ExtraSource +instance Structured ExtraSource +instance NFData ExtraSource where rnf = genericRnf + +instance Parsec ExtraSource where + parsec = do + SymbolicPathNT path <- parsec <* P.spaces + opts <- P.optional (parensLax (P.sepBy p P.spaces)) + return (ExtraSource path (fromMaybe mempty opts)) + where + p :: P.CharParsing p => p String + p = some $ P.satisfy (\c -> not (isSpace c) && not (c == ')')) + +parensLax :: (P.CharParsing m) => m a -> m a +parensLax p = P.between (P.char '(' *> P.spaces) (P.char ')' *> P.spaces) p + +instance Pretty ExtraSource where + pretty (ExtraSource path opts) = + pretty (SymbolicPathNT path) <<>> PP.parens (PP.hsep (map PP.text opts)) + +extraSourceFromPath :: SymbolicPath Pkg File -> ExtraSource +extraSourceFromPath fp = ExtraSource fp mempty diff --git a/Cabal-tests/tests/NoThunks.hs b/Cabal-tests/tests/NoThunks.hs index 6a81475dc03..ffc4a4da0d9 100644 --- a/Cabal-tests/tests/NoThunks.hs +++ b/Cabal-tests/tests/NoThunks.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE FlexibleInstances #-} #if !(__GLASGOW_HASKELL__ >= 806 && defined(MIN_VERSION_nothunks)) module Main (main) where main :: IO () @@ -72,6 +73,7 @@ instance NoThunks ConfVar instance NoThunks Dependency instance NoThunks Executable instance NoThunks ExecutableScope +instance NoThunks ExtraSource instance NoThunks FlagName instance NoThunks ForeignLib instance NoThunks ForeignLibOption diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 47a0cc1bd2c..cd0f73aeedd 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -29,8 +29,8 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy - 0x09251b46ffc5178a7526d31e794d9c62 + 0x77f4c09dc9b1c6967b07516ad35e73af md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy - 0x8fa7b2c8cc611407bfdcb734ecb460a2 + 0x69dab39bf8b56871b28a2c14d423b18a diff --git a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs index cb36fe680db..42ab97cc4b0 100644 --- a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs +++ b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs @@ -1,5 +1,6 @@ {-# OPTIONS_GHC -freduction-depth=0 #-} {-# OPTIONS_GHC -Wno-orphans #-} +{-# LANGUAGE FlexibleInstances #-} module Data.TreeDiff.Instances.Cabal () where import Data.TreeDiff @@ -77,6 +78,7 @@ instance ToExpr ExeDependency instance ToExpr Executable instance ToExpr ExecutableScope instance ToExpr ExposedModule +instance ToExpr ExtraSource instance ToExpr FlagAssignment instance ToExpr FlagName instance ToExpr ForeignLib diff --git a/Cabal/src/Distribution/PackageDescription/Check/Target.hs b/Cabal/src/Distribution/PackageDescription/Check/Target.hs index 0bf173cb980..c62f7e40756 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Target.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Target.hs @@ -445,11 +445,11 @@ checkBuildInfoPathsContent bi = do -- Paths well-formedness check for BuildInfo. checkBuildInfoPathsWellFormedness :: Monad m => BuildInfo -> CheckM m () checkBuildInfoPathsWellFormedness bi = do - mapM_ (checkPath False "asm-sources" PathKindFile . getSymbolicPath) (asmSources bi) - mapM_ (checkPath False "cmm-sources" PathKindFile . getSymbolicPath) (cmmSources bi) - mapM_ (checkPath False "c-sources" PathKindFile . getSymbolicPath) (cSources bi) - mapM_ (checkPath False "cxx-sources" PathKindFile . getSymbolicPath) (cxxSources bi) - mapM_ (checkPath False "js-sources" PathKindFile . getSymbolicPath) (jsSources bi) + mapM_ (checkPath False "asm-sources" PathKindFile . getSymbolicPath . extraSourceFile) (asmSources bi) + mapM_ (checkPath False "cmm-sources" PathKindFile . getSymbolicPath . extraSourceFile) (cmmSources bi) + mapM_ (checkPath False "c-sources" PathKindFile . getSymbolicPath . extraSourceFile) (cSources bi) + mapM_ (checkPath False "cxx-sources" PathKindFile . getSymbolicPath . extraSourceFile) (cxxSources bi) + mapM_ (checkPath False "js-sources" PathKindFile . getSymbolicPath . extraSourceFile) (jsSources bi) mapM_ (checkPath False "install-includes" PathKindFile . getSymbolicPath) (installIncludes bi) @@ -515,8 +515,8 @@ checkBuildInfoFeatures bi sv = do (PackageBuildWarning CVExtensionsDeprecated) -- asm-sources, cmm-sources and friends only w/ spec ≥ 1.10 - checkCVSources (map getSymbolicPath $ asmSources bi) - checkCVSources (map getSymbolicPath $ cmmSources bi) + checkCVSources (map (getSymbolicPath . extraSourceFile) $ asmSources bi) + checkCVSources (map (getSymbolicPath . extraSourceFile) $ cmmSources bi) checkCVSources (extraBundledLibs bi) checkCVSources (extraLibFlavours bi) diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 0ebd51e48ef..410db8d3062 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -642,35 +642,35 @@ generateCode codeGens nm pdesc bi lbi clbi verbosity = do addExtraCSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraCSources bi extras = bi{cSources = new} where - new = ordNub (extras ++ cSources bi) + new = ordNub (map extraSourceFromPath extras ++ cSources bi) -- | Add extra C++ sources generated by preprocessing to build -- information. addExtraCxxSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraCxxSources bi extras = bi{cxxSources = new} where - new = ordNub (extras ++ cxxSources bi) + new = ordNub (map extraSourceFromPath extras ++ cxxSources bi) -- | Add extra C-- sources generated by preprocessing to build -- information. addExtraCmmSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraCmmSources bi extras = bi{cmmSources = new} where - new = ordNub (extras ++ cmmSources bi) + new = ordNub (map extraSourceFromPath extras ++ cmmSources bi) -- | Add extra ASM sources generated by preprocessing to build -- information. addExtraAsmSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraAsmSources bi extras = bi{asmSources = new} where - new = ordNub (extras ++ asmSources bi) + new = ordNub (map extraSourceFromPath extras ++ asmSources bi) -- | Add extra JS sources generated by preprocessing to build -- information. addExtraJsSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraJsSources bi extras = bi{jsSources = new} where - new = ordNub (extras ++ jsSources bi) + new = ordNub (map extraSourceFromPath extras ++ jsSources bi) -- | Add extra HS modules generated by preprocessing to build -- information. @@ -716,7 +716,7 @@ replComponent preprocessComponent pkg_descr comp lbi clbi False verbosity suffixHandlers extras <- preprocessExtras verbosity comp lbi let libbi = libBuildInfo lib - lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ extras}} + lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ map extraSourceFromPath extras}} replLib replFlags pkg lbi lib' libClbi replComponent replFlags @@ -733,23 +733,23 @@ replComponent case comp of CLib lib -> do let libbi = libBuildInfo lib - lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ extras}} + lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ map extraSourceFromPath extras}} replLib replFlags pkg_descr lbi lib' clbi CFLib flib -> replFLib replFlags pkg_descr lbi flib clbi CExe exe -> do let ebi = buildInfo exe - exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ extras}} + exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map extraSourceFromPath extras}} replExe replFlags pkg_descr lbi exe' clbi CTest test@TestSuite{testInterface = TestSuiteExeV10{}} -> do let exe = testSuiteExeV10AsExe test let ebi = buildInfo exe - exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ extras}} + exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map extraSourceFromPath extras}} replExe replFlags pkg_descr lbi exe' clbi CBench bm@Benchmark{benchmarkInterface = BenchmarkExeV10{}} -> do let exe = benchmarkExeV10asExe bm let ebi = buildInfo exe - exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ extras}} + exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map extraSourceFromPath extras}} replExe replFlags pkg_descr lbi exe' clbi #if __GLASGOW_HASKELL__ < 811 -- silence pattern-match warnings prior to GHC 9.0 diff --git a/Cabal/src/Distribution/Simple/BuildTarget.hs b/Cabal/src/Distribution/Simple/BuildTarget.hs index ffa7a609e6b..1d987c7715f 100644 --- a/Cabal/src/Distribution/Simple/BuildTarget.hs +++ b/Cabal/src/Distribution/Simple/BuildTarget.hs @@ -497,11 +497,11 @@ pkgComponentInfo pkg = , cinfoSrcDirs = map getSymbolicPath $ hsSourceDirs bi , cinfoModules = componentModules c , cinfoHsFiles = map getSymbolicPath $ componentHsFiles c - , cinfoAsmFiles = map getSymbolicPath $ asmSources bi - , cinfoCmmFiles = map getSymbolicPath $ cmmSources bi - , cinfoCFiles = map getSymbolicPath $ cSources bi - , cinfoCxxFiles = map getSymbolicPath $ cxxSources bi - , cinfoJsFiles = map getSymbolicPath $ jsSources bi + , cinfoAsmFiles = map (getSymbolicPath . extraSourceFile) $ asmSources bi + , cinfoCmmFiles = map (getSymbolicPath . extraSourceFile) $ cmmSources bi + , cinfoCFiles = map (getSymbolicPath . extraSourceFile) $ cSources bi + , cinfoCxxFiles = map (getSymbolicPath . extraSourceFile) $ cxxSources bi + , cinfoJsFiles = map (getSymbolicPath . extraSourceFile) $ jsSources bi } | c <- pkgComponents pkg , let bi = componentBuildInfo c diff --git a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs index f2ca9aba02f..9304d3691ae 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs @@ -26,6 +26,7 @@ import Distribution.Simple.Program.Types import Distribution.Simple.Setup.Common (commonSetupTempFileOptions) import Distribution.System (Arch (JavaScript), Platform (..)) import Distribution.Types.ComponentLocalBuildInfo +import Distribution.Types.ExtraSource (ExtraSource(..)) import Distribution.Utils.Path import Distribution.Verbosity (Verbosity) @@ -53,23 +54,21 @@ buildAllExtraSources = , buildCmmSources ] -buildCSources - , buildCxxSources - , buildJsSources - , buildAsmSources - , buildCmmSources - :: Maybe (SymbolicPath Pkg File) - -- ^ An optional non-Haskell Main file - -> ConfiguredProgram - -- ^ The GHC configured program - -> SymbolicPath Pkg (Dir Artifacts) - -- ^ The build directory for this target - -> (Bool -> [BuildWay], Bool -> BuildWay, BuildWay) - -- ^ Needed build ways - -> PreBuildComponentInputs - -- ^ The context and component being built in it. - -> IO (NubListR (SymbolicPath Pkg File)) - -- ^ Returns the list of extra sources that were built +type ExtraSourceBuilder = + Maybe (SymbolicPath Pkg File) + -- ^ An optional non-Haskell Main file + -> ConfiguredProgram + -- ^ The GHC configured program + -> SymbolicPath Pkg (Dir Artifacts) + -- ^ The build directory for this target + -> (Bool -> [BuildWay], Bool -> BuildWay, BuildWay) + -- ^ Needed build ways + -> PreBuildComponentInputs + -- ^ The context and component being built in it. + -> IO (NubListR (SymbolicPath Pkg File)) + -- ^ Returns the list of extra sources that were built + +buildCSources :: ExtraSourceBuilder buildCSources mbMainFile = buildExtraSources "C Sources" @@ -80,9 +79,11 @@ buildCSources mbMainFile = CExe{} | Just main <- mbMainFile , isC $ getSymbolicPath main -> - cFiles ++ [main] + cFiles ++ [ExtraSource main mempty] _otherwise -> cFiles ) + +buildCxxSources :: ExtraSourceBuilder buildCxxSources mbMainFile = buildExtraSources "C++ Sources" @@ -93,9 +94,11 @@ buildCxxSources mbMainFile = CExe{} | Just main <- mbMainFile , isCxx $ getSymbolicPath main -> - cxxFiles ++ [main] + cxxFiles ++ [ExtraSource main mempty] _otherwise -> cxxFiles ) + +buildJsSources :: ExtraSourceBuilder buildJsSources _mbMainFile ghcProg buildTargetDir neededWays = do Platform hostArch _ <- hostPlatform <$> localBuildInfo let hasJsSupport = hostArch == JavaScript @@ -114,11 +117,15 @@ buildJsSources _mbMainFile ghcProg buildTargetDir neededWays = do ghcProg buildTargetDir neededWays + +buildAsmSources :: ExtraSourceBuilder buildAsmSources _mbMainFile = buildExtraSources "Assembler Sources" Internal.componentAsmGhcOptions (asmSources . componentBuildInfo) + +buildCmmSources :: ExtraSourceBuilder buildCmmSources _mbMainFile = buildExtraSources "C-- Sources" @@ -136,14 +143,14 @@ buildExtraSources -> BuildInfo -> ComponentLocalBuildInfo -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File + -> ExtraSource -> GhcOptions ) -- ^ Function to determine the @'GhcOptions'@ for the -- invocation of GHC when compiling these extra sources (e.g. -- @'Internal.componentCxxGhcOptions'@, -- @'Internal.componentCmmGhcOptions'@) - -> (Component -> [SymbolicPath Pkg File]) + -> (Component -> [ExtraSource]) -- ^ View the extra sources of a component, typically from -- the build info (e.g. @'asmSources'@, @'cSources'@). -- @'Executable'@ components might additionally add the @@ -189,8 +196,8 @@ buildExtraSources platform mbWorkDir - buildAction :: SymbolicPath Pkg File -> IO () - buildAction sourceFile = do + buildAction :: ExtraSource -> IO () + buildAction extraSource = do let baseSrcOpts = componentSourceGhcOptions verbosity @@ -198,7 +205,7 @@ buildExtraSources bi clbi buildTargetDir - sourceFile + extraSource vanillaSrcOpts = -- -fPIC is used in case you are using the repl -- of a dynamically linked GHC @@ -228,9 +235,9 @@ buildExtraSources odir = fromFlag (ghcOptObjDir vanillaSrcOpts) compileIfNeeded :: GhcOptions -> IO () - compileIfNeeded opts = do - needsRecomp <- checkNeedsRecompilation mbWorkDir sourceFile opts - when needsRecomp $ runGhcProg opts + compileIfNeeded opts' = do + needsRecomp <- checkNeedsRecompilation mbWorkDir (extraSourceFile extraSource) opts' + when needsRecomp $ runGhcProg opts' createDirectoryIfMissingVerbose verbosity True (i odir) case targetComponent targetInfo of @@ -269,4 +276,4 @@ buildExtraSources else do info verbosity ("Building " ++ description ++ "...") traverse_ buildAction sources - return (toNubListR sources) + return (toNubListR (map extraSourceFile sources)) diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index 6e27b41bc83..f4083859dea 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -357,21 +357,24 @@ includePaths lbi bi clbi odir = | dir <- mapMaybe (symbolicPathRelative_maybe . unsafeCoerceSymbolicPath) $ includeDirs bi ] -componentCcGhcOptions - :: Verbosity - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentCcGhcOptions verbosity lbi bi clbi odir filename = +type ExtraSourceGhcOptions = + Verbosity + -> LocalBuildInfo + -> BuildInfo + -> ComponentLocalBuildInfo + -> SymbolicPath Pkg (Dir Artifacts) + -> ExtraSource + -> GhcOptions + + +componentCcGhcOptions :: ExtraSourceGhcOptions +componentCcGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [filename] + , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -388,6 +391,7 @@ componentCcGhcOptions verbosity lbi bi clbi odir filename = MaximalDebugInfo -> ["-g3"] ) ++ ccOptions bi + ++ extraSourceOpts extraSource , ghcOptCcProgram = maybeToFlag $ programPath @@ -396,21 +400,14 @@ componentCcGhcOptions verbosity lbi bi clbi odir filename = , ghcOptExtra = hcOptions GHC bi } -componentCxxGhcOptions - :: Verbosity - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentCxxGhcOptions verbosity lbi bi clbi odir filename = +componentCxxGhcOptions :: ExtraSourceGhcOptions +componentCxxGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [filename] + , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -427,6 +424,7 @@ componentCxxGhcOptions verbosity lbi bi clbi odir filename = MaximalDebugInfo -> ["-g3"] ) ++ cxxOptions bi + ++ extraSourceOpts extraSource , ghcOptCcProgram = maybeToFlag $ programPath @@ -435,21 +433,14 @@ componentCxxGhcOptions verbosity lbi bi clbi odir filename = , ghcOptExtra = hcOptions GHC bi } -componentAsmGhcOptions - :: Verbosity - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentAsmGhcOptions verbosity lbi bi clbi odir filename = +componentAsmGhcOptions :: ExtraSourceGhcOptions +componentAsmGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [filename] + , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -469,21 +460,14 @@ componentAsmGhcOptions verbosity lbi bi clbi odir filename = , ghcOptObjDir = toFlag odir } -componentJsGhcOptions - :: Verbosity - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentJsGhcOptions verbosity lbi bi clbi odir filename = +componentJsGhcOptions :: ExtraSourceGhcOptions +componentJsGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [filename] + , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -577,21 +561,14 @@ toGhcOptimisation NoOptimisation = mempty -- TODO perhaps override? toGhcOptimisation NormalOptimisation = toFlag GhcNormalOptimisation toGhcOptimisation MaximumOptimisation = toFlag GhcMaximumOptimisation -componentCmmGhcOptions - :: Verbosity - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentCmmGhcOptions verbosity lbi bi clbi odir filename = +componentCmmGhcOptions :: ExtraSourceGhcOptions +componentCmmGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [filename] + , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptCppOptions = cppOptions bi , ghcOptCppIncludes = @@ -602,7 +579,7 @@ componentCmmGhcOptions verbosity lbi bi clbi odir filename = , ghcOptPackages = toNubListR $ mkGhcOptPackages (promisedPkgs lbi) clbi , ghcOptOptimisation = toGhcOptimisation (withOptimization lbi) , ghcOptDebugInfo = toFlag (withDebugInfo lbi) - , ghcOptExtra = cmmOptions bi + , ghcOptExtra = cmmOptions bi ++ extraSourceOpts extraSource , ghcOptObjDir = toFlag odir } diff --git a/Cabal/src/Distribution/Simple/GHCJS.hs b/Cabal/src/Distribution/Simple/GHCJS.hs index ca71857828e..ddf65bf5f60 100644 --- a/Cabal/src/Distribution/Simple/GHCJS.hs +++ b/Cabal/src/Distribution/Simple/GHCJS.hs @@ -60,6 +60,7 @@ import Distribution.Simple.BuildPaths import Distribution.Simple.Compiler import Distribution.Simple.Errors import Distribution.Simple.Flag +import Distribution.Simple.GHC.Build.Utils (isCxx) import Distribution.Simple.GHC.EnvironmentParser import Distribution.Simple.GHC.ImplInfo import qualified Distribution.Simple.GHC.Internal as Internal @@ -509,8 +510,6 @@ buildOrReplLib mReplFlags verbosity numJobs _pkg_descr lbi lib clbi = do -- See Note [Symbolic paths] in Distribution.Utils.Path i = interpretSymbolicPathLBI lbi - u :: SymbolicPathX allowAbs Pkg to -> FilePath - u = getSymbolicPath (ghcjsProg, _) <- requireProgram verbosity ghcjsProgram (withPrograms lbi) let runGhcjsProg = runGHC verbosity ghcjsProg comp platform mbWorkDir @@ -538,7 +537,7 @@ buildOrReplLib mReplFlags verbosity numJobs _pkg_descr lbi lib clbi = do -- modules? let cLikeFiles = fromNubListR $ toNubListR (cSources libBi) <> toNubListR (cxxSources libBi) jsSrcs = jsSources libBi - cObjs = map ((`replaceExtensionSymbolicPath` objExtension)) cLikeFiles + cObjs = map ((`replaceExtensionSymbolicPath` objExtension) . extraSourceFile) cLikeFiles baseOpts = componentGhcOptions verbosity lbi libBi clbi libTargetDir linkJsLibOpts = mempty @@ -546,9 +545,9 @@ buildOrReplLib mReplFlags verbosity numJobs _pkg_descr lbi lib clbi = do [ "-link-js-lib" , getHSLibraryName uid , "-js-lib-outputdir" - , u libTargetDir + , getSymbolicPath libTargetDir ] - ++ map u jsSrcs + ++ foldMap (\(ExtraSource file opts) -> getSymbolicPath file : opts) jsSrcs } vanillaOptsNoJsLib = baseOpts @@ -702,7 +701,7 @@ buildOrReplLib mReplFlags verbosity numJobs _pkg_descr lbi lib clbi = do info verbosity "Linking..." let cSharedObjs = map - ((`replaceExtensionSymbolicPath` ("dyn_" ++ objExtension))) + ((`replaceExtensionSymbolicPath` ("dyn_" ++ objExtension)) . extraSourceFile) (cSources libBi ++ cxxSources libBi) compiler_id = compilerId (compiler lbi) sharedLibFilePath = libTargetDir </> makeRelativePathEx (mkSharedLibName (hostPlatform lbi) compiler_id uid) @@ -1115,8 +1114,8 @@ decodeMainIsArg arg -- -- Used to correctly build and link sources. data BuildSources = BuildSources - { cSourcesFiles :: [SymbolicPath Pkg File] - , cxxSourceFiles :: [SymbolicPath Pkg File] + { cSourcesFiles :: [ExtraSource] + , cxxSourceFiles :: [ExtraSource] , inputSourceFiles :: [SymbolicPath Pkg File] , inputSourceModules :: [ModuleName] } @@ -1167,7 +1166,7 @@ gbuildSources verbosity mbWorkDir pkgId specVer tmpDir bm = return BuildSources - { cSourcesFiles = cSources bnfo + { cSourcesFiles = cSources bnfo , cxxSourceFiles = cxxSources bnfo , inputSourceFiles = [main] , inputSourceModules = filter (/= mainModName) $ exeModules exe @@ -1182,11 +1181,11 @@ gbuildSources verbosity mbWorkDir pkgId specVer tmpDir bm = } else let (csf, cxxsf) - | isCxx (getSymbolicPath main) = (cSources bnfo, main : cxxSources bnfo) + | isCxx (getSymbolicPath main) = (cSources bnfo, extraSourceFromPath main : cxxSources bnfo) -- if main is not a Haskell source -- and main is not a C++ source -- then we assume that it is a C source - | otherwise = (main : cSources bnfo, cxxSources bnfo) + | otherwise = (extraSourceFromPath main : cSources bnfo, cxxSources bnfo) in return BuildSources { cSourcesFiles = csf @@ -1204,9 +1203,6 @@ gbuildSources verbosity mbWorkDir pkgId specVer tmpDir bm = , inputSourceModules = foreignLibModules flib } - isCxx :: FilePath -> Bool - isCxx fp = elem (takeExtension fp) [".cpp", ".cxx", ".c++"] - -- | FilePath has a Haskell extension: .hs or .lhs isHaskell :: FilePath -> Bool isHaskell fp = elem (takeExtension fp) [".hs", ".lhs"] @@ -1267,8 +1263,8 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do inputModules = inputSourceModules buildSources isGhcDynamic = isDynamic comp dynamicTooSupported = supportsDynamicToo comp - cObjs = map ((`replaceExtensionSymbolicPath` objExtension)) cSrcs - cxxObjs = map ((`replaceExtensionSymbolicPath` objExtension)) cxxSrcs + cObjs = map ((`replaceExtensionSymbolicPath` objExtension) . extraSourceFile) cSrcs + cxxObjs = map ((`replaceExtensionSymbolicPath` objExtension) . extraSourceFile) cxxSrcs needDynamic = gbuildNeedDynamic lbi bm needProfiling = withProfExe lbi @@ -1470,7 +1466,7 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do -- add a warning if this occurs. odir = fromFlag (ghcOptObjDir opts) createDirectoryIfMissingVerbose verbosity True (i odir) - needsRecomp <- checkNeedsRecompilation mbWorkDir filename opts + needsRecomp <- checkNeedsRecompilation mbWorkDir (extraSourceFile filename) opts when needsRecomp $ runGhcProg opts | filename <- cxxSrcs @@ -1512,7 +1508,7 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do | otherwise = vanillaCcOpts odir = fromFlag (ghcOptObjDir opts) createDirectoryIfMissingVerbose verbosity True (i odir) - needsRecomp <- checkNeedsRecompilation mbWorkDir filename opts + needsRecomp <- checkNeedsRecompilation mbWorkDir (extraSourceFile filename) opts when needsRecomp $ runGhcProg opts | filename <- cSrcs diff --git a/Cabal/src/Distribution/Simple/SrcDist.hs b/Cabal/src/Distribution/Simple/SrcDist.hs index 67f901bf7fb..4e751ed1bbb 100644 --- a/Cabal/src/Distribution/Simple/SrcDist.hs +++ b/Cabal/src/Distribution/Simple/SrcDist.hs @@ -566,11 +566,11 @@ allSourcesBuildInfo verbosity rip mbWorkDir bi pps modules = do return $ sources ++ catMaybes bootFiles - ++ cSources bi - ++ cxxSources bi - ++ cmmSources bi - ++ asmSources bi - ++ jsSources bi + ++ map extraSourceFile (cSources bi) + ++ map extraSourceFile (cxxSources bi) + ++ map extraSourceFile (cmmSources bi) + ++ map extraSourceFile (asmSources bi) + ++ map extraSourceFile (jsSources bi) where nonEmpty' :: b -> ([a] -> b) -> [a] -> b nonEmpty' x _ [] = x diff --git a/cabal-install/src/Distribution/Client/SourceFiles.hs b/cabal-install/src/Distribution/Client/SourceFiles.hs index 1166f333f3c..52b203d18c8 100644 --- a/cabal-install/src/Distribution/Client/SourceFiles.hs +++ b/cabal-install/src/Distribution/Client/SourceFiles.hs @@ -28,6 +28,7 @@ import Distribution.Types.BuildInfo import Distribution.Types.Component import Distribution.Types.ComponentRequestedSpec (ComponentRequestedSpec) import Distribution.Types.Executable +import Distribution.Types.ExtraSource import Distribution.Types.ForeignLib import Distribution.Types.Library import Distribution.Types.PackageDescription @@ -176,11 +177,11 @@ needBuildInfo pkg_descr bi modules = do matchDirFileGlobWithDie normal (\_ _ -> return []) (specVersion pkg_descr) (Just $ makeSymbolicPath root) fpath traverse_ needIfExists $ concat - [ map getSymbolicPath $ cSources bi - , map getSymbolicPath $ cxxSources bi - , map getSymbolicPath $ jsSources bi - , map getSymbolicPath $ cmmSources bi - , map getSymbolicPath $ asmSources bi + [ map (getSymbolicPath . extraSourceFile) $ cSources bi + , map (getSymbolicPath . extraSourceFile) $ cxxSources bi + , map (getSymbolicPath . extraSourceFile) $ jsSources bi + , map (getSymbolicPath . extraSourceFile) $ cmmSources bi + , map (getSymbolicPath . extraSourceFile) $ asmSources bi , map getSymbolicPath $ expandedExtraSrcFiles ] for_ (fmap getSymbolicPath $ installIncludes bi) $ \f -> diff --git a/cabal-install/src/Distribution/Client/TargetSelector.hs b/cabal-install/src/Distribution/Client/TargetSelector.hs index b31655c59c6..61ca11f087a 100644 --- a/cabal-install/src/Distribution/Client/TargetSelector.hs +++ b/cabal-install/src/Distribution/Client/TargetSelector.hs @@ -72,6 +72,7 @@ import Distribution.PackageDescription , BenchmarkInterface (..) , BuildInfo (..) , Executable (..) + , ExtraSource (..) , PackageDescription , TestSuite (..) , TestSuiteInterface (..) @@ -1921,8 +1922,8 @@ collectKnownComponentInfo pkg = , cinfoSrcDirs = ordNub (map getSymbolicPath (hsSourceDirs bi)) , cinfoModules = ordNub (componentModules c) , cinfoHsFiles = ordNub (componentHsFiles c) - , cinfoCFiles = ordNub (map getSymbolicPath $ cSources bi) - , cinfoJsFiles = ordNub (map getSymbolicPath $ jsSources bi) + , cinfoCFiles = ordNub (map (getSymbolicPath . extraSourceFile) $ cSources bi) + , cinfoJsFiles = ordNub (map (getSymbolicPath . extraSourceFile) $ jsSources bi) } | c <- pkgComponents pkg , let bi = componentBuildInfo c diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index 2b25a64b6be..8ee582db616 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -658,7 +658,9 @@ testTargetSelectorAmbiguous reportSubCase = do withCFiles :: Executable -> [FilePath] -> Executable withCFiles exe files = - exe{buildInfo = (buildInfo exe){cSources = map unsafeMakeSymbolicPath files}} + exe{buildInfo = (buildInfo exe){cSources = map (mkExtraSource . unsafeMakeSymbolicPath) files}} + + mkExtraSource x = ExtraSource x [] withHsSrcDirs :: Executable -> [FilePath] -> Executable withHsSrcDirs exe srcDirs = diff --git a/cabal-testsuite/PackageTests/ExtraSources/cbits/test.c b/cabal-testsuite/PackageTests/ExtraSources/cbits/test.c new file mode 100644 index 00000000000..e31c5a9b7b5 --- /dev/null +++ b/cabal-testsuite/PackageTests/ExtraSources/cbits/test.c @@ -0,0 +1,3 @@ +#ifndef DOIT +#error "It does not work" +#endif diff --git a/cabal-testsuite/PackageTests/ExtraSources/extra-sources.cabal b/cabal-testsuite/PackageTests/ExtraSources/extra-sources.cabal new file mode 100644 index 00000000000..0d340f5c6bd --- /dev/null +++ b/cabal-testsuite/PackageTests/ExtraSources/extra-sources.cabal @@ -0,0 +1,10 @@ +cabal-version: 3.4 +name: extra-sources +version: 0 +build-type: Simple + +library + hs-source-dirs: src + build-depends: base + exposed-modules: MyLib + c-sources: cbits/test.c (-D DOIT=1) diff --git a/cabal-testsuite/PackageTests/ExtraSources/setup.out b/cabal-testsuite/PackageTests/ExtraSources/setup.out new file mode 100644 index 00000000000..43a3574bd1b --- /dev/null +++ b/cabal-testsuite/PackageTests/ExtraSources/setup.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring extra-sources-0... +# Setup build +Preprocessing library for extra-sources-0... +Building library for extra-sources-0... diff --git a/cabal-testsuite/PackageTests/ExtraSources/setup.test.hs b/cabal-testsuite/PackageTests/ExtraSources/setup.test.hs new file mode 100644 index 00000000000..9e2abcb188b --- /dev/null +++ b/cabal-testsuite/PackageTests/ExtraSources/setup.test.hs @@ -0,0 +1,5 @@ +import Test.Cabal.Prelude + +main = setupTest $ do + setup "configure" [] + setup "build" [] diff --git a/cabal-testsuite/PackageTests/ExtraSources/src/MyLib.hs b/cabal-testsuite/PackageTests/ExtraSources/src/MyLib.hs new file mode 100644 index 00000000000..bcdf120b02c --- /dev/null +++ b/cabal-testsuite/PackageTests/ExtraSources/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib where + +someFunc :: IO () +someFunc = mempty From db19c2f56b46d2bd3177857d487a8e4eff7c94ed Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Mon, 2 Dec 2024 10:31:43 +0800 Subject: [PATCH 02/82] feat(Cabal): include executables for simpleUserHooks and autoconfUserHooks. --- Cabal/Cabal.cabal | 14 ++++++++++++++ Cabal/src/main_configure.hs | 4 ++++ Cabal/src/main_simple.hs | 4 ++++ 3 files changed, 22 insertions(+) create mode 100644 Cabal/src/main_configure.hs create mode 100644 Cabal/src/main_simple.hs diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index 27f7c958016..dab60621228 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -415,3 +415,17 @@ library TypeOperators TypeSynonymInstances UndecidableInstances + +executable cabal-main-simple + default-language: Haskell2010 + main-is: src/main_simple.hs + build-depends: + base, + Cabal + +executable cabal-main-configure + default-language: Haskell2010 + main-is: src/main_configure.hs + build-depends: + base, + Cabal diff --git a/Cabal/src/main_configure.hs b/Cabal/src/main_configure.hs new file mode 100644 index 00000000000..577b8311e90 --- /dev/null +++ b/Cabal/src/main_configure.hs @@ -0,0 +1,4 @@ +import Distribution.Simple + +main :: IO () +main = defaultMainWithHooks autoconfUserHooks diff --git a/Cabal/src/main_simple.hs b/Cabal/src/main_simple.hs new file mode 100644 index 00000000000..00bfe1fe441 --- /dev/null +++ b/Cabal/src/main_simple.hs @@ -0,0 +1,4 @@ +import Distribution.Simple + +main :: IO () +main = defaultMain From 8d61712d54664c204f0ae294b9da96d7bffd97a6 Mon Sep 17 00:00:00 2001 From: Sylvain Henry <sylvain@haskus.fr> Date: Fri, 21 Feb 2025 13:04:40 +0100 Subject: [PATCH 03/82] fix: don't build Setup programs with -threaded Don't enable -threaded unconditionnally when building Setup.hs. We may only have vanilla libraries (but maybe we don't have them either?) Revert ae0e752eeab7d5a185295801fe54157e9012e2ba --- cabal-install/src/Distribution/Client/SetupWrapper.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index 78833af6d15..55042e212cd 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -1072,7 +1072,10 @@ getExternalSetupMethod verbosity options pkg bt = do (program, extraOpts) = case compilerFlavor compiler of GHCJS -> (ghcjsProgram, ["-build-runner"]) - _ -> (ghcProgram, ["-threaded"]) + _ -> (ghcProgram, []) + -- FIXME: don't enable -threaded unconditionnally: we may + -- only have vanilla libraries (but maybe we don't have them + -- either?) cabalDep = maybe [] From fc017bd683d3c60f32908b48071e0e67c7fae373 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sun, 23 Feb 2025 11:42:55 +0900 Subject: [PATCH 04/82] fix: static linking on MacOS by preventing '-optl-static' flag The treatment of --executable-static means we pass `-optl-static` to GHC, which in turn just passes this to the linker. This flag can not work on macOS. Fully static linking is impossible as libSystem must be linked dynamically. Thus here we disable this flag for macOS. --- Cabal/src/Distribution/Simple/GHC/Build/Link.hs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs index e26e3890ba3..78f293e7656 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs @@ -121,6 +121,14 @@ linkOrLoadComponent PD.ldOptions bi ++ [ "-static" | withFullyStaticExe lbi + -- MacOS can not link fully statically. + -- Only kernels can be linked fully statically. Everything + -- linking against libSystem must link dynamically. Thus even + -- if we link all dependencies statically, we must not pass + -- '-optl-static', as that will cause the linker to try and + -- fail. + , let Platform _hostArch hostOS = hostPlatform lbi + in hostOS /= OSX ] -- Pass extra `ld-options` given -- through to GHC's linker. From 438f94f0f9366117a0b16a9fe319adfc36abdebb Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sun, 23 Feb 2025 12:23:16 +0900 Subject: [PATCH 05/82] feat: no more vowel dropping on macOS This reverts b408167601 in spirit from #4656. --- cabal-install/src/Distribution/Client/PackageHash.hs | 5 ++--- cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index e8975b0fc57..38240c3888a 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -147,8 +147,7 @@ hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = -- @store/<libraryname>/libHS<libraryname>.dylib@ -- where libraryname contains the libraries name, version and abi hash, but in -- @store/lib/libHS<very short libraryname>.dylib@ --- where the very short library name drops all vowels from the package name, --- and truncates the hash to 4 bytes. +-- where the very short library name truncates the hash to 4 bytes. -- -- We therefore we only need one \@rpath entry to @store/lib@ instead of one -- \@rpath entry for each library. And the reduced library name saves some @@ -168,7 +167,7 @@ hashedInstalledPackageIdVeryShort pkghashinputs@PackageHashInputs{pkgHashPkgId} mkComponentId $ intercalate "-" - [ filter (not . flip elem "aeiou") (prettyShow name) + [ prettyShow name , prettyShow version , showHashValue (truncateHash 4 (hashPackageHashInputs pkghashinputs)) ] diff --git a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs index 6267a0f5684..1667106ac8b 100644 --- a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs +++ b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs @@ -115,11 +115,6 @@ normalizeOutput nenv = -- and replace it with: -- > "-package-id","<PACKAGEDEP>" -- - -- Otherwise, output can not be properly normalized as on MacOs we remove - -- vowels from packages to make the names shorter. - -- E.g. "another-framework-0.8.1.1" -> "nthr-frmwrk-0.8.1.1" - -- - -- This makes it impossible to have a stable package id, thus remove it completely. -- Check manually in your test-cases if the package-id needs to be verified. . resub ("\"-package-id\",\"([^\"]*)\"") "\"-package-id\",\"<PACKAGEDEP>\"" From e5905848e1f9c2ff3389f4b7c445b7fce2f7af66 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo <erikd@mega-nerd.com> Date: Thu, 6 Mar 2025 21:12:38 +1100 Subject: [PATCH 06/82] feat: add pre and post build hooks Run a program (named "preBuildHook") before doing a package build and another program (named "postBuildHook") after the package is built. The exit code from the pre-build hook is passed to the post-build hook. The commit includes documentation for the hooks and the security safeguards implemented to avoid the running of malicious hook files. (cherry picked from commit 5f7b47fc943eaa5a4e12714935daefe0ddfc4281) --- cabal-install/cabal-install.cabal | 1 + .../src/Distribution/Client/CmdFreeze.hs | 1 + .../src/Distribution/Client/CmdTarget.hs | 1 + .../src/Distribution/Client/Errors.hs | 36 ++++++- .../src/Distribution/Client/HashValue.hs | 6 ++ .../src/Distribution/Client/HookAccept.hs | 97 +++++++++++++++++++ .../Client/ProjectBuilding/UnpackedPackage.hs | 44 ++++++++- .../Client/ProjectConfig/Legacy.hs | 2 +- .../Client/ProjectConfig/Types.hs | 2 + .../Client/ProjectOrchestration.hs | 8 ++ .../Distribution/Client/ProjectPlanning.hs | 11 ++- .../Client/ProjectPlanning/Types.hs | 2 + cabal-install/tests/IntegrationTests2.hs | 1 + .../Distribution/Client/ProjectConfig.hs | 8 ++ .../Distribution/Client/TreeDiffInstances.hs | 4 + changelog.d/pr-10799 | 15 +++ doc/build-hooks.rst | 83 ++++++++++++++++ doc/index.rst | 1 + 18 files changed, 319 insertions(+), 4 deletions(-) create mode 100644 cabal-install/src/Distribution/Client/HookAccept.hs create mode 100644 changelog.d/pr-10799 create mode 100644 doc/build-hooks.rst diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 5aedb23aeed..c237c9d891e 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -141,6 +141,7 @@ library Distribution.Client.GlobalFlags Distribution.Client.Haddock Distribution.Client.HashValue + Distribution.Client.HookAccept Distribution.Client.HttpUtils Distribution.Client.IndexUtils Distribution.Client.IndexUtils.ActiveRepos diff --git a/cabal-install/src/Distribution/Client/CmdFreeze.hs b/cabal-install/src/Distribution/Client/CmdFreeze.hs index 29718b5d441..d6dae289354 100644 --- a/cabal-install/src/Distribution/Client/CmdFreeze.hs +++ b/cabal-install/src/Distribution/Client/CmdFreeze.hs @@ -142,6 +142,7 @@ freezeAction flags@NixStyleFlags{..} extraArgs globalFlags = do (_, elaboratedPlan, _, totalIndexState, activeRepos) <- rebuildInstallPlan verbosity + mempty distDirLayout cabalDirLayout projectConfig diff --git a/cabal-install/src/Distribution/Client/CmdTarget.hs b/cabal-install/src/Distribution/Client/CmdTarget.hs index c2edeeec89c..4c9cc59ec24 100644 --- a/cabal-install/src/Distribution/Client/CmdTarget.hs +++ b/cabal-install/src/Distribution/Client/CmdTarget.hs @@ -160,6 +160,7 @@ targetAction flags@NixStyleFlags{..} ts globalFlags = do (_, elaboratedPlan, _, _, _) <- rebuildInstallPlan verbosity + mempty distDirLayout cabalDirLayout projectConfig diff --git a/cabal-install/src/Distribution/Client/Errors.hs b/cabal-install/src/Distribution/Client/Errors.hs index ff9ad369bef..493ce2fc98b 100644 --- a/cabal-install/src/Distribution/Client/Errors.hs +++ b/cabal-install/src/Distribution/Client/Errors.hs @@ -186,7 +186,9 @@ data CabalInstallException | MissingPackageList Repo.RemoteRepo | CmdPathAcceptsNoTargets | CmdPathCommandDoesn'tSupportDryRun - deriving (Show) + | HookAcceptUnknown FilePath FilePath String + | HookAcceptHashMismatch FilePath FilePath String String + deriving (Show, Typeable) exceptionCodeCabalInstall :: CabalInstallException -> Int exceptionCodeCabalInstall e = case e of @@ -338,6 +340,8 @@ exceptionCodeCabalInstall e = case e of MissingPackageList{} -> 7160 CmdPathAcceptsNoTargets{} -> 7161 CmdPathCommandDoesn'tSupportDryRun -> 7163 + HookAcceptUnknown{} -> 7164 + HookAcceptHashMismatch{} -> 7165 exceptionMessageCabalInstall :: CabalInstallException -> String exceptionMessageCabalInstall e = case e of @@ -860,6 +864,36 @@ exceptionMessageCabalInstall e = case e of "The 'path' command accepts no target arguments." CmdPathCommandDoesn'tSupportDryRun -> "The 'path' command doesn't support the flag '--dry-run'." + HookAcceptUnknown hsPath fpath hash -> + concat + [ "The following file does not appear in the hooks-security file.\n" + , " hook file : " + , fpath + , "\n" + , " file hash : " + , hash + , "\n" + , "After checking the contents of that file, it should be added to the\n" + , "hooks-security file with either AcceptAlways or better yet an AcceptHash.\n" + , "The hooks-security file is (probably) located at: " + , hsPath + ] + HookAcceptHashMismatch hsPath fpath expected actual -> + concat + [ "\nHook file hash mismatch for:\n" + , " hook file : " + , fpath + , "\n" + , " expected hash: " + , expected + , "\n" + , " actual hash : " + , actual + , "\n" + , "The hook file should be inspected and if deemed ok, the hooks-security file updated.\n" + , "The hooks-security file is (probably) located at: " + , hsPath + ] instance Exception (VerboseException CabalInstallException) where displayException :: VerboseException CabalInstallException -> [Char] diff --git a/cabal-install/src/Distribution/Client/HashValue.hs b/cabal-install/src/Distribution/Client/HashValue.hs index c5698f27f1e..12616e07eaa 100644 --- a/cabal-install/src/Distribution/Client/HashValue.hs +++ b/cabal-install/src/Distribution/Client/HashValue.hs @@ -4,6 +4,7 @@ module Distribution.Client.HashValue ( HashValue , hashValue + , hashValueFromHex , truncateHash , showHashValue , readFileHashValue @@ -51,6 +52,11 @@ instance Structured HashValue hashValue :: LBS.ByteString -> HashValue hashValue = HashValue . SHA256.hashlazy +-- From a base16 encoded Bytestring to a HashValue with `Base16`'s +-- error passing through. +hashValueFromHex :: BS.ByteString -> Either String HashValue +hashValueFromHex bs = HashValue <$> Base16.decode bs + showHashValue :: HashValue -> String showHashValue (HashValue digest) = BS.unpack (Base16.encode digest) diff --git a/cabal-install/src/Distribution/Client/HookAccept.hs b/cabal-install/src/Distribution/Client/HookAccept.hs new file mode 100644 index 00000000000..fc7e5ae0460 --- /dev/null +++ b/cabal-install/src/Distribution/Client/HookAccept.hs @@ -0,0 +1,97 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE OverloadedStrings #-} + +module Distribution.Client.HookAccept + ( HookAccept (..) + , assertHookHash + , loadHookHasheshMap + , parseHooks + ) where + +import Distribution.Client.Compat.Prelude + +import Data.ByteString.Char8 (ByteString) +import qualified Data.ByteString.Char8 as BS + +import qualified Data.Map.Strict as Map + +import Distribution.Client.Config (getConfigFilePath) +import Distribution.Client.Errors (CabalInstallException (..)) +import Distribution.Client.HashValue (HashValue, hashValueFromHex, readFileHashValue, showHashValue) +import Distribution.Simple.Setup (Flag (..)) +import Distribution.Simple.Utils (dieWithException) +import Distribution.Verbosity (normal) + +import System.FilePath (takeDirectory, (</>)) + +data HookAccept + = AcceptAlways + | AcceptHash HashValue + deriving (Eq, Show, Generic) + +instance Monoid HookAccept where + mempty = AcceptAlways -- Should never be needed. + mappend = (<>) + +instance Semigroup HookAccept where + AcceptAlways <> AcceptAlways = AcceptAlways + AcceptAlways <> AcceptHash h = AcceptHash h + AcceptHash h <> AcceptAlways = AcceptHash h + AcceptHash h <> _ = AcceptHash h + +instance Binary HookAccept +instance Structured HookAccept + +assertHookHash :: Map FilePath HookAccept -> FilePath -> IO () +assertHookHash m fpath = do + actualHash <- readFileHashValue fpath + hsPath <- getHooksSecurityFilePath NoFlag + case Map.lookup fpath m of + Nothing -> + dieWithException normal $ + HookAcceptUnknown hsPath fpath (showHashValue actualHash) + Just AcceptAlways -> pure () + Just (AcceptHash expectedHash) -> + when (actualHash /= expectedHash) $ + dieWithException normal $ + HookAcceptHashMismatch + hsPath + fpath + (showHashValue expectedHash) + (showHashValue actualHash) + +getHooksSecurityFilePath :: Flag FilePath -> IO FilePath +getHooksSecurityFilePath configFileFlag = do + hfpath <- getConfigFilePath configFileFlag + pure $ takeDirectory hfpath </> "hooks-security" + +loadHookHasheshMap :: Flag FilePath -> IO (Map FilePath HookAccept) +loadHookHasheshMap configFileFlag = do + hookFilePath <- getHooksSecurityFilePath configFileFlag + handleNotExists $ fmap parseHooks (BS.readFile hookFilePath) + where + handleNotExists :: IO (Map FilePath HookAccept) -> IO (Map FilePath HookAccept) + handleNotExists action = catchIO action $ \_ -> return mempty + +parseHooks :: ByteString -> Map FilePath HookAccept +parseHooks = Map.fromList . map parse . cleanUp . BS.lines + where + cleanUp :: [ByteString] -> [ByteString] + cleanUp = filter (not . BS.null) . map rmComments + + rmComments :: ByteString -> ByteString + rmComments = fst . BS.breakSubstring "--" + +parse :: ByteString -> (FilePath, HookAccept) +parse bs = + case BS.words bs of + [fp, "AcceptAlways"] -> (BS.unpack fp, AcceptAlways) + [fp, "AcceptHash"] -> buildAcceptHash fp "00" + [fp, "AcceptHash", h] -> buildAcceptHash fp h + _ -> error $ "Not able to parse:" ++ show bs + where + buildAcceptHash :: ByteString -> ByteString -> (FilePath, HookAccept) + buildAcceptHash fp h = + case hashValueFromHex h of + Left err -> error $ "Distribution.Client.HookAccept.parse :" ++ err + Right hv -> (BS.unpack fp, AcceptHash hv) diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index e19c52157c0..fe5c10662e6 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -30,6 +30,7 @@ module Distribution.Client.ProjectBuilding.UnpackedPackage import Distribution.Client.Compat.Prelude import Prelude () +import Distribution.Client.HookAccept (assertHookHash) import Distribution.Client.PackageHash (renderPackageHashInputs) import Distribution.Client.ProjectBuilding.Types import Distribution.Client.ProjectConfig @@ -105,7 +106,7 @@ import qualified Data.ByteString.Lazy.Char8 as LBS.Char8 import qualified Data.List.NonEmpty as NE import Control.Exception (ErrorCall, Handler (..), SomeAsyncException, assert, catches, onException) -import System.Directory (canonicalizePath, createDirectoryIfMissing, doesDirectoryExist, doesFileExist, removeFile) +import System.Directory (canonicalizePath, createDirectoryIfMissing, doesDirectoryExist, doesFileExist, getCurrentDirectory, removeFile) import System.FilePath (dropDrive, normalise, takeDirectory, (<.>), (</>)) import System.IO (Handle, IOMode (AppendMode), withFile) import System.Semaphore (SemaphoreName (..)) @@ -697,7 +698,48 @@ buildAndInstallUnpackedPackage runConfigure PBBuildPhase{runBuild} -> do noticeProgress ProgressBuilding + hooksDir <- (</> "cabalHooks") <$> getCurrentDirectory + -- run preBuildHook. If it returns with 0, we assume the build was + -- successful. If not, run the build. + preBuildHookFile <- canonicalizePath (hooksDir </> "preBuildHook") + hookExists <- doesFileExist preBuildHookFile + preCode <- + if hookExists + then do + assertHookHash (pkgConfigHookHashes pkgshared) preBuildHookFile + rawSystemExitCode + verbosity + (Just srcdir) + preBuildHookFile + [ (unUnitId $ installedUnitId rpkg) + , (getSymbolicPath srcdir) + , (getSymbolicPath builddir) + ] + Nothing + `catchIO` (\_ -> pure (ExitFailure 10)) + else pure ExitSuccess + -- Regardless of whether the preBuildHook exists or not, or whether it returned an + -- error or not, we want to run the build command. + -- If the preBuildHook downloads a cached version of the build products, the following + -- should be a NOOP. runBuild + -- not sure, if we want to care about a failed postBuildHook? + postBuildHookFile <- canonicalizePath (hooksDir </> "postBuildHook") + hookExists' <- doesFileExist postBuildHookFile + when hookExists' $ do + assertHookHash (pkgConfigHookHashes pkgshared) postBuildHookFile + void $ + rawSystemExitCode + verbosity + (Just srcdir) + postBuildHookFile + [ (unUnitId $ installedUnitId rpkg) + , (getSymbolicPath srcdir) + , (getSymbolicPath builddir) + , show preCode + ] + Nothing + `catchIO` (\_ -> pure (ExitFailure 10)) PBHaddockPhase{runHaddock} -> do noticeProgress ProgressHaddock runHaddock diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 10858d5601d..7d1bee02daa 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -714,7 +714,7 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags } = globalFlags projectConfigPackageDBs = (fmap . fmap) (interpretPackageDB Nothing) projectConfigPackageDBs_ - + projectConfigHookHashes = mempty -- :: Map FilePath HookAccept ConfigFlags { configCommonFlags = commonFlags , configHcFlavor = projectConfigHcFlavor diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 1a2b6ae2fa6..4f1558fa215 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -33,6 +33,7 @@ import Distribution.Client.BuildReports.Types import Distribution.Client.Dependency.Types ( PreSolver ) +import Distribution.Client.HookAccept (HookAccept (..)) import Distribution.Client.Targets ( UserConstraint ) @@ -227,6 +228,7 @@ data ProjectConfigShared = ProjectConfigShared , projectConfigPreferOldest :: Flag PreferOldest , projectConfigProgPathExtra :: NubList FilePath , projectConfigMultiRepl :: Flag Bool + , projectConfigHookHashes :: Map FilePath HookAccept -- More things that only make sense for manual mode, not --local mode -- too much control! -- projectConfigShadowPkgs :: Flag Bool, diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index a14d43e4b99..9907193458d 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -176,6 +176,8 @@ import qualified Data.List.NonEmpty as NE import qualified Data.Map as Map import qualified Data.Set as Set import Distribution.Client.Errors +import Distribution.Client.HookAccept (loadHookHasheshMap) + import Distribution.Package import Distribution.Simple.Command (commandShowOptions) import Distribution.Simple.Compiler @@ -363,6 +365,8 @@ withInstallPlan , installedPackages } action = do + hookHashes <- loadHookHasheshMap (projectConfigConfigFile $ projectConfigShared projectConfig) + -- Take the project configuration and make a plan for how to build -- everything in the project. This is independent of any specific targets -- the user has asked for. @@ -370,6 +374,7 @@ withInstallPlan (elaboratedPlan, _, elaboratedShared, _, _) <- rebuildInstallPlan verbosity + hookHashes distDirLayout cabalDirLayout projectConfig @@ -392,6 +397,8 @@ runProjectPreBuildPhase , installedPackages } selectPlanSubset = do + hookHashes <- loadHookHasheshMap (projectConfigConfigFile $ projectConfigShared projectConfig) + -- Take the project configuration and make a plan for how to build -- everything in the project. This is independent of any specific targets -- the user has asked for. @@ -399,6 +406,7 @@ runProjectPreBuildPhase (elaboratedPlan, _, elaboratedShared, _, _) <- rebuildInstallPlan verbosity + hookHashes distDirLayout cabalDirLayout projectConfig diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index c04bca730d7..7e10677437c 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -117,6 +117,7 @@ import Distribution.Client.Dependency import Distribution.Client.DistDirLayout import Distribution.Client.FetchUtils import Distribution.Client.HashValue +import Distribution.Client.HookAccept (HookAccept) import Distribution.Client.HttpUtils import Distribution.Client.JobControl import Distribution.Client.PackageHash @@ -589,6 +590,7 @@ Binary ProgramDb instance. -- rebuildInstallPlan :: Verbosity + -> Map FilePath HookAccept -> DistDirLayout -> CabalDirLayout -> ProjectConfig @@ -604,6 +606,7 @@ rebuildInstallPlan -- ^ @(improvedPlan, elaboratedPlan, _, _, _)@ rebuildInstallPlan verbosity + hookHashes distDirLayout@DistDirLayout { distProjectRootDirectory , distProjectCacheFile @@ -621,7 +624,7 @@ rebuildInstallPlan fileMonitorImprovedPlan -- react to changes in the project config, -- the package .cabal files and the path - (projectConfigMonitored, localPackages, progsearchpath) + (projectConfigMonitored, localPackages, progsearchpath, hookHashes) $ do -- And so is the elaborated plan that the improved plan based on (elaboratedPlan, elaboratedShared, totalIndexState, activeRepos) <- @@ -631,6 +634,7 @@ rebuildInstallPlan ( projectConfigMonitored , localPackages , progsearchpath + , hookHashes ) $ do compilerEtc <- phaseConfigureCompiler projectConfig @@ -737,6 +741,7 @@ rebuildInstallPlan , compiler , platform , programDbSignature progdb + , hookHashes ) $ do installedPkgIndex <- @@ -865,6 +870,7 @@ rebuildInstallPlan liftIO . runLogProgress verbosity $ elaborateInstallPlan verbosity + hookHashes platform compiler progdb @@ -1585,6 +1591,7 @@ planPackages -- matching that of the classic @cabal install --user@ or @--global@ elaborateInstallPlan :: Verbosity + -> Map FilePath HookAccept -> Platform -> Compiler -> ProgramDb @@ -1602,6 +1609,7 @@ elaborateInstallPlan -> LogProgress (ElaboratedInstallPlan, ElaboratedSharedConfig) elaborateInstallPlan verbosity + hookHashes platform compiler compilerprogdb @@ -1625,6 +1633,7 @@ elaborateInstallPlan , pkgConfigCompiler = compiler , pkgConfigCompilerProgs = compilerprogdb , pkgConfigReplOptions = mempty + , pkgConfigHookHashes = hookHashes } preexistingInstantiatedPkgs :: Map UnitId FullUnitId diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 7ee5cb52f41..484c4cad297 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -84,6 +84,7 @@ import Distribution.Client.Types import Distribution.Backpack import Distribution.Backpack.ModuleShape +import Distribution.Client.HookAccept (HookAccept (..)) import Distribution.Compat.Graph (IsNode (..)) import Distribution.InstalledPackageInfo (InstalledPackageInfo) import Distribution.ModuleName (ModuleName) @@ -190,6 +191,7 @@ data ElaboratedSharedConfig = ElaboratedSharedConfig -- ghc & ghc-pkg). Once constructed, only the 'configuredPrograms' are -- used. , pkgConfigReplOptions :: ReplOptions + , pkgConfigHookHashes :: Map FilePath HookAccept } deriving (Show, Generic) diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index 8ee582db616..273be658906 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -2195,6 +2195,7 @@ planProject testdir cliConfig = do (elaboratedPlan, _, elaboratedShared, _, _) <- rebuildInstallPlan verbosity + mempty distDirLayout cabalDirLayout projectConfig diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index bf69b20ee04..371766fedb1 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -11,6 +11,7 @@ module UnitTests.Distribution.Client.ProjectConfig (tests) where import Control.Monad +import qualified Data.ByteString.Lazy.Char8 as LBS import Data.Either (isRight) import Data.Foldable (for_) import Data.List (intercalate, isPrefixOf, (\\)) @@ -26,6 +27,8 @@ import System.IO.Unsafe (unsafePerformIO) import Distribution.Deprecated.ParseUtils import qualified Distribution.Deprecated.ReadP as Parse +import Distribution.Client.HashValue (hashValue) +import Distribution.Client.HookAccept (HookAccept (..)) import Distribution.Compiler import Distribution.Package import Distribution.PackageDescription @@ -638,6 +641,7 @@ instance Arbitrary ProjectConfigShared where projectConfigPreferOldest <- arbitrary projectConfigProgPathExtra <- toNubList <$> listOf arbitraryShortToken projectConfigMultiRepl <- arbitrary + projectConfigHookHashes <- arbitrary return ProjectConfigShared{..} where arbitraryConstraints :: Gen [(UserConstraint, ConstraintSource)] @@ -684,6 +688,7 @@ instance Arbitrary ProjectConfigShared where <*> shrinker projectConfigPreferOldest <*> shrinker projectConfigProgPathExtra <*> shrinker projectConfigMultiRepl + <*> shrinker projectConfigHookHashes where preShrink_Constraints = map fst postShrink_Constraints = map (\uc -> (uc, projectConfigConstraintSource)) @@ -691,6 +696,9 @@ instance Arbitrary ProjectConfigShared where projectConfigConstraintSource :: ConstraintSource projectConfigConstraintSource = ConstraintSourceProjectConfig nullProjectConfigPath +instance Arbitrary HookAccept where + arbitrary = elements [AcceptAlways, AcceptHash (hashValue $ LBS.pack "hash")] + instance Arbitrary ProjectConfigProvenance where arbitrary = elements [Implicit, Explicit (ProjectConfigPath $ "cabal.project" :| [])] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs b/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs index 179fef5688a..42c38a7bc82 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs @@ -13,6 +13,8 @@ import Distribution.Solver.Types.Settings import Distribution.Client.BuildReports.Types import Distribution.Client.CmdInstall.ClientInstallFlags import Distribution.Client.Dependency.Types +import Distribution.Client.HashValue (HashValue) +import Distribution.Client.HookAccept (HookAccept (..)) import Distribution.Client.IndexUtils.ActiveRepos import Distribution.Client.IndexUtils.IndexState import Distribution.Client.IndexUtils.Timestamp @@ -45,6 +47,8 @@ instance ToExpr ProjectConfigPath instance ToExpr ConstraintSource instance ToExpr CountConflicts instance ToExpr FineGrainedConflicts +instance ToExpr HashValue +instance ToExpr HookAccept instance ToExpr IndependentGoals instance ToExpr InstallMethod instance ToExpr InstallOutcome diff --git a/changelog.d/pr-10799 b/changelog.d/pr-10799 new file mode 100644 index 00000000000..3f37124aebb --- /dev/null +++ b/changelog.d/pr-10799 @@ -0,0 +1,15 @@ +synopsis: Add pre and post build hooks +packages: cabal-install +prs: #10799 +issues: #9892 +significance: significant + +description: { + +- Run a program (named "preBuildHook") before doing a package build and another program + (named "postBuildHook") after the package is built. +- These programs are project local and need to be in the `cabalHooks` directory which is + in the same directory as the `cabal.project` file. +- The absence of these programs will be ignored. +- How to check and run these hooks securely is specified in the documentation. +} diff --git a/doc/build-hooks.rst b/doc/build-hooks.rst new file mode 100644 index 00000000000..82e53693dc4 --- /dev/null +++ b/doc/build-hooks.rst @@ -0,0 +1,83 @@ +Build Hooks +=========== + +Build hooks are programs that are run before (pre-build hook) and +after (post-build hook) a package (including package dependencies) +is built. The hooks are completely generic and can even be absent +(their absence is ignored). Regardless of the return code of the +pre-build hook, the normal build is executed. In the case where +the pre-build hook provides a pre-built version of what the build +step would provide, the build step is still run, but should be +little more than a NOOP. + +Build hooks are project local rather than global to the user +because a single user may want to use one set of hooks in one +project and another set of hooks (or even none at all) for another +project. + +Since the hook files are project local (and hence likely to be committed +to revision control), a naive implementation of these hooks would be +a potential security issue. A solution to this potential security +issue has been implemented and described in the Hook Security section +below. + + +Possible Use Cases +------------------ + +Possible use cases include: + +* Fine grained benchmarking of individual package build times. +* Build product caching. + + +Location of Hook Files +---------------------- + +The two hook files are `cabalHooks/preBuildHook` and +`cabalHooks/postBuildHook` where the `cabalHooks` directory is in +the same directory as the `cabal.project` file. On UNIX style +systems, these hooks need to be marked as user executable programs. + + +Hook Parameters Exit Codes +-------------------------- + +The pre-build hook is passed three parameters; the unit id (from cabal), +the source directory and the build directory. The post-build hook is +passed the same three parameters, plus the exit code of the pre-build +hook. + +The exit codes for the two hooks are ignored by cabal apart from cabal +capturing the exit code for the pre-build hook and passing it to the +post-build hook. + + +Hook Security +------------- +These hook files are generic executable programs and are stored local to +the project. To prevent the running of malicious hook files, the +hook files are only run, it they are mentioned in the `hooks-security` +file which is located in the users home `.cabal` directory, usually +either `$HOME/.cabal/` or `$HOME/.config/cabal/`. + +The `hooks-security` file should contain one entry per line. Blank lines +are ignored, as are Haskell style single line comments (starts with "--" +and goes until the end of the line). Each entry should contain the full +hook file path, at least one space and either "AcceptAlways" or +"AcceptHash" followed by at least one space and the hexadecimal encoded +hash of the file. The `hooks-security` file is read once when `cabal` is +started and the entries inserted into a `Map`. + +When `cabal` detects a "preBuildHook" or "postBuildHook" it looks up +the full file path in the `Map`. If the path is not found in the `Map`, +`cabal` will die with an error message suggesting that the hook file +be manually inspected and if deemed safe, added to the `hooks-security` +file. + +If the hook file path is in the `Map` and it was specified as +"AcceptAlways" the hook will be run. If the `Map` entry is "AcceptHash" +with a hash, the hash of the hook file will be calculated and compared +against the supplied hash. If the hashes match, the hook will be run. +If there is a hash mismatch, `cabal` will abort with an error message +about the hash mismatch. diff --git a/doc/index.rst b/doc/index.rst index 4bd13c65d7a..a721b77ed63 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -20,6 +20,7 @@ Welcome to the Cabal User Guide how-to-run-in-windows how-to-use-backpack how-to-report-bugs + build-hooks .. toctree:: :caption: Cabal Reference From d4c0c0135dc37072e7f6cde03ee87bef49302c51 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Thu, 13 Mar 2025 13:18:55 +0800 Subject: [PATCH 07/82] feat: support generated cmm-sources --- .../PackageDescription/FieldGrammar.hs | 22 ++++-- .../src/Distribution/Types/BuildInfo.hs | 14 ++-- .../src/Distribution/Types/BuildInfo/Lens.hs | 14 ++-- .../src/Distribution/Types/ExtraSource.hs | 77 +++++++++++++------ Cabal-syntax/src/Distribution/Utils/Path.hs | 4 +- Cabal-tests/tests/NoThunks.hs | 5 +- .../src/Data/TreeDiff/Instances/Cabal.hs | 5 +- Cabal/src/Distribution/Simple/Build.hs | 20 ++--- .../Simple/GHC/Build/ExtraSources.hs | 31 +++++--- Cabal/src/Distribution/Simple/GHC/Internal.hs | 44 +++++++---- Cabal/src/Distribution/Simple/GHCJS.hs | 14 ++-- .../src/Distribution/Client/TargetSelector.hs | 2 +- cabal-install/tests/IntegrationTests2.hs | 6 +- 13 files changed, 165 insertions(+), 93 deletions(-) diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index bb6f3f25eee..22912564e49 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -174,7 +174,8 @@ libraryFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) - , c (List VCat (Identity ExtraSource) ExtraSource) + , c (List VCat (Identity (ExtraSource Pkg)) (ExtraSource Pkg)) + , c (List VCat (Identity (ExtraSource Build)) (ExtraSource Build)) , c (List CommaVCat (Identity ModuleReexport) ModuleReexport) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -225,7 +226,8 @@ foreignLibFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) - , c (List VCat (Identity ExtraSource) ExtraSource) + , c (List VCat (Identity (ExtraSource Pkg)) (ExtraSource Pkg)) + , c (List VCat (Identity (ExtraSource Build)) (ExtraSource Build)) , c (List FSep (Identity ForeignLibOption) ForeignLibOption) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -265,7 +267,8 @@ executableFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) - , c (List VCat (Identity ExtraSource) ExtraSource) + , c (List VCat (Identity (ExtraSource Pkg)) (ExtraSource Pkg)) + , c (List VCat (Identity (ExtraSource Build)) (ExtraSource Build)) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -342,7 +345,8 @@ testSuiteFieldGrammar , c (List CommaFSep Token String) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) - , c (List VCat (Identity ExtraSource) ExtraSource) + , c (List VCat (Identity (ExtraSource Pkg)) (ExtraSource Pkg)) + , c (List VCat (Identity (ExtraSource Build)) (ExtraSource Build)) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -487,7 +491,8 @@ benchmarkFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) - , c (List VCat (Identity ExtraSource) ExtraSource) + , c (List VCat (Identity (ExtraSource Pkg)) (ExtraSource Pkg)) + , c (List VCat (Identity (ExtraSource Build)) (ExtraSource Build)) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -590,7 +595,8 @@ buildInfoFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) - , c (List VCat (Identity ExtraSource) ExtraSource) + , c (List VCat (Identity (ExtraSource Pkg)) (ExtraSource Pkg)) + , c (List VCat (Identity (ExtraSource Build)) (ExtraSource Build)) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) , c (List FSep Token String) @@ -637,6 +643,8 @@ buildInfoFieldGrammar = ^^^ availableSince CabalSpecV3_0 [] <*> monoidalFieldAla "cmm-sources" formatExtraSources L.cmmSources ^^^ availableSince CabalSpecV3_0 [] + <*> monoidalFieldAla "autogen-cmm-sources" formatExtraSources L.autogenCmmSources + -- FIXME ^^^ availableSince CabalSpecV3_0 [] <*> monoidalFieldAla "c-sources" formatExtraSources L.cSources <*> monoidalFieldAla "cxx-sources" formatExtraSources L.cxxSources ^^^ availableSince CabalSpecV2_2 [] @@ -840,7 +848,7 @@ formatOtherExtensions = alaList' FSep MQuoted formatOtherModules :: [ModuleName] -> List VCat (MQuoted ModuleName) ModuleName formatOtherModules = alaList' VCat MQuoted -formatExtraSources :: [ExtraSource] -> List VCat (Identity ExtraSource) ExtraSource +formatExtraSources :: [ExtraSource pkg] -> List VCat (Identity (ExtraSource pkg)) (ExtraSource pkg) formatExtraSources = alaList' VCat Identity ------------------------------------------------------------------------------- diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs index a4a68546b92..1d7340e4de5 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs @@ -72,15 +72,17 @@ data BuildInfo = BuildInfo -- ^ support frameworks for Mac OS X , extraFrameworkDirs :: [SymbolicPath Pkg (Dir Framework)] -- ^ extra locations to find frameworks - , asmSources :: [ExtraSource] + , asmSources :: [ExtraSource Pkg] -- ^ Assembly source files - , cmmSources :: [ExtraSource] + , cmmSources :: [ExtraSource Pkg] -- ^ C-- source files - , cSources :: [ExtraSource] + , autogenCmmSources :: [ExtraSource Build] + -- ^ C-- generated source files + , cSources :: [ExtraSource Pkg] -- ^ C source files - , cxxSources :: [ExtraSource] + , cxxSources :: [ExtraSource Pkg] -- ^ C++ source files - , jsSources :: [ExtraSource] + , jsSources :: [ExtraSource Pkg] -- ^ JavaScript source file , hsSourceDirs :: [SymbolicPath Pkg (Dir Source)] -- ^ where to look for the Haskell module hierarchy @@ -172,6 +174,7 @@ instance Monoid BuildInfo where , extraFrameworkDirs = [] , asmSources = [] , cmmSources = [] + , autogenCmmSources = [] , cSources = [] , cxxSources = [] , jsSources = [] @@ -225,6 +228,7 @@ instance Semigroup BuildInfo where , extraFrameworkDirs = combineNub extraFrameworkDirs , asmSources = combineNub asmSources , cmmSources = combineNub cmmSources + , autogenCmmSources = combineNub autogenCmmSources , cSources = combineNub cSources , cxxSources = combineNub cxxSources , jsSources = combineNub jsSources diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs index e50b41485a8..2d82a81a0bd 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs @@ -80,23 +80,27 @@ class HasBuildInfo a where extraFrameworkDirs = buildInfo . extraFrameworkDirs {-# INLINE extraFrameworkDirs #-} - asmSources :: Lens' a [ExtraSource] + asmSources :: Lens' a [ExtraSource Pkg] asmSources = buildInfo . asmSources {-# INLINE asmSources #-} - cmmSources :: Lens' a [ExtraSource] + autogenCmmSources :: Lens' a [ExtraSource Build] + autogenCmmSources = buildInfo . autogenCmmSources + {-# INLINE autogenCmmSources #-} + + cmmSources :: Lens' a [ExtraSource Pkg] cmmSources = buildInfo . cmmSources {-# INLINE cmmSources #-} - cSources :: Lens' a [ExtraSource] + cSources :: Lens' a [ExtraSource Pkg] cSources = buildInfo . cSources {-# INLINE cSources #-} - cxxSources :: Lens' a [ExtraSource] + cxxSources :: Lens' a [ExtraSource Pkg] cxxSources = buildInfo . cxxSources {-# INLINE cxxSources #-} - jsSources :: Lens' a [ExtraSource] + jsSources :: Lens' a [ExtraSource Pkg] jsSources = buildInfo . jsSources {-# INLINE jsSources #-} diff --git a/Cabal-syntax/src/Distribution/Types/ExtraSource.hs b/Cabal-syntax/src/Distribution/Types/ExtraSource.hs index f9ba481502c..4b888a0d28e 100644 --- a/Cabal-syntax/src/Distribution/Types/ExtraSource.hs +++ b/Cabal-syntax/src/Distribution/Types/ExtraSource.hs @@ -1,10 +1,12 @@ +{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE TypeFamilies #-} module Distribution.Types.ExtraSource ( ExtraSource (..) - , extraSourceFromPath + , ExtraSourceClass (..) ) where import Distribution.Compat.Prelude @@ -12,37 +14,66 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import Distribution.Utils.Path (SymbolicPath, FileOrDir(..), Pkg) +import Distribution.Utils.Path (Build, FileOrDir (..), Pkg, RelativePath, SymbolicPath, relativeSymbolicPath, unsafeCoerceSymbolicPath) import qualified Distribution.Compat.CharParsing as P import qualified Text.PrettyPrint as PP -import Distribution.FieldGrammar.Newtypes (SymbolicPathNT(..)) -data ExtraSource = ExtraSource - { extraSourceFile :: SymbolicPath Pkg File - , extraSourceOpts :: [String] - } +data family ExtraSource pkg + +data instance ExtraSource Pkg = ExtraSourcePkg (SymbolicPath Pkg File) [String] + deriving (Generic, Show, Read, Eq, Ord, Typeable, Data) + +data instance ExtraSource Build = ExtraSourceBuild (RelativePath Build File) [String] deriving (Generic, Show, Read, Eq, Ord, Typeable, Data) -instance Binary ExtraSource -instance Structured ExtraSource -instance NFData ExtraSource where rnf = genericRnf +class ExtraSourceClass e where + extraSourceOpts :: e -> [String] + extraSourceFile :: e -> SymbolicPath Pkg 'File + +instance ExtraSourceClass (ExtraSource Pkg) where + extraSourceOpts (ExtraSourcePkg _ opts) = opts + extraSourceFile (ExtraSourcePkg f _) = f + +instance ExtraSourceClass (ExtraSource Build) where + extraSourceOpts (ExtraSourceBuild _ opts) = opts + + -- FIXME + extraSourceFile (ExtraSourceBuild f _) = unsafeCoerceSymbolicPath (relativeSymbolicPath f) -instance Parsec ExtraSource where +instance Binary (ExtraSource Pkg) +instance Structured (ExtraSource Pkg) +instance NFData (ExtraSource Pkg) where rnf = genericRnf + +instance Binary (ExtraSource Build) +instance Structured (ExtraSource Build) +instance NFData (ExtraSource Build) where rnf = genericRnf + +instance Parsec (ExtraSource Pkg) where parsec = do - SymbolicPathNT path <- parsec <* P.spaces - opts <- P.optional (parensLax (P.sepBy p P.spaces)) - return (ExtraSource path (fromMaybe mempty opts)) + path <- parsec <* P.spaces + opts <- P.optional (parensLax (P.sepBy p P.spaces)) + return (ExtraSourcePkg path (fromMaybe mempty opts)) where p :: P.CharParsing p => p String - p = some $ P.satisfy (\c -> not (isSpace c) && not (c == ')')) + p = some $ P.satisfy (\c -> not (isSpace c) && (c /= ')')) -parensLax :: (P.CharParsing m) => m a -> m a -parensLax p = P.between (P.char '(' *> P.spaces) (P.char ')' *> P.spaces) p +instance Parsec (ExtraSource Build) where + parsec = do + path <- parsec <* P.spaces + opts <- P.optional (parensLax (P.sepBy p P.spaces)) + return (ExtraSourceBuild path (fromMaybe mempty opts)) + where + p :: P.CharParsing p => p String + p = some $ P.satisfy (\c -> not (isSpace c) && (c /= ')')) -instance Pretty ExtraSource where - pretty (ExtraSource path opts) = - pretty (SymbolicPathNT path) <<>> PP.parens (PP.hsep (map PP.text opts)) +instance Pretty (ExtraSource Pkg) where + pretty (ExtraSourcePkg path opts) = + pretty path <<>> PP.parens (PP.hsep (map PP.text opts)) -extraSourceFromPath :: SymbolicPath Pkg File -> ExtraSource -extraSourceFromPath fp = ExtraSource fp mempty +instance Pretty (ExtraSource Build) where + pretty (ExtraSourceBuild path opts) = + pretty path <<>> PP.parens (PP.hsep (map PP.text opts)) + +parensLax :: P.CharParsing m => m a -> m a +parensLax p = P.between (P.char '(' *> P.spaces) (P.char ')' *> P.spaces) p diff --git a/Cabal-syntax/src/Distribution/Utils/Path.hs b/Cabal-syntax/src/Distribution/Utils/Path.hs index a0f18a1dfdd..3d63703f501 100644 --- a/Cabal-syntax/src/Distribution/Utils/Path.hs +++ b/Cabal-syntax/src/Distribution/Utils/Path.hs @@ -460,7 +460,7 @@ data CWD -- | Abstract directory: package directory (e.g. a directory containing the @.cabal@ file). -- -- See Note [Symbolic paths] in Distribution.Utils.Path. -data Pkg +data Pkg deriving (Data) -- | Abstract directory: dist directory (e.g. @dist-newstyle@). -- @@ -490,7 +490,7 @@ data Framework -- | Abstract directory: build directory. -- -- See Note [Symbolic paths] in Distribution.Utils.Path. -data Build +data Build deriving (Data) -- | Abstract directory: directory for build artifacts, such as documentation or @.hie@ files. -- diff --git a/Cabal-tests/tests/NoThunks.hs b/Cabal-tests/tests/NoThunks.hs index ffc4a4da0d9..63f6bcae070 100644 --- a/Cabal-tests/tests/NoThunks.hs +++ b/Cabal-tests/tests/NoThunks.hs @@ -25,7 +25,7 @@ import Distribution.ModuleName (ModuleName) import Distribution.PackageDescription.Parsec (parseGenericPackageDescription) import Distribution.SPDX (License, LicenseExceptionId, LicenseExpression, LicenseId, LicenseRef, SimpleLicenseExpression) import Distribution.System (Arch, OS) -import Distribution.Utils.Path (SymbolicPathX) +import Distribution.Utils.Path (SymbolicPathX, Pkg, Build) import Distribution.Utils.ShortText (ShortText) import Distribution.Version (Version, VersionRange) import Language.Haskell.Extension (Extension, KnownExtension, Language) @@ -73,7 +73,8 @@ instance NoThunks ConfVar instance NoThunks Dependency instance NoThunks Executable instance NoThunks ExecutableScope -instance NoThunks ExtraSource +instance NoThunks (ExtraSource Build) +instance NoThunks (ExtraSource Pkg) instance NoThunks FlagName instance NoThunks ForeignLib instance NoThunks ForeignLibOption diff --git a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs index 42ab97cc4b0..fd7e4eea3c0 100644 --- a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs +++ b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs @@ -29,7 +29,7 @@ import Distribution.Types.DumpBuildInfo (DumpBuildInfo) import Distribution.Types.PackageVersionConstraint import Distribution.Types.UnitId (DefUnitId, UnitId) import Distribution.Utils.NubList (NubList) -import Distribution.Utils.Path (SymbolicPathX) +import Distribution.Utils.Path (SymbolicPathX, Build, Pkg) import Distribution.Utils.ShortText (ShortText, fromShortText) import Distribution.Verbosity import Distribution.Verbosity.Internal @@ -78,7 +78,8 @@ instance ToExpr ExeDependency instance ToExpr Executable instance ToExpr ExecutableScope instance ToExpr ExposedModule -instance ToExpr ExtraSource +instance ToExpr (ExtraSource Build) +instance ToExpr (ExtraSource Pkg) instance ToExpr FlagAssignment instance ToExpr FlagName instance ToExpr ForeignLib diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 410db8d3062..402f27467d2 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -642,35 +642,35 @@ generateCode codeGens nm pdesc bi lbi clbi verbosity = do addExtraCSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraCSources bi extras = bi{cSources = new} where - new = ordNub (map extraSourceFromPath extras ++ cSources bi) + new = ordNub (map (flip ExtraSourcePkg []) extras ++ cSources bi) -- | Add extra C++ sources generated by preprocessing to build -- information. addExtraCxxSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraCxxSources bi extras = bi{cxxSources = new} where - new = ordNub (map extraSourceFromPath extras ++ cxxSources bi) + new = ordNub (map (flip ExtraSourcePkg []) extras ++ cxxSources bi) -- | Add extra C-- sources generated by preprocessing to build -- information. addExtraCmmSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraCmmSources bi extras = bi{cmmSources = new} where - new = ordNub (map extraSourceFromPath extras ++ cmmSources bi) + new = ordNub (map (flip ExtraSourcePkg []) extras ++ cmmSources bi) -- | Add extra ASM sources generated by preprocessing to build -- information. addExtraAsmSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraAsmSources bi extras = bi{asmSources = new} where - new = ordNub (map extraSourceFromPath extras ++ asmSources bi) + new = ordNub (map (flip ExtraSourcePkg []) extras ++ asmSources bi) -- | Add extra JS sources generated by preprocessing to build -- information. addExtraJsSources :: BuildInfo -> [SymbolicPath Pkg File] -> BuildInfo addExtraJsSources bi extras = bi{jsSources = new} where - new = ordNub (map extraSourceFromPath extras ++ jsSources bi) + new = ordNub (map (flip ExtraSourcePkg []) extras ++ jsSources bi) -- | Add extra HS modules generated by preprocessing to build -- information. @@ -716,7 +716,7 @@ replComponent preprocessComponent pkg_descr comp lbi clbi False verbosity suffixHandlers extras <- preprocessExtras verbosity comp lbi let libbi = libBuildInfo lib - lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ map extraSourceFromPath extras}} + lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ map (flip ExtraSourcePkg []) extras}} replLib replFlags pkg lbi lib' libClbi replComponent replFlags @@ -733,23 +733,23 @@ replComponent case comp of CLib lib -> do let libbi = libBuildInfo lib - lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ map extraSourceFromPath extras}} + lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ map (flip ExtraSourcePkg []) extras}} replLib replFlags pkg_descr lbi lib' clbi CFLib flib -> replFLib replFlags pkg_descr lbi flib clbi CExe exe -> do let ebi = buildInfo exe - exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map extraSourceFromPath extras}} + exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map (flip ExtraSourcePkg []) extras}} replExe replFlags pkg_descr lbi exe' clbi CTest test@TestSuite{testInterface = TestSuiteExeV10{}} -> do let exe = testSuiteExeV10AsExe test let ebi = buildInfo exe - exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map extraSourceFromPath extras}} + exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map (flip ExtraSourcePkg []) extras}} replExe replFlags pkg_descr lbi exe' clbi CBench bm@Benchmark{benchmarkInterface = BenchmarkExeV10{}} -> do let exe = benchmarkExeV10asExe bm let ebi = buildInfo exe - exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map extraSourceFromPath extras}} + exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ map (flip ExtraSourcePkg []) extras}} replExe replFlags pkg_descr lbi exe' clbi #if __GLASGOW_HASKELL__ < 811 -- silence pattern-match warnings prior to GHC 9.0 diff --git a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs index 9304d3691ae..800059a9402 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs @@ -1,5 +1,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DisambiguateRecordFields #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RankNTypes #-} @@ -26,7 +28,7 @@ import Distribution.Simple.Program.Types import Distribution.Simple.Setup.Common (commonSetupTempFileOptions) import Distribution.System (Arch (JavaScript), Platform (..)) import Distribution.Types.ComponentLocalBuildInfo -import Distribution.Types.ExtraSource (ExtraSource(..)) +import Distribution.Types.ExtraSource (ExtraSource (..)) import Distribution.Utils.Path import Distribution.Verbosity (Verbosity) @@ -52,9 +54,10 @@ buildAllExtraSources = , buildJsSources , buildAsmSources , buildCmmSources + , buildAutogenCmmSources ] -type ExtraSourceBuilder = +type ExtraSourceBuilder = Maybe (SymbolicPath Pkg File) -- ^ An optional non-Haskell Main file -> ConfiguredProgram @@ -79,7 +82,7 @@ buildCSources mbMainFile = CExe{} | Just main <- mbMainFile , isC $ getSymbolicPath main -> - cFiles ++ [ExtraSource main mempty] + cFiles ++ [ExtraSourcePkg main mempty] _otherwise -> cFiles ) @@ -94,7 +97,7 @@ buildCxxSources mbMainFile = CExe{} | Just main <- mbMainFile , isCxx $ getSymbolicPath main -> - cxxFiles ++ [ExtraSource main mempty] + cxxFiles ++ [ExtraSourcePkg main mempty] _otherwise -> cxxFiles ) @@ -132,25 +135,34 @@ buildCmmSources _mbMainFile = Internal.componentCmmGhcOptions (cmmSources . componentBuildInfo) +buildAutogenCmmSources :: ExtraSourceBuilder +buildAutogenCmmSources _mbMainFile= + buildExtraSources + "C-- Generated Sources" + Internal.componentCmmGhcOptions + (autogenCmmSources . componentBuildInfo) + -- | Create 'PreBuildComponentRules' for a given type of extra build sources -- which are compiled via a GHC invocation with the given options. Used to -- define built-in extra sources, such as, C, Cxx, Js, Asm, and Cmm sources. buildExtraSources - :: String + :: forall from + . Internal.SourcePath (ExtraSource from) + => String -- ^ String describing the extra sources being built, for printing. -> ( Verbosity -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> SymbolicPath Pkg (Dir Artifacts) - -> ExtraSource + -> ExtraSource from -> GhcOptions ) -- ^ Function to determine the @'GhcOptions'@ for the -- invocation of GHC when compiling these extra sources (e.g. -- @'Internal.componentCxxGhcOptions'@, -- @'Internal.componentCmmGhcOptions'@) - -> (Component -> [ExtraSource]) + -> (Component -> [ExtraSource from]) -- ^ View the extra sources of a component, typically from -- the build info (e.g. @'asmSources'@, @'cSources'@). -- @'Executable'@ components might additionally add the @@ -196,7 +208,6 @@ buildExtraSources platform mbWorkDir - buildAction :: ExtraSource -> IO () buildAction extraSource = do let baseSrcOpts = componentSourceGhcOptions @@ -236,7 +247,7 @@ buildExtraSources compileIfNeeded :: GhcOptions -> IO () compileIfNeeded opts' = do - needsRecomp <- checkNeedsRecompilation mbWorkDir (extraSourceFile extraSource) opts' + needsRecomp <- checkNeedsRecompilation mbWorkDir (Internal.sourcePath lbi extraSource) opts' when needsRecomp $ runGhcProg opts' createDirectoryIfMissingVerbose verbosity True (i odir) @@ -276,4 +287,4 @@ buildExtraSources else do info verbosity ("Building " ++ description ++ "...") traverse_ buildAction sources - return (toNubListR (map extraSourceFile sources)) + return (toNubListR (map (Internal.sourcePath lbi) sources)) diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index f4083859dea..dd046fcbece 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -1,5 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE RankNTypes #-} ----------------------------------------------------------------------------- @@ -47,6 +48,9 @@ module Distribution.Simple.GHC.Internal , ghcEnvironmentFileName , renderGhcEnvironmentFile , renderGhcEnvironmentFileEntry + + -- * Paths + , SourcePath (..) ) where import Distribution.Compat.Prelude @@ -311,7 +315,6 @@ getExtensions verbosity implInfo ghcProg = do then lines str else -- Older GHCs only gave us either Foo or NoFoo, -- so we have to work out the other one ourselves - [ extStr'' | extStr <- lines str , let extStr' = case extStr of @@ -331,7 +334,6 @@ getExtensions verbosity implInfo ghcProg = do -- Since it was not a proper extension, it could -- not be turned off, hence we omit a -- DisableExtension entry here. - (EnableExtension NondecreasingIndentation, Nothing) : extensions0 else extensions0 @@ -357,24 +359,23 @@ includePaths lbi bi clbi odir = | dir <- mapMaybe (symbolicPathRelative_maybe . unsafeCoerceSymbolicPath) $ includeDirs bi ] -type ExtraSourceGhcOptions = +type ExtraSourceGhcOptions pkg = Verbosity -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> SymbolicPath Pkg (Dir Artifacts) - -> ExtraSource + -> ExtraSource pkg -> GhcOptions - -componentCcGhcOptions :: ExtraSourceGhcOptions +componentCcGhcOptions :: SourcePath (ExtraSource pkg) => ExtraSourceGhcOptions pkg componentCcGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] + , ghcOptInputFiles = toNubListR [sourcePath lbi extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -395,19 +396,19 @@ componentCcGhcOptions verbosity lbi bi clbi odir extraSource = , ghcOptCcProgram = maybeToFlag $ programPath - <$> lookupProgram gccProgram (withPrograms lbi) + <$> lookupProgram gccProgram (withPrograms lbi) , ghcOptObjDir = toFlag odir , ghcOptExtra = hcOptions GHC bi } -componentCxxGhcOptions :: ExtraSourceGhcOptions +componentCxxGhcOptions :: SourcePath (ExtraSource pkg) => ExtraSourceGhcOptions pkg componentCxxGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] + , ghcOptInputFiles = toNubListR [sourcePath lbi extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -428,19 +429,19 @@ componentCxxGhcOptions verbosity lbi bi clbi odir extraSource = , ghcOptCcProgram = maybeToFlag $ programPath - <$> lookupProgram gccProgram (withPrograms lbi) + <$> lookupProgram gccProgram (withPrograms lbi) , ghcOptObjDir = toFlag odir , ghcOptExtra = hcOptions GHC bi } -componentAsmGhcOptions :: ExtraSourceGhcOptions +componentAsmGhcOptions :: SourcePath (ExtraSource pkg) => ExtraSourceGhcOptions pkg componentAsmGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] + , ghcOptInputFiles = toNubListR [sourcePath lbi extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -460,14 +461,14 @@ componentAsmGhcOptions verbosity lbi bi clbi odir extraSource = , ghcOptObjDir = toFlag odir } -componentJsGhcOptions :: ExtraSourceGhcOptions +componentJsGhcOptions :: SourcePath (ExtraSource pkg) => ExtraSourceGhcOptions pkg componentJsGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] + , ghcOptInputFiles = toNubListR [sourcePath lbi extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptHideAllPackages = toFlag True , ghcOptPackageDBs = withPackageDB lbi @@ -561,14 +562,14 @@ toGhcOptimisation NoOptimisation = mempty -- TODO perhaps override? toGhcOptimisation NormalOptimisation = toFlag GhcNormalOptimisation toGhcOptimisation MaximumOptimisation = toFlag GhcMaximumOptimisation -componentCmmGhcOptions :: ExtraSourceGhcOptions +componentCmmGhcOptions :: SourcePath (ExtraSource pkg) => ExtraSourceGhcOptions pkg componentCmmGhcOptions verbosity lbi bi clbi odir extraSource = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! ghcOptVerbosity = toFlag (min verbosity normal) , ghcOptMode = toFlag GhcModeCompile - , ghcOptInputFiles = toNubListR [extraSourceFile extraSource] + , ghcOptInputFiles = toNubListR [sourcePath lbi extraSource] , ghcOptCppIncludePath = includePaths lbi bi clbi odir , ghcOptCppOptions = cppOptions bi , ghcOptCppIncludes = @@ -815,3 +816,12 @@ renderGhcEnvironmentFileEntry entry = case entry of UserPackageDB -> "user-package-db" SpecificPackageDB dbfile -> "package-db " ++ dbfile GhcEnvFileClearPackageDbStack -> "clear-package-db" + +class ExtraSourceClass e => SourcePath e where + sourcePath :: LocalBuildInfo -> e -> SymbolicPath Pkg 'File + +instance SourcePath (ExtraSource Pkg) where + sourcePath _ (ExtraSourcePkg f _) = f + +instance SourcePath (ExtraSource Build) where + sourcePath lbi (ExtraSourceBuild f _) = buildDir lbi </> f diff --git a/Cabal/src/Distribution/Simple/GHCJS.hs b/Cabal/src/Distribution/Simple/GHCJS.hs index ddf65bf5f60..967981ee045 100644 --- a/Cabal/src/Distribution/Simple/GHCJS.hs +++ b/Cabal/src/Distribution/Simple/GHCJS.hs @@ -547,7 +547,7 @@ buildOrReplLib mReplFlags verbosity numJobs _pkg_descr lbi lib clbi = do , "-js-lib-outputdir" , getSymbolicPath libTargetDir ] - ++ foldMap (\(ExtraSource file opts) -> getSymbolicPath file : opts) jsSrcs + ++ foldMap (\e -> getSymbolicPath (extraSourceFile e) : extraSourceOpts e) jsSrcs } vanillaOptsNoJsLib = baseOpts @@ -1114,8 +1114,8 @@ decodeMainIsArg arg -- -- Used to correctly build and link sources. data BuildSources = BuildSources - { cSourcesFiles :: [ExtraSource] - , cxxSourceFiles :: [ExtraSource] + { cSourcesFiles :: [ExtraSource Pkg] + , cxxSourceFiles :: [ExtraSource Pkg] , inputSourceFiles :: [SymbolicPath Pkg File] , inputSourceModules :: [ModuleName] } @@ -1161,8 +1161,8 @@ gbuildSources verbosity mbWorkDir pkgId specVer tmpDir bm = -- have no excuse anymore to keep doing it wrong... ;-) warn verbosity $ "Enabling workaround for Main module '" - ++ prettyShow mainModName - ++ "' listed in 'other-modules' illegally!" + ++ prettyShow mainModName + ++ "' listed in 'other-modules' illegally!" return BuildSources @@ -1181,11 +1181,11 @@ gbuildSources verbosity mbWorkDir pkgId specVer tmpDir bm = } else let (csf, cxxsf) - | isCxx (getSymbolicPath main) = (cSources bnfo, extraSourceFromPath main : cxxSources bnfo) + | isCxx (getSymbolicPath main) = (cSources bnfo, ExtraSourcePkg main [] : cxxSources bnfo) -- if main is not a Haskell source -- and main is not a C++ source -- then we assume that it is a C source - | otherwise = (extraSourceFromPath main : cSources bnfo, cxxSources bnfo) + | otherwise = (ExtraSourcePkg main [] : cSources bnfo, cxxSources bnfo) in return BuildSources { cSourcesFiles = csf diff --git a/cabal-install/src/Distribution/Client/TargetSelector.hs b/cabal-install/src/Distribution/Client/TargetSelector.hs index 61ca11f087a..d74aff42e3e 100644 --- a/cabal-install/src/Distribution/Client/TargetSelector.hs +++ b/cabal-install/src/Distribution/Client/TargetSelector.hs @@ -72,7 +72,7 @@ import Distribution.PackageDescription , BenchmarkInterface (..) , BuildInfo (..) , Executable (..) - , ExtraSource (..) + , ExtraSourceClass (..) , PackageDescription , TestSuite (..) , TestSuiteInterface (..) diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index 273be658906..dd54fea54d0 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -70,7 +71,7 @@ import qualified Distribution.Simple.Flag as Flag import Distribution.Simple.Setup (CommonSetupFlags (..), HaddockFlags (..), HaddockProjectFlags (..), defaultCommonSetupFlags, defaultHaddockFlags, defaultHaddockProjectFlags, toFlag) import Distribution.System import Distribution.Text -import Distribution.Utils.Path (unsafeMakeSymbolicPath) +import Distribution.Utils.Path (FileOrDir (File), Pkg, SymbolicPath, unsafeMakeSymbolicPath) import Distribution.Version import IntegrationTests2.CPP @@ -660,7 +661,8 @@ testTargetSelectorAmbiguous reportSubCase = do withCFiles exe files = exe{buildInfo = (buildInfo exe){cSources = map (mkExtraSource . unsafeMakeSymbolicPath) files}} - mkExtraSource x = ExtraSource x [] + mkExtraSource :: SymbolicPath Pkg File -> ExtraSource Pkg + mkExtraSource x = ExtraSourcePkg x [] withHsSrcDirs :: Executable -> [FilePath] -> Executable withHsSrcDirs exe srcDirs = From c44c4a957c5e4fdedaa2c252bb0ecdbefac4de0d Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Fri, 7 Mar 2025 13:02:21 +0800 Subject: [PATCH 08/82] refactor: jsem is irrelevant to fetching packages This has to be cleaned up but it does not make sense to pass the compiler. --- .../src/Distribution/Client/CmdInstall.hs | 1 - .../src/Distribution/Client/ProjectConfig.hs | 21 ++++++------------- .../Distribution/Client/ProjectPlanning.hs | 9 +++----- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/cabal-install/src/Distribution/Client/CmdInstall.hs b/cabal-install/src/Distribution/Client/CmdInstall.hs index 63cf59169a3..07a72119b75 100644 --- a/cabal-install/src/Distribution/Client/CmdInstall.hs +++ b/cabal-install/src/Distribution/Client/CmdInstall.hs @@ -467,7 +467,6 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project fetchAndReadSourcePackages verbosity distDirLayout - (Just compiler) (projectConfigShared config) (projectConfigBuildOnly config) [ProjectPackageRemoteTarball uri | uri <- uris] diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index b9f2cfed6c6..e966ad29624 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -1261,7 +1261,6 @@ mplusMaybeT ma mb = do fetchAndReadSourcePackages :: Verbosity -> DistDirLayout - -> Maybe Compiler -> ProjectConfigShared -> ProjectConfigBuildOnly -> [ProjectPackageLocation] @@ -1269,7 +1268,6 @@ fetchAndReadSourcePackages fetchAndReadSourcePackages verbosity distDirLayout - compiler projectConfigShared projectConfigBuildOnly pkgLocations = do @@ -1306,9 +1304,7 @@ fetchAndReadSourcePackages syncAndReadSourcePackagesRemoteRepos verbosity distDirLayout - compiler projectConfigShared - projectConfigBuildOnly (fromFlag (projectConfigOfflineMode projectConfigBuildOnly)) [repo | ProjectPackageRemoteRepo repo <- pkgLocations] @@ -1425,23 +1421,16 @@ fetchAndReadSourcePackageRemoteTarball syncAndReadSourcePackagesRemoteRepos :: Verbosity -> DistDirLayout - -> Maybe Compiler -> ProjectConfigShared - -> ProjectConfigBuildOnly -> Bool -> [SourceRepoList] -> Rebuild [PackageSpecifier (SourcePackage UnresolvedPkgLoc)] syncAndReadSourcePackagesRemoteRepos verbosity DistDirLayout{distDownloadSrcDirectory} - compiler ProjectConfigShared { projectConfigProgPathExtra } - ProjectConfigBuildOnly - { projectConfigUseSemaphore - , projectConfigNumJobs - } offlineMode repos = do repos' <- @@ -1462,14 +1451,15 @@ syncAndReadSourcePackagesRemoteRepos ] let progPathExtra = fromNubList projectConfigProgPathExtra + getConfiguredVCS <- delayInitSharedResources $ \repoType -> let vcs = Map.findWithDefault (error $ "Unknown VCS: " ++ prettyShow repoType) repoType knownVCSs in configureVCS verbosity progPathExtra vcs - concat - <$> rerunConcurrentlyIfChanged + x <- + rerunConcurrentlyIfChanged verbosity - (newJobControlFromParStrat verbosity compiler parStrat (Just maxNumFetchJobs)) + (newParallelJobControl maxNumFetchJobs) [ ( monitor , repoGroup' , do @@ -1487,8 +1477,9 @@ syncAndReadSourcePackagesRemoteRepos [PackageSpecifier (SourcePackage UnresolvedPkgLoc)] monitor = newFileMonitor (pathStem <.> "cache") ] + + return (concat x) where - parStrat = resolveNumJobsSetting projectConfigUseSemaphore projectConfigNumJobs syncRepoGroupAndReadSourcePackages :: VCS ConfiguredProgram -> FilePath diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 7e10677437c..37d0a4a3bdb 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -401,11 +401,11 @@ rebuildProjectConfig (compiler, Platform arch os, _) <- configureCompiler verbosity distDirLayout (fst (PD.ignoreConditions projectConfigSkeleton) <> cliConfig) pure (os, arch, compiler) - (projectConfig, compiler) <- instantiateProjectConfigSkeletonFetchingCompiler fetchCompiler mempty projectConfigSkeleton + (projectConfig, _compiler) <- instantiateProjectConfigSkeletonFetchingCompiler fetchCompiler mempty projectConfigSkeleton when (projectConfigDistDir (projectConfigShared $ projectConfig) /= NoFlag) $ liftIO $ warn verbosity "The builddir option is not supported in project and config files. It will be ignored." - localPackages <- phaseReadLocalPackages compiler (projectConfig <> cliConfig) + localPackages <- phaseReadLocalPackages (projectConfig <> cliConfig) return (projectConfig, localPackages) let configfiles = @@ -437,11 +437,9 @@ rebuildProjectConfig -- NOTE: These are all packages mentioned in the project configuration. -- Whether or not they will be considered local to the project will be decided by `shouldBeLocal`. phaseReadLocalPackages - :: Maybe Compiler - -> ProjectConfig + :: ProjectConfig -> Rebuild [PackageSpecifier UnresolvedSourcePackage] phaseReadLocalPackages - compiler projectConfig@ProjectConfig { projectConfigShared , projectConfigBuildOnly @@ -456,7 +454,6 @@ rebuildProjectConfig fetchAndReadSourcePackages verbosity distDirLayout - compiler projectConfigShared projectConfigBuildOnly pkgLocations From 9b66d2cb6229e5864ef1d1c1ffee59bb2d8d9780 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Thu, 6 Mar 2025 12:17:18 +0800 Subject: [PATCH 09/82] refactor: introduce resolveProgramDb --- .../src/Distribution/Client/ProjectConfig.hs | 11 +++++++++++ .../src/Distribution/Client/ProjectPlanning.hs | 8 +++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index e966ad29624..5bf2ab41e94 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -57,6 +57,7 @@ module Distribution.Client.ProjectConfig , BuildTimeSettings (..) , resolveBuildTimeSettings , resolveNumJobsSetting + , resolveProgramDb -- * Checking configuration , checkBadPerPackageCompilerPaths @@ -175,6 +176,9 @@ import Distribution.Simple.InstallDirs ) import Distribution.Simple.Program ( ConfiguredProgram (..) + , ProgramDb + , defaultProgramDb + , userSpecifyPaths ) import Distribution.Simple.Setup ( Flag (Flag) @@ -245,6 +249,7 @@ import System.IO ) import Distribution.Deprecated.ProjectParseUtils (ProjectParseError (..), ProjectParseWarning) +import Distribution.Simple.Program.Db (prependProgramSearchPath) import Distribution.Solver.Types.ProjectConfigPath ---------------------------------------- @@ -554,6 +559,12 @@ resolveNumJobsSetting projectConfigUseSemaphore projectConfigNumJobs = 1 -> Serial n -> NumJobs (Just n) +resolveProgramDb :: Verbosity -> PackageConfig -> IO ProgramDb +resolveProgramDb verbosity pkgconf = do + let extraPath = fromNubList (packageConfigProgramPathExtra pkgconf) + progdb <- prependProgramSearchPath verbosity extraPath [] defaultProgramDb + return $ userSpecifyPaths (Map.toList (getMapLast (packageConfigProgramPaths pkgconf))) progdb + --------------------------------------------- -- Reading and writing project config files -- diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 37d0a4a3bdb..84f5111e139 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -476,7 +476,7 @@ configureCompiler , projectConfigHcPkg } , projectConfigLocalPackages = - PackageConfig + projectConfigLocalPackages@PackageConfig { packageConfigProgramPaths , packageConfigProgramPathExtra } @@ -497,16 +497,14 @@ configureCompiler ) $ do liftIO $ info verbosity "Compiler settings changed, reconfiguring..." - let extraPath = fromNubList packageConfigProgramPathExtra - progdb <- liftIO $ prependProgramSearchPath verbosity extraPath [] defaultProgramDb - let progdb' = userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths)) progdb + progdb <- liftIO $ resolveProgramDb verbosity projectConfigLocalPackages result@(_, _, progdb'') <- liftIO $ Cabal.configCompilerEx hcFlavor hcPath hcPkg - progdb' + progdb verbosity -- Note that we added the user-supplied program locations and args From 0516edb55f418a4704b219065b201a86337fa124 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Wed, 5 Mar 2025 15:04:43 +0800 Subject: [PATCH 10/82] wip: introduce build and host toolchains --- .../src/Distribution/Client/Config.hs | 3 ++ .../Client/ProjectConfig/Legacy.hs | 13 ++++---- .../Client/ProjectConfig/Types.hs | 3 ++ .../src/Distribution/Client/Setup.hs | 30 ++++++++++++++++++- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 419d7d603ea..61384f495fb 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -573,6 +573,9 @@ instance Semigroup SavedConfig where combineMonoid savedConfigureExFlags configAllowOlder , configWriteGhcEnvironmentFilesPolicy = combine configWriteGhcEnvironmentFilesPolicy + , configHostHcFlavor = combine configHostHcFlavor + , configHostHcPath = combine configHostHcPath + , configHostHcPkg = combine configHostHcPkg } where combine = combine' savedConfigureExFlags diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 7d1bee02daa..f5030f58b5c 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -704,6 +704,13 @@ convertLegacyAllPackageFlags convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags projectFlags projectConfigMultiRepl = ProjectConfigShared{..} where + projectConfigHostHcFlavor = NoFlag + projectConfigHostHcPath = NoFlag + projectConfigHostHcPkg = NoFlag + projectConfigPackageDBs = (fmap . fmap) (interpretPackageDB Nothing) projectConfigPackageDBs_ + projectConfigHookHashes = mempty -- :: Map FilePath HookAccept + projectConfigDistDir = fmap getSymbolicPath projectConfigAbsoluteDistDir + GlobalFlags { globalConfigFile = projectConfigConfigFile , globalRemoteRepos = projectConfigRemoteRepos @@ -713,8 +720,6 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags , globalStoreDir = projectConfigStoreDir } = globalFlags - projectConfigPackageDBs = (fmap . fmap) (interpretPackageDB Nothing) projectConfigPackageDBs_ - projectConfigHookHashes = mempty -- :: Map FilePath HookAccept ConfigFlags { configCommonFlags = commonFlags , configHcFlavor = projectConfigHcFlavor @@ -730,8 +735,6 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags { setupDistPref = projectConfigAbsoluteDistDir } = commonFlags - projectConfigDistDir = fmap getSymbolicPath projectConfigAbsoluteDistDir - ConfigExFlags { configCabalVersion = projectConfigCabalVersion , configExConstraints = projectConfigConstraints @@ -1010,7 +1013,7 @@ convertToLegacySharedConfig } configExFlags = - ConfigExFlags + mempty { configCabalVersion = projectConfigCabalVersion , configAppend = mempty , configBackup = mempty diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 4f1558fa215..5657bb4b605 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -192,6 +192,9 @@ data ProjectConfigShared = ProjectConfigShared , projectConfigHcFlavor :: Flag CompilerFlavor , projectConfigHcPath :: Flag FilePath , projectConfigHcPkg :: Flag FilePath + , projectConfigHostHcFlavor :: Flag CompilerFlavor + , projectConfigHostHcPath :: Flag FilePath + , projectConfigHostHcPkg :: Flag FilePath , projectConfigHaddockIndex :: Flag PathTemplate , -- Only makes sense for manual mode, not --local mode -- too much control! diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 78fcf7c2e1f..da399b604a7 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -162,7 +162,7 @@ import Distribution.ReadE ) import Distribution.Simple.Command hiding (boolOpt, boolOpt') import qualified Distribution.Simple.Command as Command -import Distribution.Simple.Compiler (Compiler, PackageDB, PackageDBStack) +import Distribution.Simple.Compiler (Compiler, CompilerFlavor (..), PackageDB, PackageDBStack) import Distribution.Simple.Configure ( computeEffectiveProfiling , configCompilerAuxEx @@ -920,6 +920,9 @@ data ConfigExFlags = ConfigExFlags , configAllowOlder :: Maybe AllowOlder , configWriteGhcEnvironmentFilesPolicy :: Flag WriteGhcEnvironmentFilesPolicy + , configHostHcFlavor :: Flag CompilerFlavor + , configHostHcPath :: Flag FilePath + , configHostHcPkg :: Flag FilePath } deriving (Eq, Show, Generic) @@ -1047,6 +1050,31 @@ configureExOptions _showOrParseArgs src = writeGhcEnvironmentFilesPolicyParser writeGhcEnvironmentFilesPolicyPrinter ) + , option + [] + ["host-compiler"] + "host compiler" + configHostHcFlavor + (\v flags -> flags{configHostHcFlavor = v}) + ( choiceOpt + [ (Flag GHC, ("g", ["ghc"]), "compile with GHC") + , (Flag GHCJS, ([], ["ghcjs"]), "compile with GHCJS") + ] + ) + , option + "W" + ["with-host-compiler", "with-host-hc"] + "give the path to the compiler for the host toolchain" + configHostHcPath + (\v flags -> flags{configHostHcPath = v}) + (reqArgFlag "PATH") + , option + "" + ["with-host-hc-pkg"] + "give the path to the package tool for the host toolchain" + configHostHcPkg + (\v flags -> flags{configHostHcPkg = v}) + (reqArgFlag "PATH") ] writeGhcEnvironmentFilesPolicyParser :: ReadE (Flag WriteGhcEnvironmentFilesPolicy) From 61f100feb82ecb08c6f798ceb0664a80b81cd155 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Thu, 6 Mar 2025 12:57:12 +0800 Subject: [PATCH 11/82] wip: thread toolchains everywhere --- Cabal/src/Distribution/Simple/Program/Db.hs | 15 + .../src/Distribution/Client/CmdExec.hs | 10 +- .../src/Distribution/Client/CmdHaddock.hs | 47 ++-- .../Distribution/Client/CmdHaddockProject.hs | 61 ++-- .../src/Distribution/Client/CmdListBin.hs | 2 +- .../src/Distribution/Client/CmdPath.hs | 11 +- .../src/Distribution/Client/CmdRepl.hs | 12 +- .../Distribution/Client/ProjectBuilding.hs | 3 +- .../Client/ProjectBuilding/UnpackedPackage.hs | 30 +- .../Client/ProjectOrchestration.hs | 10 +- .../Distribution/Client/ProjectPlanOutput.hs | 53 ++-- .../Distribution/Client/ProjectPlanning.hs | 261 +++++++++--------- .../Client/ProjectPlanning/Types.hs | 47 +++- .../src/Distribution/Client/ScriptUtils.hs | 15 +- cabal-install/tests/IntegrationTests2.hs | 8 +- .../Distribution/Client/ProjectConfig.hs | 6 + 16 files changed, 337 insertions(+), 254 deletions(-) diff --git a/Cabal/src/Distribution/Simple/Program/Db.hs b/Cabal/src/Distribution/Simple/Program/Db.hs index c76b38e9923..bc5d0714aa3 100644 --- a/Cabal/src/Distribution/Simple/Program/Db.hs +++ b/Cabal/src/Distribution/Simple/Program/Db.hs @@ -67,6 +67,7 @@ module Distribution.Simple.Program.Db , ConfiguredProgs , updateUnconfiguredProgs , updateConfiguredProgs + , programDbSignature ) where import Distribution.Compat.Prelude @@ -564,3 +565,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 + ] diff --git a/cabal-install/src/Distribution/Client/CmdExec.hs b/cabal-install/src/Distribution/Client/CmdExec.hs index caa680a3a3a..c0f565738fb 100644 --- a/cabal-install/src/Distribution/Client/CmdExec.hs +++ b/cabal-install/src/Distribution/Client/CmdExec.hs @@ -55,7 +55,9 @@ import Distribution.Client.ProjectPlanning ) import qualified Distribution.Client.ProjectPlanning as Planning import Distribution.Client.ProjectPlanning.Types - ( dataDirsEnvironmentForPlan + ( Toolchain (..) + , Toolchains (..) + , dataDirsEnvironmentForPlan ) import Distribution.Client.Setup ( ConfigFlags (configCommonFlags) @@ -170,7 +172,7 @@ execAction flags@NixStyleFlags{..} extraArgs globalFlags = do -- Some dependencies may have executables. Let's put those on the PATH. let extraPaths = pathAdditions baseCtx buildCtx - pkgProgs = pkgConfigCompilerProgs (elaboratedShared buildCtx) + pkgProgs = toolchainProgramDb $ buildToolchain $ pkgConfigToolchains (elaboratedShared buildCtx) extraEnvVars = dataDirsEnvironmentForPlan (distDirLayout baseCtx) @@ -185,7 +187,7 @@ execAction flags@NixStyleFlags{..} extraArgs globalFlags = do -- point at the file. -- In case ghc is too old to support environment files, -- we pass the same info as arguments - let compiler = pkgConfigCompiler $ elaboratedShared buildCtx + let compiler = toolchainCompiler $ buildToolchain $ pkgConfigToolchains $ elaboratedShared buildCtx envFilesSupported = supportsPkgEnvFiles (getImplInfo compiler) case extraArgs of [] -> dieWithException verbosity SpecifyAnExecutable @@ -243,7 +245,7 @@ matchCompilerPath elaboratedShared program = programPath program `elem` (programPath <$> configuredCompilers) where - configuredCompilers = configuredPrograms $ pkgConfigCompilerProgs elaboratedShared + configuredCompilers = configuredPrograms $ toolchainProgramDb $ buildToolchain $ pkgConfigToolchains elaboratedShared -- | Execute an action with a temporary .ghc.environment file reflecting the -- current environment. The action takes an environment containing the env diff --git a/cabal-install/src/Distribution/Client/CmdHaddock.hs b/cabal-install/src/Distribution/Client/CmdHaddock.hs index 677589e3e35..4b35b1f9f2e 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddock.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddock.hs @@ -27,9 +27,6 @@ import Distribution.Client.ProjectConfig.Types , ProjectConfig (..) ) import Distribution.Client.ProjectOrchestration -import Distribution.Client.ProjectPlanning - ( ElaboratedSharedConfig (..) - ) import Distribution.Client.Setup ( CommonSetupFlags (..) , ConfigFlags (..) @@ -48,13 +45,6 @@ import Distribution.Simple.Command , usageAlternatives ) import Distribution.Simple.Flag (Flag (..)) -import Distribution.Simple.Program.Builtin - ( haddockProgram - ) -import Distribution.Simple.Program.Db - ( addKnownProgram - , reconfigurePrograms - ) import Distribution.Simple.Setup ( HaddockFlags (..) , fromFlagOrDefault @@ -160,6 +150,7 @@ haddockAction relFlags targetStrings globalFlags = do projCtx{buildSettings = (buildSettings projCtx){buildSettingHaddockOpen = True}} | otherwise = projCtx + absProjectConfig <- mkConfigAbsolute relProjectConfig let baseCtx = relBaseCtx{projectConfig = absProjectConfig} @@ -188,28 +179,32 @@ haddockAction relFlags targetStrings globalFlags = do TargetActionHaddock targets elaboratedPlan + return (elaboratedPlan', targets) printPlan verbosity baseCtx buildCtx - progs <- - reconfigurePrograms - verbosity - (haddockProgramPaths haddockFlags) - (haddockProgramArgs haddockFlags) - -- we need to insert 'haddockProgram' before we reconfigure it, - -- otherwise 'set - . addKnownProgram haddockProgram - . pkgConfigCompilerProgs - . elaboratedShared - $ buildCtx + -- TODO + -- progs <- + -- reconfigurePrograms + -- verbosity + -- (haddockProgramPaths haddockFlags) + -- (haddockProgramArgs haddockFlags) + -- -- we need to insert 'haddockProgram' before we reconfigure it, + -- -- otherwise 'set + -- . addKnownProgram haddockProgram + -- . pkgConfigCompilerProgs + -- . elaboratedShared + -- $ buildCtx + + -- TODO let buildCtx' = buildCtx - { elaboratedShared = - (elaboratedShared buildCtx) - { pkgConfigCompilerProgs = progs - } - } + -- { elaboratedShared = + -- (elaboratedShared buildCtx) + -- { pkgConfigCompilerProgs = progs + -- } + -- } buildOutcomes <- runProjectBuildPhase verbosity baseCtx buildCtx' runProjectPostBuildPhase verbosity baseCtx buildCtx' buildOutcomes diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs index 0635a77d68e..680e538513b 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs @@ -37,7 +37,9 @@ import Distribution.Client.ProjectPlanning , TargetAction (..) ) import Distribution.Client.ProjectPlanning.Types - ( elabDistDirParams + ( Toolchain (..) + , Toolchains (..) + , elabDistDirParams ) import Distribution.Client.ScriptUtils ( AcceptNoTargets (..) @@ -72,14 +74,6 @@ import Distribution.Simple.Haddock (createHaddockIndex) import Distribution.Simple.InstallDirs ( toPathTemplate ) -import Distribution.Simple.Program.Builtin - ( haddockProgram - ) -import Distribution.Simple.Program.Db - ( addKnownProgram - , reconfigurePrograms - , requireProgramVersion - ) import Distribution.Simple.Setup ( HaddockFlags (..) , HaddockProjectFlags (..) @@ -100,8 +94,6 @@ import Distribution.Types.PackageDescription (PackageDescription (benchmarks, su import Distribution.Types.PackageId (pkgName) import Distribution.Types.PackageName (unPackageName) import Distribution.Types.UnitId (unUnitId) -import Distribution.Types.Version (mkVersion) -import Distribution.Types.VersionRange (orLaterVersion) import Distribution.Verbosity as Verbosity ( normal ) @@ -166,24 +158,26 @@ haddockProjectAction flags _extraArgs globalFlags = do pkgs :: [Either InstalledPackageInfo ElaboratedConfiguredPackage] pkgs = matchingPackages elaboratedPlan - progs <- - reconfigurePrograms - verbosity - (haddockProjectProgramPaths flags) - (haddockProjectProgramArgs flags) - -- we need to insert 'haddockProgram' before we reconfigure it, - -- otherwise 'set - . addKnownProgram haddockProgram - . pkgConfigCompilerProgs - $ sharedConfig - let sharedConfig' = sharedConfig{pkgConfigCompilerProgs = progs} - - _ <- - requireProgramVersion - verbosity - haddockProgram - (orLaterVersion (mkVersion [2, 26, 1])) - progs + -- TODO + -- progs <- + -- reconfigurePrograms + -- verbosity + -- (haddockProjectProgramPaths flags) + -- (haddockProjectProgramArgs flags) + -- -- we need to insert 'haddockProgram' before we reconfigure it, + -- -- otherwise 'set + -- . addKnownProgram haddockProgram + -- . pkgConfigCompilerProgs + -- $ sharedConfig + -- let sharedConfig' = sharedConfig{pkgConfigCompilerProgs = progs} + let sharedConfig' = sharedConfig + + -- _ <- + -- requireProgramVersion + -- verbosity + -- haddockProgram + -- (orLaterVersion (mkVersion [2, 26, 1])) + -- progs -- -- Build project; we need to build dependencies. @@ -301,7 +295,7 @@ haddockProjectAction flags _extraArgs globalFlags = do packageDir = storePackageDirectory (cabalStoreDirLayout cabalLayout) - (pkgConfigCompiler sharedConfig') + (toolchainCompiler $ buildToolchain $ pkgConfigToolchains sharedConfig') (elabUnitId package) -- TODO: use `InstallDirTemplates` docDir = packageDir </> "share" </> "doc" </> "html" @@ -344,11 +338,12 @@ haddockProjectAction flags _extraArgs globalFlags = do ] , haddockProjectUseUnicode = NoFlag } + -- NOTE: this lives in Cabal createHaddockIndex verbosity - (pkgConfigCompilerProgs sharedConfig') - (pkgConfigCompiler sharedConfig') - (pkgConfigPlatform sharedConfig') + (toolchainProgramDb $ buildToolchain $ pkgConfigToolchains sharedConfig') + (toolchainCompiler $ buildToolchain $ pkgConfigToolchains sharedConfig') + (toolchainPlatform $ buildToolchain $ pkgConfigToolchains sharedConfig') Nothing flags' where diff --git a/cabal-install/src/Distribution/Client/CmdListBin.hs b/cabal-install/src/Distribution/Client/CmdListBin.hs index df16b98e1a2..44b78b0347c 100644 --- a/cabal-install/src/Distribution/Client/CmdListBin.hs +++ b/cabal-install/src/Distribution/Client/CmdListBin.hs @@ -205,7 +205,7 @@ listbinAction flags@NixStyleFlags{..} args globalFlags = do _ -> [] plat :: Platform - plat = pkgConfigPlatform elaboratedSharedConfig + plat = toolchainPlatform $ buildToolchain $ pkgConfigToolchains elaboratedSharedConfig -- here and in PlanOutput, -- use binDirectoryFor? diff --git a/cabal-install/src/Distribution/Client/CmdPath.hs b/cabal-install/src/Distribution/Client/CmdPath.hs index d7587219665..ae70fbaf9ee 100644 --- a/cabal-install/src/Distribution/Client/CmdPath.hs +++ b/cabal-install/src/Distribution/Client/CmdPath.hs @@ -1,4 +1,5 @@ {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RecordWildCards #-} -- | @@ -40,6 +41,7 @@ import Distribution.Client.ProjectConfig.Types ) import Distribution.Client.ProjectOrchestration import Distribution.Client.ProjectPlanning +import Distribution.Client.ProjectPlanning.Types (Toolchain (..), Toolchains (..)) import Distribution.Client.RebuildMonad (runRebuild) import Distribution.Client.ScriptUtils import Distribution.Client.Setup @@ -242,10 +244,11 @@ pathAction flags@NixStyleFlags{extraFlags = pathFlags', ..} cliTargetStrings glo if not $ fromFlagOrDefault False (pathCompiler pathFlags) then pure Nothing else do - (compiler, _, progDb) <- runRebuild (distProjectRootDirectory . distDirLayout $ baseCtx) $ configureCompiler verbosity (distDirLayout baseCtx) (projectConfig baseCtx) - compilerProg <- requireCompilerProg verbosity compiler - (configuredCompilerProg, _) <- requireProgram verbosity compilerProg progDb - pure $ Just $ mkCompilerInfo configuredCompilerProg compiler + let projectRoot = distProjectRootDirectory (distDirLayout baseCtx) + Toolchains{buildToolchain} <- runRebuild projectRoot $ configureCompiler verbosity (distDirLayout baseCtx) (projectConfig baseCtx) + compilerProg <- requireCompilerProg verbosity (toolchainCompiler buildToolchain) + (configuredCompilerProg, _) <- requireProgram verbosity compilerProg (toolchainProgramDb buildToolchain) + pure $ Just $ mkCompilerInfo configuredCompilerProg (toolchainCompiler buildToolchain) paths <- for (fromFlagOrDefault [] $ pathDirectories pathFlags) $ \p -> do t <- getPathLocation baseCtx p diff --git a/cabal-install/src/Distribution/Client/CmdRepl.hs b/cabal-install/src/Distribution/Client/CmdRepl.hs index a75524bbca6..7570e11aa84 100644 --- a/cabal-install/src/Distribution/Client/CmdRepl.hs +++ b/cabal-install/src/Distribution/Client/CmdRepl.hs @@ -55,7 +55,9 @@ import Distribution.Client.ProjectPlanning , ElaboratedSharedConfig (..) ) import Distribution.Client.ProjectPlanning.Types - ( elabOrderExeDependencies + ( Toolchain (..) + , Toolchains (..) + , elabOrderExeDependencies , showElaboratedInstallPlan ) import Distribution.Client.ScriptUtils @@ -344,7 +346,7 @@ replAction flags@NixStyleFlags{extraFlags = r@ReplFlags{..}, ..} targetStrings g -- especially in the no-project case. withInstallPlan (lessVerbose verbosity) baseCtx' $ \elaboratedPlan sharedConfig -> do -- targets should be non-empty map, but there's no NonEmptyMap yet. - targets <- validatedTargets (projectConfigShared (projectConfig ctx)) (pkgConfigCompiler sharedConfig) elaboratedPlan targetSelectors + targets <- validatedTargets (projectConfigShared (projectConfig ctx)) (toolchainCompiler $ buildToolchain $ pkgConfigToolchains sharedConfig) elaboratedPlan targetSelectors let (unitId, _) = fromMaybe (error "panic: targets should be non-empty") $ safeHead $ Map.toList targets @@ -368,7 +370,7 @@ replAction flags@NixStyleFlags{extraFlags = r@ReplFlags{..}, ..} targetStrings g let ProjectBaseContext{..} = baseCtx'' -- Recalculate with updated project. - targets <- validatedTargets (projectConfigShared projectConfig) (pkgConfigCompiler elaboratedShared') elaboratedPlan targetSelectors + targets <- validatedTargets (projectConfigShared projectConfig) (toolchainCompiler $ buildToolchain $ pkgConfigToolchains elaboratedShared') elaboratedPlan targetSelectors let elaboratedPlan' = @@ -400,7 +402,7 @@ replAction flags@NixStyleFlags{extraFlags = r@ReplFlags{..}, ..} targetStrings g , targetsMap = targets } - ElaboratedSharedConfig{pkgConfigCompiler = compiler} = elaboratedShared' + ElaboratedSharedConfig{pkgConfigToolchains = Toolchains{hostToolchain = Toolchain{toolchainCompiler = compiler}}} = elaboratedShared' repl_flags = case originalComponent of Just oci -> generateReplFlags includeTransitive elaboratedPlan' oci @@ -441,7 +443,7 @@ replAction flags@NixStyleFlags{extraFlags = r@ReplFlags{..}, ..} targetStrings g -- HACK: Just combine together all env overrides, placing the most common things last -- ghc program with overridden PATH - (ghcProg, _) <- requireProgram verbosity ghcProgram (pkgConfigCompilerProgs (elaboratedShared buildCtx')) + (ghcProg, _) <- requireProgram verbosity ghcProgram (toolchainProgramDb $ buildToolchain $ pkgConfigToolchains (elaboratedShared buildCtx')) let ghcProg' = ghcProg{programOverrideEnv = [("PATH", Just sp)]} -- Find what the unit files are, and start a repl based on all the response diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding.hs b/cabal-install/src/Distribution/Client/ProjectBuilding.hs index 7bf6de869a5..93e9c93b918 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding.hs @@ -343,8 +343,7 @@ rebuildTargets storeDirLayout installPlan sharedPackageConfig@ElaboratedSharedConfig - { pkgConfigCompiler = compiler - , pkgConfigCompilerProgs = progdb + { pkgConfigToolchains = Toolchains{hostToolchain = Toolchain{toolchainCompiler = compiler, toolchainProgramDb = progdb}} } pkgsBuildStatus buildSettings@BuildTimeSettings diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index fe5c10662e6..3908a1d12d1 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -178,8 +178,14 @@ buildAndRegisterUnpackedPackage registerLock cacheLock pkgshared@ElaboratedSharedConfig - { pkgConfigCompiler = compiler - , pkgConfigCompilerProgs = progdb + { pkgConfigToolchains = + Toolchains + { buildToolchain = + Toolchain + { toolchainCompiler = compiler + , toolchainProgramDb = progdb + } + } } plan rpkg@(ReadyPackage pkg) @@ -451,7 +457,15 @@ buildInplaceUnpackedPackage buildSettings@BuildTimeSettings{buildSettingHaddockOpen} registerLock cacheLock - pkgshared@ElaboratedSharedConfig{pkgConfigPlatform = Platform _ os} + pkgshared@ElaboratedSharedConfig + { pkgConfigToolchains = + Toolchains + { buildToolchain = + Toolchain + { toolchainPlatform = Platform _ os + } + } + } plan rpkg@(ReadyPackage pkg) buildStatus @@ -657,8 +671,14 @@ buildAndInstallUnpackedPackage registerLock cacheLock pkgshared@ElaboratedSharedConfig - { pkgConfigCompiler = compiler - , pkgConfigPlatform = platform + { pkgConfigToolchains = + Toolchains + { buildToolchain = + Toolchain + { toolchainCompiler = compiler + , toolchainPlatform = platform + } + } } plan rpkg@(ReadyPackage pkg) diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 9907193458d..5480e90537e 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -525,7 +525,7 @@ runProjectPostBuildPhase AlwaysWriteGhcEnvironmentFiles -> True NeverWriteGhcEnvironmentFiles -> False WriteGhcEnvironmentFilesOnlyForGhc844AndNewer -> - let compiler = pkgConfigCompiler elaboratedShared + let compiler = toolchainCompiler $ buildToolchain $ pkgConfigToolchains elaboratedShared ghcCompatVersion = compilerCompatVersion GHC compiler in maybe False (>= mkVersion [8, 4, 4]) ghcCompatVersion @@ -1089,7 +1089,7 @@ printPlan in -- Not necessary to "escape" it, it's just for user output unwords . ("" :) $ commandShowOptions - (Setup.configureCommand (pkgConfigCompilerProgs elaboratedShared)) + (Setup.configureCommand (toolchainProgramDb $ buildToolchain $ pkgConfigToolchains elaboratedShared)) partialConfigureFlags showBuildStatus :: BuildStatus -> String @@ -1121,7 +1121,7 @@ printPlan showBuildProfile = "Build profile: " ++ unwords - [ "-w " ++ (showCompilerId . pkgConfigCompiler) elaboratedShared + [ "-w " ++ (showCompilerId . toolchainCompiler . buildToolchain . pkgConfigToolchains) elaboratedShared , "-O" ++ ( case globalOptimization <> localOptimization of -- if local is not set, read global Setup.Flag NoOptimisation -> "0" @@ -1134,8 +1134,8 @@ printPlan writeBuildReports :: BuildTimeSettings -> ProjectBuildContext -> ElaboratedInstallPlan -> BuildOutcomes -> IO () writeBuildReports settings buildContext plan buildOutcomes = do - let plat@(Platform arch os) = pkgConfigPlatform . elaboratedShared $ buildContext - comp = pkgConfigCompiler . elaboratedShared $ buildContext + let plat@(Platform arch os) = toolchainPlatform . buildToolchain . pkgConfigToolchains . elaboratedShared $ buildContext + comp = toolchainCompiler . buildToolchain . pkgConfigToolchains . elaboratedShared $ buildContext getRepo (RepoTarballPackage r _ _) = Just r getRepo _ = Nothing fromPlanPackage (InstallPlan.Configured pkg) (Just result) = diff --git a/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs b/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs index b6b5dc8dd79..a38a792481e 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs @@ -46,9 +46,7 @@ import Distribution.Simple.BuildPaths ) import Distribution.Simple.Compiler import Distribution.Simple.GHC - ( GhcEnvironmentFileEntry (..) - , GhcImplInfo (supportsPkgEnvFiles) - , getImplInfo + ( GhcEnvironmentFileEntry (GhcEnvFileComment) , simpleGhcEnvironmentFile , writeGhcEnvironmentFile ) @@ -57,9 +55,9 @@ import Distribution.System import Distribution.Types.Version ( mkVersion ) -import Distribution.Utils.Path hiding - ( (<.>) - , (</>) +import Distribution.Utils.Path + ( getSymbolicPath + , makeSymbolicPath ) import Distribution.Verbosity @@ -107,7 +105,7 @@ encodePlanAsJson distDirLayout elaboratedInstallPlan elaboratedSharedConfig = [ "cabal-version" J..= jdisplay cabalInstallVersion , "cabal-lib-version" J..= jdisplay cabalVersion , "compiler-id" - J..= (J.String . showCompilerId . pkgConfigCompiler) + J..= (J.String . showCompilerId . toolchainCompiler . hostToolchain . pkgConfigToolchains) elaboratedSharedConfig , "os" J..= jdisplay os , "arch" J..= jdisplay arch @@ -115,7 +113,7 @@ encodePlanAsJson distDirLayout elaboratedInstallPlan elaboratedSharedConfig = ] where plat :: Platform - plat@(Platform arch os) = pkgConfigPlatform elaboratedSharedConfig + plat@(Platform arch os) = toolchainPlatform . hostToolchain . pkgConfigToolchains $ elaboratedSharedConfig installPlanToJ :: ElaboratedInstallPlan -> [J.Value] installPlanToJ = map planPackageToJ . InstallPlan.toList @@ -799,7 +797,7 @@ createPackageEnvironment elaboratedPlan elaboratedShared buildStatus - | compilerFlavor (pkgConfigCompiler elaboratedShared) == GHC = + | compilerFlavor (toolchainCompiler $ hostToolchain $ pkgConfigToolchains elaboratedShared) == GHC = do envFileM <- writePlanGhcEnvironment @@ -829,29 +827,30 @@ writePlanGhcEnvironment writePlanGhcEnvironment path elaboratedInstallPlan - ElaboratedSharedConfig - { pkgConfigCompiler = compiler - , pkgConfigPlatform = platform - } - postBuildStatus - | compilerFlavor compiler == GHC - , supportsPkgEnvFiles (getImplInfo compiler) = - -- TODO: check ghcjs compat - fmap Just $ - writeGhcEnvironmentFile + elaboratedSharedConfig + postBuildStatus = + -- \| compilerFlavor compiler == GHC + -- , supportsPkgEnvFiles (getImplInfo compiler) = + + -- TODO: check ghcjs compat + fmap Just $ + writeGhcEnvironmentFile + path + -- FIXME + (toolchainPlatform (hostToolchain (pkgConfigToolchains elaboratedSharedConfig))) + -- FIXME + (compilerVersion (toolchainCompiler (hostToolchain (pkgConfigToolchains elaboratedSharedConfig)))) + ( renderGhcEnvironmentFile path - platform - (compilerVersion compiler) - ( renderGhcEnvironmentFile - path - elaboratedInstallPlan - postBuildStatus - ) + elaboratedInstallPlan + postBuildStatus + ) + -- TODO: [required eventually] support for writing user-wide package -- environments, e.g. like a global project, but we would not put the -- env file in the home dir, rather it lives under ~/.ghc/ -writePlanGhcEnvironment _ _ _ _ = return Nothing +-- writePlanGhcEnvironment _ _ _ _ = return Nothing renderGhcEnvironmentFile :: FilePath diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 84f5111e139..ab82ec14c62 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -95,6 +95,9 @@ module Distribution.Client.ProjectPlanning , binDirectories , storePackageInstallDirs , storePackageInstallDirs' + + -- * Re-exports for backward compatibility + , programDbSignature ) where import Distribution.Client.Compat.Prelude @@ -398,8 +401,8 @@ rebuildProjectConfig let fetchCompiler = do -- have to create the cache directory before configuring the compiler liftIO $ createDirectoryIfMissingVerbose verbosity True distProjectCacheDirectory - (compiler, Platform arch os, _) <- configureCompiler verbosity distDirLayout (fst (PD.ignoreConditions projectConfigSkeleton) <> cliConfig) - pure (os, arch, compiler) + Toolchains{hostToolchain = Toolchain{toolchainCompiler = compiler, toolchainPlatform = Platform arch os}} <- configureCompiler verbosity distDirLayout (fst (PD.ignoreConditions projectConfigSkeleton) <> cliConfig) + return (os, arch, compiler) (projectConfig, _compiler) <- instantiateProjectConfigSkeletonFetchingCompiler fetchCompiler mempty projectConfigSkeleton when (projectConfigDistDir (projectConfigShared $ projectConfig) /= NoFlag) $ @@ -462,7 +465,7 @@ configureCompiler :: Verbosity -> DistDirLayout -> ProjectConfig - -> Rebuild (Compiler, Platform, ProgramDb) + -> Rebuild Toolchains configureCompiler verbosity DistDirLayout @@ -474,6 +477,9 @@ configureCompiler { projectConfigHcFlavor , projectConfigHcPath , projectConfigHcPkg + , projectConfigHostHcFlavor + , projectConfigHostHcPath + , projectConfigHostHcPkg } , projectConfigLocalPackages = projectConfigLocalPackages@PackageConfig @@ -497,35 +503,55 @@ configureCompiler ) $ do liftIO $ info verbosity "Compiler settings changed, reconfiguring..." - progdb <- liftIO $ resolveProgramDb verbosity projectConfigLocalPackages - result@(_, _, progdb'') <- - liftIO $ - Cabal.configCompilerEx - hcFlavor - hcPath - hcPkg - progdb - verbosity - -- Note that we added the user-supplied program locations and args - -- for /all/ programs, not just those for the compiler prog and - -- compiler-related utils. In principle we don't know which programs - -- the compiler will configure (and it does vary between compilers). - -- We do know however that the compiler will only configure the - -- programs it cares about, and those are the ones we monitor here. - monitorFiles (programsMonitorFiles progdb'') - - -- Note: There is currently a bug here: we are dropping unconfigured - -- programs from the 'ProgramDb' when we re-use the cache created by - -- 'rerunIfChanged'. - -- - -- See Note [Caching the result of configuring the compiler] + defdb <- liftIO $ resolveProgramDb verbosity projectConfigLocalPackages + + buildToolchain <- do + (compiler, platform, progdb) <- + liftIO $ + Cabal.configCompilerEx + hcFlavor + hcPath + hcPkg + defdb + verbosity + + -- Note that we added the user-supplied program locations and args + -- for /all/ programs, not just those for the compiler prog and + -- compiler-related utils. In principle we don't know which programs + -- the compiler will configure (and it does vary between compilers). + -- We do know however that the compiler will only configure the + -- programs it cares about, and those are the ones we monitor here. + monitorFiles (programsMonitorFiles progdb) + return Toolchain{toolchainCompiler = compiler, toolchainPlatform = platform, toolchainProgramDb = progdb} + + hostToolchain <- do + (compiler, platform, progdb) <- + liftIO $ + Cabal.configCompilerEx + hostHcFlavor + hostHcPath + hostHcPkg + defdb + verbosity - return result + -- Note that we added the user-supplied program locations and args + -- for /all/ programs, not just those for the compiler prog and + -- compiler-related utils. In principle we don't know which programs + -- the compiler will configure (and it does vary between compilers). + -- We do know however that the compiler will only configure the + -- programs it cares about, and those are the ones we monitor here. + monitorFiles (programsMonitorFiles progdb) + return Toolchain{toolchainCompiler = compiler, toolchainPlatform = platform, toolchainProgramDb = progdb} + + return Toolchains{buildToolchain, hostToolchain} where hcFlavor = flagToMaybe projectConfigHcFlavor hcPath = flagToMaybe projectConfigHcPath hcPkg = flagToMaybe projectConfigHcPkg + hostHcFlavor = flagToMaybe projectConfigHostHcFlavor <|> flagToMaybe projectConfigHcFlavor + hostHcPath = flagToMaybe projectConfigHostHcPath <|> flagToMaybe projectConfigHcPath + hostHcPkg = flagToMaybe projectConfigHostHcPkg <|> flagToMaybe projectConfigHcPkg {- Note [Caching the result of configuring the compiler] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -632,12 +658,16 @@ rebuildInstallPlan , hookHashes ) $ do - compilerEtc <- phaseConfigureCompiler projectConfig - _ <- phaseConfigurePrograms projectConfig compilerEtc + toolchains <- phaseConfigureToolchain projectConfig + + liftIO $ print ("build compiler", compilerId $ toolchainCompiler $ buildToolchain toolchains) + liftIO $ print ("host compiler", compilerId $ toolchainCompiler $ buildToolchain toolchains) + + -- _ <- phaseConfigurePrograms projectConfig compilerEtc (solverPlan, pkgConfigDB, totalIndexState, activeRepos) <- phaseRunSolver projectConfig - compilerEtc + toolchains localPackages (fromMaybe mempty mbInstalledPackages) ( elaboratedPlan @@ -645,7 +675,7 @@ rebuildInstallPlan ) <- phaseElaboratePlan projectConfig - compilerEtc + toolchains pkgConfigDB solverPlan localPackages @@ -673,10 +703,11 @@ rebuildInstallPlan -- This is moderately expensive and doesn't change that often so we cache -- it independently. -- - phaseConfigureCompiler + phaseConfigureToolchain :: ProjectConfig - -> Rebuild (Compiler, Platform, ProgramDb) - phaseConfigureCompiler = configureCompiler verbosity distDirLayout + -> Rebuild Toolchains + phaseConfigureToolchain = do + configureCompiler verbosity distDirLayout -- Configuring other programs. -- @@ -690,19 +721,19 @@ rebuildInstallPlan -- all local packages, but that all the programs configured so far are the -- compiler program or related util programs. -- - phaseConfigurePrograms - :: ProjectConfig - -> (Compiler, Platform, ProgramDb) - -> Rebuild () - phaseConfigurePrograms projectConfig (_, _, compilerprogdb) = do - -- Users are allowed to specify program locations independently for - -- each package (e.g. to use a particular version of a pre-processor - -- for some packages). However they cannot do this for the compiler - -- itself as that's just not going to work. So we check for this. - liftIO $ - checkBadPerPackageCompilerPaths - (configuredPrograms compilerprogdb) - (getMapMappend (projectConfigSpecificPackage projectConfig)) + -- phaseConfigurePrograms + -- :: ProjectConfig + -- -> (Compiler, Platform, ProgramDb) + -- -> Rebuild () + -- phaseConfigurePrograms projectConfig (_, _, compilerprogdb) = do + -- -- Users are allowed to specify program locations independently for + -- -- each package (e.g. to use a particular version of a pre-processor + -- -- for some packages). However they cannot do this for the compiler + -- -- itself as that's just not going to work. So we check for this. + -- liftIO $ + -- checkBadPerPackageCompilerPaths + -- (configuredPrograms compilerprogdb) + -- (getMapMappend (projectConfigSpecificPackage projectConfig)) -- TODO: [required eventually] find/configure other programs that the -- user specifies. @@ -715,7 +746,7 @@ rebuildInstallPlan -- phaseRunSolver :: ProjectConfig - -> (Compiler, Platform, ProgramDb) + -> Toolchains -> [PackageSpecifier UnresolvedSourcePackage] -> InstalledPackageIndex -> Rebuild (SolverInstallPlan, Maybe PkgConfigDb, IndexUtils.TotalIndexState, IndexUtils.ActiveRepos) @@ -724,7 +755,7 @@ rebuildInstallPlan { projectConfigShared , projectConfigBuildOnly } - (compiler, platform, progdb) + toolchains localPackages installedPackages = rerunIfChanged @@ -733,26 +764,24 @@ rebuildInstallPlan ( solverSettings , localPackages , localPackagesEnabledStanzas - , compiler - , platform - , programDbSignature progdb + , toolchains , hookHashes ) $ do installedPkgIndex <- getInstalledPackages verbosity - compiler - progdb - platform + (buildToolchain toolchains) corePackageDbs + (sourcePkgDb, tis, ar) <- getSourcePackages verbosity withRepoCtx (solverSettingIndexState solverSettings) (solverSettingActiveRepos solverSettings) - pkgConfigDB <- getPkgConfigDb verbosity progdb + + pkgConfigDB <- getPkgConfigDb verbosity (toolchainProgramDb $ buildToolchain toolchains) -- TODO: [code cleanup] it'd be better if the Compiler contained the -- ConfiguredPrograms that it needs, rather than relying on the progdb @@ -765,8 +794,7 @@ rebuildInstallPlan foldProgress logMsg (pure . Left) (pure . Right) $ planPackages verbosity - compiler - platform + (hostToolchain toolchains) solverSettings (installedPackages <> installedPkgIndex) sourcePkgDb @@ -775,7 +803,7 @@ rebuildInstallPlan localPackagesEnabledStanzas case planOrError of Left msg -> do - reportPlanningFailure projectConfig compiler platform localPackages + reportPlanningFailure projectConfig (hostToolchain toolchains) localPackages dieWithException verbosity $ PhaseRunSolverErr msg Right plan -> return (plan, pkgConfigDB, tis, ar) where @@ -830,7 +858,7 @@ rebuildInstallPlan -- phaseElaboratePlan :: ProjectConfig - -> (Compiler, Platform, ProgramDb) + -> Toolchains -> Maybe PkgConfigDb -> SolverInstallPlan -> [PackageSpecifier (SourcePackage (PackageLocation loc))] @@ -846,7 +874,7 @@ rebuildInstallPlan , projectConfigSpecificPackage , projectConfigBuildOnly } - (compiler, platform, progdb) + toolchains pkgConfigDB solverPlan localPackages = do @@ -859,16 +887,14 @@ rebuildInstallPlan (packageLocationsSignature solverPlan) $ getPackageSourceHashes verbosity withRepoCtx solverPlan - defaultInstallDirs <- liftIO $ userInstallDirTemplates compiler + defaultInstallDirs <- liftIO $ userInstallDirTemplates (toolchainCompiler (hostToolchain toolchains)) let installDirs = fmap Cabal.fromFlag $ (fmap Flag defaultInstallDirs) <> (projectConfigInstallDirs projectConfigShared) (elaboratedPlan, elaboratedShared) <- liftIO . runLogProgress verbosity $ elaborateInstallPlan verbosity hookHashes - platform - compiler - progdb + toolchains pkgConfigDB distDirLayout cabalStoreDirLayout @@ -939,12 +965,12 @@ rebuildInstallPlan -- matches up as expected, e.g. no dangling deps, files deleted. return improvedPlan where - compiler = pkgConfigCompiler elaboratedShared + compiler = toolchainCompiler (hostToolchain (pkgConfigToolchains elaboratedShared)) -- | If a 'PackageSpecifier' refers to a single package, return Just that -- package. -reportPlanningFailure :: ProjectConfig -> Compiler -> Platform -> [PackageSpecifier UnresolvedSourcePackage] -> IO () -reportPlanningFailure projectConfig comp platform pkgSpecifiers = +reportPlanningFailure :: ProjectConfig -> Toolchain -> [PackageSpecifier UnresolvedSourcePackage] -> IO () +reportPlanningFailure projectConfig Toolchain{toolchainCompiler = comp, toolchainPlatform = platform} pkgSpecifiers = when reportFailure $ BuildReports.storeLocal (compilerInfo comp) @@ -992,44 +1018,28 @@ programsMonitorFiles progdb = (programPath prog) ] --- | 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 - ] - getInstalledPackages :: Verbosity - -> Compiler - -> ProgramDb - -> Platform + -> Toolchain -> PackageDBStackCWD -> Rebuild InstalledPackageIndex -getInstalledPackages verbosity compiler progdb platform packagedbs = do +getInstalledPackages verbosity Toolchain{toolchainCompiler, toolchainPlatform, toolchainProgramDb} packagedbs = do monitorFiles . map monitorFileOrDirectory =<< liftIO ( IndexUtils.getInstalledPackagesMonitorFiles verbosity - compiler + toolchainCompiler Nothing -- use ambient working directory (coercePackageDBStack packagedbs) - progdb - platform + toolchainProgramDb + toolchainPlatform ) liftIO $ IndexUtils.getInstalledPackages verbosity - compiler + toolchainCompiler packagedbs - progdb + toolchainProgramDb {- --TODO: [nice to have] use this but for sanity / consistency checking @@ -1261,8 +1271,7 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do planPackages :: Verbosity - -> Compiler - -> Platform + -> Toolchain -> SolverSettings -> InstalledPackageIndex -> SourcePackageDb @@ -1272,8 +1281,7 @@ planPackages -> Progress String String SolverInstallPlan planPackages verbosity - comp - platform + Toolchain{toolchainCompiler = compiler, toolchainPlatform = platform} SolverSettings{..} installedPkgIndex sourcePkgDb @@ -1282,7 +1290,7 @@ planPackages pkgStanzasEnable = resolveDependencies platform - (compilerInfo comp) + (compilerInfo compiler) pkgConfigDB resolverParams where @@ -1325,7 +1333,7 @@ planPackages . removeLowerBounds solverSettingAllowOlder . removeUpperBounds solverSettingAllowNewer . addDefaultSetupDependencies - ( mkDefaultSetupDeps comp platform + ( mkDefaultSetupDeps compiler platform . PD.packageDescription . srcpkgDescription ) @@ -1459,8 +1467,8 @@ planPackages | otherwise = mkVersion [1, 20] where isGHC = compFlav `elem` [GHC, GHCJS] - compFlav = compilerFlavor comp - compVer = compilerVersion comp + compFlav = compilerFlavor compiler + compVer = compilerVersion compiler -- As we can't predict the future, we also place a global upper -- bound on the lib:Cabal version we know how to interact with: @@ -1587,9 +1595,7 @@ planPackages elaborateInstallPlan :: Verbosity -> Map FilePath HookAccept - -> Platform - -> Compiler - -> ProgramDb + -> Toolchains -> Maybe PkgConfigDb -> DistDirLayout -> StoreDirLayout @@ -1605,9 +1611,18 @@ elaborateInstallPlan elaborateInstallPlan verbosity hookHashes - platform - compiler - compilerprogdb + toolchains@Toolchains + { buildToolchain = + Toolchain + { toolchainCompiler = compiler + , toolchainProgramDb = compilerprogdb + } + , hostToolchain = + Toolchain + { toolchainCompiler = hostCompiler + , toolchainPlatform = hostPlatform + } + } pkgConfigDB distDirLayout@DistDirLayout{..} storeDirLayout@StoreDirLayout{storePackageDBStack} @@ -1624,9 +1639,7 @@ elaborateInstallPlan where elaboratedSharedConfig = ElaboratedSharedConfig - { pkgConfigPlatform = platform - , pkgConfigCompiler = compiler - , pkgConfigCompilerProgs = compilerprogdb + { pkgConfigToolchains = toolchains , pkgConfigReplOptions = mempty , pkgConfigHookHashes = hookHashes } @@ -2190,8 +2203,8 @@ elaborateInstallPlan flags elabEnabledSpec (const Satisfied) - platform - (compilerInfo compiler) + hostPlatform + (compilerInfo hostCompiler) [] gdesc of Right (desc, _) -> desc @@ -3851,8 +3864,9 @@ setupHsScriptOptions -- - if we commit to a Cabal version, the logic in Nothing else Just elabSetupScriptCliVersion - , useCompiler = Just pkgConfigCompiler - , usePlatform = Just pkgConfigPlatform + , useCompiler = Just (toolchainCompiler $ buildToolchain $ pkgConfigToolchains) + , usePlatform = Just (toolchainPlatform $ buildToolchain $ pkgConfigToolchains) + , useProgramDb = toolchainProgramDb $ buildToolchain $ pkgConfigToolchains , usePackageDB = elabSetupPackageDBStack , usePackageIndex = Nothing , useDependencies = @@ -3862,7 +3876,6 @@ setupHsScriptOptions ] , useDependenciesExclusive = True , useVersionMacros = elabSetupScriptStyle == SetupCustomExplicitDeps - , useProgramDb = pkgConfigCompilerProgs , useDistPref = builddir , useLoggingHandle = Nothing -- this gets set later , useWorkingDir = Just srcdir @@ -3947,9 +3960,9 @@ computeInstallDirs storeDirLayout defaultInstallDirs elaboratedShared elab ( InstallDirs.absoluteInstallDirs (elabPkgSourceId elab) (elabUnitId elab) - (compilerInfo (pkgConfigCompiler elaboratedShared)) + (compilerInfo (toolchainCompiler $ buildToolchain $ pkgConfigToolchains elaboratedShared)) InstallDirs.NoCopyDest - (pkgConfigPlatform elaboratedShared) + (toolchainPlatform $ buildToolchain $ pkgConfigToolchains elaboratedShared) defaultInstallDirs ) { -- absoluteInstallDirs sets these as 'undefined' but we have @@ -3962,7 +3975,7 @@ computeInstallDirs storeDirLayout defaultInstallDirs elaboratedShared elab -- use special simplified install dirs storePackageInstallDirs' storeDirLayout - (pkgConfigCompiler elaboratedShared) + (toolchainCompiler $ buildToolchain $ pkgConfigToolchains elaboratedShared) (elabUnitId elab) -- TODO: [code cleanup] perhaps reorder this code @@ -3983,7 +3996,7 @@ setupHsConfigureFlags mkSymbolicPath plan (ReadyPackage elab@ElaboratedConfiguredPackage{..}) - sharedConfig@ElaboratedSharedConfig{..} + sharedConfig@ElaboratedSharedConfig{pkgConfigToolchains = Toolchains{buildToolchain}} configCommonFlags = do -- explicitly clear, then our package db stack -- TODO: [required eventually] have to do this differently for older Cabal versions @@ -4053,7 +4066,7 @@ setupHsConfigureFlags ["-hide-all-packages"] elabProgramArgs configProgramPathExtra = toNubList elabProgramPathExtra - configHcFlavor = toFlag (compilerFlavor pkgConfigCompiler) + configHcFlavor = toFlag (compilerFlavor $ toolchainCompiler buildToolchain) configHcPath = mempty -- we use configProgramPaths instead configHcPkg = mempty -- we use configProgramPaths instead configDumpBuildInfo = toFlag elabDumpBuildInfo @@ -4111,7 +4124,7 @@ setupHsConfigureFlags configUserInstall = mempty -- don't rely on defaults configPrograms_ = mempty -- never use, shouldn't exist configUseResponseFiles = mempty - configAllowDependingOnPrivateLibs = Flag $ not $ libraryVisibilitySupported pkgConfigCompiler + configAllowDependingOnPrivateLibs = Flag $ not $ libraryVisibilitySupported (toolchainCompiler buildToolchain) configIgnoreBuildTools = mempty cidToGivenComponent :: ConfiguredId -> GivenComponent @@ -4286,13 +4299,13 @@ setupHsHaddockFlags -> Cabal.HaddockFlags setupHsHaddockFlags (ElaboratedConfiguredPackage{..}) - (ElaboratedSharedConfig{..}) + (ElaboratedSharedConfig{pkgConfigToolchains = Toolchains{buildToolchain}}) _buildTimeSettings common = Cabal.HaddockFlags { haddockCommonFlags = common , haddockProgramPaths = - case lookupProgram haddockProgram pkgConfigCompilerProgs of + case lookupProgram haddockProgram (toolchainProgramDb buildToolchain) of Nothing -> mempty Just prg -> [ @@ -4430,11 +4443,11 @@ packageHashConfigInputs :: ElaboratedSharedConfig -> ElaboratedConfiguredPackage -> PackageHashConfigInputs -packageHashConfigInputs shared@ElaboratedSharedConfig{..} pkg = +packageHashConfigInputs shared@ElaboratedSharedConfig{pkgConfigToolchains = Toolchains{buildToolchain}} pkg = PackageHashConfigInputs - { pkgHashCompilerId = compilerId pkgConfigCompiler - , pkgHashCompilerABI = compilerAbiTag pkgConfigCompiler - , pkgHashPlatform = pkgConfigPlatform + { pkgHashCompilerId = compilerId (toolchainCompiler buildToolchain) + , pkgHashCompilerABI = compilerAbiTag (toolchainCompiler buildToolchain) + , pkgHashPlatform = toolchainPlatform buildToolchain , pkgHashFlagAssignment = elabFlagAssignment , pkgHashConfigureScriptArgs = elabConfigureScriptArgs , pkgHashVanillaLib = withVanillaLib diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 484c4cad297..8e52d778330 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -58,6 +58,10 @@ module Distribution.Client.ProjectPlanning.Types , isBenchComponentTarget , componentOptionalStanza + -- * Toolchain + , Toolchain (..) + , Toolchains (..) + -- * Setup script , SetupScriptStyle (..) ) where @@ -100,6 +104,7 @@ import Distribution.Simple.LocalBuildInfo , LibraryName (..) ) import Distribution.Simple.Program +import Distribution.Simple.Program.Db (configuredPrograms) import Distribution.Simple.Setup ( DumpBuildInfo (..) , HaddockTarget @@ -184,9 +189,7 @@ showElaboratedInstallPlan = InstallPlan.showInstallPlan_gen showNode -- even platform and compiler could be different if we're building things -- like a server + client with ghc + ghcjs data ElaboratedSharedConfig = ElaboratedSharedConfig - { pkgConfigPlatform :: Platform - , pkgConfigCompiler :: Compiler -- TODO: [code cleanup] replace with CompilerInfo - , pkgConfigCompilerProgs :: ProgramDb + { pkgConfigToolchains :: Toolchains -- ^ The programs that the compiler configured (e.g. for GHC, the progs -- ghc & ghc-pkg). Once constructed, only the 'configuredPrograms' are -- used. @@ -344,10 +347,10 @@ normaliseConfiguredPackage :: ElaboratedSharedConfig -> ElaboratedConfiguredPackage -> ElaboratedConfiguredPackage -normaliseConfiguredPackage ElaboratedSharedConfig{pkgConfigCompilerProgs} pkg = +normaliseConfiguredPackage ElaboratedSharedConfig{pkgConfigToolchains = Toolchains{buildToolchain}} pkg = pkg{elabProgramArgs = Map.mapMaybeWithKey lookupFilter (elabProgramArgs pkg)} where - knownProgramDb = addKnownPrograms builtinPrograms pkgConfigCompilerProgs + knownProgramDb = addKnownPrograms builtinPrograms (toolchainProgramDb buildToolchain) pkgDesc :: PackageDescription pkgDesc = elabPkgDescription pkg @@ -540,8 +543,8 @@ elabDistDirParams shared elab = , distParamComponentName = case elabPkgOrComp elab of ElabComponent comp -> compComponentName comp ElabPackage _ -> Nothing - , distParamCompilerId = compilerId (pkgConfigCompiler shared) - , distParamPlatform = pkgConfigPlatform shared + , distParamCompilerId = compilerId $ toolchainCompiler $ hostToolchain $ pkgConfigToolchains shared + , distParamPlatform = toolchainPlatform $ hostToolchain $ pkgConfigToolchains shared , distParamOptimization = LBC.withOptimization $ elabBuildOptions elab } @@ -909,6 +912,36 @@ componentOptionalStanza (CD.ComponentTest _) = Just TestStanzas componentOptionalStanza (CD.ComponentBench _) = Just BenchStanzas componentOptionalStanza _ = Nothing +--------------------------- +-- Toolchain +-- + +data Toolchain = Toolchain + { toolchainPlatform :: Platform + , toolchainCompiler :: Compiler + , toolchainProgramDb :: ProgramDb + } + deriving (Show, Generic, Typeable) + +-- TODO: review this +instance Eq Toolchain where + lhs == rhs = + (((==) `on` toolchainPlatform) lhs rhs) + && (((==) `on` toolchainCompiler) lhs rhs) + && ((((==)) `on` (configuredPrograms . toolchainProgramDb)) lhs rhs) + +instance Binary Toolchain +instance Structured Toolchain + +data Toolchains = Toolchains + { buildToolchain :: Toolchain + , hostToolchain :: Toolchain + } + deriving (Eq, Show, Generic, Typeable) + +instance Binary Toolchains +instance Structured Toolchains + --------------------------- -- Setup.hs script policy -- diff --git a/cabal-install/src/Distribution/Client/ScriptUtils.hs b/cabal-install/src/Distribution/Client/ScriptUtils.hs index 440de3c84ad..72950f36e0d 100644 --- a/cabal-install/src/Distribution/Client/ScriptUtils.hs +++ b/cabal-install/src/Distribution/Client/ScriptUtils.hs @@ -195,6 +195,7 @@ import qualified Data.ByteString.Char8 as BS import Data.ByteString.Lazy () import qualified Data.Set as S import Distribution.Client.Errors +import Distribution.Client.ProjectPlanning.Types (Toolchain (..), Toolchains (..)) import Distribution.Utils.Path ( unsafeMakeSymbolicPath ) @@ -361,9 +362,9 @@ withContextAndSelectors noTargets kind flags@NixStyleFlags{..} targetStrings glo exists <- doesFileExist script if exists then do - ctx <- withGlobalConfig verbosity globalConfigFlag (scriptBaseCtx script) + baseCtx <- withGlobalConfig verbosity globalConfigFlag (scriptBaseCtx script) - let projectRoot = distProjectRootDirectory $ distDirLayout ctx + let projectRoot = distProjectRootDirectory $ distDirLayout baseCtx writeFile (projectRoot </> "scriptlocation") =<< canonicalizePath script scriptContents <- BS.readFile script @@ -375,14 +376,14 @@ withContextAndSelectors noTargets kind flags@NixStyleFlags{..} targetStrings glo (fromNubList . projectConfigProgPathExtra $ projectConfigShared cliConfig) (flagToMaybe . projectConfigHttpTransport $ projectConfigBuildOnly cliConfig) - projectCfgSkeleton <- readProjectBlockFromScript verbosity httpTransport (distDirLayout ctx) (takeFileName script) scriptContents + projectCfgSkeleton <- readProjectBlockFromScript verbosity httpTransport (distDirLayout baseCtx) (takeFileName script) scriptContents - createDirectoryIfMissingVerbose verbosity True (distProjectCacheDirectory $ distDirLayout ctx) - (compiler, platform@(Platform arch os), _) <- runRebuild projectRoot $ configureCompiler verbosity (distDirLayout ctx) (fst (ignoreConditions projectCfgSkeleton) <> projectConfig ctx) + createDirectoryIfMissingVerbose verbosity True (distProjectCacheDirectory $ distDirLayout baseCtx) + Toolchains{buildToolchain = Toolchain{toolchainPlatform = platform@(Platform arch os), toolchainCompiler = compiler}} <- runRebuild projectRoot $ configureCompiler verbosity (distDirLayout baseCtx) (fst (ignoreConditions projectCfgSkeleton) <> projectConfig baseCtx) (projectCfg, _) <- instantiateProjectConfigSkeletonFetchingCompiler (pure (os, arch, compiler)) mempty projectCfgSkeleton - let ctx' = ctx & lProjectConfig %~ (<> projectCfg) + let ctx' = baseCtx & lProjectConfig %~ (<> projectCfg) build_dir = distBuildDirectory (distDirLayout ctx') $ (scriptDistDirParams script) ctx' compiler platform exePath = build_dir </> "bin" </> scriptExeFileName script @@ -588,7 +589,7 @@ fakeProjectSourcePackage projectRoot = sourcePackage movedExePath :: UnqualComponentName -> DistDirLayout -> ElaboratedSharedConfig -> ElaboratedConfiguredPackage -> Maybe FilePath movedExePath selectedComponent distDirLayout elabShared elabConfigured = do exe <- find ((== selectedComponent) . exeName) . executables $ elabPkgDescription elabConfigured - let CompilerId flavor _ = (compilerId . pkgConfigCompiler) elabShared + let CompilerId flavor _ = (compilerId . toolchainCompiler . buildToolchain . pkgConfigToolchains) elabShared opts <- lookup flavor (perCompilerFlavorToList . options $ buildInfo exe) let projectRoot = distProjectRootDirectory distDirLayout fmap (projectRoot </>) . lookup "-o" $ reverse (zip opts (drop 1 opts)) diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index dd54fea54d0..c6c33735900 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -1891,10 +1891,10 @@ testSetupScriptStyles config reportSubCase = do let isOSX (Platform _ OSX) = True isOSX _ = False - compilerVer = compilerVersion (pkgConfigCompiler sharedConfig) + compilerVer = compilerVersion (toolchainCompiler $ buildToolchain $ pkgConfigToolchains sharedConfig) -- Skip the Custom tests when the shipped Cabal library is buggy unless - ( (isOSX (pkgConfigPlatform sharedConfig) && (compilerVer < mkVersion [7, 10])) + ( (isOSX (toolchainPlatform $ buildToolchain $ pkgConfigToolchains sharedConfig) && (compilerVer < mkVersion [7, 10])) -- 9.10 ships Cabal 3.12.0.0 affected by #9940 || (mkVersion [9, 10] <= compilerVer && compilerVer < mkVersion [9, 11]) ) @@ -1908,7 +1908,7 @@ testSetupScriptStyles config reportSubCase = do removeFile (basedir </> testdir1 </> "marker") -- implicit deps implies 'Cabal < 2' which conflicts w/ GHC 8.2 or later - when (compilerVersion (pkgConfigCompiler sharedConfig) < mkVersion [8, 2]) $ do + when (compilerVersion (toolchainCompiler $ buildToolchain $ pkgConfigToolchains sharedConfig) < mkVersion [8, 2]) $ do reportSubCase (show SetupCustomImplicitDeps) (plan2, res2) <- executePlan =<< planProject testdir2 config pkg2 <- expectPackageInstalled plan2 res2 pkgidA @@ -2784,7 +2784,7 @@ testHaddockProjectDependencies config = do (_, _, sharedConfig) <- planProject testdir config -- `haddock-project` is only supported by `haddock-2.26.1` and above which is -- shipped with `ghc-9.4` - when (compilerVersion (pkgConfigCompiler sharedConfig) > mkVersion [9, 4]) $ do + when (compilerVersion (toolchainCompiler $ buildToolchain $ pkgConfigToolchains sharedConfig) > mkVersion [9, 4]) $ do let dir = basedir </> testdir cleanHaddockProject testdir withCurrentDirectory dir $ do diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index 371766fedb1..a77415fec49 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -613,6 +613,9 @@ instance Arbitrary ProjectConfigShared where projectConfigHcFlavor <- arbitrary projectConfigHcPath <- arbitraryFlag arbitraryShortToken projectConfigHcPkg <- arbitraryFlag arbitraryShortToken + projectConfigHostHcFlavor <- arbitrary + projectConfigHostHcPath <- arbitraryFlag arbitraryShortToken + projectConfigHostHcPkg <- arbitraryFlag arbitraryShortToken projectConfigHaddockIndex <- arbitrary projectConfigInstallDirs <- fixInstallDirs <$> arbitrary projectConfigPackageDBs <- shortListOf 2 arbitrary @@ -660,6 +663,9 @@ instance Arbitrary ProjectConfigShared where <*> shrinker projectConfigHcFlavor <*> shrinkerAla (fmap NonEmpty) projectConfigHcPath <*> shrinkerAla (fmap NonEmpty) projectConfigHcPkg + <*> shrinker projectConfigHostHcFlavor + <*> shrinkerAla (fmap NonEmpty) projectConfigHostHcPath + <*> shrinkerAla (fmap NonEmpty) projectConfigHostHcPkg <*> shrinker projectConfigHaddockIndex <*> shrinker projectConfigInstallDirs <*> shrinker projectConfigPackageDBs From bb80d2a3f04a0380b5060fc72308798fcad3b11f Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 6 Mar 2025 20:29:25 +0900 Subject: [PATCH 12/82] wip: Thread HostHc into the proper places. --- .../src/Distribution/Client/ProjectConfig/Legacy.hs | 6 +++--- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index f5030f58b5c..b29b3cf47f9 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -704,9 +704,6 @@ convertLegacyAllPackageFlags convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags projectFlags projectConfigMultiRepl = ProjectConfigShared{..} where - projectConfigHostHcFlavor = NoFlag - projectConfigHostHcPath = NoFlag - projectConfigHostHcPkg = NoFlag projectConfigPackageDBs = (fmap . fmap) (interpretPackageDB Nothing) projectConfigPackageDBs_ projectConfigHookHashes = mempty -- :: Map FilePath HookAccept projectConfigDistDir = fmap getSymbolicPath projectConfigAbsoluteDistDir @@ -744,6 +741,9 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags , configAllowNewer = projectConfigAllowNewer , configWriteGhcEnvironmentFilesPolicy = projectConfigWriteGhcEnvironmentFilesPolicy + , configHostHcFlavor = projectConfigHostHcFlavor + , configHostHcPath = projectConfigHostHcPath + , configHostHcPkg = projectConfigHostHcPkg } = configExFlags InstallFlags diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index ab82ec14c62..f429819daba 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -661,7 +661,7 @@ rebuildInstallPlan toolchains <- phaseConfigureToolchain projectConfig liftIO $ print ("build compiler", compilerId $ toolchainCompiler $ buildToolchain toolchains) - liftIO $ print ("host compiler", compilerId $ toolchainCompiler $ buildToolchain toolchains) + liftIO $ print ("host compiler", compilerId $ toolchainCompiler $ hostToolchain toolchains) -- _ <- phaseConfigurePrograms projectConfig compilerEtc (solverPlan, pkgConfigDB, totalIndexState, activeRepos) <- @@ -3864,9 +3864,10 @@ setupHsScriptOptions -- - if we commit to a Cabal version, the logic in Nothing else Just elabSetupScriptCliVersion - , useCompiler = Just (toolchainCompiler $ buildToolchain $ pkgConfigToolchains) - , usePlatform = Just (toolchainPlatform $ buildToolchain $ pkgConfigToolchains) - , useProgramDb = toolchainProgramDb $ buildToolchain $ pkgConfigToolchains + , -- for Setup.hs, we _always_ want to use the HOST toolchain. + useCompiler = Just (toolchainCompiler $ hostToolchain $ pkgConfigToolchains) + , usePlatform = Just (toolchainPlatform $ hostToolchain $ pkgConfigToolchains) + , useProgramDb = toolchainProgramDb $ hostToolchain $ pkgConfigToolchains , usePackageDB = elabSetupPackageDBStack , usePackageIndex = Nothing , useDependencies = From b1a44bdaba5bed7bb54c7629d609228d1cc209e7 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Fri, 7 Mar 2025 15:20:07 +0800 Subject: [PATCH 13/82] wip: log more details from the SolverInstallPlan --- .../src/Distribution/Solver/Modular.hs | 32 ++++++++++++++++--- .../Distribution/Client/ProjectPlanning.hs | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular.hs b/cabal-install-solver/src/Distribution/Solver/Modular.hs index 9111b2d78d0..2c0883d2fba 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular.hs @@ -34,7 +34,7 @@ import Distribution.Solver.Modular.IndexConversion import Distribution.Solver.Modular.Log ( SolverFailure(..), displayLogMessages ) import Distribution.Solver.Modular.Package - ( PN ) + ( PN, showPI ) import Distribution.Solver.Modular.RetryLog import Distribution.Solver.Modular.Solver ( SolverConfig(..), PruneAfterFirstSuccess(..), solve ) @@ -54,15 +54,37 @@ import Distribution.Simple.Setup import Distribution.Simple.Utils ( ordNubBy ) import Distribution.Verbosity +import Distribution.Solver.Modular.Configured (CP (..)) +import qualified Distribution.Solver.Types.ComponentDeps as ComponentDeps +import Distribution.Pretty (Pretty (..)) +import Text.PrettyPrint (text, vcat, Doc, nest, ($+$)) +import Distribution.Solver.Types.OptionalStanza (showStanzas, optStanzaSetNull) +import Distribution.Types.Flag (nullFlagAssignment) +showCP :: CP QPN -> Doc +showCP (CP qpi fa es ds) = + text "package:" <+> text (showPI qpi) $+$ nest 2 ( + vcat + [ if nullFlagAssignment fa then mempty else text "flags:" <+> pretty fa + , if optStanzaSetNull es then mempty else text "stanzas:" <+> text (showStanzas es) + , vcat + [ text "component" <+> pretty c $+$ + nest 2 (text "dependencies" $+$ + nest 2 (vcat [ text (showPI dep) | dep <- deps])) + | (c, deps) <- ComponentDeps.toList ds + ] + ]) + -- | Ties the two worlds together: classic cabal-install vs. the modular -- solver. Performs the necessary translations before and after. modularResolver :: SolverConfig -> DependencyResolver loc -modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns = - uncurry postprocess <$> -- convert install plan - solve' sc cinfo idx pkgConfigDB pprefs gcs pns - where +modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns = do + (assignment, revdepmap) <- solve' sc cinfo idx pkgConfigDB pprefs gcs pns + let cp = toCPs assignment revdepmap + Step (show (vcat (map showCP cp))) $ + return $ postprocess assignment revdepmap + where -- Indices have to be converted into solver-specific uniform index. idx = convPIs os arch cinfo gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) iidx sidx -- Constraints have to be converted into a finite map indexed by PN. diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index f429819daba..11021bb70b1 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -819,7 +819,7 @@ rebuildInstallPlan projectConfigBuildOnly solverSettings = resolveSolverSettings projectConfig - logMsg message rest = debugNoWrap verbosity message >> rest + logMsg message rest = infoNoWrap verbosity message >> rest localPackagesEnabledStanzas = Map.fromList From c13273e0f7da838e515b87b4ca2d79708b28a460 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Fri, 7 Mar 2025 15:59:14 +0800 Subject: [PATCH 14/82] wip: pass qualified package name into the SolverInstallPlan --- .../Solver/Modular/ConfiguredConversion.hs | 32 +++++++++---------- .../Solver/Types/InstSolverPackage.hs | 2 ++ .../Distribution/Solver/Types/PackagePath.hs | 22 ++++++++++--- .../Solver/Types/SolverPackage.hs | 2 ++ .../src/Distribution/Client/Dependency.hs | 2 +- .../Distribution/Client/ProjectPlanning.hs | 4 ++- 6 files changed, 42 insertions(+), 22 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index 0e2e8ad5baa..89b57e2c783 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -6,8 +6,6 @@ import Data.Maybe import Prelude hiding (pi) import Data.Either (partitionEithers) -import Distribution.Package (UnitId, packageId) - import qualified Distribution.Simple.PackageIndex as SI import Distribution.Solver.Modular.Configured @@ -29,36 +27,38 @@ convCP :: SI.InstalledPackageIndex -> CI.PackageIndex (SourcePackage loc) -> CP QPN -> ResolverPackage loc convCP iidx sidx (CP qpi fa es ds) = - case convPI qpi of - Left pi -> PreExisting $ + case qpi of + -- Installed + (PI qpn (I _ (Inst pi))) -> + PreExisting $ InstSolverPackage { - instSolverPkgIPI = fromJust $ SI.lookupUnitId iidx pi, + instSolverQPN = qpn, + instSolverPkgIPI = fromMaybe (error "convCP: lookupUnitId failed") $ SI.lookupUnitId iidx pi, instSolverPkgLibDeps = fmap fst ds', instSolverPkgExeDeps = fmap snd ds' } - Right pi -> Configured $ + -- "In repo" i.e. a source package + (PI qpn@(Q _path pn) (I v InRepo)) -> + let pi = PackageIdentifier pn v in + Configured $ SolverPackage { - solverPkgSource = srcpkg, + solverPkgQPN = qpn, + solverPkgSource = fromMaybe (error "convCP: lookupPackageId failed") $ CI.lookupPackageId sidx pi, solverPkgFlags = fa, solverPkgStanzas = es, solverPkgLibDeps = fmap fst ds', solverPkgExeDeps = fmap snd ds' } - where - srcpkg = fromMaybe (error "convCP: lookupPackageId failed") $ CI.lookupPackageId sidx pi where ds' :: ComponentDeps ([SolverId] {- lib -}, [SolverId] {- exe -}) ds' = fmap (partitionEithers . map convConfId) ds -convPI :: PI QPN -> Either UnitId PackageId -convPI (PI _ (I _ (Inst pi))) = Left pi -convPI pi = Right (packageId (either id id (convConfId pi))) - convConfId :: PI QPN -> Either SolverId {- is lib -} SolverId {- is exe -} convConfId (PI (Q (PackagePath _ q) pn) (I v loc)) = case loc of - Inst pi -> Left (PreExistingId sourceId pi) - _otherwise + Inst pi -> + Left (PreExistingId sourceId pi) + InRepo | QualExe _ pn' <- q -- NB: the dependencies of the executable are also -- qualified. So the way to tell if this is an executable @@ -67,6 +67,6 @@ convConfId (PI (Q (PackagePath _ q) pn) (I v loc)) = -- silly and didn't allow arbitrarily nested build-tools -- dependencies, so a shallow check works. , pn == pn' -> Right (PlannedId sourceId) - | otherwise -> Left (PlannedId sourceId) + | otherwise -> Left (PlannedId sourceId) where sourceId = PackageIdentifier pn v diff --git a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs index 871a0dd15a9..15fb9d510ec 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs @@ -8,6 +8,7 @@ import Prelude () import Distribution.Package ( Package(..), HasMungedPackageId(..), HasUnitId(..) ) import Distribution.Solver.Types.ComponentDeps ( ComponentDeps ) +import Distribution.Solver.Types.PackagePath (QPN) import Distribution.Solver.Types.SolverId import Distribution.Types.MungedPackageId import Distribution.Types.PackageId @@ -17,6 +18,7 @@ import Distribution.InstalledPackageInfo (InstalledPackageInfo) -- | An 'InstSolverPackage' is a pre-existing installed package -- specified by the dependency solver. data InstSolverPackage = InstSolverPackage { + instSolverQPN :: QPN, instSolverPkgIPI :: InstalledPackageInfo, instSolverPkgLibDeps :: ComponentDeps [SolverId], instSolverPkgExeDeps :: ComponentDeps [SolverId] diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs b/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs index 4fc4df25f97..05727ffe8c9 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE DeriveGeneric #-} module Distribution.Solver.Types.PackagePath ( PackagePath(..) , Namespace(..) @@ -18,7 +20,10 @@ import qualified Text.PrettyPrint as Disp -- | A package path consists of a namespace and a package path inside that -- namespace. data PackagePath = PackagePath Namespace Qualifier - deriving (Eq, Ord, Show) + deriving (Eq, Ord, Show, Generic) + +instance Binary PackagePath +instance Structured PackagePath -- | Top-level namespace -- @@ -30,7 +35,10 @@ data Namespace = -- | A namespace for a specific build target | Independent PackageName - deriving (Eq, Ord, Show) + deriving (Eq, Ord, Show, Generic) + +instance Binary Namespace +instance Structured Namespace -- | Pretty-prints a namespace. The result is either empty or -- ends in a period, so it can be prepended onto a qualifier. @@ -68,7 +76,10 @@ data Qualifier = -- tracked only @pn2@, that would require us to pick only one -- version of an executable over the entire install plan.) | QualExe PackageName PackageName - deriving (Eq, Ord, Show) + deriving (Eq, Ord, Show, Generic) + +instance Binary Qualifier +instance Structured Qualifier -- | Pretty-prints a qualifier. The result is either empty or -- ends in a period, so it can be prepended onto a package name. @@ -87,11 +98,14 @@ dispQualifier (QualBase pn) = pretty pn <<>> Disp.text "." -- | A qualified entity. Pairs a package path with the entity. data Qualified a = Q PackagePath a - deriving (Eq, Ord, Show) + deriving (Eq, Ord, Show, Generic) -- | Qualified package name. type QPN = Qualified PackageName +instance Binary (Qualified PackageName) +instance Structured (Qualified PackageName) + -- | Pretty-prints a qualified package name. dispQPN :: QPN -> Disp.Doc dispQPN (Q (PackagePath ns qual) pn) = diff --git a/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs index 186f140aefe..b3748254ebb 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs @@ -10,6 +10,7 @@ import Distribution.Package ( Package(..) ) import Distribution.PackageDescription ( FlagAssignment ) import Distribution.Solver.Types.ComponentDeps ( ComponentDeps ) import Distribution.Solver.Types.OptionalStanza +import Distribution.Solver.Types.PackagePath (QPN) import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SourcePackage @@ -21,6 +22,7 @@ import Distribution.Solver.Types.SourcePackage -- but for symmetry we have the parameter. (Maybe it can be removed.) -- data SolverPackage loc = SolverPackage { + solverPkgQPN :: QPN, solverPkgSource :: SourcePackage loc, solverPkgFlags :: FlagAssignment, solverPkgStanzas :: OptionalStanzaSet, diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index d59bc611c44..af759a2fedf 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -1023,7 +1023,7 @@ configuredPackageProblems configuredPackageProblems platform cinfo - (SolverPackage pkg specifiedFlags stanzas specifiedDeps0 _specifiedExeDeps') = + (SolverPackage _qpn pkg specifiedFlags stanzas specifiedDeps0 _specifiedExeDeps') = [ DuplicateFlag flag | flag <- PD.findDuplicateFlagAssignments specifiedFlags ] diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 11021bb70b1..f30e11ad23e 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1685,7 +1685,7 @@ elaborateInstallPlan :: (SolverId -> [ElaboratedPlanPackage]) -> SolverPackage UnresolvedPkgLoc -> LogProgress [ElaboratedConfiguredPackage] - elaborateSolverToComponents mapDep spkg@(SolverPackage _ _ _ deps0 exe_deps0) = + elaborateSolverToComponents mapDep spkg@(SolverPackage qpn _ _ _ deps0 exe_deps0) = case mkComponentsGraph (elabEnabledSpec elab0) pd of Right g -> do let src_comps = componentsGraphToList g @@ -2075,6 +2075,7 @@ elaborateInstallPlan elaborateSolverToPackage pkgWhyNotPerComponent pkg@( SolverPackage + qpn (SourcePackage pkgid _gpd _srcloc _descOverride) _flags _stanzas @@ -2178,6 +2179,7 @@ elaborateInstallPlan -> (ElaboratedConfiguredPackage, LogProgress ()) elaborateSolverToCommon pkg@( SolverPackage + qpn (SourcePackage pkgid gdesc srcloc descOverride) flags stanzas From 8b90158f841f3105d4c134bc026922924415881e Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Fri, 14 Mar 2025 11:57:51 +0800 Subject: [PATCH 15/82] refactor(cabal-install-solver)!: remove QualifyOptions Remove QualifyOptions by setting qoSetupIndependent to be always true (the current default) and qoBaseShim false (this must have been just a hack of some sort). --- .../Distribution/Solver/Modular/Builder.hs | 6 +- .../Distribution/Solver/Modular/Dependency.hs | 198 ++++++++---------- .../Distribution/Solver/Modular/Explore.hs | 2 +- .../src/Distribution/Solver/Modular/Index.hs | 16 -- .../Distribution/Solver/Modular/Linking.hs | 8 +- .../Distribution/Solver/Modular/Validate.hs | 8 +- 6 files changed, 100 insertions(+), 138 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs index 5d196f4fd9f..9de9ea16ee2 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs @@ -50,8 +50,7 @@ data BuildState = BS { index :: Index, -- ^ information about packages and their dependencies rdeps :: RevDepMap, -- ^ set of all package goals, completed and open, with reverse dependencies open :: [OpenGoal], -- ^ set of still open goals (flag and package goals) - next :: BuildType, -- ^ kind of node to generate next - qualifyOptions :: QualifyOptions -- ^ qualification options + next :: BuildType -- ^ kind of node to generate next } -- | Map of available linking targets. @@ -105,7 +104,7 @@ scopedExtendOpen :: QPN -> FlaggedDeps PN -> FlagInfo -> scopedExtendOpen qpn fdeps fdefs s = extendOpen qpn gs s where -- Qualify all package names - qfdeps = qualifyDeps (qualifyOptions s) qpn fdeps + qfdeps = qualifyDeps qpn fdeps -- Introduce all package flags qfdefs = L.map (\ (fn, b) -> Flagged (FN qpn fn) b [] []) $ M.toList fdefs -- Combine new package and flag goals @@ -255,7 +254,6 @@ buildTree idx (IndependentGoals ind) igs = , rdeps = M.fromList (L.map (\ qpn -> (qpn, [])) qpns) , open = L.map topLevelGoal qpns , next = Goals - , qualifyOptions = defaultQualifyOptions idx } , linkingState = M.empty } diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs index 27debc9c6f0..78ac86c89f2 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs @@ -1,34 +1,38 @@ {-# LANGUAGE DeriveFunctor #-} -{-# LANGUAGE RecordWildCards #-} -module Distribution.Solver.Modular.Dependency ( - -- * Variables - Var(..) + +module Distribution.Solver.Modular.Dependency + ( -- * Variables + Var (..) , showVar , varPN + -- * Conflict sets , ConflictSet , ConflictMap , CS.showConflictSet + -- * Constrained instances - , CI(..) + , CI (..) + -- * Flagged dependencies , FlaggedDeps - , FlaggedDep(..) - , LDep(..) - , Dep(..) - , PkgComponent(..) - , ExposedComponent(..) - , DependencyReason(..) + , FlaggedDep (..) + , LDep (..) + , Dep (..) + , PkgComponent (..) + , ExposedComponent (..) + , DependencyReason (..) , showDependencyReason , flattenFlaggedDeps - , QualifyOptions(..) , qualifyDeps , unqualifyDeps + -- * Reverse dependency map , RevDepMap + -- * Goals - , Goal(..) - , GoalReason(..) + , Goal (..) + , GoalReason (..) , QGoalReason , goalToVar , varToConflictSet @@ -39,21 +43,21 @@ module Distribution.Solver.Modular.Dependency ( , dependencyReasonToConflictSetWithVersionConflict ) where -import Prelude () import qualified Data.Map as M import qualified Data.Set as S import Distribution.Solver.Compat.Prelude hiding (pi) +import Prelude () -import Language.Haskell.Extension (Extension(..), Language(..)) +import Language.Haskell.Extension (Extension (..), Language (..)) -import Distribution.Solver.Modular.ConflictSet (ConflictSet, ConflictMap) +import Distribution.Solver.Modular.ConflictSet (ConflictMap, ConflictSet) +import qualified Distribution.Solver.Modular.ConflictSet as CS import Distribution.Solver.Modular.Flag import Distribution.Solver.Modular.Package import Distribution.Solver.Modular.Var import Distribution.Solver.Modular.Version -import qualified Distribution.Solver.Modular.ConflictSet as CS -import Distribution.Solver.Types.ComponentDeps (Component(..)) +import Distribution.Solver.Types.ComponentDeps (Component (..)) import Distribution.Solver.Types.PackagePath import Distribution.Types.LibraryName import Distribution.Types.PkgconfigVersionRange @@ -85,14 +89,14 @@ type FlaggedDeps qpn = [FlaggedDep qpn] -- | Flagged dependencies can either be plain dependency constraints, -- or flag-dependent dependency trees. -data FlaggedDep qpn = - -- | Dependencies which are conditional on a flag choice. +data FlaggedDep qpn + = -- | Dependencies which are conditional on a flag choice. Flagged (FN qpn) FInfo (TrueFlaggedDeps qpn) (FalseFlaggedDeps qpn) - -- | Dependencies which are conditional on whether or not a stanza + | -- | Dependencies which are conditional on whether or not a stanza -- (e.g., a test suite or benchmark) is enabled. - | Stanza (SN qpn) (TrueFlaggedDeps qpn) - -- | Dependencies which are always enabled, for the component 'comp'. - | Simple (LDep qpn) Component + Stanza (SN qpn) (TrueFlaggedDeps qpn) + | -- | Dependencies which are always enabled, for the component 'comp'. + Simple (LDep qpn) Component -- | Conservatively flatten out flagged dependencies -- @@ -102,10 +106,10 @@ flattenFlaggedDeps = concatMap aux where aux :: FlaggedDep qpn -> [(LDep qpn, Component)] aux (Flagged _ _ t f) = flattenFlaggedDeps t ++ flattenFlaggedDeps f - aux (Stanza _ t) = flattenFlaggedDeps t - aux (Simple d c) = [(d, c)] + aux (Stanza _ t) = flattenFlaggedDeps t + aux (Simple d c) = [(d, c)] -type TrueFlaggedDeps qpn = FlaggedDeps qpn +type TrueFlaggedDeps qpn = FlaggedDeps qpn type FalseFlaggedDeps qpn = FlaggedDeps qpn -- | A 'Dep' labeled with the reason it was introduced. @@ -119,11 +123,16 @@ data LDep qpn = LDep (DependencyReason qpn) (Dep qpn) -- | A dependency (constraint) associates a package name with a constrained -- instance. It can also represent other types of dependencies, such as -- dependencies on language extensions. -data Dep qpn = Dep (PkgComponent qpn) CI -- ^ dependency on a package component - | Ext Extension -- ^ dependency on a language extension - | Lang Language -- ^ dependency on a language version - | Pkg PkgconfigName PkgconfigVersionRange -- ^ dependency on a pkg-config package - deriving Functor +data Dep qpn + = -- | dependency on a package component + Dep (PkgComponent qpn) CI + | -- | dependency on a language extension + Ext Extension + | -- | dependency on a language version + Lang Language + | -- | dependency on a pkg-config package + Pkg PkgconfigName PkgconfigVersionRange + deriving (Functor) -- | An exposed component within a package. This type is used to represent -- build-depends and build-tool-depends dependencies. @@ -132,8 +141,8 @@ data PkgComponent qpn = PkgComponent qpn ExposedComponent -- | A component that can be depended upon by another package, i.e., a library -- or an executable. -data ExposedComponent = - ExposedLib LibraryName +data ExposedComponent + = ExposedLib LibraryName | ExposedExe UnqualComponentName deriving (Eq, Ord, Show) @@ -147,43 +156,25 @@ data DependencyReason qpn = DependencyReason qpn (Map Flag FlagValue) (S.Set Sta -- | Print the reason that a dependency was introduced. showDependencyReason :: DependencyReason QPN -> String showDependencyReason (DependencyReason qpn flags stanzas) = - intercalate " " $ - showQPN qpn + intercalate " " $ + showQPN qpn : map (uncurry showFlagValue) (M.toList flags) - ++ map (\s -> showSBool s True) (S.toList stanzas) - --- | Options for goal qualification (used in 'qualifyDeps') --- --- See also 'defaultQualifyOptions' -data QualifyOptions = QO { - -- | Do we have a version of base relying on another version of base? - qoBaseShim :: Bool - - -- Should dependencies of the setup script be treated as independent? - , qoSetupIndependent :: Bool - } - deriving Show + ++ map (\s -> showSBool s True) (S.toList stanzas) -- | Apply built-in rules for package qualifiers -- --- Although the behaviour of 'qualifyDeps' depends on the 'QualifyOptions', --- it is important that these 'QualifyOptions' are _static_. Qualification --- does NOT depend on flag assignment; in other words, it behaves the same no --- matter which choices the solver makes (modulo the global 'QualifyOptions'); --- we rely on this in 'linkDeps' (see comment there). --- -- NOTE: It's the _dependencies_ of a package that may or may not be independent -- from the package itself. Package flag choices must of course be consistent. -qualifyDeps :: QualifyOptions -> QPN -> FlaggedDeps PN -> FlaggedDeps QPN -qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go +qualifyDeps :: QPN -> FlaggedDeps PN -> FlaggedDeps QPN +qualifyDeps (Q pp@(PackagePath ns q) pn) = go where go :: FlaggedDeps PN -> FlaggedDeps QPN go = map go1 go1 :: FlaggedDep PN -> FlaggedDep QPN go1 (Flagged fn nfo t f) = Flagged (fmap (Q pp) fn) nfo (go t) (go f) - go1 (Stanza sn t) = Stanza (fmap (Q pp) sn) (go t) - go1 (Simple dep comp) = Simple (goLDep dep comp) comp + go1 (Stanza sn t) = Stanza (fmap (Q pp) sn) (go t) + go1 (Simple dep comp) = Simple (goLDep dep comp) comp -- Suppose package B has a setup dependency on package A. -- This will be recorded as something like @@ -197,15 +188,14 @@ qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go goLDep (LDep dr dep) comp = LDep (fmap (Q pp) dr) (goD dep comp) goD :: Dep PN -> Component -> Dep QPN - goD (Ext ext) _ = Ext ext - goD (Lang lang) _ = Lang lang - goD (Pkg pkn vr) _ = Pkg pkn vr + goD (Ext ext) _ = Ext ext + goD (Lang lang) _ = Lang lang + goD (Pkg pkn vr) _ = Pkg pkn vr goD (Dep dep@(PkgComponent qpn (ExposedExe _)) ci) _ = - Dep (Q (PackagePath ns (QualExe pn qpn)) <$> dep) ci - goD (Dep dep@(PkgComponent qpn (ExposedLib _)) ci) comp - | qBase qpn = Dep (Q (PackagePath ns (QualBase pn)) <$> dep) ci - | qSetup comp = Dep (Q (PackagePath ns (QualSetup pn)) <$> dep) ci - | otherwise = Dep (Q (PackagePath ns inheritedQ ) <$> dep) ci + Dep (Q (PackagePath ns (QualExe pn qpn)) <$> dep) ci + goD (Dep dep@(PkgComponent _qpn (ExposedLib _)) ci) comp + | comp == ComponentSetup = Dep (Q (PackagePath ns (QualSetup pn)) <$> dep) ci + | otherwise = Dep (Q (PackagePath ns inheritedQ) <$> dep) ci -- If P has a setup dependency on Q, and Q has a regular dependency on R, then -- we say that the 'Setup' qualifier is inherited: P has an (indirect) setup @@ -216,18 +206,10 @@ qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go -- a detailed discussion. inheritedQ :: Qualifier inheritedQ = case q of - QualSetup _ -> q - QualExe _ _ -> q - QualToplevel -> q - QualBase _ -> QualToplevel - - -- Should we qualify this goal with the 'Base' package path? - qBase :: PN -> Bool - qBase dep = qoBaseShim && unPackageName dep == "base" - - -- Should we qualify this goal with the 'Setup' package path? - qSetup :: Component -> Bool - qSetup comp = qoSetupIndependent && comp == ComponentSetup + QualSetup _ -> q + QualExe _ _ -> q + QualToplevel -> q + QualBase _ -> QualToplevel -- | Remove qualifiers from set of dependencies -- @@ -244,8 +226,8 @@ unqualifyDeps = go go1 :: FlaggedDep QPN -> FlaggedDep PN go1 (Flagged fn nfo t f) = Flagged (fmap unq fn) nfo (go t) (go f) - go1 (Stanza sn t) = Stanza (fmap unq sn) (go t) - go1 (Simple dep comp) = Simple (goLDep dep) comp + go1 (Stanza sn t) = Stanza (fmap unq sn) (go t) + go1 (Simple dep comp) = Simple (goLDep dep) comp goLDep :: LDep QPN -> LDep PN goLDep (LDep dr dep) = LDep (fmap unq dr) (fmap unq dep) @@ -271,8 +253,8 @@ data Goal qpn = Goal (Var qpn) (GoalReason qpn) deriving (Eq, Show, Functor) -- | Reason why a goal is being added to a goal set. -data GoalReason qpn = - UserGoal -- introduced by a build target +data GoalReason qpn + = UserGoal -- introduced by a build target | DependencyGoal (DependencyReason qpn) -- introduced by a package deriving (Eq, Show, Functor) @@ -288,7 +270,7 @@ varToConflictSet = CS.singleton -- | Convert a 'GoalReason' to a 'ConflictSet' that can be used when the goal -- leads to a conflict. goalReasonToConflictSet :: GoalReason QPN -> ConflictSet -goalReasonToConflictSet UserGoal = CS.empty +goalReasonToConflictSet UserGoal = CS.empty goalReasonToConflictSet (DependencyGoal dr) = dependencyReasonToConflictSet dr -- | Convert a 'GoalReason' to a 'ConflictSet' containing the reason that the @@ -302,14 +284,14 @@ goalReasonToConflictSetWithConflict :: QPN -> GoalReason QPN -> ConflictSet goalReasonToConflictSetWithConflict goal (DependencyGoal (DependencyReason qpn flags stanzas)) | M.null flags && S.null stanzas = CS.singletonWithConflict (P qpn) $ CS.GoalConflict goal -goalReasonToConflictSetWithConflict _ gr = goalReasonToConflictSet gr +goalReasonToConflictSetWithConflict _ gr = goalReasonToConflictSet gr -- | This function returns the solver variables responsible for the dependency. -- It drops the values chosen for flag and stanza variables, which are only -- needed for log messages. dependencyReasonToConflictSet :: DependencyReason QPN -> ConflictSet dependencyReasonToConflictSet (DependencyReason qpn flags stanzas) = - CS.fromList $ P qpn : flagVars ++ map stanzaToVar (S.toList stanzas) + CS.fromList $ P qpn : flagVars ++ map stanzaToVar (S.toList stanzas) where -- Filter out any flags that introduced the dependency with both values. -- They don't need to be included in the conflict set, because changing the @@ -327,16 +309,19 @@ dependencyReasonToConflictSet (DependencyReason qpn flags stanzas) = -- This function currently only specifies the reason for the conflict in the -- simple case where the 'DependencyReason' does not involve any flags or -- stanzas. Otherwise, it falls back to calling 'dependencyReasonToConflictSet'. -dependencyReasonToConflictSetWithVersionConstraintConflict :: QPN - -> Ver - -> DependencyReason QPN - -> ConflictSet dependencyReasonToConflictSetWithVersionConstraintConflict - dependency excludedVersion dr@(DependencyReason qpn flags stanzas) - | M.null flags && S.null stanzas = - CS.singletonWithConflict (P qpn) $ - CS.VersionConstraintConflict dependency excludedVersion - | otherwise = dependencyReasonToConflictSet dr + :: QPN + -> Ver + -> DependencyReason QPN + -> ConflictSet +dependencyReasonToConflictSetWithVersionConstraintConflict + dependency + excludedVersion + dr@(DependencyReason qpn flags stanzas) + | M.null flags && S.null stanzas = + CS.singletonWithConflict (P qpn) $ + CS.VersionConstraintConflict dependency excludedVersion + | otherwise = dependencyReasonToConflictSet dr -- | Convert a 'DependencyReason' to a 'ConflictSet' specifying that the -- conflict occurred because the conflict set variables introduced a version of @@ -346,13 +331,16 @@ dependencyReasonToConflictSetWithVersionConstraintConflict -- This function currently only specifies the reason for the conflict in the -- simple case where the 'DependencyReason' does not involve any flags or -- stanzas. Otherwise, it falls back to calling 'dependencyReasonToConflictSet'. -dependencyReasonToConflictSetWithVersionConflict :: QPN - -> CS.OrderedVersionRange - -> DependencyReason QPN - -> ConflictSet dependencyReasonToConflictSetWithVersionConflict - pkgWithVersionConstraint constraint dr@(DependencyReason qpn flags stanzas) - | M.null flags && S.null stanzas = - CS.singletonWithConflict (P qpn) $ - CS.VersionConflict pkgWithVersionConstraint constraint - | otherwise = dependencyReasonToConflictSet dr + :: QPN + -> CS.OrderedVersionRange + -> DependencyReason QPN + -> ConflictSet +dependencyReasonToConflictSetWithVersionConflict + pkgWithVersionConstraint + constraint + dr@(DependencyReason qpn flags stanzas) + | M.null flags && S.null stanzas = + CS.singletonWithConflict (P qpn) $ + CS.VersionConflict pkgWithVersionConstraint constraint + | otherwise = dependencyReasonToConflictSet dr diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs index 90038a28f5c..d047ecda38e 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs @@ -270,7 +270,7 @@ exploreLog mbj enableBj fineGrainedConflicts (CountConflicts countConflicts) idx couldResolveConflicts :: QPN -> POption -> S.Set CS.Conflict -> Maybe ConflictSet couldResolveConflicts currentQPN@(Q _ pn) (POption i@(I v _) _) conflicts = let (PInfo deps _ _ _) = idx M.! pn M.! i - qdeps = qualifyDeps (defaultQualifyOptions idx) currentQPN deps + qdeps = qualifyDeps currentQPN deps couldBeResolved :: CS.Conflict -> Maybe ConflictSet couldBeResolved CS.OtherConflict = Nothing diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs index 2f28d12de85..28ed5c9cd2d 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs @@ -4,7 +4,6 @@ module Distribution.Solver.Modular.Index , ComponentInfo(..) , IsVisible(..) , IsBuildable(..) - , defaultQualifyOptions , mkIndex ) where @@ -57,18 +56,3 @@ mkIndex xs = M.map M.fromList (groupMap (L.map (\ (pn, i, pi) -> (pn, (i, pi))) groupMap :: Ord a => [(a, b)] -> Map a [b] groupMap xs = M.fromListWith (flip (++)) (L.map (\ (x, y) -> (x, [y])) xs) - -defaultQualifyOptions :: Index -> QualifyOptions -defaultQualifyOptions idx = QO { - qoBaseShim = or [ dep == base - | -- Find all versions of base .. - Just is <- [M.lookup base idx] - -- .. which are installed .. - , (I _ver (Inst _), PInfo deps _comps _flagNfo _fr) <- M.toList is - -- .. and flatten all their dependencies .. - , (LDep _ (Dep (PkgComponent dep _) _ci), _comp) <- flattenFlaggedDeps deps - ] - , qoSetupIndependent = True - } - where - base = mkPackageName "base" diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs index 15514472c80..ead3e10c6d4 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs @@ -61,8 +61,6 @@ data ValidateState = VS { , vsLinks :: Map QPN LinkGroup , vsFlags :: FAssignment , vsStanzas :: SAssignment - , vsQualifyOptions :: QualifyOptions - -- Saved qualified dependencies. Every time 'validateLinking' makes a -- package choice, it qualifies the package's dependencies and saves them in -- this map. Then the qualified dependencies are available for subsequent @@ -101,7 +99,7 @@ validateLinking index = (`runReader` initVS) . go goP qpn@(Q _pp pn) opt@(POption i _) r = do vs <- ask let PInfo deps _ _ _ = vsIndex vs ! pn ! i - qdeps = qualifyDeps (vsQualifyOptions vs) qpn deps + qdeps = qualifyDeps qpn deps newSaved = M.insert qpn qdeps (vsSaved vs) case execUpdateState (pickPOption qpn opt qdeps) vs of Left (cs, err) -> return $ Fail cs (DependenciesNotLinked err) @@ -129,7 +127,6 @@ validateLinking index = (`runReader` initVS) . go , vsLinks = M.empty , vsFlags = M.empty , vsStanzas = M.empty - , vsQualifyOptions = defaultQualifyOptions index , vsSaved = M.empty } @@ -275,8 +272,7 @@ linkDeps target = \deps -> do requalify :: FlaggedDeps QPN -> UpdateState (FlaggedDeps QPN) requalify deps = do - vs <- get - return $ qualifyDeps (vsQualifyOptions vs) target (unqualifyDeps deps) + return $ qualifyDeps target (unqualifyDeps deps) pickFlag :: QFN -> Bool -> UpdateState () pickFlag qfn b = do diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs index 4af149b31cf..d6de20cc1de 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs @@ -108,9 +108,7 @@ data ValidateState = VS { -- Map from package name to the components that are required from that -- package. - requiredComponents :: Map QPN ComponentDependencyReasons, - - qualifyOptions :: QualifyOptions + requiredComponents :: Map QPN ComponentDependencyReasons } newtype Validate a = Validate (Reader ValidateState a) @@ -200,11 +198,10 @@ validate = go svd <- asks saved -- obtain saved dependencies aComps <- asks availableComponents rComps <- asks requiredComponents - qo <- asks qualifyOptions -- obtain dependencies and index-dictated exclusions introduced by the choice let (PInfo deps comps _ mfr) = idx ! pn ! i -- qualify the deps in the current scope - let qdeps = qualifyDeps qo qpn deps + let qdeps = qualifyDeps qpn deps -- the new active constraints are given by the instance we have chosen, -- plus the dependency information we have for that instance let newactives = extractAllDeps pfa psa qdeps @@ -577,5 +574,4 @@ validateTree cinfo idx pkgConfigDb t = runValidate (validate t) VS { , pa = PA M.empty M.empty M.empty , availableComponents = M.empty , requiredComponents = M.empty - , qualifyOptions = defaultQualifyOptions idx } From a696671da00fe58d65218fae006efddc95cb351f Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Fri, 14 Mar 2025 12:16:18 +0800 Subject: [PATCH 16/82] refactor(cabal-install-solver)!: remove deadcode principalPP and setupPP seem to have gone unused since 8194fab5671a86fc2446a39ec27fcbd1e19c7418 --- .../Distribution/Solver/Modular/Package.hs | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs index ccd0e4d4a70..6b35808902a 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs @@ -11,8 +11,6 @@ module Distribution.Solver.Modular.Package , QPV , instI , makeIndependent - , primaryPP - , setupPP , showI , showPI , unPN @@ -77,29 +75,6 @@ instI :: I -> Bool instI (I _ (Inst _)) = True instI _ = False --- | Is the package in the primary group of packages. This is used to --- determine (1) if we should try to establish stanza preferences --- for this goal, and (2) whether or not a user specified @--constraint@ --- should apply to this dependency (grep 'primaryPP' to see the --- use sites). In particular this does not include packages pulled in --- as setup deps. --- -primaryPP :: PackagePath -> Bool -primaryPP (PackagePath _ns q) = go q - where - go QualToplevel = True - go (QualBase _) = True - go (QualSetup _) = False - go (QualExe _ _) = False - --- | Is the package a dependency of a setup script. This is used to --- establish whether or not certain constraints should apply to this --- dependency (grep 'setupPP' to see the use sites). --- -setupPP :: PackagePath -> Bool -setupPP (PackagePath _ns (QualSetup _)) = True -setupPP (PackagePath _ns _) = False - -- | Qualify a target package with its own name so that its dependencies are not -- required to be consistent with other targets. makeIndependent :: PN -> QPN From d908ca3875b5eba904fa18e5a9e8232ce8ca27d2 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Fri, 14 Mar 2025 12:35:12 +0800 Subject: [PATCH 17/82] wip move Toolchain into cabal-install-solver --- .../cabal-install-solver.cabal | 1 + .../Client/ProjectPlanning/Types.hs | 20 +------------------ 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index 3f3b84644cf..4a20a369fee 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -95,6 +95,7 @@ library Distribution.Solver.Types.SolverId Distribution.Solver.Types.SolverPackage Distribution.Solver.Types.SourcePackage + Distribution.Solver.Types.System Distribution.Solver.Types.Variable build-depends: diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 8e52d778330..7432e1897ae 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -104,7 +104,6 @@ import Distribution.Simple.LocalBuildInfo , LibraryName (..) ) import Distribution.Simple.Program -import Distribution.Simple.Program.Db (configuredPrograms) import Distribution.Simple.Setup ( DumpBuildInfo (..) , HaddockTarget @@ -113,9 +112,9 @@ import Distribution.Simple.Setup ) import Distribution.Simple.Utils (ordNub) import Distribution.Solver.Types.ComponentDeps (ComponentDeps) +import Distribution.Solver.Types.System import qualified Distribution.Solver.Types.ComponentDeps as CD import Distribution.Solver.Types.OptionalStanza -import Distribution.System import Distribution.Types.ComponentRequestedSpec import qualified Distribution.Types.LocalBuildConfig as LBC import Distribution.Types.PackageDescription (PackageDescription (..)) @@ -916,23 +915,6 @@ componentOptionalStanza _ = Nothing -- Toolchain -- -data Toolchain = Toolchain - { toolchainPlatform :: Platform - , toolchainCompiler :: Compiler - , toolchainProgramDb :: ProgramDb - } - deriving (Show, Generic, Typeable) - --- TODO: review this -instance Eq Toolchain where - lhs == rhs = - (((==) `on` toolchainPlatform) lhs rhs) - && (((==) `on` toolchainCompiler) lhs rhs) - && ((((==)) `on` (configuredPrograms . toolchainProgramDb)) lhs rhs) - -instance Binary Toolchain -instance Structured Toolchain - data Toolchains = Toolchains { buildToolchain :: Toolchain , hostToolchain :: Toolchain From 9a4f854e3da0a0113f6bfbd0e46c7118962de32f Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Fri, 14 Mar 2025 17:30:03 +0800 Subject: [PATCH 18/82] wip --- .../cabal-install-solver.cabal | 3 +- .../src/Distribution/Solver/Types/Stage.hs | 18 ++ .../Distribution/Solver/Types/Toolchain.hs | 49 ++++++ .../Distribution/Client/ProjectPlanning.hs | 154 +++++++++--------- .../Client/ProjectPlanning/Types.hs | 20 +-- 5 files changed, 151 insertions(+), 93 deletions(-) create mode 100644 cabal-install-solver/src/Distribution/Solver/Types/Stage.hs create mode 100644 cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index 4a20a369fee..c1145254b6c 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -95,7 +95,8 @@ library Distribution.Solver.Types.SolverId Distribution.Solver.Types.SolverPackage Distribution.Solver.Types.SourcePackage - Distribution.Solver.Types.System + Distribution.Solver.Types.Stage + Distribution.Solver.Types.Toolchain Distribution.Solver.Types.Variable build-depends: diff --git a/cabal-install-solver/src/Distribution/Solver/Types/Stage.hs b/cabal-install-solver/src/Distribution/Solver/Types/Stage.hs new file mode 100644 index 00000000000..0365ef515c1 --- /dev/null +++ b/cabal-install-solver/src/Distribution/Solver/Types/Stage.hs @@ -0,0 +1,18 @@ +{-# LANGUAGE DeriveGeneric #-} + +module Distribution.Solver.Types.Stage + ( Stage (..) + ) where + +import Distribution.Compat.Prelude +import Prelude () + +data Stage + = -- | -- The system where the build is running + Build + | -- | -- The system where the built artifacts will run + Host + deriving (Eq, Read, Show, Generic, Typeable) + +instance Binary Stage +instance Structured Stage diff --git a/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs new file mode 100644 index 00000000000..182101b8899 --- /dev/null +++ b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs @@ -0,0 +1,49 @@ +{-# LANGUAGE DeriveGeneric #-} + +module Distribution.Solver.Types.Toolchain + ( Toolchain (..) + , Toolchains (..) + , toolchainFor + ) where + +import Distribution.Compat.Prelude +import Prelude () + +import Distribution.Simple.Compiler +import Distribution.Simple.Program.Db +import Distribution.Solver.Types.Stage (Stage (..)) +import Distribution.System + +--------------------------- +-- Toolchain +-- + +data Toolchain = Toolchain + { toolchainPlatform :: Platform + , toolchainCompiler :: Compiler + , toolchainProgramDb :: ProgramDb + } + deriving (Show, Generic, Typeable) + +-- TODO: review this +instance Eq Toolchain where + lhs == rhs = + (((==) `on` toolchainPlatform) lhs rhs) + && (((==) `on` toolchainCompiler) lhs rhs) + && ((((==)) `on` (configuredPrograms . toolchainProgramDb)) lhs rhs) + +instance Binary Toolchain +instance Structured Toolchain + +data Toolchains = Toolchains + { buildToolchain :: Toolchain + , hostToolchain :: Toolchain + } + deriving (Eq, Show, Generic, Typeable) + +toolchainFor :: Stage -> Toolchains -> Toolchain +toolchainFor Build = buildToolchain +toolchainFor Host = hostToolchain + +instance Binary Toolchains +instance Structured Toolchains diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index f30e11ad23e..1990ad8a415 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -221,6 +221,8 @@ import qualified Distribution.Simple.InstallDirs as InstallDirs import qualified Distribution.Simple.LocalBuildInfo as Cabal import qualified Distribution.Simple.Setup as Cabal import qualified Distribution.Solver.Types.ComponentDeps as CD +import Distribution.Solver.Types.Stage +import Distribution.Solver.Types.Toolchain import qualified Distribution.Compat.Graph as Graph @@ -1611,18 +1613,7 @@ elaborateInstallPlan elaborateInstallPlan verbosity hookHashes - toolchains@Toolchains - { buildToolchain = - Toolchain - { toolchainCompiler = compiler - , toolchainProgramDb = compilerprogdb - } - , hostToolchain = - Toolchain - { toolchainCompiler = hostCompiler - , toolchainPlatform = hostPlatform - } - } + toolchains pkgConfigDB distDirLayout@DistDirLayout{..} storeDirLayout@StoreDirLayout{storePackageDBStack} @@ -2201,12 +2192,19 @@ elaborateInstallPlan elabIsCanonical = True elabPkgSourceId = pkgid + + -- TODO: temporarily set everything to build on build + elabStage = Build + elabCompiler = toolchainCompiler (toolchainFor elabStage toolchains) + elabPlatform = toolchainPlatform (toolchainFor elabStage toolchains) + elabProgramDb = toolchainProgramDb (toolchainFor elabStage toolchains) + elabPkgDescription = case PD.finalizePD flags elabEnabledSpec (const Satisfied) - hostPlatform - (compilerInfo hostCompiler) + elabPlatform + (compilerInfo elabCompiler) [] gdesc of Right (desc, _) -> desc @@ -2281,6 +2279,10 @@ elaborateInstallPlan deps0 elabSetupPackageDBStack = buildAndRegisterDbs + inplacePackageDbs = corePackageDbs ++ [distPackageDB (compilerId elabCompiler)] + + corePackageDbs = storePackageDBStack elabCompiler (projectConfigPackageDBs sharedPackageConfig) + elabInplaceBuildPackageDBStack = inplacePackageDbs elabInplaceRegisterPackageDBStack = inplacePackageDbs elabInplaceSetupPackageDBStack = inplacePackageDbs @@ -2291,17 +2293,21 @@ elaborateInstallPlan elabPkgDescriptionOverride = descOverride + pkgsUseSharedLibrary :: Set PackageId + pkgsUseSharedLibrary = + packagesWithLibDepsDownwardClosedProperty (needsSharedLib elabCompiler) + elabBuildOptions = LBC.BuildOptions { withVanillaLib = perPkgOptionFlag pkgid True packageConfigVanillaLib -- TODO: [required feature]: also needs to be handled recursively - , withSharedLib = canBuildSharedLibs && pkgid `Set.member` pkgsUseSharedLibrary + , withSharedLib = canBuildSharedLibs elabCompiler && pkgid `Set.member` pkgsUseSharedLibrary , withStaticLib = perPkgOptionFlag pkgid False packageConfigStaticLib , withDynExe = perPkgOptionFlag pkgid False packageConfigDynExe , withFullyStaticExe = perPkgOptionFlag pkgid False packageConfigFullyStaticExe , withGHCiLib = perPkgOptionFlag pkgid False packageConfigGHCiLib -- TODO: [required feature] needs to default to enabled on windows still , withProfExe = perPkgOptionFlag pkgid False packageConfigProf - , withProfLib = canBuildProfilingLibs && pkgid `Set.member` pkgsUseProfilingLibrary - , withProfLibShared = canBuildProfilingSharedLibs && pkgid `Set.member` pkgsUseProfilingLibraryShared + , withProfLib = canBuildProfilingLibs elabCompiler && pkgid `Set.member` pkgsUseProfilingLibrary + , withProfLibShared = canBuildProfilingSharedLibs elabCompiler && pkgid `Set.member` pkgsUseProfilingLibraryShared , exeCoverage = perPkgOptionFlag pkgid False packageConfigCoverage , libCoverage = perPkgOptionFlag pkgid False packageConfigCoverage , withOptimization = perPkgOptionFlag pkgid NormalOptimisation packageConfigOptimization @@ -2334,13 +2340,13 @@ elaborateInstallPlan elabProgramPaths = Map.fromList [ (programId prog, programPath prog) - | prog <- configuredPrograms compilerprogdb + | prog <- configuredPrograms elabProgramDb ] <> perPkgOptionMapLast pkgid packageConfigProgramPaths elabProgramArgs = Map.fromList [ (programId prog, args) - | prog <- configuredPrograms compilerprogdb + | prog <- configuredPrograms elabProgramDb , let args = programOverrideArgs $ addHaddockIfDocumentationEnabled prog , not (null args) ] @@ -2422,12 +2428,6 @@ elaborateInstallPlan mempty perpkg = maybe mempty f (Map.lookup (packageName pkg) perPackageConfig) - inplacePackageDbs = - corePackageDbs - ++ [distPackageDB (compilerId compiler)] - - corePackageDbs = storePackageDBStack compiler (projectConfigPackageDBs sharedPackageConfig) - -- For this local build policy, every package that lives in a local source -- dir (as opposed to a tarball), or depends on such a package, will be -- built inplace into a shared dist dir. Tarball packages that depend on @@ -2458,13 +2458,13 @@ elaborateInstallPlan -- TODO: localPackages is a misnomer, it's all project packages -- here is where we decide which ones will be local! - pkgsUseSharedLibrary :: Set PackageId - pkgsUseSharedLibrary = - packagesWithLibDepsDownwardClosedProperty needsSharedLib + pkgsUseProfilingLibrary :: Set PackageId + pkgsUseProfilingLibrary = + packagesWithLibDepsDownwardClosedProperty needsProfilingLib - needsSharedLib pkgid = + needsSharedLib compiler pkgid = fromMaybe - compilerShouldUseSharedLibByDefault + (compilerShouldUseSharedLibByDefault compiler) -- Case 1: --enable-shared or --disable-shared is passed explicitly, honour that. ( case pkgSharedLib of Just v -> Just v @@ -2475,7 +2475,7 @@ elaborateInstallPlan -- Case 3: If --enable-profiling is passed, then we are going to -- build profiled dynamic, so no need for shared libraries. case pkgProf of - Just True -> if canBuildProfilingSharedLibs then Nothing else Just True + Just True -> if canBuildProfilingSharedLibs compiler then Nothing else Just True _ -> Just True -- But don't necessarily turn off shared library generation if -- --disable-executable-dynamic is passed. The shared objects might @@ -2487,52 +2487,7 @@ elaborateInstallPlan pkgDynExe = perPkgOptionMaybe pkgid packageConfigDynExe pkgProf = perPkgOptionMaybe pkgid packageConfigProf - -- TODO: [code cleanup] move this into the Cabal lib. It's currently open - -- coded in Distribution.Simple.Configure, but should be made a proper - -- function of the Compiler or CompilerInfo. - compilerShouldUseSharedLibByDefault = - case compilerFlavor compiler of - GHC -> GHC.compilerBuildWay compiler == DynWay && canBuildSharedLibs - GHCJS -> GHCJS.isDynamic compiler - _ -> False - - compilerShouldUseProfilingLibByDefault = - case compilerFlavor compiler of - GHC -> GHC.compilerBuildWay compiler == ProfWay && canBuildProfilingLibs - _ -> False - - compilerShouldUseProfilingSharedLibByDefault = - case compilerFlavor compiler of - GHC -> GHC.compilerBuildWay compiler == ProfDynWay && canBuildProfilingSharedLibs - _ -> False - - -- Returns False if we definitely can't build shared libs - canBuildWayLibs predicate = case predicate compiler of - Just can_build -> can_build - -- If we don't know for certain, just assume we can - -- which matches behaviour in previous cabal releases - Nothing -> True - - canBuildSharedLibs = canBuildWayLibs dynamicSupported - canBuildProfilingLibs = canBuildWayLibs profilingVanillaSupported - canBuildProfilingSharedLibs = canBuildWayLibs profilingDynamicSupported - - wayWarnings pkg = do - when - (needsProfilingLib pkg && not canBuildProfilingLibs) - (warnProgress (text "Compiler does not support building p libraries, profiling is disabled")) - when - (needsSharedLib pkg && not canBuildSharedLibs) - (warnProgress (text "Compiler does not support building dyn libraries, dynamic libraries are disabled")) - when - (needsProfilingLibShared pkg && not canBuildProfilingSharedLibs) - (warnProgress (text "Compiler does not support building p_dyn libraries, profiling dynamic libraries are disabled.")) - - pkgsUseProfilingLibrary :: Set PackageId - pkgsUseProfilingLibrary = - packagesWithLibDepsDownwardClosedProperty needsProfilingLib - - needsProfilingLib pkg = + needsProfilingLib compiler pkg = fromFlagOrDefault compilerShouldUseProfilingLibByDefault (profBothFlag <> profLibFlag) where pkgid = packageId pkg @@ -2590,6 +2545,51 @@ elaborateInstallPlan -- package config validation/resolution pass. ] +-- TODO: [code cleanup] move this into the Cabal lib. It's currently open +-- coded in Distribution.Simple.Configure, but should be made a proper +-- function of the Compiler or CompilerInfo. +compilerShouldUseSharedLibByDefault :: Compiler -> Bool +compilerShouldUseSharedLibByDefault compiler = + case compilerFlavor compiler of + GHC -> GHC.compilerBuildWay compiler == DynWay && canBuildSharedLibs compiler + GHCJS -> GHCJS.isDynamic compiler + _ -> False + +-- TODO: [code cleanup] move this into the Cabal lib. +compilerShouldUseProfilingLibByDefault :: Compiler -> Bool +compilerShouldUseProfilingLibByDefault compiler = + case compilerFlavor compiler of + GHC -> GHC.compilerBuildWay compiler == ProfWay && canBuildProfilingLibs compiler + _ -> False + +-- TODO: [code cleanup] move this into the Cabal lib. +compilerShouldUseProfilingSharedLibByDefault :: Compiler -> Bool +compilerShouldUseProfilingSharedLibByDefault compiler = + case compilerFlavor compiler of + GHC -> GHC.compilerBuildWay compiler == ProfDynWay && canBuildProfilingSharedLibs compiler + _ -> False + +-- Returns False if we definitely can't build shared libs +-- TODO: [code cleanup] move this into the Cabal lib. +canBuildWayLibs :: (t -> Maybe Bool) -> t -> Bool +canBuildWayLibs predicate compiler = case predicate compiler of + Just can_build -> can_build + -- If we don't know for certain, just assume we can + -- which matches behaviour in previous cabal releases + Nothing -> True + +-- TODO: [code cleanup] move this into the Cabal lib. +canBuildSharedLibs :: Compiler -> Bool +canBuildSharedLibs = canBuildWayLibs dynamicSupported + +-- TODO: [code cleanup] move this into the Cabal lib. +canBuildProfilingLibs :: Compiler -> Bool +canBuildProfilingLibs = canBuildWayLibs profilingVanillaSupported + +-- TODO: [code cleanup] move this into the Cabal lib. +canBuildProfilingSharedLibs :: Compiler -> Bool +canBuildProfilingSharedLibs = canBuildWayLibs profilingDynamicSupported + -- TODO: [nice to have] config consistency checking: -- + profiling libs & exes, exe needs lib, recursive -- + shared libs & exes, exe needs lib, recursive diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 7432e1897ae..16b791105ef 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -112,7 +112,8 @@ import Distribution.Simple.Setup ) import Distribution.Simple.Utils (ordNub) import Distribution.Solver.Types.ComponentDeps (ComponentDeps) -import Distribution.Solver.Types.System +import Distribution.Solver.Types.Stage +import Distribution.Solver.Types.Toolchain import qualified Distribution.Solver.Types.ComponentDeps as CD import Distribution.Solver.Types.OptionalStanza import Distribution.Types.ComponentRequestedSpec @@ -250,7 +251,9 @@ data ElaboratedConfiguredPackage = ElaboratedConfiguredPackage -- to disable. This tells us which ones we build by default, and -- helps with error messages when the user asks to build something -- they explicitly disabled. - -- + + , elabStage :: Stage + -- TODO: The 'Bool' here should be refined into an ADT with three -- cases: NotRequested, ExplicitlyRequested and -- ImplicitlyRequested. A stanza is explicitly requested if @@ -911,19 +914,6 @@ componentOptionalStanza (CD.ComponentTest _) = Just TestStanzas componentOptionalStanza (CD.ComponentBench _) = Just BenchStanzas componentOptionalStanza _ = Nothing ---------------------------- --- Toolchain --- - -data Toolchains = Toolchains - { buildToolchain :: Toolchain - , hostToolchain :: Toolchain - } - deriving (Eq, Show, Generic, Typeable) - -instance Binary Toolchains -instance Structured Toolchains - --------------------------- -- Setup.hs script policy -- From 27a5f68b95c6853b5ca12a794985ab6d9849072d Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Mon, 17 Mar 2025 11:49:51 +0800 Subject: [PATCH 19/82] drop elaborationWarnings --- .../Distribution/Client/ProjectPlanning.hs | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 1990ad8a415..7630d0050bf 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1693,7 +1693,6 @@ elaborateInstallPlan let whyNotPerComp = why_not_per_component src_comps case NE.nonEmpty whyNotPerComp of Nothing -> do - elaborationWarnings return comps Just notPerCompReasons -> do checkPerPackageOk comps notPerCompReasons @@ -1766,7 +1765,7 @@ elaborateInstallPlan <+> fsep (punctuate comma $ map (text . whyNotPerComponent) $ toList reasons) -- TODO: Maybe exclude Backpack too - (elab0, elaborationWarnings) = elaborateSolverToCommon spkg + elab0 = elaborateSolverToCommon spkg pkgid = elabPkgSourceId elab0 pd = elabPkgDescription elab0 @@ -2078,11 +2077,17 @@ elaborateInstallPlan -- Knot tying: the final elab includes the -- pkgInstalledId, which is calculated by hashing many -- of the other fields of the elaboratedPackage. - elaborationWarnings return elab where - (elab0@ElaboratedConfiguredPackage{..}, elaborationWarnings) = - elaborateSolverToCommon pkg + elab = + elab1 + { elabInstallDirs = + computeInstallDirs + storeDirLayout + defaultInstallDirs + elaboratedSharedConfig + elab1 + } elab1 = elab0 @@ -2093,15 +2098,9 @@ elaborateInstallPlan , elabModuleShape = modShape } - elab = - elab1 - { elabInstallDirs = - computeInstallDirs - storeDirLayout - defaultInstallDirs - elaboratedSharedConfig - elab1 - } + elab0@ElaboratedConfiguredPackage{..} = + elaborateSolverToCommon pkg + modShape = case find (matchElabPkg (== (CLibName LMainLibName))) comps of Nothing -> emptyModuleShape @@ -2167,7 +2166,7 @@ elaborateInstallPlan elaborateSolverToCommon :: SolverPackage UnresolvedPkgLoc - -> (ElaboratedConfiguredPackage, LogProgress ()) + -> ElaboratedConfiguredPackage elaborateSolverToCommon pkg@( SolverPackage qpn @@ -2177,7 +2176,7 @@ elaborateInstallPlan deps0 _exe_deps0 ) = - (elaboratedPackage, wayWarnings pkgid) + elaboratedPackage where elaboratedPackage = ElaboratedConfiguredPackage{..} From bf465c1f4c7f8210f617f7d7316a611666d542c5 Mon Sep 17 00:00:00 2001 From: Andrea Bedini <andrea@andreabedini.com> Date: Mon, 17 Mar 2025 11:52:39 +0800 Subject: [PATCH 20/82] needsProfilingLib cannot per per compiler just yet I would need to rework packagesWithLibDepsDownwardClosedProperty. It has to be done but not now. --- .../Distribution/Client/ProjectPlanning.hs | 67 ++++++++++--------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 7630d0050bf..af9c8b8a895 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -2486,9 +2486,10 @@ elaborateInstallPlan pkgDynExe = perPkgOptionMaybe pkgid packageConfigDynExe pkgProf = perPkgOptionMaybe pkgid packageConfigProf - needsProfilingLib compiler pkg = - fromFlagOrDefault compilerShouldUseProfilingLibByDefault (profBothFlag <> profLibFlag) + needsProfilingLib pkg = fromFlagOrDefault False (profBothFlag <> profLibFlag) where + -- fromFlagOrDefault compilerShouldUseProfilingLibByDefault (profBothFlag <> profLibFlag) + pkgid = packageId pkg profBothFlag = lookupPerPkgOption pkgid packageConfigProf profLibFlag = lookupPerPkgOption pkgid packageConfigProfLib @@ -2497,24 +2498,26 @@ elaborateInstallPlan pkgsUseProfilingLibraryShared = packagesWithLibDepsDownwardClosedProperty needsProfilingLibShared + -- TODO: review this logic needsProfilingLibShared pkg = - fromMaybe - compilerShouldUseProfilingSharedLibByDefault - -- case 1: If --enable-profiling-shared is passed explicitly, honour that - ( case profLibSharedFlag of - Just v -> Just v - Nothing -> case pkgDynExe of - Just True -> - case pkgProf of - -- case 2: --enable-executable-dynamic + --enable-profiling - -- turn on shared profiling libraries - Just True -> if canBuildProfilingSharedLibs then Just True else Nothing - _ -> Nothing - -- But don't necessarily turn off shared library generation is - -- --disable-executable-dynamic is passed. The shared objects might - -- be needed for something different. - _ -> Nothing - ) + -- fromMaybe + -- compilerShouldUseProfilingSharedLibByDefault + -- -- case 1: If --enable-profiling-shared is passed explicitly, honour that + case profLibSharedFlag of + Just v -> v + Nothing -> case pkgDynExe of + Just True -> + case pkgProf of + -- case 2: --enable-executable-dynamic + --enable-profiling + -- turn on shared profiling libraries + -- Just True -> if canBuildProfilingSharedLibs then Just True else Nothing + Just True -> True + _ -> False + -- But don't necessarily turn off shared library generation is + -- --disable-executable-dynamic is passed. The shared objects might + -- be needed for something different. + -- _ -> Nothing + _ -> False where pkgid = packageId pkg profLibSharedFlag = perPkgOptionMaybe pkgid packageConfigProfShared @@ -2554,19 +2557,19 @@ compilerShouldUseSharedLibByDefault compiler = GHCJS -> GHCJS.isDynamic compiler _ -> False --- TODO: [code cleanup] move this into the Cabal lib. -compilerShouldUseProfilingLibByDefault :: Compiler -> Bool -compilerShouldUseProfilingLibByDefault compiler = - case compilerFlavor compiler of - GHC -> GHC.compilerBuildWay compiler == ProfWay && canBuildProfilingLibs compiler - _ -> False - --- TODO: [code cleanup] move this into the Cabal lib. -compilerShouldUseProfilingSharedLibByDefault :: Compiler -> Bool -compilerShouldUseProfilingSharedLibByDefault compiler = - case compilerFlavor compiler of - GHC -> GHC.compilerBuildWay compiler == ProfDynWay && canBuildProfilingSharedLibs compiler - _ -> False +-- -- TODO: [code cleanup] move this into the Cabal lib. +-- compilerShouldUseProfilingLibByDefault :: Compiler -> Bool +-- compilerShouldUseProfilingLibByDefault compiler = +-- case compilerFlavor compiler of +-- GHC -> GHC.compilerBuildWay compiler == ProfWay && canBuildProfilingLibs compiler +-- _ -> False + +-- -- TODO: [code cleanup] move this into the Cabal lib. +-- compilerShouldUseProfilingSharedLibByDefault :: Bool +-- compilerShouldUseProfilingSharedLibByDefault = +-- case compilerFlavor compiler of +-- GHC -> GHC.compilerBuildWay compiler == ProfDynWay && canBuildProfilingSharedLibs compiler +-- _ -> False -- Returns False if we definitely can't build shared libs -- TODO: [code cleanup] move this into the Cabal lib. From da1abc650c7fe6a6e0d5b286b3ef20cdbdba4a26 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sat, 15 Mar 2025 20:44:18 +0900 Subject: [PATCH 21/82] Add CompilerId to IPI --- Cabal-syntax/src/Distribution/Compiler.hs | 11 ++++++++++- .../src/Distribution/Types/InstalledPackageInfo.hs | 2 ++ .../Types/InstalledPackageInfo/FieldGrammar.hs | 3 +++ .../Distribution/Types/InstalledPackageInfo/Lens.hs | 5 +++++ Cabal/src/Distribution/Simple/GHC.hs | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index 40148776ee1..879547234ae 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -184,12 +184,18 @@ instance Pretty CompilerId where | v == nullVersion = pretty f | otherwise = pretty f <<>> Disp.char '-' <<>> pretty v +instance Pretty (Maybe CompilerId) where + pretty = maybe Disp.empty pretty + instance Parsec CompilerId where parsec = do flavour <- parsec version <- (P.char '-' >> parsec) <|> return nullVersion return (CompilerId flavour version) +instance Parsec (Maybe CompilerId) where + parsec = Just <$> parsec <|> return Nothing + lowercase :: String -> String lowercase = map toLower @@ -216,9 +222,11 @@ data CompilerInfo = CompilerInfo , compilerInfoExtensions :: Maybe [Extension] -- ^ Supported extensions, if known. } - deriving (Generic, Show, Read) + deriving (Generic, Show, Read, Eq) instance Binary CompilerInfo +instance Structured CompilerInfo +instance NFData CompilerInfo where rnf = genericRnf data AbiTag = NoAbiTag @@ -227,6 +235,7 @@ data AbiTag instance Binary AbiTag instance Structured AbiTag +instance NFData AbiTag where rnf = genericRnf instance Pretty AbiTag where pretty NoAbiTag = Disp.empty diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs index f57457d2e5b..03c0b9cae3c 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs @@ -16,6 +16,7 @@ import Prelude () import Distribution.Backpack import Distribution.Compat.Graph (IsNode (..)) +import Distribution.Compiler (CompilerId) import Distribution.License import Distribution.ModuleName import Distribution.Package hiding (installedUnitId) @@ -93,6 +94,7 @@ data InstalledPackageInfo = InstalledPackageInfo , haddockInterfaces :: [FilePath] , haddockHTMLs :: [FilePath] , pkgRoot :: Maybe FilePath + , pkgCompiler :: Maybe CompilerId } deriving (Eq, Generic, Read, Show) diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index 7578907b590..c2e77292c07 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -15,6 +15,7 @@ import Distribution.Backpack import Distribution.CabalSpecVersion import Distribution.Compat.Lens (Lens', (&), (.~)) import Distribution.Compat.Newtype +import Distribution.Compiler (CompilerId(..)) import Distribution.FieldGrammar import Distribution.FieldGrammar.FieldDescrs import Distribution.License @@ -73,6 +74,7 @@ ipiFieldGrammar , c ExposedModules , c InstWith , c SpecLicenseLenient + , c (Identity (Maybe CompilerId)) ) => g InstalledPackageInfo InstalledPackageInfo ipiFieldGrammar = @@ -125,6 +127,7 @@ ipiFieldGrammar = <@> monoidalFieldAla "haddock-interfaces" (alaList' FSep FilePathNT) L.haddockInterfaces <@> monoidalFieldAla "haddock-html" (alaList' FSep FilePathNT) L.haddockHTMLs <@> optionalFieldAla "pkgroot" FilePathNT L.pkgRoot + <@> optionalFieldDef "compiler" L.pkgCompiler Nothing where mkInstalledPackageInfo _ Basic{..} = InstalledPackageInfo diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs index 47fa1c96f40..9e7798e443d 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs @@ -7,6 +7,7 @@ import Distribution.Compat.Lens import Distribution.Compat.Prelude import Prelude () +import Distribution.Compiler (CompilerId) import Distribution.Backpack (OpenModule) import Distribution.License (License) import Distribution.ModuleName (ModuleName) @@ -194,3 +195,7 @@ pkgRoot f s = fmap (\x -> s{T.pkgRoot = x}) (f (T.pkgRoot s)) libVisibility :: Lens' InstalledPackageInfo LibraryVisibility libVisibility f s = fmap (\x -> s{T.libVisibility = x}) (f (T.libVisibility s)) {-# INLINE libVisibility #-} + +pkgCompiler :: Lens' InstalledPackageInfo (Maybe CompilerId) +pkgCompiler f s = fmap (\x -> s{T.pkgCompiler = x}) (f (T.pkgCompiler s)) +{-# INLINE pkgCompiler #-} diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 45fbee0fed1..9d02cac5fac 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -418,6 +418,7 @@ getInstalledPackages -> ProgramDb -> IO InstalledPackageIndex getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do + print $ ("getInstalledPackages", (compilerId comp), packagedbs) checkPackageDbEnvVar verbosity checkPackageDbStack verbosity comp packagedbs pkgss <- getInstalledPackages' verbosity mbWorkDir packagedbs progdb From b3ae65d5459ffe02f88a5a5f0d93fa03346a09cd Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sat, 15 Mar 2025 21:10:34 +0900 Subject: [PATCH 22/82] Cleanup and Add the compilerId to the installedPackageIndex --- Cabal-syntax/src/Distribution/Compiler.hs | 1 + Cabal/src/Distribution/Simple/GHC.hs | 7 +++++-- Cabal/src/Distribution/Simple/Register.hs | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index 879547234ae..cef915a25d3 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -1,6 +1,7 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE FlexibleInstances #-} ----------------------------------------------------------------------------- diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 9d02cac5fac..a41c6d4a5d9 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -88,7 +88,7 @@ import Control.Monad (forM_) import Data.List (stripPrefix) import qualified Data.Map as Map import Distribution.CabalSpecVersion -import Distribution.InstalledPackageInfo (InstalledPackageInfo) +import Distribution.InstalledPackageInfo (InstalledPackageInfo(pkgCompiler)) import qualified Distribution.InstalledPackageInfo as InstalledPackageInfo import Distribution.Package import Distribution.PackageDescription as PD @@ -422,7 +422,10 @@ getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do checkPackageDbEnvVar verbosity checkPackageDbStack verbosity comp packagedbs pkgss <- getInstalledPackages' verbosity mbWorkDir packagedbs progdb - index <- toPackageIndex verbosity pkgss progdb + let pkgss' = [ (packagedb, (\pkg -> pkg{pkgCompiler = Just (compilerId comp)}) <$> pkgs) + | (packagedb, pkgs) <- pkgss + ] + index <- toPackageIndex verbosity pkgss' progdb return $! hackRtsPackage index where hackRtsPackage index = diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index 0bd7312cbc4..f5078f69f3d 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -553,6 +553,7 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi , IPI.haddockHTMLs = [htmldir installDirs | hasModules] , IPI.pkgRoot = Nothing , IPI.libVisibility = libVisibility lib + , IPI.pkgCompiler = Nothing } where ghc84 = case compilerId $ compiler lbi of From cca7205a2641710274cbc1acf2a67b2290591f9d Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 17 Mar 2025 10:09:20 +0900 Subject: [PATCH 23/82] Ensure dependency unit-ids are updated correctly. --- Cabal/src/Distribution/Simple/GHC.hs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index a41c6d4a5d9..04280e5e0eb 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -88,7 +88,7 @@ import Control.Monad (forM_) import Data.List (stripPrefix) import qualified Data.Map as Map import Distribution.CabalSpecVersion -import Distribution.InstalledPackageInfo (InstalledPackageInfo(pkgCompiler)) +import Distribution.InstalledPackageInfo (InstalledPackageInfo) import qualified Distribution.InstalledPackageInfo as InstalledPackageInfo import Distribution.Package import Distribution.PackageDescription as PD @@ -422,7 +422,10 @@ getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do checkPackageDbEnvVar verbosity checkPackageDbStack verbosity comp packagedbs pkgss <- getInstalledPackages' verbosity mbWorkDir packagedbs progdb - let pkgss' = [ (packagedb, (\pkg -> pkg{pkgCompiler = Just (compilerId comp)}) <$> pkgs) + let pkgss' = [ (packagedb, (\pkg -> pkg{ InstalledPackageInfo.pkgCompiler = Just (compilerId comp) + ,InstalledPackageInfo.installedUnitId = ((\x -> mkUnitId $ prettyShow (compilerId comp) ++ ":" ++ (unUnitId x)) . InstalledPackageInfo.installedUnitId) pkg + ,InstalledPackageInfo.depends = (map (\x -> mkUnitId $ prettyShow (compilerId comp) ++ ":" ++ (unUnitId x)) . InstalledPackageInfo.depends) pkg }) + <$> pkgs) | (packagedb, pkgs) <- pkgss ] index <- toPackageIndex verbosity pkgss' progdb From a68d450acd0586a5f20827680739f05de08daecd Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 17 Mar 2025 13:16:41 +0900 Subject: [PATCH 24/82] Plan with build _and_ host package indices. --- .../src/Distribution/Client/ProjectPlanning.hs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index af9c8b8a895..73b9d02c0a5 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -770,7 +770,12 @@ rebuildInstallPlan , hookHashes ) $ do - installedPkgIndex <- + hinstalledPkgIndex <- + getInstalledPackages + verbosity + (hostToolchain toolchains) + corePackageDbs + binstalledPkgIndex <- getInstalledPackages verbosity (buildToolchain toolchains) @@ -796,9 +801,9 @@ rebuildInstallPlan foldProgress logMsg (pure . Left) (pure . Right) $ planPackages verbosity - (hostToolchain toolchains) + (hostToolchain toolchains) -- FIXME: this should be `toolchains`. solverSettings - (installedPackages <> installedPkgIndex) + (installedPackages <> hinstalledPkgIndex <> binstalledPkgIndex) sourcePkgDb pkgConfigDB localPackages From ddbdd71929a4d5d6b53af2eca47235ced2074aaa Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Fri, 14 Mar 2025 14:01:43 +0900 Subject: [PATCH 25/82] Add Stage = Host | Build --- .../Solver/Modular/ConfiguredConversion.hs | 6 +++--- .../Distribution/Solver/Modular/Explore.hs | 2 +- .../src/Distribution/Solver/Modular/Index.hs | 15 +++++++++++++++ .../Solver/Modular/IndexConversion.hs | 4 ++-- .../Distribution/Solver/Modular/Package.hs | 19 ++++++++++++++----- .../Distribution/Solver/Modular/Preference.hs | 12 ++++++------ .../Distribution/Solver/Modular/Validate.hs | 4 ++-- 7 files changed, 43 insertions(+), 19 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index 89b57e2c783..670850a9439 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -29,7 +29,7 @@ convCP :: SI.InstalledPackageIndex -> convCP iidx sidx (CP qpi fa es ds) = case qpi of -- Installed - (PI qpn (I _ (Inst pi))) -> + (PI qpn (I {- FIXME -} Host _ (Inst pi))) -> PreExisting $ InstSolverPackage { instSolverQPN = qpn, @@ -38,7 +38,7 @@ convCP iidx sidx (CP qpi fa es ds) = instSolverPkgExeDeps = fmap snd ds' } -- "In repo" i.e. a source package - (PI qpn@(Q _path pn) (I v InRepo)) -> + (PI qpn@(Q _path pn) (I {- FIXME -} Host v InRepo)) -> let pi = PackageIdentifier pn v in Configured $ SolverPackage { @@ -54,7 +54,7 @@ convCP iidx sidx (CP qpi fa es ds) = ds' = fmap (partitionEithers . map convConfId) ds convConfId :: PI QPN -> Either SolverId {- is lib -} SolverId {- is exe -} -convConfId (PI (Q (PackagePath _ q) pn) (I v loc)) = +convConfId (PI (Q (PackagePath _ q) pn) (I _stage v loc)) = case loc of Inst pi -> Left (PreExistingId sourceId pi) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs index d047ecda38e..8dfa9c88bf3 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs @@ -268,7 +268,7 @@ exploreLog mbj enableBj fineGrainedConflicts (CountConflicts countConflicts) idx -- Skipping it is an optimization. If false, it returns a new conflict set -- to be merged with the previous one. couldResolveConflicts :: QPN -> POption -> S.Set CS.Conflict -> Maybe ConflictSet - couldResolveConflicts currentQPN@(Q _ pn) (POption i@(I v _) _) conflicts = + couldResolveConflicts currentQPN@(Q _ pn) (POption i@(I _stage v _) _) conflicts = let (PInfo deps _ _ _) = idx M.! pn M.! i qdeps = qualifyDeps currentQPN deps diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs index 28ed5c9cd2d..85e158a3182 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs @@ -56,3 +56,18 @@ mkIndex xs = M.map M.fromList (groupMap (L.map (\ (pn, i, pi) -> (pn, (i, pi))) groupMap :: Ord a => [(a, b)] -> Map a [b] groupMap xs = M.fromListWith (flip (++)) (L.map (\ (x, y) -> (x, [y])) xs) + +defaultQualifyOptions :: Index -> QualifyOptions +defaultQualifyOptions idx = QO { + qoBaseShim = or [ dep == base + | -- Find all versions of base .. + Just is <- [M.lookup base idx] + -- .. which are installed .. + , (I _ver _stage (Inst _), PInfo deps _comps _flagNfo _fr) <- M.toList is + -- .. and flatten all their dependencies .. + , (LDep _ (Dep (PkgComponent dep _) _ci), _comp) <- flattenFlaggedDeps deps + ] + , qoSetupIndependent = True + } + where + base = mkPackageName "base" diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index 72d0b8193e3..b8ad3e4949a 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -81,7 +81,7 @@ convIPI' (ShadowPkgs sip) idx = -- | Extract/recover the package ID from an installed package info, and convert it to a solver's I. convId :: IPI.InstalledPackageInfo -> (PN, I) -convId ipi = (pn, I ver $ Inst $ IPI.installedUnitId ipi) +convId ipi = (pn, I {- FIXME -} Host ver $ Inst $ IPI.installedUnitId ipi) where MungedPackageId mpn ver = mungedId ipi -- HACK. See Note [Index conversion with internal libraries] pn = encodeCompatPackageName mpn @@ -163,7 +163,7 @@ convSPI' os arch cinfo constraints strfl solveExes = convSP :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint] -> StrongFlags -> SolveExecutables -> SourcePackage loc -> (PN, I, PInfo) convSP os arch cinfo constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) = - let i = I pv InRepo + let i = I {- FIXME -} Host pv InRepo pkgConstraints = fromMaybe [] $ M.lookup pn constraints in (pn, i, convGPD os arch cinfo pkgConstraints strfl solveExes pn gpd) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs index 6b35808902a..2b4a423adcc 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs @@ -1,6 +1,7 @@ {-# LANGUAGE DeriveFunctor #-} module Distribution.Solver.Modular.Package ( I(..) + , Stage(..) , Loc(..) , PackageId , PackageIdentifier(..) @@ -49,14 +50,22 @@ type PId = UnitId data Loc = Inst PId | InRepo deriving (Eq, Ord, Show) +-- | Stage. A stage in the build process. +data Stage = Build | Host + deriving (Eq, Ord, Show) + +showStage :: Stage -> String +showStage Build = "[build]" +showStage Host = "[host ]" + -- | Instance. A version number and a location. -data I = I Ver Loc +data I = I Stage Ver Loc deriving (Eq, Ord, Show) -- | String representation of an instance. showI :: I -> String -showI (I v InRepo) = showVer v -showI (I v (Inst uid)) = showVer v ++ "/installed" ++ extractPackageAbiHash uid +showI (I s v InRepo) = showStage s ++ showVer v +showI (I s v (Inst uid)) = showStage s ++ showVer v ++ "/installed" ++ extractPackageAbiHash uid where extractPackageAbiHash xs = case first reverse $ break (=='-') $ reverse (prettyShow xs) of @@ -72,8 +81,8 @@ showPI :: PI QPN -> String showPI (PI qpn i) = showQPN qpn ++ "-" ++ showI i instI :: I -> Bool -instI (I _ (Inst _)) = True -instI _ = False +instI (I _ _ (Inst _)) = True +instI _ = False -- | Qualify a target package with its own name so that its dependencies are not -- required to be consistent with other targets. diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs index 9e0d5fb4d22..c8bf9209528 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs @@ -72,7 +72,7 @@ addWeight :: (PN -> [Ver] -> POption -> Weight) -> EndoTreeTrav d c addWeight f = addWeights [f] version :: POption -> Ver -version (POption (I v _) _) = v +version (POption (I _ v _) _) = v -- | Prefer to link packages whenever possible. preferLinked :: EndoTreeTrav d c @@ -139,8 +139,8 @@ preferPackagePreferences pcs = -- Prefer installed packages over non-installed packages. installed :: POption -> Weight - installed (POption (I _ (Inst _)) _) = 0 - installed _ = 1 + installed (POption (I _ _ (Inst _)) _) = 0 + installed _ = 1 -- | Traversal that tries to establish package stanza enable\/disable -- preferences. Works by reordering the branches of stanza choices. @@ -184,7 +184,7 @@ processPackageConstraintP qpn c i (LabeledPackageConstraint (PackageConstraint s else r where go :: I -> PackageProperty -> Tree d c - go (I v _) (PackagePropertyVersion vr) + go (I _stage v _) (PackagePropertyVersion vr) | checkVR vr v = r | otherwise = Fail c (GlobalConstraintVersion vr src) go _ PackagePropertyInstalled @@ -338,10 +338,10 @@ avoidReinstalls p = go | otherwise = PChoiceF qpn rdm gr cs where disableReinstalls = - let installed = [ v | (_, POption (I v (Inst _)) _, _) <- W.toList cs ] + let installed = [ v | (_, POption (I _stage v (Inst _)) _, _) <- W.toList cs ] in W.mapWithKey (notReinstall installed) cs - notReinstall vs (POption (I v InRepo) _) _ | v `elem` vs = + notReinstall vs (POption (I _stage v InRepo) _) _ | v `elem` vs = Fail (varToConflictSet (P qpn)) CannotReinstall notReinstall _ _ x = x diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs index d6de20cc1de..e0ad47e32b8 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs @@ -449,14 +449,14 @@ merge (MergedDepFixed comp1 vs1 i1) (PkgDep vs2 (PkgComponent p comp2) ci@(Fixed , ( ConflictingDep vs1 (PkgComponent p comp1) (Fixed i1) , ConflictingDep vs2 (PkgComponent p comp2) ci ) ) -merge (MergedDepFixed comp1 vs1 i@(I v _)) (PkgDep vs2 (PkgComponent p comp2) ci@(Constrained vr)) +merge (MergedDepFixed comp1 vs1 i@(I _stage v _)) (PkgDep vs2 (PkgComponent p comp2) ci@(Constrained vr)) | checkVR vr v = Right $ MergedDepFixed comp1 vs1 i | otherwise = Left ( createConflictSetForVersionConflict p v vs1 vr vs2 , ( ConflictingDep vs1 (PkgComponent p comp1) (Fixed i) , ConflictingDep vs2 (PkgComponent p comp2) ci ) ) -merge (MergedDepConstrained vrOrigins) (PkgDep vs2 (PkgComponent p comp2) ci@(Fixed i@(I v _))) = +merge (MergedDepConstrained vrOrigins) (PkgDep vs2 (PkgComponent p comp2) ci@(Fixed i@(I _stage v _))) = go vrOrigins -- I tried "reverse vrOrigins" here, but it seems to slow things down ... where go :: [VROrigin] -> Either (ConflictSet, (ConflictingDep, ConflictingDep)) MergedPkgDep From 08db0c17403522d3c51cbf983f44e0e37bf8ada3 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 10:05:29 +0900 Subject: [PATCH 26/82] Fixup pkgCompiler --- Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs index 03c0b9cae3c..defb1922607 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs @@ -176,4 +176,5 @@ emptyInstalledPackageInfo = , haddockHTMLs = [] , pkgRoot = Nothing , libVisibility = LibraryVisibilityPrivate + , pkgCompiler = Nothing } From c83ed1caf1a47d5f486655dd71489792629f2ee1 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 10:05:38 +0900 Subject: [PATCH 27/82] Fixup cherry-pick --- .../src/Distribution/Solver/Modular/Index.hs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs index 85e158a3182..1f84e0ba161 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs @@ -57,17 +57,3 @@ mkIndex xs = M.map M.fromList (groupMap (L.map (\ (pn, i, pi) -> (pn, (i, pi))) groupMap :: Ord a => [(a, b)] -> Map a [b] groupMap xs = M.fromListWith (flip (++)) (L.map (\ (x, y) -> (x, [y])) xs) -defaultQualifyOptions :: Index -> QualifyOptions -defaultQualifyOptions idx = QO { - qoBaseShim = or [ dep == base - | -- Find all versions of base .. - Just is <- [M.lookup base idx] - -- .. which are installed .. - , (I _ver _stage (Inst _), PInfo deps _comps _flagNfo _fr) <- M.toList is - -- .. and flatten all their dependencies .. - , (LDep _ (Dep (PkgComponent dep _) _ci), _comp) <- flattenFlaggedDeps deps - ] - , qoSetupIndependent = True - } - where - base = mkPackageName "base" From 5f7fbb8d188596bf4927796b8eae8b4fd802cffb Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 10:51:30 +0900 Subject: [PATCH 28/82] Thread toolchains everywhere. --- .../src/Distribution/Solver/Modular.hs | 17 +++++---- .../Solver/Modular/IndexConversion.hs | 32 +++++++++------- .../src/Distribution/Solver/Modular/Solver.hs | 8 ++-- .../Solver/Types/DependencyResolver.hs | 4 +- .../Distribution/Solver/Types/Toolchain.hs | 8 ++++ .../src/Distribution/Client/Configure.hs | 3 +- .../src/Distribution/Client/Dependency.hs | 37 +++++++++---------- .../src/Distribution/Client/Fetch.hs | 4 +- .../src/Distribution/Client/Freeze.hs | 4 +- .../src/Distribution/Client/Install.hs | 4 +- .../Distribution/Client/ProjectPlanning.hs | 16 ++++---- 11 files changed, 76 insertions(+), 61 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular.hs b/cabal-install-solver/src/Distribution/Solver/Modular.hs index 2c0883d2fba..733cdc87aa0 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular.hs @@ -57,8 +57,9 @@ import Distribution.Verbosity import Distribution.Solver.Modular.Configured (CP (..)) import qualified Distribution.Solver.Types.ComponentDeps as ComponentDeps import Distribution.Pretty (Pretty (..)) -import Text.PrettyPrint (text, vcat, Doc, nest, ($+$)) +import Text.PrettyPrint (text, vcat, Doc, nest, ($+$)) import Distribution.Solver.Types.OptionalStanza (showStanzas, optStanzaSetNull) +import Distribution.Solver.Types.Toolchain ( Toolchains ) import Distribution.Types.Flag (nullFlagAssignment) @@ -75,18 +76,18 @@ showCP (CP qpi fa es ds) = | (c, deps) <- ComponentDeps.toList ds ] ]) - + -- | Ties the two worlds together: classic cabal-install vs. the modular -- solver. Performs the necessary translations before and after. modularResolver :: SolverConfig -> DependencyResolver loc -modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns = do - (assignment, revdepmap) <- solve' sc cinfo idx pkgConfigDB pprefs gcs pns +modularResolver sc toolchains iidx sidx pkgConfigDB pprefs pcs pns = do + (assignment, revdepmap) <- solve' sc toolchains idx pkgConfigDB pprefs gcs pns let cp = toCPs assignment revdepmap Step (show (vcat (map showCP cp))) $ return $ postprocess assignment revdepmap where -- Indices have to be converted into solver-specific uniform index. - idx = convPIs os arch cinfo gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) iidx sidx + idx = convPIs toolchains gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) iidx sidx -- Constraints have to be converted into a finite map indexed by PN. gcs = M.fromListWith (++) (map pair pcs) where @@ -136,21 +137,21 @@ modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns -- complete, i.e., it shows the whole chain of dependencies from the user -- targets to the conflicting packages. solve' :: SolverConfig - -> CompilerInfo + -> Toolchains -> Index -> Maybe PkgConfigDb -> (PN -> PackagePreferences) -> Map PN [LabeledPackageConstraint] -> Set PN -> Progress String String (Assignment, RevDepMap) -solve' sc cinfo idx pkgConfigDB pprefs gcs pns = +solve' sc toolchains idx pkgConfigDB pprefs gcs pns = toProgress $ retry (runSolver printFullLog sc) createErrorMsg where runSolver :: Bool -> SolverConfig -> RetryLog String SolverFailure (Assignment, RevDepMap) runSolver keepLog sc' = displayLogMessages keepLog $ - solve sc' cinfo idx pkgConfigDB pprefs gcs pns + solve sc' toolchains idx pkgConfigDB pprefs gcs pns createErrorMsg :: SolverFailure -> RetryLog String String (Assignment, RevDepMap) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index b8ad3e4949a..44fa7b9ca8a 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -14,6 +14,7 @@ import qualified Distribution.InstalledPackageInfo as IPI import Distribution.Compiler import Distribution.Package -- from Cabal import Distribution.Simple.BuildToolDepends -- from Cabal +import Distribution.Simple.Compiler (compilerInfo) import Distribution.Types.ExeDependency -- from Cabal import Distribution.Types.PkgconfigDependency -- from Cabal import Distribution.Types.ComponentName -- from Cabal @@ -34,6 +35,7 @@ import Distribution.Solver.Types.PackageConstraint import qualified Distribution.Solver.Types.PackageIndex as CI import Distribution.Solver.Types.Settings import Distribution.Solver.Types.SourcePackage +import Distribution.Solver.Types.Toolchain ( Toolchains(..), Toolchain(..) ) import Distribution.Solver.Modular.Dependency as D import Distribution.Solver.Modular.Flag as F @@ -53,13 +55,13 @@ import Distribution.Solver.Modular.Version -- resolving these situations. However, the right thing to do is to -- fix the problem there, so for now, shadowing is only activated if -- explicitly requested. -convPIs :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint] +convPIs :: Toolchains -> Map PN [LabeledPackageConstraint] -> ShadowPkgs -> StrongFlags -> SolveExecutables -> SI.InstalledPackageIndex -> CI.PackageIndex (SourcePackage loc) -> Index -convPIs os arch comp constraints sip strfl solveExes iidx sidx = +convPIs toolchains constraints sip strfl solveExes iidx sidx = mkIndex $ - convIPI' sip iidx ++ convSPI' os arch comp constraints strfl solveExes sidx + convIPI' sip iidx ++ convSPI' toolchains constraints strfl solveExes sidx -- | Convert a Cabal installed package index to the simpler, -- more uniform index format of the solver. @@ -153,31 +155,33 @@ convIPId dr comp idx ipid = -- | Convert a cabal-install source package index to the simpler, -- more uniform index format of the solver. -convSPI' :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint] +convSPI' :: Toolchains -> Map PN [LabeledPackageConstraint] -> StrongFlags -> SolveExecutables -> CI.PackageIndex (SourcePackage loc) -> [(PN, I, PInfo)] -convSPI' os arch cinfo constraints strfl solveExes = - L.map (convSP os arch cinfo constraints strfl solveExes) . CI.allPackages +convSPI' toolchains constraints strfl solveExes = + L.concatMap (convSP toolchains constraints strfl solveExes) . CI.allPackages -- | Convert a single source package into the solver-specific format. -convSP :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint] - -> StrongFlags -> SolveExecutables -> SourcePackage loc -> (PN, I, PInfo) -convSP os arch cinfo constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) = - let i = I {- FIXME -} Host pv InRepo - pkgConstraints = fromMaybe [] $ M.lookup pn constraints - in (pn, i, convGPD os arch cinfo pkgConstraints strfl solveExes pn gpd) +convSP :: Toolchains -> Map PN [LabeledPackageConstraint] + -> StrongFlags -> SolveExecutables -> SourcePackage loc -> [(PN, I, PInfo)] +convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) = + let pkgConstraints = fromMaybe [] $ M.lookup pn constraints + in [(pn, I Host pv InRepo, convGPD (hostToolchain toolchains) pkgConstraints strfl solveExes pn gpd) + ,(pn, I Build pv InRepo, convGPD (buildToolchain toolchains) pkgConstraints strfl solveExes pn gpd)] -- We do not use 'flattenPackageDescription' or 'finalizePD' -- from 'Distribution.PackageDescription.Configuration' here, because we -- want to keep the condition tree, but simplify much of the test. -- | Convert a generic package description to a solver-specific 'PInfo'. -convGPD :: OS -> Arch -> CompilerInfo -> [LabeledPackageConstraint] +convGPD :: Toolchain -> [LabeledPackageConstraint] -> StrongFlags -> SolveExecutables -> PN -> GenericPackageDescription -> PInfo -convGPD os arch cinfo constraints strfl solveExes pn +convGPD toolchain constraints strfl solveExes pn (GenericPackageDescription pkg scannedVersion flags mlib sub_libs flibs exes tests benchs) = let + cinfo = compilerInfo (toolchainCompiler toolchain) + (Platform arch os) = toolchainPlatform toolchain fds = flagInfo strfl flags diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index b2c89fc1537..58de7c9740d 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -24,6 +24,7 @@ import Distribution.Solver.Types.PackagePreferences import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb) import Distribution.Solver.Types.LabeledPackageConstraint import Distribution.Solver.Types.Settings +import Distribution.Solver.Types.Toolchain ( Toolchains(..), Toolchain(..) ) import Distribution.Solver.Types.Variable import Distribution.Solver.Modular.Assignment @@ -44,6 +45,7 @@ import Distribution.Solver.Modular.Tree import qualified Distribution.Solver.Modular.PSQ as PSQ import Distribution.Simple.Setup (BooleanFlag(..)) +import Distribution.Simple.Compiler (compilerInfo) #ifdef DEBUG_TRACETREE import qualified Distribution.Solver.Modular.ConflictSet as CS @@ -89,14 +91,14 @@ newtype PruneAfterFirstSuccess = PruneAfterFirstSuccess Bool -- before exploration. -- solve :: SolverConfig -- ^ solver parameters - -> CompilerInfo + -> Toolchains -> Index -- ^ all available packages as an index -> Maybe PkgConfigDb -- ^ available pkg-config pkgs -> (PN -> PackagePreferences) -- ^ preferences -> M.Map PN [LabeledPackageConstraint] -- ^ global constraints -> S.Set PN -- ^ global goals -> RetryLog Message SolverFailure (Assignment, RevDepMap) -solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals = +solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = explorePhase . traceTree "cycles.json" id . detectCycles . @@ -137,7 +139,7 @@ solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals = P.enforceManualFlags userConstraints validationCata = P.enforceSingleInstanceRestriction . validateLinking idx . - validateTree cinfo idx pkgConfigDB + validateTree (compilerInfo (toolchainCompiler (hostToolchain toolchains))) idx pkgConfigDB prunePhase = (if asBool (avoidReinstalls sc) then P.avoidReinstalls (const True) else id) . (case onlyConstrained sc of OnlyConstrainedAll -> diff --git a/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs b/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs index 139a6d2b33d..d4e9c2ea707 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs @@ -16,6 +16,7 @@ import Distribution.Solver.Types.SourcePackage import Distribution.Simple.PackageIndex ( InstalledPackageIndex ) import Distribution.Package ( PackageName ) import Distribution.Compiler ( CompilerInfo ) +import Distribution.Solver.Types.Toolchain ( Toolchains ) import Distribution.System ( Platform ) -- | A dependency resolver is a function that works out an installation plan @@ -26,8 +27,7 @@ import Distribution.System ( Platform ) -- solving the package dependency problem and we want to make it easy to swap -- in alternatives. -- -type DependencyResolver loc = Platform - -> CompilerInfo +type DependencyResolver loc = Toolchains -> InstalledPackageIndex -> PackageIndex (SourcePackage loc) -> Maybe PkgConfigDb diff --git a/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs index 182101b8899..3126a4abfbd 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs @@ -4,6 +4,7 @@ module Distribution.Solver.Types.Toolchain ( Toolchain (..) , Toolchains (..) , toolchainFor + , mkToolchainsWithHost ) where import Distribution.Compat.Prelude @@ -47,3 +48,10 @@ toolchainFor Host = hostToolchain instance Binary Toolchains instance Structured Toolchains + +mkToolchainsWithHost :: Platform -> Compiler -> Toolchains +mkToolchainsWithHost platform compiler = + Toolchains + { buildToolchain = Toolchain platform compiler (error "build program db missing") + , hostToolchain = Toolchain platform compiler (error "host program db missing") + } diff --git a/cabal-install/src/Distribution/Client/Configure.hs b/cabal-install/src/Distribution/Client/Configure.hs index 048a7db963e..f62ee83e61c 100644 --- a/cabal-install/src/Distribution/Client/Configure.hs +++ b/cabal-install/src/Distribution/Client/Configure.hs @@ -67,6 +67,7 @@ import Distribution.Solver.Types.PkgConfigDb ) import Distribution.Solver.Types.Settings import Distribution.Solver.Types.SourcePackage +import Distribution.Solver.Types.Toolchain (mkToolchainsWithHost) import Distribution.Client.SavedFlags (readCommandFlags, writeCommandFlags) import Distribution.Package @@ -470,7 +471,7 @@ planLocalPackage (SourcePackageDb mempty packagePrefs) [SpecificSourcePackage localPkg] - return (resolveDependencies platform (compilerInfo comp) pkgConfigDb resolverParams) + return (resolveDependencies (mkToolchainsWithHost platform comp) pkgConfigDb resolverParams) -- | Call an installer for an 'SourcePackage' but override the configure -- flags with the ones given by the 'ReadyPackage'. In particular the diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index af759a2fedf..4b5422d145a 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -115,6 +115,7 @@ import Distribution.PackageDescription.Configuration import qualified Distribution.PackageDescription.Configuration as PD import Distribution.Simple.PackageIndex (InstalledPackageIndex) import qualified Distribution.Simple.PackageIndex as InstalledPackageIndex +import Distribution.Simple.Compiler (compilerInfo) import Distribution.Simple.Setup ( asBool ) @@ -153,6 +154,7 @@ import Distribution.Solver.Types.Settings import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SolverPackage import Distribution.Solver.Types.SourcePackage +import Distribution.Solver.Types.Toolchain import Distribution.Solver.Types.Variable import Control.Exception @@ -782,14 +784,13 @@ runSolver = modularResolver -- a 'Progress' structure that can be unfolded to provide progress information, -- logging messages and the final result or an error. resolveDependencies - :: Platform - -> CompilerInfo + :: Toolchains -> Maybe PkgConfigDb -> DepResolverParams -> Progress String String SolverInstallPlan -resolveDependencies platform comp pkgConfigDB params = +resolveDependencies toolchains pkgConfigDB params = Step (showDepResolverParams finalparams) $ - fmap (validateSolverResult platform comp indGoals) $ + fmap (validateSolverResult toolchains indGoals) $ runSolver ( SolverConfig reordGoals @@ -808,8 +809,7 @@ resolveDependencies platform comp pkgConfigDB params = verbosity (PruneAfterFirstSuccess False) ) - platform - comp + toolchains installedPkgIndex sourcePkgIndex pkgConfigDB @@ -909,13 +909,12 @@ interpretPackagesPreference selected defaultPref prefs = -- | Make an install plan from the output of the dep resolver. -- It checks that the plan is valid, or it's an error in the dep resolver. validateSolverResult - :: Platform - -> CompilerInfo + :: Toolchains -> IndependentGoals -> [ResolverPackage UnresolvedPkgLoc] -> SolverInstallPlan -validateSolverResult platform comp indepGoals pkgs = - case planPackagesProblems platform comp pkgs of +validateSolverResult toolchains indepGoals pkgs = + case planPackagesProblems toolchains pkgs of [] -> case SolverInstallPlan.new indepGoals graph of Right plan -> plan Left problems -> error (formatPlanProblems problems) @@ -960,14 +959,13 @@ showPlanPackageProblem (DuplicatePackageSolverId pid dups) = ++ " duplicate instances." planPackagesProblems - :: Platform - -> CompilerInfo + :: Toolchains -> [ResolverPackage UnresolvedPkgLoc] -> [PlanPackageProblem] -planPackagesProblems platform cinfo pkgs = +planPackagesProblems toolchains pkgs = [ InvalidConfiguredPackage pkg packageProblems | Configured pkg <- pkgs - , let packageProblems = configuredPackageProblems platform cinfo pkg + , let packageProblems = configuredPackageProblems toolchains pkg , not (null packageProblems) ] ++ [ DuplicatePackageSolverId (Graph.nodeKey aDup) dups @@ -1016,13 +1014,11 @@ showPackageProblem (InvalidDep dep pkgid) = -- in the configuration given by the flag assignment, all the package -- dependencies are satisfied by the specified packages. configuredPackageProblems - :: Platform - -> CompilerInfo + :: Toolchains -> SolverPackage UnresolvedPkgLoc -> [PackageProblem] configuredPackageProblems - platform - cinfo + toolchains (SolverPackage _qpn pkg specifiedFlags stanzas specifiedDeps0 _specifiedExeDeps') = [ DuplicateFlag flag | flag <- PD.findDuplicateFlagAssignments specifiedFlags @@ -1096,8 +1092,9 @@ configuredPackageProblems specifiedFlags compSpec (const Satisfied) - platform - cinfo + -- FIXME: HARDCODED HOST TOOLCHAIN here. + (toolchainPlatform (hostToolchain toolchains)) + (compilerInfo (toolchainCompiler (hostToolchain toolchains))) [] (srcpkgDescription pkg) of Right (resolvedPkg, _) -> diff --git a/cabal-install/src/Distribution/Client/Fetch.hs b/cabal-install/src/Distribution/Client/Fetch.hs index 033d3a01e14..abe6d181a7f 100644 --- a/cabal-install/src/Distribution/Client/Fetch.hs +++ b/cabal-install/src/Distribution/Client/Fetch.hs @@ -38,6 +38,7 @@ import Distribution.Solver.Types.OptionalStanza import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb, readPkgConfigDb) import Distribution.Solver.Types.SolverPackage import Distribution.Solver.Types.SourcePackage +import Distribution.Solver.Types.Toolchain (mkToolchainsWithHost) import Distribution.Client.Errors import Distribution.Package @@ -174,8 +175,7 @@ planPackages installPlan <- foldProgress logMsg (dieWithException verbosity . PlanPackages . show) return $ resolveDependencies - platform - (compilerInfo comp) + (mkToolchainsWithHost platform comp) pkgConfigDb resolverParams diff --git a/cabal-install/src/Distribution/Client/Freeze.hs b/cabal-install/src/Distribution/Client/Freeze.hs index a03b45b6a2d..abcc69797f9 100644 --- a/cabal-install/src/Distribution/Client/Freeze.hs +++ b/cabal-install/src/Distribution/Client/Freeze.hs @@ -52,6 +52,7 @@ import Distribution.Solver.Types.LabeledPackageConstraint import Distribution.Solver.Types.OptionalStanza import Distribution.Solver.Types.PkgConfigDb import Distribution.Solver.Types.SolverId +import Distribution.Solver.Types.Toolchain (mkToolchainsWithHost) import Distribution.Client.Errors import Distribution.Package @@ -212,8 +213,7 @@ planPackages installPlan <- foldProgress logMsg (dieWithException verbosity . FreezeException) return $ resolveDependencies - platform - (compilerInfo comp) + (mkToolchainsWithHost platform comp) pkgConfigDb resolverParams diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 635cd7e1689..6c9a605c553 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -141,6 +141,7 @@ import Distribution.Solver.Types.PkgConfigDb ) import Distribution.Solver.Types.Settings import Distribution.Solver.Types.SourcePackage as SourcePackage +import Distribution.Solver.Types.Toolchain (mkToolchainsWithHost) import Distribution.Client.ProjectConfig import Distribution.Client.Utils @@ -585,8 +586,7 @@ planPackages pkgConfigDb pkgSpecifiers = resolveDependencies - platform - (compilerInfo comp) + (mkToolchainsWithHost platform comp) pkgConfigDb resolverParams >>= if onlyDeps then pruneInstallPlan pkgSpecifiers else return diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 73b9d02c0a5..16639d54270 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1278,7 +1278,7 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do planPackages :: Verbosity - -> Toolchain + -> Toolchains -> SolverSettings -> InstalledPackageIndex -> SourcePackageDb @@ -1288,7 +1288,7 @@ planPackages -> Progress String String SolverInstallPlan planPackages verbosity - Toolchain{toolchainCompiler = compiler, toolchainPlatform = platform} + toolchains SolverSettings{..} installedPkgIndex sourcePkgDb @@ -1296,8 +1296,7 @@ planPackages localPackages pkgStanzasEnable = resolveDependencies - platform - (compilerInfo compiler) + toolchains pkgConfigDB resolverParams where @@ -1340,7 +1339,9 @@ planPackages . removeLowerBounds solverSettingAllowOlder . removeUpperBounds solverSettingAllowNewer . addDefaultSetupDependencies - ( mkDefaultSetupDeps compiler platform + ( mkDefaultSetupDeps + (toolchainCompiler (buildToolchain toolchains)) + (toolchainPlatform (buildToolchain toolchains)) . PD.packageDescription . srcpkgDescription ) @@ -1474,8 +1475,9 @@ planPackages | otherwise = mkVersion [1, 20] where isGHC = compFlav `elem` [GHC, GHCJS] - compFlav = compilerFlavor compiler - compVer = compilerVersion compiler + -- FIXME: We assume HOST here. + compFlav = compilerFlavor (toolchainCompiler (hostToolchain toolchains)) + compVer = compilerVersion (toolchainCompiler (hostToolchain toolchains)) -- As we can't predict the future, we also place a global upper -- bound on the lib:Cabal version we know how to interact with: From 20068b0e7eb6c4d99099b87f3a3cc65a0a87746a Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 11:27:46 +0900 Subject: [PATCH 29/82] s/Host/Build/g --- .../src/Distribution/Client/Config.hs | 6 ++--- .../Client/ProjectConfig/Legacy.hs | 6 ++--- .../Client/ProjectConfig/Types.hs | 6 ++--- .../Distribution/Client/ProjectPlanning.hs | 24 +++++++++---------- .../src/Distribution/Client/Setup.hs | 18 +++++++------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 61384f495fb..d27fd14f9e6 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -573,9 +573,9 @@ instance Semigroup SavedConfig where combineMonoid savedConfigureExFlags configAllowOlder , configWriteGhcEnvironmentFilesPolicy = combine configWriteGhcEnvironmentFilesPolicy - , configHostHcFlavor = combine configHostHcFlavor - , configHostHcPath = combine configHostHcPath - , configHostHcPkg = combine configHostHcPkg + , configBuildHcFlavor = combine configBuildHcFlavor + , configBuildHcPath = combine configBuildHcPath + , configBuildHcPkg = combine configBuildHcPkg } where combine = combine' savedConfigureExFlags diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index b29b3cf47f9..9be3a34ae6e 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -741,9 +741,9 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags , configAllowNewer = projectConfigAllowNewer , configWriteGhcEnvironmentFilesPolicy = projectConfigWriteGhcEnvironmentFilesPolicy - , configHostHcFlavor = projectConfigHostHcFlavor - , configHostHcPath = projectConfigHostHcPath - , configHostHcPkg = projectConfigHostHcPkg + , configBuildHcFlavor = projectConfigBuildHcFlavor + , configBuildHcPath = projectConfigBuildHcPath + , configBuildHcPkg = projectConfigBuildHcPkg } = configExFlags InstallFlags diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 5657bb4b605..8a0a74ac9ed 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -192,9 +192,9 @@ data ProjectConfigShared = ProjectConfigShared , projectConfigHcFlavor :: Flag CompilerFlavor , projectConfigHcPath :: Flag FilePath , projectConfigHcPkg :: Flag FilePath - , projectConfigHostHcFlavor :: Flag CompilerFlavor - , projectConfigHostHcPath :: Flag FilePath - , projectConfigHostHcPkg :: Flag FilePath + , projectConfigBuildHcFlavor :: Flag CompilerFlavor + , projectConfigBuildHcPath :: Flag FilePath + , projectConfigBuildHcPkg :: Flag FilePath , projectConfigHaddockIndex :: Flag PathTemplate , -- Only makes sense for manual mode, not --local mode -- too much control! diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 16639d54270..fe0a6e7b03c 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -479,9 +479,9 @@ configureCompiler { projectConfigHcFlavor , projectConfigHcPath , projectConfigHcPkg - , projectConfigHostHcFlavor - , projectConfigHostHcPath - , projectConfigHostHcPkg + , projectConfigBuildHcFlavor + , projectConfigBuildHcPath + , projectConfigBuildHcPkg } , projectConfigLocalPackages = projectConfigLocalPackages@PackageConfig @@ -512,9 +512,9 @@ configureCompiler (compiler, platform, progdb) <- liftIO $ Cabal.configCompilerEx - hcFlavor - hcPath - hcPkg + buildHcFlavor + buildHcPath + buildHcPkg defdb verbosity @@ -531,9 +531,9 @@ configureCompiler (compiler, platform, progdb) <- liftIO $ Cabal.configCompilerEx - hostHcFlavor - hostHcPath - hostHcPkg + hcFlavor + hcPath + hcPkg defdb verbosity @@ -551,9 +551,9 @@ configureCompiler hcFlavor = flagToMaybe projectConfigHcFlavor hcPath = flagToMaybe projectConfigHcPath hcPkg = flagToMaybe projectConfigHcPkg - hostHcFlavor = flagToMaybe projectConfigHostHcFlavor <|> flagToMaybe projectConfigHcFlavor - hostHcPath = flagToMaybe projectConfigHostHcPath <|> flagToMaybe projectConfigHcPath - hostHcPkg = flagToMaybe projectConfigHostHcPkg <|> flagToMaybe projectConfigHcPkg + buildHcFlavor = flagToMaybe projectConfigBuildHcFlavor <|> flagToMaybe projectConfigHcFlavor + buildHcPath = flagToMaybe projectConfigBuildHcPath <|> flagToMaybe projectConfigHcPath + buildHcPkg = flagToMaybe projectConfigBuildHcPkg <|> flagToMaybe projectConfigHcPkg {- Note [Caching the result of configuring the compiler] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index da399b604a7..b10ee9dee49 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -920,9 +920,9 @@ data ConfigExFlags = ConfigExFlags , configAllowOlder :: Maybe AllowOlder , configWriteGhcEnvironmentFilesPolicy :: Flag WriteGhcEnvironmentFilesPolicy - , configHostHcFlavor :: Flag CompilerFlavor - , configHostHcPath :: Flag FilePath - , configHostHcPkg :: Flag FilePath + , configBuildHcFlavor :: Flag CompilerFlavor + , configBuildHcPath :: Flag FilePath + , configBuildHcPkg :: Flag FilePath } deriving (Eq, Show, Generic) @@ -1054,8 +1054,8 @@ configureExOptions _showOrParseArgs src = [] ["host-compiler"] "host compiler" - configHostHcFlavor - (\v flags -> flags{configHostHcFlavor = v}) + configBuildHcFlavor + (\v flags -> flags{configBuildHcFlavor = v}) ( choiceOpt [ (Flag GHC, ("g", ["ghc"]), "compile with GHC") , (Flag GHCJS, ([], ["ghcjs"]), "compile with GHCJS") @@ -1065,15 +1065,15 @@ configureExOptions _showOrParseArgs src = "W" ["with-host-compiler", "with-host-hc"] "give the path to the compiler for the host toolchain" - configHostHcPath - (\v flags -> flags{configHostHcPath = v}) + configBuildHcPath + (\v flags -> flags{configBuildHcPath = v}) (reqArgFlag "PATH") , option "" ["with-host-hc-pkg"] "give the path to the package tool for the host toolchain" - configHostHcPkg - (\v flags -> flags{configHostHcPkg = v}) + configBuildHcPkg + (\v flags -> flags{configBuildHcPkg = v}) (reqArgFlag "PATH") ] From 672e511b4fad8f1e60e784d1cddc7191a5a8cb47 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 11:27:57 +0900 Subject: [PATCH 30/82] Add WeightedPSQ.filterKey --- .../src/Distribution/Solver/Modular/WeightedPSQ.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/WeightedPSQ.hs b/cabal-install-solver/src/Distribution/Solver/Modular/WeightedPSQ.hs index 94def7be196..747017148d7 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/WeightedPSQ.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/WeightedPSQ.hs @@ -9,6 +9,7 @@ module Distribution.Solver.Modular.WeightedPSQ ( , weights , isZeroOrOne , filter + , filterKey , lookup , mapWithKey , mapWeightsWithKey @@ -34,6 +35,10 @@ newtype WeightedPSQ w k v = WeightedPSQ [(w, k, v)] filter :: (v -> Bool) -> WeightedPSQ k w v -> WeightedPSQ k w v filter p (WeightedPSQ xs) = WeightedPSQ (L.filter (p . triple_3) xs) +-- | /O(N)/. +filterKey :: (k -> Bool) -> WeightedPSQ w k v -> WeightedPSQ w k v +filterKey p (WeightedPSQ xs) = WeightedPSQ (L.filter (p . triple_2) xs) + -- | /O(1)/. Return @True@ if the @WeightedPSQ@ contains zero or one elements. isZeroOrOne :: WeightedPSQ w k v -> Bool isZeroOrOne (WeightedPSQ []) = True From 075b2a6a18507cd9bebfe4b13e367b1734b3ee08 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 11:28:47 +0900 Subject: [PATCH 31/82] More toolchain threading --- .../Solver/Modular/IndexConversion.hs | 31 +++++++++++-------- .../Distribution/Client/ProjectPlanning.hs | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index 44fa7b9ca8a..9ab501e904a 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -24,6 +24,7 @@ import Distribution.Types.MungedPackageName -- from Cabal import Distribution.PackageDescription -- from Cabal import Distribution.PackageDescription.Configuration import qualified Distribution.Simple.PackageIndex as SI +import Distribution.Simple.Compiler (compilerId) import Distribution.System import Distribution.Solver.Types.ComponentDeps @@ -61,15 +62,15 @@ convPIs :: Toolchains -> Map PN [LabeledPackageConstraint] -> Index convPIs toolchains constraints sip strfl solveExes iidx sidx = mkIndex $ - convIPI' sip iidx ++ convSPI' toolchains constraints strfl solveExes sidx + convIPI' toolchains sip iidx ++ convSPI' toolchains constraints strfl solveExes sidx -- | Convert a Cabal installed package index to the simpler, -- more uniform index format of the solver. -convIPI' :: ShadowPkgs -> SI.InstalledPackageIndex -> [(PN, I, PInfo)] -convIPI' (ShadowPkgs sip) idx = +convIPI' :: Toolchains -> ShadowPkgs -> SI.InstalledPackageIndex -> [(PN, I, PInfo)] +convIPI' toolchains (ShadowPkgs sip) idx = -- apply shadowing whenever there are multiple installed packages with -- the same version - [ maybeShadow (convIP idx pkg) + [ maybeShadow (convIP toolchains idx pkg) -- IMPORTANT to get internal libraries. See -- Note [Index conversion with internal libraries] | (_, pkgs) <- SI.allPackagesBySourcePackageIdAndLibName idx @@ -82,16 +83,20 @@ convIPI' (ShadowPkgs sip) idx = shadow x = x -- | Extract/recover the package ID from an installed package info, and convert it to a solver's I. -convId :: IPI.InstalledPackageInfo -> (PN, I) -convId ipi = (pn, I {- FIXME -} Host ver $ Inst $ IPI.installedUnitId ipi) +convId :: Toolchains -> IPI.InstalledPackageInfo -> (PN, I) +convId toolchains ipi = (pn, I stage ver $ Inst $ IPI.installedUnitId ipi) where MungedPackageId mpn ver = mungedId ipi -- HACK. See Note [Index conversion with internal libraries] pn = encodeCompatPackageName mpn + stage = case IPI.pkgCompiler ipi of + Just c | c == compilerId (toolchainCompiler (buildToolchain toolchains)) -> Build + Just c | c == compilerId (toolchainCompiler (hostToolchain toolchains)) -> Host + _ -> error "convId: unhandled compiler" -- | Convert a single installed package into the solver-specific format. -convIP :: SI.InstalledPackageIndex -> IPI.InstalledPackageInfo -> (PN, I, PInfo) -convIP idx ipi = - case traverse (convIPId (DependencyReason pn M.empty S.empty) comp idx) (IPI.depends ipi) of +convIP :: Toolchains -> SI.InstalledPackageIndex -> IPI.InstalledPackageInfo -> (PN, I, PInfo) +convIP toolchains idx ipi = + case traverse (convIPId toolchains (DependencyReason pn M.empty S.empty) comp idx) (IPI.depends ipi) of Left u -> (pn, i, PInfo [] M.empty M.empty (Just (Broken u))) Right fds -> (pn, i, PInfo fds components M.empty Nothing) where @@ -103,7 +108,7 @@ convIP idx ipi = , compIsBuildable = IsBuildable True } - (pn, i) = convId ipi + (pn, i) = convId toolchains ipi -- 'sourceLibName' is unreliable, but for now we only really use this for -- primary libs anyways @@ -143,11 +148,11 @@ convIP idx ipi = -- May return Nothing if the package can't be found in the index. That -- indicates that the original package having this dependency is broken -- and should be ignored. -convIPId :: DependencyReason PN -> Component -> SI.InstalledPackageIndex -> UnitId -> Either UnitId (FlaggedDep PN) -convIPId dr comp idx ipid = +convIPId :: Toolchains -> DependencyReason PN -> Component -> SI.InstalledPackageIndex -> UnitId -> Either UnitId (FlaggedDep PN) +convIPId toolchains dr comp idx ipid = case SI.lookupUnitId idx ipid of Nothing -> Left ipid - Just ipi -> let (pn, i) = convId ipi + Just ipi -> let (pn, i) = convId toolchains ipi name = ExposedLib LMainLibName -- TODO: Handle sub-libraries. in Right (D.Simple (LDep dr (Dep (PkgComponent pn name) (Fixed i))) comp) -- NB: something we pick up from the diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index fe0a6e7b03c..fd999487dd0 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -801,7 +801,7 @@ rebuildInstallPlan foldProgress logMsg (pure . Left) (pure . Right) $ planPackages verbosity - (hostToolchain toolchains) -- FIXME: this should be `toolchains`. + toolchains solverSettings (installedPackages <> hinstalledPkgIndex <> binstalledPkgIndex) sourcePkgDb From 9698a71c5cdea660032dd5dacce322ab3a512db9 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 14:42:44 +0900 Subject: [PATCH 32/82] Stop `Stage`, which now lives in D.S.T.Stage --- .../src/Distribution/Solver/Modular/Package.hs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs index 2b4a423adcc..3d2b3026c92 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs @@ -25,6 +25,7 @@ import Distribution.Pretty (prettyShow) import Distribution.Solver.Modular.Version import Distribution.Solver.Types.PackagePath +import Distribution.Solver.Types.Stage (Stage (..)) -- | A package name. type PN = PackageName @@ -50,10 +51,6 @@ type PId = UnitId data Loc = Inst PId | InRepo deriving (Eq, Ord, Show) --- | Stage. A stage in the build process. -data Stage = Build | Host - deriving (Eq, Ord, Show) - showStage :: Stage -> String showStage Build = "[build]" showStage Host = "[host ]" From 7b27c1a5b49a203dc2b177e73b0bab8e49d1e9a5 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 14:42:53 +0900 Subject: [PATCH 33/82] Add Ord Stage --- cabal-install-solver/src/Distribution/Solver/Types/Stage.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/Stage.hs b/cabal-install-solver/src/Distribution/Solver/Types/Stage.hs index 0365ef515c1..b2595a33089 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/Stage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/Stage.hs @@ -12,7 +12,7 @@ data Stage Build | -- | -- The system where the built artifacts will run Host - deriving (Eq, Read, Show, Generic, Typeable) + deriving (Eq, Ord, Read, Show, Generic, Typeable) instance Binary Stage instance Structured Stage From 0b47c0629697d5dd7a172f017c9a333f41aed4a2 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 14:44:26 +0900 Subject: [PATCH 34/82] Add stage to SolverPackage, and use stage from elabStage --- .../Solver/Modular/ConfiguredConversion.hs | 5 +- .../Solver/Types/SolverPackage.hs | 2 + .../src/Distribution/Client/Dependency.hs | 2 +- .../Client/ProjectBuilding/UnpackedPackage.hs | 50 +++++++++---------- .../Client/ProjectOrchestration.hs | 1 + .../Distribution/Client/ProjectPlanning.hs | 10 ++-- 6 files changed, 37 insertions(+), 33 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index 670850a9439..d391345d0eb 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -29,7 +29,7 @@ convCP :: SI.InstalledPackageIndex -> convCP iidx sidx (CP qpi fa es ds) = case qpi of -- Installed - (PI qpn (I {- FIXME -} Host _ (Inst pi))) -> + (PI qpn (I _stage _ (Inst pi))) -> PreExisting $ InstSolverPackage { instSolverQPN = qpn, @@ -38,11 +38,12 @@ convCP iidx sidx (CP qpi fa es ds) = instSolverPkgExeDeps = fmap snd ds' } -- "In repo" i.e. a source package - (PI qpn@(Q _path pn) (I {- FIXME -} Host v InRepo)) -> + (PI qpn@(Q _path pn) (I stage v InRepo)) -> let pi = PackageIdentifier pn v in Configured $ SolverPackage { solverPkgQPN = qpn, + solverPkgStage = stage, solverPkgSource = fromMaybe (error "convCP: lookupPackageId failed") $ CI.lookupPackageId sidx pi, solverPkgFlags = fa, solverPkgStanzas = es, diff --git a/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs index b3748254ebb..956bc5dff6e 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs @@ -13,6 +13,7 @@ import Distribution.Solver.Types.OptionalStanza import Distribution.Solver.Types.PackagePath (QPN) import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SourcePackage +import Distribution.Solver.Types.Stage (Stage (..)) -- | A 'SolverPackage' is a package specified by the dependency solver. -- It will get elaborated into a 'ConfiguredPackage' or even an @@ -23,6 +24,7 @@ import Distribution.Solver.Types.SourcePackage -- data SolverPackage loc = SolverPackage { solverPkgQPN :: QPN, + solverPkgStage :: Stage, solverPkgSource :: SourcePackage loc, solverPkgFlags :: FlagAssignment, solverPkgStanzas :: OptionalStanzaSet, diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 4b5422d145a..65f8a06ac97 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -1019,7 +1019,7 @@ configuredPackageProblems -> [PackageProblem] configuredPackageProblems toolchains - (SolverPackage _qpn pkg specifiedFlags stanzas specifiedDeps0 _specifiedExeDeps') = + (SolverPackage _qpn _stage pkg specifiedFlags stanzas specifiedDeps0 _specifiedExeDeps') = [ DuplicateFlag flag | flag <- PD.findDuplicateFlagAssignments specifiedFlags ] diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index 3908a1d12d1..3ca93d62fd5 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -80,7 +80,9 @@ import Distribution.Simple.Command (CommandUI) import Distribution.Simple.Compiler ( PackageDBStackCWD , coercePackageDBStack + , showCompilerId ) +import Distribution.Solver.Types.Stage import qualified Distribution.Simple.InstallDirs as InstallDirs import Distribution.Simple.LocalBuildInfo ( ComponentName (..) @@ -178,15 +180,7 @@ buildAndRegisterUnpackedPackage registerLock cacheLock pkgshared@ElaboratedSharedConfig - { pkgConfigToolchains = - Toolchains - { buildToolchain = - Toolchain - { toolchainCompiler = compiler - , toolchainProgramDb = progdb - } - } - } + { pkgConfigToolchains = toolchains } plan rpkg@(ReadyPackage pkg) srcdir @@ -260,6 +254,10 @@ buildAndRegisterUnpackedPackage return () where + (compiler, progdb) = case elabStage pkg of + Host -> (toolchainCompiler (hostToolchain toolchains), toolchainProgramDb (hostToolchain toolchains)) + Build -> (toolchainCompiler (buildToolchain toolchains), toolchainProgramDb (buildToolchain toolchains)) + uid = installedUnitId rpkg comp_par_strat = case maybe_semaphore of @@ -458,14 +456,7 @@ buildInplaceUnpackedPackage registerLock cacheLock pkgshared@ElaboratedSharedConfig - { pkgConfigToolchains = - Toolchains - { buildToolchain = - Toolchain - { toolchainPlatform = Platform _ os - } - } - } + { pkgConfigToolchains = toolchains } plan rpkg@(ReadyPackage pkg) buildStatus @@ -610,6 +601,10 @@ buildInplaceUnpackedPackage , buildResultLogFile = Nothing } where + Platform _ os = case elabStage pkg of + Host -> toolchainPlatform (hostToolchain toolchains) + Build -> toolchainPlatform (buildToolchain toolchains) + dparams = elabDistDirParams pkgshared pkg packageFileMonitor = newPackageFileMonitor pkgshared distDirLayout dparams @@ -671,15 +666,7 @@ buildAndInstallUnpackedPackage registerLock cacheLock pkgshared@ElaboratedSharedConfig - { pkgConfigToolchains = - Toolchains - { buildToolchain = - Toolchain - { toolchainCompiler = compiler - , toolchainPlatform = platform - } - } - } + { pkgConfigToolchains = toolchains } plan rpkg@(ReadyPackage pkg) srcdir @@ -826,6 +813,10 @@ buildAndInstallUnpackedPackage , buildResultLogFile = mlogFile } where + (compiler, platform) = case elabStage pkg of + Host -> (toolchainCompiler (hostToolchain toolchains), toolchainPlatform (hostToolchain toolchains)) + Build -> (toolchainCompiler (buildToolchain toolchains), toolchainPlatform (buildToolchain toolchains)) + uid = installedUnitId rpkg pkgid = packageId rpkg @@ -836,13 +827,20 @@ buildAndInstallUnpackedPackage prettyShow pkgid ++ " (all, legacy fallback: " ++ unwords (map whyNotPerComponent $ NE.toList pkgWhyNotPerComponent) + ++ ", " + ++ dispcompiler (elabStage pkg) ++ ")" -- Packages built per component ElabComponent comp -> prettyShow pkgid ++ " (" ++ maybe "custom" prettyShow (compComponentName comp) + ++ ", " + ++ dispcompiler (elabStage pkg) ++ ")" + dispcompiler :: Stage -> String + dispcompiler Host = showCompilerId (toolchainCompiler (hostToolchain toolchains)) + dispcompiler Build = showCompilerId (toolchainCompiler (buildToolchain toolchains)) noticeProgress :: ProgressPhase -> IO () noticeProgress phase = diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 5480e90537e..d7600d59ede 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -1002,6 +1002,7 @@ printPlan unwords $ filter (not . null) $ [ " -" + , show (elabStage elab) , if verbosity >= deafening then prettyShow (installedUnitId elab) else prettyShow (packageId elab) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index fd999487dd0..9adb49631d8 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1683,7 +1683,7 @@ elaborateInstallPlan :: (SolverId -> [ElaboratedPlanPackage]) -> SolverPackage UnresolvedPkgLoc -> LogProgress [ElaboratedConfiguredPackage] - elaborateSolverToComponents mapDep spkg@(SolverPackage qpn _ _ _ deps0 exe_deps0) = + elaborateSolverToComponents mapDep spkg@(SolverPackage _qpn _stage _ _ _ deps0 exe_deps0) = case mkComponentsGraph (elabEnabledSpec elab0) pd of Right g -> do let src_comps = componentsGraphToList g @@ -2072,7 +2072,8 @@ elaborateInstallPlan elaborateSolverToPackage pkgWhyNotPerComponent pkg@( SolverPackage - qpn + _qpn + _stage (SourcePackage pkgid _gpd _srcloc _descOverride) _flags _stanzas @@ -2176,7 +2177,8 @@ elaborateInstallPlan -> ElaboratedConfiguredPackage elaborateSolverToCommon pkg@( SolverPackage - qpn + _qpn + stage (SourcePackage pkgid gdesc srcloc descOverride) flags stanzas @@ -2200,7 +2202,7 @@ elaborateInstallPlan elabPkgSourceId = pkgid -- TODO: temporarily set everything to build on build - elabStage = Build + elabStage = stage elabCompiler = toolchainCompiler (toolchainFor elabStage toolchains) elabPlatform = toolchainPlatform (toolchainFor elabStage toolchains) elabProgramDb = toolchainProgramDb (toolchainFor elabStage toolchains) From 17102ac520162951cb82d22cfeedadcf3d5b3e5a Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 16:16:23 +0900 Subject: [PATCH 35/82] Make it work [somewhat] --- Cabal/src/Distribution/Simple/GHC.hs | 5 +- .../Distribution/Solver/Modular/Preference.hs | 15 ++++ .../src/Distribution/Solver/Modular/Solver.hs | 22 ++++++ .../Distribution/Client/ProjectBuilding.hs | 2 +- .../Client/ProjectOrchestration.hs | 7 +- .../Distribution/Client/ProjectPlanning.hs | 69 ++++++++++++++----- 6 files changed, 97 insertions(+), 23 deletions(-) diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 04280e5e0eb..8a7bad44b38 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -418,13 +418,10 @@ getInstalledPackages -> ProgramDb -> IO InstalledPackageIndex getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do - print $ ("getInstalledPackages", (compilerId comp), packagedbs) checkPackageDbEnvVar verbosity checkPackageDbStack verbosity comp packagedbs pkgss <- getInstalledPackages' verbosity mbWorkDir packagedbs progdb - let pkgss' = [ (packagedb, (\pkg -> pkg{ InstalledPackageInfo.pkgCompiler = Just (compilerId comp) - ,InstalledPackageInfo.installedUnitId = ((\x -> mkUnitId $ prettyShow (compilerId comp) ++ ":" ++ (unUnitId x)) . InstalledPackageInfo.installedUnitId) pkg - ,InstalledPackageInfo.depends = (map (\x -> mkUnitId $ prettyShow (compilerId comp) ++ ":" ++ (unUnitId x)) . InstalledPackageInfo.depends) pkg }) + let pkgss' = [ (packagedb, (\pkg -> pkg{ InstalledPackageInfo.pkgCompiler = Just (compilerId comp) }) <$> pkgs) | (packagedb, pkgs) <- pkgss ] diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs index c8bf9209528..9cd16d703db 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs @@ -15,6 +15,7 @@ module Distribution.Solver.Modular.Preference , onlyConstrained , sortGoals , pruneAfterFirstSuccess + , pruneHostFromSetup ) where import Prelude () @@ -347,6 +348,20 @@ avoidReinstalls p = go x go x = x +-- | Ensure that Setup (Build time) dependencies only have Build dependencies +-- available and that Host dependencies only have Host dependencies available. +pruneHostFromSetup :: EndoTreeTrav d c +pruneHostFromSetup = go + where + go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ (QualSetup _)) _) <- qpn = + PChoiceF qpn rdm gr (W.filterKey (not . isHost) cs) + go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ _) _) <- qpn = + PChoiceF qpn rdm gr (W.filterKey isHost cs) + go x = x + + isHost :: POption -> Bool + isHost (POption (I s _ _) _) = s == Host + -- | Require all packages to be mentioned in a constraint or as a goal. onlyConstrained :: (PN -> Bool) -> EndoTreeTrav d QGoalReason onlyConstrained p = go diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 58de7c9740d..fa6fae2e667 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -47,6 +47,8 @@ import qualified Distribution.Solver.Modular.PSQ as PSQ import Distribution.Simple.Setup (BooleanFlag(..)) import Distribution.Simple.Compiler (compilerInfo) +import qualified Distribution.Solver.Modular.WeightedPSQ as W + #ifdef DEBUG_TRACETREE import qualified Distribution.Solver.Modular.ConflictSet as CS import qualified Distribution.Solver.Modular.WeightedPSQ as W @@ -100,6 +102,7 @@ solve :: SolverConfig -- ^ solver parameters -> RetryLog Message SolverFailure (Assignment, RevDepMap) solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = explorePhase . + stageBuildDeps "B" . traceTree "cycles.json" id . detectCycles . traceTree "heuristics.json" id . @@ -112,6 +115,9 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = validationCata . traceTree "pruned.json" id . trav prunePhase . + -- stageBuildDeps "A'" . + trav P.pruneHostFromSetup . + stageBuildDeps "A" . traceTree "build.json" id $ buildPhase where @@ -148,6 +154,22 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = id) buildPhase = buildTree idx (independentGoals sc) (S.toList userGoals) + stageBuildDeps prefix = go + where go :: Tree d c -> Tree d c + go (PChoice qpn rdm gr cs) | (Q (PackagePath _ (QualSetup _)) _) <- qpn = + (PChoice qpn rdm gr (trace (prefix ++ show qpn ++ '\n':unlines (map (" - " ++) candidates)) (go <$> cs))) + where candidates = map show . filter (\(I _s _v l) -> l /= InRepo) . map (\(_w, (POption i _), _v) -> i) $ W.toList cs + go (PChoice qpn rdm gr cs) = + (PChoice qpn rdm gr (go <$> cs)) + go (FChoice qfn rdm gr t b d cs) = + FChoice qfn rdm gr t b d (go <$> cs) + go (SChoice qsn rdm gr t cs) = + SChoice qsn rdm gr t (go <$> cs) + go (GoalChoice rdm cs) = + GoalChoice rdm (go <$> cs) + go x@(Fail _ _) = x + go x@(Done _ _) = x + allExplicit = M.keysSet userConstraints `S.union` userGoals pkgIsExplicit :: PN -> Bool diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding.hs b/cabal-install/src/Distribution/Client/ProjectBuilding.hs index 93e9c93b918..a2aa390e8a7 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding.hs @@ -214,7 +214,7 @@ rebuildTargetsDryRun distDirLayout@DistDirLayout{..} shared = BuildInplaceOnly{} -> do -- TODO: [nice to have] use a proper file monitor rather -- than this dir exists test - exists <- doesDirectoryExist srcdir + exists <- doesDirectoryExist (traceShowId srcdir) if exists then dryRunLocalPkg pkg depsBuildStatus srcdir else return (BuildStatusUnpack tarball) diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index d7600d59ede..348eb031093 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -1001,8 +1001,9 @@ printPlan showPkgAndReason (ReadyPackage elab) = unwords $ filter (not . null) $ + -- FIXME: ideally we'd like to display the compiler in there as well. + -- we do have access to elabStage, but the toolchain isn't around. [ " -" - , show (elabStage elab) , if verbosity >= deafening then prettyShow (installedUnitId elab) else prettyShow (packageId elab) @@ -1122,7 +1123,9 @@ printPlan showBuildProfile = "Build profile: " ++ unwords - [ "-w " ++ (showCompilerId . toolchainCompiler . buildToolchain . pkgConfigToolchains) elaboratedShared + [ "-w " ++ (showCompilerId . toolchainCompiler . hostToolchain . pkgConfigToolchains) elaboratedShared + -- FIXME: this should only be shown if hostToolchain /= buildToolchain + , "-W " ++ (showCompilerId . toolchainCompiler . buildToolchain . pkgConfigToolchains) elaboratedShared , "-O" ++ ( case globalOptimization <> localOptimization of -- if local is not set, read global Setup.Flag NoOptimisation -> "0" diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 9adb49631d8..a4922769bc2 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -167,6 +167,7 @@ import Distribution.Solver.Types.Settings import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SolverPackage import Distribution.Solver.Types.SourcePackage +import Distribution.Solver.Types.Stage import Distribution.ModuleName import Distribution.Package @@ -219,9 +220,10 @@ import qualified Distribution.Simple.GHC as GHC import qualified Distribution.Simple.GHCJS as GHCJS import qualified Distribution.Simple.InstallDirs as InstallDirs import qualified Distribution.Simple.LocalBuildInfo as Cabal +import qualified Distribution.Simple.PackageIndex as PI import qualified Distribution.Simple.Setup as Cabal import qualified Distribution.Solver.Types.ComponentDeps as CD -import Distribution.Solver.Types.Stage +-- import Distribution.Solver.Types.Stage import Distribution.Solver.Types.Toolchain import qualified Distribution.Compat.Graph as Graph @@ -770,11 +772,38 @@ rebuildInstallPlan , hookHashes ) $ do + -- InstalledPackageIndex + -- type InstalledPackageIndex = PackageIndex IPI.InstalledPackageInfo + -- data PackageIndex a = PackageIndex + -- { -- The primary index. Each InstalledPackageInfo record is uniquely identified + -- -- by its UnitId. + -- -- + -- unitIdIndex :: !(Map UnitId a) + -- , -- This auxiliary index maps package names (case-sensitively) to all the + -- -- versions and instances of that package. This allows us to find all + -- -- versions satisfying a dependency. + -- -- + -- -- It is a three-level index. The first level is the package name, + -- -- the second is the package version and the final level is instances + -- -- of the same package version. These are unique by UnitId + -- -- and are kept in preference order. + -- -- + -- -- FIXME: Clarify what "preference order" means. Check that this invariant is + -- -- preserved. See #1463 for discussion. + -- packageIdIndex :: !(Map (PackageName, LibraryName) (Map Version [a])) + -- } + -- deriving (Eq, Generic, Show, Read) + -- + -- can probably use fromList $ Map.elems $ on it. hinstalledPkgIndex <- getInstalledPackages verbosity (hostToolchain toolchains) corePackageDbs + -- this is an aweful hack, however `getInstalledPackages` is + -- terribly invovled everywhere so we'll have to do with this + -- for now. FIXME! + -- let hinstalledPkgIndex' = PI.fromList $ PI.allPackages hinstalledPkgIndex binstalledPkgIndex <- getInstalledPackages verbosity @@ -797,6 +826,8 @@ rebuildInstallPlan liftIO $ do notice verbosity "Resolving dependencies..." + liftIO $ print ("build compiler", compilerId $ toolchainCompiler $ buildToolchain toolchains) + liftIO $ print ("host compiler", compilerId $ toolchainCompiler $ hostToolchain toolchains) planOrError <- foldProgress logMsg (pure . Left) (pure . Right) $ planPackages @@ -2275,8 +2306,8 @@ elaborateInstallPlan then BuildInplaceOnly OnDisk else BuildAndInstall elabPackageDbs = projectConfigPackageDBs sharedPackageConfig - elabBuildPackageDBStack = buildAndRegisterDbs - elabRegisterPackageDBStack = buildAndRegisterDbs + elabBuildPackageDBStack = buildAndRegisterDbs stage + elabRegisterPackageDBStack = buildAndRegisterDbs stage elabSetupScriptStyle = packageSetupScriptStyle elabPkgDescription elabSetupScriptCliVersion = @@ -2285,19 +2316,25 @@ elaborateInstallPlan elabPkgDescription libDepGraph deps0 - elabSetupPackageDBStack = buildAndRegisterDbs - inplacePackageDbs = corePackageDbs ++ [distPackageDB (compilerId elabCompiler)] + -- This code is ... a bit nuts. We need to parameterise the DB stack + -- over the stage. (which is also assigned to elabStage). And now + -- we have inplace, core, ... other DBStacks, for the Setup however, + -- we _must_ force it to use the Build stage stack. As that's where + -- the setup dependencies will be found. + elabSetupPackageDBStack = buildAndRegisterDbs Build + + inplacePackageDbs stage = corePackageDbs stage ++ [distPackageDB (compilerId (toolchainCompiler (toolchainFor stage toolchains)))] - corePackageDbs = storePackageDBStack elabCompiler (projectConfigPackageDBs sharedPackageConfig) + corePackageDbs stage = storePackageDBStack (toolchainCompiler (toolchainFor stage toolchains)) (projectConfigPackageDBs sharedPackageConfig) - elabInplaceBuildPackageDBStack = inplacePackageDbs - elabInplaceRegisterPackageDBStack = inplacePackageDbs - elabInplaceSetupPackageDBStack = inplacePackageDbs + elabInplaceBuildPackageDBStack = inplacePackageDbs stage + elabInplaceRegisterPackageDBStack = inplacePackageDbs stage + elabInplaceSetupPackageDBStack = inplacePackageDbs stage - buildAndRegisterDbs - | shouldBuildInplaceOnly pkg = inplacePackageDbs - | otherwise = corePackageDbs + buildAndRegisterDbs stage + | shouldBuildInplaceOnly pkg = inplacePackageDbs stage + | otherwise = corePackageDbs stage elabPkgDescriptionOverride = descOverride @@ -3877,10 +3914,10 @@ setupHsScriptOptions -- - if we commit to a Cabal version, the logic in Nothing else Just elabSetupScriptCliVersion - , -- for Setup.hs, we _always_ want to use the HOST toolchain. - useCompiler = Just (toolchainCompiler $ hostToolchain $ pkgConfigToolchains) - , usePlatform = Just (toolchainPlatform $ hostToolchain $ pkgConfigToolchains) - , useProgramDb = toolchainProgramDb $ hostToolchain $ pkgConfigToolchains + , -- for Setup.hs, we _always_ want to use the BUILD toolchain. + useCompiler = Just (toolchainCompiler $ buildToolchain $ pkgConfigToolchains) + , usePlatform = Just (toolchainPlatform $ buildToolchain $ pkgConfigToolchains) + , useProgramDb = toolchainProgramDb $ buildToolchain $ pkgConfigToolchains , usePackageDB = elabSetupPackageDBStack , usePackageIndex = Nothing , useDependencies = From 1677003e122a5495da8fb45b95e4485d867dbb1d Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 17:57:42 +0900 Subject: [PATCH 36/82] Make sure we are aware of BOTH build and host compilers. --- .../src/Distribution/Client/ProjectPlanning.hs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index a4922769bc2..aac4708e6b3 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -826,8 +826,6 @@ rebuildInstallPlan liftIO $ do notice verbosity "Resolving dependencies..." - liftIO $ print ("build compiler", compilerId $ toolchainCompiler $ buildToolchain toolchains) - liftIO $ print ("host compiler", compilerId $ toolchainCompiler $ hostToolchain toolchains) planOrError <- foldProgress logMsg (pure . Left) (pure . Right) $ planPackages @@ -991,10 +989,11 @@ rebuildInstallPlan -> Rebuild ElaboratedInstallPlan phaseImprovePlan elaboratedPlan elaboratedShared = do liftIO $ debug verbosity "Improving the install plan..." - storePkgIdSet <- getStoreEntries cabalStoreDirLayout compiler + hstorePkgIdSet <- getStoreEntries cabalStoreDirLayout hcompiler + bstorePkgIdSet <- getStoreEntries cabalStoreDirLayout bcompiler let improvedPlan = improveInstallPlanWithInstalledPackages - storePkgIdSet + (hstorePkgIdSet `Set.union` bstorePkgIdSet) elaboratedPlan liftIO $ debugNoWrap verbosity (showElaboratedInstallPlan improvedPlan) -- TODO: [nice to have] having checked which packages from the store @@ -1003,7 +1002,8 @@ rebuildInstallPlan -- matches up as expected, e.g. no dangling deps, files deleted. return improvedPlan where - compiler = toolchainCompiler (hostToolchain (pkgConfigToolchains elaboratedShared)) + hcompiler = toolchainCompiler (hostToolchain (pkgConfigToolchains elaboratedShared)) + bcompiler = toolchainCompiler (buildToolchain (pkgConfigToolchains elaboratedShared)) -- | If a 'PackageSpecifier' refers to a single package, return Just that -- package. From d449b914b58e4c8c06729d3c86a97e2de08ae950 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 17:58:39 +0900 Subject: [PATCH 37/82] Drop debugging --- cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs | 3 --- 1 file changed, 3 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index fa6fae2e667..887c1fce563 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -102,7 +102,6 @@ solve :: SolverConfig -- ^ solver parameters -> RetryLog Message SolverFailure (Assignment, RevDepMap) solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = explorePhase . - stageBuildDeps "B" . traceTree "cycles.json" id . detectCycles . traceTree "heuristics.json" id . @@ -115,9 +114,7 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = validationCata . traceTree "pruned.json" id . trav prunePhase . - -- stageBuildDeps "A'" . trav P.pruneHostFromSetup . - stageBuildDeps "A" . traceTree "build.json" id $ buildPhase where From a2144ecc7431bec60ef652a27d0d11fa5d35a915 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 18:00:39 +0900 Subject: [PATCH 38/82] Drop more debugging --- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 3 --- 1 file changed, 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index aac4708e6b3..3b790a56d7e 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -664,9 +664,6 @@ rebuildInstallPlan $ do toolchains <- phaseConfigureToolchain projectConfig - liftIO $ print ("build compiler", compilerId $ toolchainCompiler $ buildToolchain toolchains) - liftIO $ print ("host compiler", compilerId $ toolchainCompiler $ hostToolchain toolchains) - -- _ <- phaseConfigurePrograms projectConfig compilerEtc (solverPlan, pkgConfigDB, totalIndexState, activeRepos) <- phaseRunSolver From d183c9b10eb049571d3be2897f74ca3e3531f6f1 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 18 Mar 2025 20:59:17 +0900 Subject: [PATCH 39/82] Fix build-depends also. --- .../src/Distribution/Solver/Modular/Preference.hs | 5 +++++ .../src/Distribution/Solver/Modular/Solver.hs | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs index 9cd16d703db..9adaa8cf410 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs @@ -353,8 +353,13 @@ avoidReinstalls p = go pruneHostFromSetup :: EndoTreeTrav d c pruneHostFromSetup = go where + -- for Setup(.hs) and build-depends, we want to force Build packages. go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ (QualSetup _)) _) <- qpn = PChoiceF qpn rdm gr (W.filterKey (not . isHost) cs) + -- QualExe are build-depends. Structure is QualExe (comp) (build-depend). + go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ (QualExe _ _)) _) <- qpn = + PChoiceF qpn rdm gr (W.filterKey (not . isHost) cs) + -- everything else use Host packages. go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ _) _) <- qpn = PChoiceF qpn rdm gr (W.filterKey isHost cs) go x = x diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 887c1fce563..2efd0610dcd 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -115,6 +115,7 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = traceTree "pruned.json" id . trav prunePhase . trav P.pruneHostFromSetup . + -- stageBuildDeps "build: " . traceTree "build.json" id $ buildPhase where @@ -153,9 +154,15 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = stageBuildDeps prefix = go where go :: Tree d c -> Tree d c + -- For Setup we must use the build compiler, as the host compiler + -- may not be able to produce code that runs on the build machine. go (PChoice qpn rdm gr cs) | (Q (PackagePath _ (QualSetup _)) _) <- qpn = (PChoice qpn rdm gr (trace (prefix ++ show qpn ++ '\n':unlines (map (" - " ++) candidates)) (go <$> cs))) where candidates = map show . filter (\(I _s _v l) -> l /= InRepo) . map (\(_w, (POption i _), _v) -> i) $ W.toList cs + -- Same for build-depends. These show up as QualExe (component) (build-depends). + go (PChoice qpn rdm gr cs) | (Q (PackagePath _ (QualExe _ _)) _) <- qpn = + (PChoice qpn rdm gr (trace (prefix ++ show qpn ++ '\n':unlines (map (" - " ++) candidates)) (go <$> cs))) + where candidates = map show . filter (\(I _s _v l) -> l /= InRepo) . map (\(_w, (POption i _), _v) -> i) $ W.toList cs go (PChoice qpn rdm gr cs) = (PChoice qpn rdm gr (go <$> cs)) go (FChoice qfn rdm gr t b d cs) = From 184755d76ffc133174ba83b1ca6467ca9c3260a4 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Wed, 19 Mar 2025 09:38:19 +0900 Subject: [PATCH 40/82] it's build-compiler, not host-compiler for -W --- cabal-install/src/Distribution/Client/Setup.hs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index b10ee9dee49..a429836dc90 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -1052,8 +1052,8 @@ configureExOptions _showOrParseArgs src = ) , option [] - ["host-compiler"] - "host compiler" + ["build-compiler"] + "build compiler" configBuildHcFlavor (\v flags -> flags{configBuildHcFlavor = v}) ( choiceOpt @@ -1063,15 +1063,15 @@ configureExOptions _showOrParseArgs src = ) , option "W" - ["with-host-compiler", "with-host-hc"] - "give the path to the compiler for the host toolchain" + ["with-build-compiler", "with-build-hc"] + "give the path to the compiler for the build toolchain" configBuildHcPath (\v flags -> flags{configBuildHcPath = v}) (reqArgFlag "PATH") , option "" - ["with-host-hc-pkg"] - "give the path to the package tool for the host toolchain" + ["with-build-hc-pkg"] + "give the path to the package tool for the build toolchain" configBuildHcPkg (\v flags -> flags{configBuildHcPkg = v}) (reqArgFlag "PATH") From 57fca266863a7980878a856b1da953df0cb6a021 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Wed, 19 Mar 2025 10:27:17 +0900 Subject: [PATCH 41/82] Don't prune if buildIsHost --- .../src/Distribution/Solver/Modular/Solver.hs | 4 ++-- .../src/Distribution/Solver/Types/Toolchain.hs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 2efd0610dcd..8604fa35c47 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -24,7 +24,7 @@ import Distribution.Solver.Types.PackagePreferences import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb) import Distribution.Solver.Types.LabeledPackageConstraint import Distribution.Solver.Types.Settings -import Distribution.Solver.Types.Toolchain ( Toolchains(..), Toolchain(..) ) +import Distribution.Solver.Types.Toolchain ( Toolchains(..), Toolchain(..), buildIsHost ) import Distribution.Solver.Types.Variable import Distribution.Solver.Modular.Assignment @@ -114,7 +114,7 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = validationCata . traceTree "pruned.json" id . trav prunePhase . - trav P.pruneHostFromSetup . + (if buildIsHost toolchains then id else trav P.pruneHostFromSetup) . -- stageBuildDeps "build: " . traceTree "build.json" id $ buildPhase diff --git a/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs index 3126a4abfbd..d7b9312520b 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs @@ -1,10 +1,12 @@ {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE NamedFieldPuns #-} module Distribution.Solver.Types.Toolchain ( Toolchain (..) , Toolchains (..) , toolchainFor , mkToolchainsWithHost + , buildIsHost ) where import Distribution.Compat.Prelude @@ -55,3 +57,7 @@ mkToolchainsWithHost platform compiler = { buildToolchain = Toolchain platform compiler (error "build program db missing") , hostToolchain = Toolchain platform compiler (error "host program db missing") } + +buildIsHost :: Toolchains -> Bool +buildIsHost Toolchains {buildToolchain, hostToolchain} = + buildToolchain == hostToolchain From 8b3bd3412188adc99d799ad8d3212933ed0edb5d Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Wed, 19 Mar 2025 12:47:47 +0900 Subject: [PATCH 42/82] prune inRepo from build deps --- .../src/Distribution/Solver/Modular/Preference.hs | 12 +++++++++--- .../src/Distribution/Solver/Modular/Solver.hs | 10 +++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs index 9adaa8cf410..6976bbccff2 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs @@ -350,22 +350,28 @@ avoidReinstalls p = go -- | Ensure that Setup (Build time) dependencies only have Build dependencies -- available and that Host dependencies only have Host dependencies available. +-- We also do not want to use InRepo dependencies for setup/build-depends. This +-- easily leads to cycles. pruneHostFromSetup :: EndoTreeTrav d c pruneHostFromSetup = go where -- for Setup(.hs) and build-depends, we want to force Build packages. go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ (QualSetup _)) _) <- qpn = - PChoiceF qpn rdm gr (W.filterKey (not . isHost) cs) + PChoiceF qpn rdm gr (W.filterKey (not . isHostOrRepo) cs) -- QualExe are build-depends. Structure is QualExe (comp) (build-depend). go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ (QualExe _ _)) _) <- qpn = - PChoiceF qpn rdm gr (W.filterKey (not . isHost) cs) + PChoiceF qpn rdm gr (W.filterKey (not . isHostOrRepo) cs) -- everything else use Host packages. go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ _) _) <- qpn = PChoiceF qpn rdm gr (W.filterKey isHost cs) go x = x isHost :: POption -> Bool - isHost (POption (I s _ _) _) = s == Host + isHost (POption (I s _v _l) _) = s == Host + isInRepo :: POption -> Bool + isInRepo (POption (I _s _v l) _) = l == InRepo + isHostOrRepo :: POption -> Bool + isHostOrRepo (POption (I s _v l) _) = s == Host || l == InRepo -- | Require all packages to be mentioned in a constraint or as a goal. onlyConstrained :: (PN -> Bool) -> EndoTreeTrav d QGoalReason diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 8604fa35c47..91d19badc25 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -114,8 +114,8 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = validationCata . traceTree "pruned.json" id . trav prunePhase . + stageBuildDeps "build: " . (if buildIsHost toolchains then id else trav P.pruneHostFromSetup) . - -- stageBuildDeps "build: " . traceTree "build.json" id $ buildPhase where @@ -158,11 +158,15 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = -- may not be able to produce code that runs on the build machine. go (PChoice qpn rdm gr cs) | (Q (PackagePath _ (QualSetup _)) _) <- qpn = (PChoice qpn rdm gr (trace (prefix ++ show qpn ++ '\n':unlines (map (" - " ++) candidates)) (go <$> cs))) - where candidates = map show . filter (\(I _s _v l) -> l /= InRepo) . map (\(_w, (POption i _), _v) -> i) $ W.toList cs + where candidates = map show + -- . filter (\(I _s _v l) -> l /= InRepo) + . map (\(_w, (POption i _), _v) -> i) $ W.toList cs -- Same for build-depends. These show up as QualExe (component) (build-depends). go (PChoice qpn rdm gr cs) | (Q (PackagePath _ (QualExe _ _)) _) <- qpn = (PChoice qpn rdm gr (trace (prefix ++ show qpn ++ '\n':unlines (map (" - " ++) candidates)) (go <$> cs))) - where candidates = map show . filter (\(I _s _v l) -> l /= InRepo) . map (\(_w, (POption i _), _v) -> i) $ W.toList cs + where candidates = map show + -- . filter (\(I _s _v l) -> l /= InRepo) + . map (\(_w, (POption i _), _v) -> i) $ W.toList cs go (PChoice qpn rdm gr cs) = (PChoice qpn rdm gr (go <$> cs)) go (FChoice qfn rdm gr t b d cs) = From 1c536a3d9f8c35b155470b79f23ac3e74b3cbb14 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 20 Mar 2025 15:30:59 +0900 Subject: [PATCH 43/82] Add `--build-package-db`. --- .../src/Distribution/Client/Config.hs | 1 + .../Client/ProjectConfig/Legacy.hs | 2 ++ .../Client/ProjectConfig/Types.hs | 1 + .../Distribution/Client/ProjectPlanning.hs | 19 +++++++++++++------ .../src/Distribution/Client/Setup.hs | 14 ++++++++++++++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index d27fd14f9e6..71888779578 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -576,6 +576,7 @@ instance Semigroup SavedConfig where , configBuildHcFlavor = combine configBuildHcFlavor , configBuildHcPath = combine configBuildHcPath , configBuildHcPkg = combine configBuildHcPkg + , configBuildPackageDBs = lastNonEmpty configBuildPackageDBs } where combine = combine' savedConfigureExFlags diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 9be3a34ae6e..7c357c70a8a 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -705,6 +705,7 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags ProjectConfigShared{..} where projectConfigPackageDBs = (fmap . fmap) (interpretPackageDB Nothing) projectConfigPackageDBs_ + projectConfigBuildPackageDBs = (fmap . fmap) (interpretPackageDB Nothing) projectConfigBuildPackageDBs_ projectConfigHookHashes = mempty -- :: Map FilePath HookAccept projectConfigDistDir = fmap getSymbolicPath projectConfigAbsoluteDistDir @@ -744,6 +745,7 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags , configBuildHcFlavor = projectConfigBuildHcFlavor , configBuildHcPath = projectConfigBuildHcPath , configBuildHcPkg = projectConfigBuildHcPkg + , configBuildPackageDBs = projectConfigBuildPackageDBs_ } = configExFlags InstallFlags diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 8a0a74ac9ed..0ae0bcd6d6a 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -202,6 +202,7 @@ data ProjectConfigShared = ProjectConfigShared projectConfigInstallDirs :: InstallDirs (Flag PathTemplate) , projectConfigPackageDBs :: [Maybe PackageDBCWD] + , projectConfigBuildPackageDBs :: [Maybe PackageDBCWD] , -- configuration used both by the solver and other phases projectConfigRemoteRepos :: NubList RemoteRepo -- ^ Available Hackage servers. diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 3b790a56d7e..081e1bf3e49 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -796,7 +796,7 @@ rebuildInstallPlan getInstalledPackages verbosity (hostToolchain toolchains) - corePackageDbs + (corePackageDbs Host) -- this is an aweful hack, however `getInstalledPackages` is -- terribly invovled everywhere so we'll have to do with this -- for now. FIXME! @@ -805,7 +805,7 @@ rebuildInstallPlan getInstalledPackages verbosity (buildToolchain toolchains) - corePackageDbs + (corePackageDbs Build) (sourcePkgDb, tis, ar) <- getSourcePackages @@ -840,9 +840,13 @@ rebuildInstallPlan dieWithException verbosity $ PhaseRunSolverErr msg Right plan -> return (plan, pkgConfigDB, tis, ar) where - corePackageDbs :: PackageDBStackCWD - corePackageDbs = - Cabal.interpretPackageDbFlags False (projectConfigPackageDBs projectConfigShared) + corePackageDbs :: Stage -> PackageDBStackCWD + corePackageDbs stage = + Cabal.interpretPackageDbFlags False (packageDBs stage) + + packageDBs Host = projectConfigPackageDBs projectConfigShared + packageDBs Build = projectConfigBuildPackageDBs projectConfigShared + withRepoCtx :: (RepoContext -> IO a) -> IO a withRepoCtx = @@ -2323,7 +2327,10 @@ elaborateInstallPlan inplacePackageDbs stage = corePackageDbs stage ++ [distPackageDB (compilerId (toolchainCompiler (toolchainFor stage toolchains)))] - corePackageDbs stage = storePackageDBStack (toolchainCompiler (toolchainFor stage toolchains)) (projectConfigPackageDBs sharedPackageConfig) + corePackageDbs stage = storePackageDBStack (toolchainCompiler (toolchainFor stage toolchains)) (packageDBs stage) + + packageDBs Host = projectConfigPackageDBs sharedPackageConfig + packageDBs Build = projectConfigBuildPackageDBs sharedPackageConfig elabInplaceBuildPackageDBStack = inplacePackageDbs stage elabInplaceRegisterPackageDBStack = inplacePackageDbs stage diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index a429836dc90..05e94256e64 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -923,6 +923,7 @@ data ConfigExFlags = ConfigExFlags , configBuildHcFlavor :: Flag CompilerFlavor , configBuildHcPath :: Flag FilePath , configBuildHcPkg :: Flag FilePath + , configBuildPackageDBs :: [Maybe PackageDB] } deriving (Eq, Show, Generic) @@ -1075,6 +1076,19 @@ configureExOptions _showOrParseArgs src = configBuildHcPkg (\v flags -> flags{configBuildHcPkg = v}) (reqArgFlag "PATH") + , option + "" + ["build-package-db"] + ( "Append the given package database to the list of package" + ++ " databases used (to satisfy dependencies and register into)." + ++ " May be a specific file, 'global' or 'user'. The initial list" + ++ " is ['global'], ['global', 'user'], or ['global', $sandbox]," + ++ " depending on context. Use 'clear' to reset the list to empty." + ++ " See the user guide for details." + ) + configBuildPackageDBs + (\v flags -> flags{configBuildPackageDBs = v}) + (reqArg' "DB" readPackageDbList showPackageDbList) ] writeGhcEnvironmentFilesPolicyParser :: ReadE (Flag WriteGhcEnvironmentFilesPolicy) From 675f0865ec9afae9590a97b84fa8c1d85bafff02 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 20 Mar 2025 15:31:43 +0900 Subject: [PATCH 44/82] Fixup: Really only filter HOST, not InRepo. --- .../src/Distribution/Solver/Modular/Preference.hs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs index 6976bbccff2..e17287324f5 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs @@ -357,10 +357,10 @@ pruneHostFromSetup = go where -- for Setup(.hs) and build-depends, we want to force Build packages. go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ (QualSetup _)) _) <- qpn = - PChoiceF qpn rdm gr (W.filterKey (not . isHostOrRepo) cs) + PChoiceF qpn rdm gr (W.filterKey (not . isHost) cs) -- QualExe are build-depends. Structure is QualExe (comp) (build-depend). go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ (QualExe _ _)) _) <- qpn = - PChoiceF qpn rdm gr (W.filterKey (not . isHostOrRepo) cs) + PChoiceF qpn rdm gr (W.filterKey (not . isHost) cs) -- everything else use Host packages. go (PChoiceF qpn rdm gr cs) | (Q (PackagePath _ _) _) <- qpn = PChoiceF qpn rdm gr (W.filterKey isHost cs) @@ -368,10 +368,6 @@ pruneHostFromSetup = go isHost :: POption -> Bool isHost (POption (I s _v _l) _) = s == Host - isInRepo :: POption -> Bool - isInRepo (POption (I _s _v l) _) = l == InRepo - isHostOrRepo :: POption -> Bool - isHostOrRepo (POption (I s _v l) _) = s == Host || l == InRepo -- | Require all packages to be mentioned in a constraint or as a goal. onlyConstrained :: (PN -> Bool) -> EndoTreeTrav d QGoalReason From 6bfb13b92317e899d36c509d6e972faaabf92b77 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 20 Mar 2025 20:24:10 +0900 Subject: [PATCH 45/82] Fixup host/build package-db --- .../src/Distribution/Client/ProjectPlanning.hs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 081e1bf3e49..389685e379c 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -845,7 +845,9 @@ rebuildInstallPlan Cabal.interpretPackageDbFlags False (packageDBs stage) packageDBs Host = projectConfigPackageDBs projectConfigShared - packageDBs Build = projectConfigBuildPackageDBs projectConfigShared + packageDBs Build + | buildIsHost toolchains, null (projectConfigBuildPackageDBs projectConfigShared) = projectConfigPackageDBs projectConfigShared + | otherwise = projectConfigBuildPackageDBs projectConfigShared withRepoCtx :: (RepoContext -> IO a) -> IO a @@ -2330,7 +2332,9 @@ elaborateInstallPlan corePackageDbs stage = storePackageDBStack (toolchainCompiler (toolchainFor stage toolchains)) (packageDBs stage) packageDBs Host = projectConfigPackageDBs sharedPackageConfig - packageDBs Build = projectConfigBuildPackageDBs sharedPackageConfig + packageDBs Build + | buildIsHost toolchains, null (projectConfigBuildPackageDBs sharedPackageConfig) = projectConfigPackageDBs sharedPackageConfig + | otherwise = projectConfigBuildPackageDBs sharedPackageConfig elabInplaceBuildPackageDBStack = inplacePackageDbs stage elabInplaceRegisterPackageDBStack = inplacePackageDbs stage @@ -4030,7 +4034,7 @@ computeInstallDirs storeDirLayout defaultInstallDirs elaboratedShared elab -- use special simplified install dirs storePackageInstallDirs' storeDirLayout - (toolchainCompiler $ buildToolchain $ pkgConfigToolchains elaboratedShared) + (toolchainCompiler $ hostToolchain $ pkgConfigToolchains elaboratedShared) (elabUnitId elab) -- TODO: [code cleanup] perhaps reorder this code From 6ca784e4beddd567f2de77d547edcd4337a68f96 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 20 Mar 2025 20:24:30 +0900 Subject: [PATCH 46/82] Cleaup --- .../src/Distribution/Solver/Modular/Solver.hs | 3 ++- .../src/Distribution/Client/ProjectPlanning.hs | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 91d19badc25..89c7daa0223 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -114,8 +114,9 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = validationCata . traceTree "pruned.json" id . trav prunePhase . - stageBuildDeps "build: " . + -- stageBuildDeps "post-prune: " . (if buildIsHost toolchains then id else trav P.pruneHostFromSetup) . + -- stageBuildDeps "build: " . traceTree "build.json" id $ buildPhase where diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 389685e379c..fc3cfa90280 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -181,7 +181,7 @@ import Distribution.Simple.LocalBuildInfo ) import Distribution.Simple.BuildWay -import Distribution.Simple.PackageIndex (InstalledPackageIndex) +import Distribution.Simple.PackageIndex (InstalledPackageIndex, allPackages) import Distribution.Simple.Program import Distribution.Simple.Program.Db import Distribution.Simple.Program.Find @@ -805,7 +805,9 @@ rebuildInstallPlan getInstalledPackages verbosity (buildToolchain toolchains) - (corePackageDbs Build) + -- FIXME: HACK + -- if host and build compiler are the same, we want to get -package-db in here. + (corePackageDbs $ if buildIsHost toolchains then Host else Build) (sourcePkgDb, tis, ar) <- getSourcePackages @@ -823,6 +825,12 @@ rebuildInstallPlan liftIO $ do notice verbosity "Resolving dependencies..." + -- putStrLn "== installedPackages" + -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages installedPackages + -- putStrLn "== binstalledPackages" + -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages binstalledPkgIndex + -- putStrLn "== hinstalledPackages" + -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages hinstalledPkgIndex planOrError <- foldProgress logMsg (pure . Left) (pure . Right) $ planPackages From 418e8c54cc22f8aefa0adce283c579cd8db13f2d Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sat, 22 Mar 2025 20:13:19 +0900 Subject: [PATCH 47/82] Fix assert --- .../Distribution/Client/ProjectBuilding/UnpackedPackage.hs | 5 ++++- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 1 + .../src/Distribution/Client/ProjectPlanning/Types.hs | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index 3ca93d62fd5..1a1e286596b 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -761,7 +761,10 @@ buildAndInstallUnpackedPackage | otherwise = do assert ( elabRegisterPackageDBStack pkg - == storePackageDBStack compiler (elabPackageDbs pkg) + == storePackageDBStack compiler (case elabStage pkg of + Host -> elabPackageDbs pkg + Build -> elabBuildPackageDbs pkg + ) ) (return ()) _ <- diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index fc3cfa90280..bb90d600c50 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -2317,6 +2317,7 @@ elaborateInstallPlan then BuildInplaceOnly OnDisk else BuildAndInstall elabPackageDbs = projectConfigPackageDBs sharedPackageConfig + elabBuildPackageDbs = projectConfigBuildPackageDBs sharedPackageConfig elabBuildPackageDBStack = buildAndRegisterDbs stage elabRegisterPackageDBStack = buildAndRegisterDbs stage diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 16b791105ef..a4f22a25f2b 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -253,7 +253,7 @@ data ElaboratedConfiguredPackage = ElaboratedConfiguredPackage -- they explicitly disabled. , elabStage :: Stage - + -- TODO: The 'Bool' here should be refined into an ADT with three -- cases: NotRequested, ExplicitlyRequested and -- ImplicitlyRequested. A stanza is explicitly requested if @@ -268,6 +268,7 @@ data ElaboratedConfiguredPackage = ElaboratedConfiguredPackage -- just happen not to have any tests. (But perhaps we should -- warn if ALL local packages don't have any tests.) , elabPackageDbs :: [Maybe PackageDBCWD] + , elabBuildPackageDbs :: [Maybe PackageDBCWD] , elabSetupPackageDBStack :: PackageDBStackCWD , elabBuildPackageDBStack :: PackageDBStackCWD , elabRegisterPackageDBStack :: PackageDBStackCWD From bb65785bd7dc018bc3779ba250c1c564cb9d773a Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 08:21:29 +0900 Subject: [PATCH 48/82] fixup! Fixup host/build package-db --- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index bb90d600c50..a55f6bee2da 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -4028,7 +4028,7 @@ computeInstallDirs storeDirLayout defaultInstallDirs elaboratedShared elab ( InstallDirs.absoluteInstallDirs (elabPkgSourceId elab) (elabUnitId elab) - (compilerInfo (toolchainCompiler $ buildToolchain $ pkgConfigToolchains elaboratedShared)) + (compilerInfo (toolchainCompiler $ toolchainFor (elabStage elab) $ pkgConfigToolchains elaboratedShared)) InstallDirs.NoCopyDest (toolchainPlatform $ buildToolchain $ pkgConfigToolchains elaboratedShared) defaultInstallDirs @@ -4043,7 +4043,7 @@ computeInstallDirs storeDirLayout defaultInstallDirs elaboratedShared elab -- use special simplified install dirs storePackageInstallDirs' storeDirLayout - (toolchainCompiler $ hostToolchain $ pkgConfigToolchains elaboratedShared) + (toolchainCompiler $ toolchainFor (elabStage elab) $ pkgConfigToolchains elaboratedShared) (elabUnitId elab) -- TODO: [code cleanup] perhaps reorder this code From 674f2b200ac8af30d60cdead452ebd7ca0485961 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 08:22:17 +0900 Subject: [PATCH 49/82] Add cabal.project: build-packages --- .../src/Distribution/Client/ProjectConfig.hs | 5 ++++- .../src/Distribution/Client/ProjectConfig/Legacy.hs | 11 +++++++++++ .../src/Distribution/Client/ProjectConfig/Types.hs | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index 5bf2ab41e94..fd96eb4d2f3 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -798,6 +798,8 @@ defaultImplicitProjectConfig = mempty { -- We expect a package in the current directory. projectPackages = ["./*.cabal"] + -- By default we do not assume any special build packages. + , projectBuildPackages = [] , projectConfigProvenance = Set.singleton Implicit } @@ -1084,11 +1086,12 @@ findProjectPackages DistDirLayout{distProjectRootDirectory} ProjectConfig{..} = do requiredPkgs <- findPackageLocations True projectPackages + buildPkgs <- findPackageLocations True projectBuildPackages optionalPkgs <- findPackageLocations False projectPackagesOptional let repoPkgs = map ProjectPackageRemoteRepo projectPackagesRepo namedPkgs = map ProjectPackageNamed projectPackagesNamed - return (concat [requiredPkgs, optionalPkgs, repoPkgs, namedPkgs]) + return (concat [requiredPkgs, buildPkgs, optionalPkgs, repoPkgs, namedPkgs]) where findPackageLocations :: Bool -> [String] -> Rebuild [ProjectPackageLocation] findPackageLocations required pkglocstr = do diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 7c357c70a8a..bc8268d1506 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -408,6 +408,7 @@ parseProjectSkeleton cacheDir httpTransport verbosity projectDir source (Project -- can redefine the parsers directly for the new types. data LegacyProjectConfig = LegacyProjectConfig { legacyPackages :: [String] + , legacyBuildPackages :: [String] , legacyPackagesOptional :: [String] , legacyPackagesRepo :: [SourceRepoList] , legacyPackagesNamed :: [PackageVersionConstraint] @@ -613,6 +614,7 @@ convertLegacyProjectConfig :: LegacyProjectConfig -> ProjectConfig convertLegacyProjectConfig LegacyProjectConfig { legacyPackages + , legacyBuildPackages , legacyPackagesOptional , legacyPackagesRepo , legacyPackagesNamed @@ -637,6 +639,7 @@ convertLegacyProjectConfig } = ProjectConfig { projectPackages = legacyPackages + , projectBuildPackages = legacyBuildPackages , projectPackagesOptional = legacyPackagesOptional , projectPackagesRepo = legacyPackagesRepo , projectPackagesNamed = legacyPackagesNamed @@ -936,6 +939,7 @@ convertToLegacyProjectConfig :: ProjectConfig -> LegacyProjectConfig convertToLegacyProjectConfig projectConfig@ProjectConfig { projectPackages + , projectBuildPackages , projectPackagesOptional , projectPackagesRepo , projectPackagesNamed @@ -945,6 +949,7 @@ convertToLegacyProjectConfig } = LegacyProjectConfig { legacyPackages = projectPackages + , legacyBuildPackages = projectBuildPackages , legacyPackagesOptional = projectPackagesOptional , legacyPackagesRepo = projectPackagesRepo , legacyPackagesNamed = projectPackagesNamed @@ -1316,6 +1321,12 @@ legacyProjectConfigFieldDescrs constraintSrc = parsePackageLocationTokenQ legacyPackages (\v flags -> flags{legacyPackages = v}) + , newLineListField + "build-packages" + (Disp.text . renderPackageLocationToken) + parsePackageLocationTokenQ + legacyBuildPackages + (\v flags -> flags{legacyBuildPackages = v}) , newLineListField "optional-packages" (Disp.text . renderPackageLocationToken) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 0ae0bcd6d6a..0f82fbcc12f 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -129,6 +129,11 @@ data ProjectConfig = ProjectConfig -- ^ Packages in this project, including local dirs, local .cabal files -- local and remote tarballs. When these are file globs, they must -- match at least one package. + , projectBuildPackages :: [String] + -- ^ Packages in this project, including local dirs, local .cabal files + -- local and remote tarballs considered only for build-time dependencies + -- (build-type: Custom orHooks; build-depends, ...). When these are file + -- globs, they must match at least one package. , projectPackagesOptional :: [String] -- ^ Like 'projectConfigPackageGlobs' but /optional/ in the sense that -- file globs are allowed to match nothing. The primary use case for From 79b31e10d39ee54e68e2055587728b4f92c49145 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:52:30 +0900 Subject: [PATCH 50/82] Add compiler to PackageId --- Cabal-syntax/src/Distribution/Compiler.hs | 2 +- .../PackageDescription/FieldGrammar.hs | 4 +++- .../Distribution/Types/InstalledPackageInfo.hs | 10 +++++----- .../Types/InstalledPackageInfo/FieldGrammar.hs | 13 ++++++++----- .../src/Distribution/Types/MungedPackageId.hs | 17 ++++++++++------- .../Distribution/Types/PackageDescription.hs | 1 + .../src/Distribution/Types/PackageId.hs | 12 ++++++++---- .../src/Distribution/Types/PackageId/Lens.hs | 6 ++++++ .../Types/PackageVersionConstraint.hs | 4 ++-- .../Backpack/PreExistingComponent.hs | 4 ++-- .../src/Distribution/Backpack/ReadyComponent.hs | 1 + .../Distribution/PackageDescription/Check.hs | 2 +- Cabal/src/Distribution/Simple/Build.hs | 2 +- Cabal/src/Distribution/Simple/Build/Macros.hs | 6 +++--- Cabal/src/Distribution/Simple/Configure.hs | 5 +++-- Cabal/src/Distribution/Simple/PackageIndex.hs | 13 +++++++++---- .../src/Distribution/Types/PackageName/Magic.hs | 2 +- .../Solver/Modular/ConfiguredConversion.hs | 4 ++-- .../Solver/Types/InstSolverPackage.hs | 4 ++-- .../Client/BuildReports/Anonymous.hs | 2 +- .../src/Distribution/Client/Dependency.hs | 2 +- .../src/Distribution/Client/IndexUtils.hs | 8 ++++---- .../src/Distribution/Client/Install.hs | 2 +- .../src/Distribution/Client/PackageHash.hs | 4 ++-- .../src/Distribution/Client/SetupWrapper.hs | 6 +++--- .../Distribution/Client/SolverInstallPlan.hs | 2 +- .../src/Distribution/Client/Types/AllowNewer.hs | 2 +- 27 files changed, 83 insertions(+), 57 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index cef915a25d3..a4ac948570f 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -174,7 +174,7 @@ instance (Semigroup a, Monoid a) => Monoid (PerCompilerFlavor a) where -- ------------------------------------------------------------ data CompilerId = CompilerId CompilerFlavor Version - deriving (Eq, Generic, Ord, Read, Show) + deriving (Eq, Generic, Ord, Read, Show, Data) instance Binary CompilerId instance Structured CompilerId diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index 22912564e49..27e98ee0a82 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -74,7 +74,7 @@ import Prelude () import Distribution.CabalSpecVersion import Distribution.Compat.Newtype (Newtype, pack', unpack') -import Distribution.Compiler (CompilerFlavor (..), PerCompilerFlavor (..)) +import Distribution.Compiler (CompilerFlavor (..), PerCompilerFlavor (..), CompilerId) import Distribution.FieldGrammar import Distribution.Fields import Distribution.ModuleName (ModuleName) @@ -101,6 +101,7 @@ packageDescriptionFieldGrammar , c (Identity BuildType) , c (Identity PackageName) , c (Identity Version) + , c (Identity CompilerId) , forall from to. c (List FSep (RelativePathNT from to) (RelativePath from to)) , forall from to. c (List VCat (RelativePathNT from to) (RelativePath from to)) , c (List FSep TestedWith (CompilerFlavor, VersionRange)) @@ -150,6 +151,7 @@ packageDescriptionFieldGrammar = PackageIdentifier <$> uniqueField "name" L.pkgName <*> uniqueField "version" L.pkgVersion + <*> optionalField "compiler" L.pkgCompiler licenseFilesGrammar = (++) diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs index defb1922607..ee1dfca5888 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs @@ -16,10 +16,10 @@ import Prelude () import Distribution.Backpack import Distribution.Compat.Graph (IsNode (..)) -import Distribution.Compiler (CompilerId) +import Distribution.Compiler (CompilerId, buildCompilerId) import Distribution.License import Distribution.ModuleName -import Distribution.Package hiding (installedUnitId) +import Distribution.Package hiding (installedUnitId, pkgCompiler) import Distribution.Types.AbiDependency import Distribution.Types.ExposedModule import Distribution.Types.LibraryName @@ -121,8 +121,8 @@ instance IsNode InstalledPackageInfo where nodeNeighbors = depends mungedPackageId :: InstalledPackageInfo -> MungedPackageId -mungedPackageId ipi = - MungedPackageId (mungedPackageName ipi) (packageVersion ipi) +mungedPackageId ipi@InstalledPackageInfo{pkgCompiler = comp} = + MungedPackageId (mungedPackageName ipi) (packageVersion ipi) comp -- | Returns the munged package name, which we write into @name@ for -- compatibility with old versions of GHC. @@ -132,7 +132,7 @@ mungedPackageName ipi = MungedPackageName (packageName ipi) (sourceLibName ipi) emptyInstalledPackageInfo :: InstalledPackageInfo emptyInstalledPackageInfo = InstalledPackageInfo - { sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion + { sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion Nothing , sourceLibName = LMainLibName , installedComponentId_ = mkComponentId "" , installedUnitId = mkUnitId "" diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index c2e77292c07..151aaf4b119 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -20,7 +20,7 @@ import Distribution.FieldGrammar import Distribution.FieldGrammar.FieldDescrs import Distribution.License import Distribution.ModuleName -import Distribution.Package +import Distribution.Package hiding (pkgCompiler) import Distribution.Parsec import Distribution.Pretty import Distribution.Types.LibraryName @@ -38,7 +38,7 @@ import qualified Text.PrettyPrint as Disp import Distribution.Types.InstalledPackageInfo import qualified Distribution.Types.InstalledPackageInfo.Lens as L -import qualified Distribution.Types.PackageId.Lens as L +import qualified Distribution.Types.PackageId.Lens as L hiding (pkgCompiler) -- Note: GHC goes nuts and inlines everything, -- One can see e.g. in -ddump-simpl-stats: @@ -133,7 +133,7 @@ ipiFieldGrammar = InstalledPackageInfo -- _basicPkgName is not used -- setMaybePackageId says it can be no-op. - (PackageIdentifier pn _basicVersion) + (PackageIdentifier pn _basicVersion _basicCompilerId) (combineLibraryName ln _basicLibName) (mkComponentId "") -- installedComponentId_, not in use _basicLibVisibility @@ -256,6 +256,7 @@ data Basic = Basic , _basicPkgName :: Maybe PackageName , _basicLibName :: LibraryName , _basicLibVisibility :: LibraryVisibility + , _basicCompilerId :: Maybe CompilerId } basic :: Lens' InstalledPackageInfo Basic @@ -268,14 +269,16 @@ basic f ipi = g <$> f b (maybePackageName ipi) (sourceLibName ipi) (libVisibility ipi) + (pkgCompiler ipi) - g (Basic n v pn ln lv) = + g (Basic n v pn ln lv compid) = ipi & setMungedPackageName n & L.sourcePackageId . L.pkgVersion .~ v & setMaybePackageName pn & L.sourceLibName .~ ln & L.libVisibility .~ lv + & L.pkgCompiler .~ compid basicName :: Lens' Basic MungedPackageName basicName f b = (\x -> b{_basicName = x}) <$> f (_basicName b) @@ -319,7 +322,7 @@ basicFieldGrammar = <*> optionalField "lib-name" basicLibName <*> optionalFieldDef "visibility" basicLibVisibility LibraryVisibilityPrivate where - mkBasic n v pn ln lv = Basic n v pn ln' lv' + mkBasic n v pn ln lv = Basic n v pn ln' lv' Nothing where ln' = maybe LMainLibName LSubLibName ln -- Older GHCs (<8.8) always report installed libraries as private diff --git a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs index 8e879620478..b0edcd99bf5 100644 --- a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs @@ -15,6 +15,7 @@ import Distribution.Types.LibraryName import Distribution.Types.MungedPackageName import Distribution.Types.PackageId import Distribution.Version (Version, nullVersion) +import Distribution.Compiler (CompilerId) import qualified Text.PrettyPrint as Disp @@ -27,6 +28,7 @@ data MungedPackageId = MungedPackageId -- 'MungedPackageName'. , mungedVersion :: Version -- ^ The version of this package / component, eg 1.2 + , mingledCompilerId :: Maybe CompilerId } deriving (Generic, Read, Show, Eq, Ord, Data) @@ -41,8 +43,9 @@ instance Structured MungedPackageId -- >>> prettyShow $ MungedPackageId (MungedPackageName "servant" (LSubLibName "lackey")) (mkVersion [0,1,2]) -- "z-servant-z-lackey-0.1.2" instance Pretty MungedPackageId where - pretty (MungedPackageId n v) - | v == nullVersion = pretty n -- if no version, don't show version. + pretty (MungedPackageId n v c) + | v == nullVersion = pretty c <<>> Disp.char '-' <<>> pretty n -- if no version, don't show version. + | Just c' <- c = pretty c' <<>> Disp.char '-' <<>> pretty n <<>> Disp.char '-' <<>> pretty v | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v -- | @@ -66,15 +69,15 @@ instance Pretty MungedPackageId where -- Nothing instance Parsec MungedPackageId where parsec = do - PackageIdentifier pn v <- parsec - return $ MungedPackageId (decodeCompatPackageName pn) v + PackageIdentifier pn v comp <- parsec + return $ MungedPackageId (decodeCompatPackageName pn) v comp instance NFData MungedPackageId where - rnf (MungedPackageId name version) = rnf name `seq` rnf version + rnf (MungedPackageId name version compiler) = rnf name `seq` rnf version `seq` rnf compiler computeCompatPackageId :: PackageId -> LibraryName -> MungedPackageId -computeCompatPackageId (PackageIdentifier pn vr) ln = - MungedPackageId (MungedPackageName pn ln) vr +computeCompatPackageId (PackageIdentifier pn vr comp) ln = + MungedPackageId (MungedPackageName pn ln) vr comp -- $setup -- >>> :seti -XOverloadedStrings diff --git a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs index 4b00a8ef526..17f72e54c95 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs @@ -207,6 +207,7 @@ emptyPackageDescription = PackageIdentifier (mkPackageName "") nullVersion + Nothing , licenseRaw = Right UnspecifiedLicense -- TODO: , licenseFiles = [] , specVersion = CabalSpecV1_0 diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index 9cd88a2f810..ca9bfbfc967 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -13,6 +13,7 @@ import Distribution.Parsec (Parsec (..), simpleParsec) import Distribution.Pretty import Distribution.Types.PackageName import Distribution.Version (Version, nullVersion) +import Distribution.Compiler (CompilerId) import qualified Data.List.NonEmpty as NE import qualified Distribution.Compat.CharParsing as P @@ -27,6 +28,7 @@ data PackageIdentifier = PackageIdentifier -- ^ The name of this package, eg. foo , pkgVersion :: Version -- ^ the version of this package, eg 1.2 + , pkgCompiler :: Maybe CompilerId } deriving (Generic, Read, Show, Eq, Ord, Data) @@ -34,8 +36,9 @@ instance Binary PackageIdentifier instance Structured PackageIdentifier instance Pretty PackageIdentifier where - pretty (PackageIdentifier n v) - | v == nullVersion = pretty n -- if no version, don't show version. + pretty (PackageIdentifier n v c) + | v == nullVersion = pretty c <<>> Disp.char '-' <<>> pretty n -- if no version, don't show version. + | Just c' <- c = pretty c' <<>> Disp.char '-' <<>> pretty n <<>> Disp.char '-' <<>> pretty v | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v -- | @@ -61,15 +64,16 @@ instance Pretty PackageIdentifier where -- Nothing instance Parsec PackageIdentifier where parsec = do + comp <- parsec <* P.char '-' xs' <- P.sepByNonEmpty component (P.char '-') (v, xs) <- case simpleParsec (NE.last xs') of Nothing -> return (nullVersion, toList xs') -- all components are version Just v -> return (v, NE.init xs') if not (null xs) && all (\c -> all (/= '.') c && not (all isDigit c)) xs - then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v + then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v comp else fail "all digits or a dot in a portion of package name" where component = P.munch1 (\c -> isAlphaNum c || c == '.') instance NFData PackageIdentifier where - rnf (PackageIdentifier name version) = rnf name `seq` rnf version + rnf (PackageIdentifier name version compiler) = rnf name `seq` rnf version `seq` rnf compiler diff --git a/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs b/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs index 08305234fbd..5a4682c7ed3 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs @@ -10,6 +10,7 @@ import Prelude () import Distribution.Types.PackageId (PackageIdentifier) import Distribution.Types.PackageName (PackageName) import Distribution.Version (Version) +import Distribution.Compiler (CompilerId) import qualified Distribution.Types.PackageId as T @@ -20,3 +21,8 @@ pkgName f s = fmap (\x -> s{T.pkgName = x}) (f (T.pkgName s)) pkgVersion :: Lens' PackageIdentifier Version pkgVersion f s = fmap (\x -> s{T.pkgVersion = x}) (f (T.pkgVersion s)) {-# INLINE pkgVersion #-} + +pkgCompiler :: Lens' PackageIdentifier (Maybe CompilerId) +pkgCompiler f s = fmap (\x -> s{T.pkgCompiler = x}) (f (T.pkgCompiler s)) +{-# INLINE pkgCompiler #-} + diff --git a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs index 013226ca2d5..5c2b8d9b0b1 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs @@ -53,7 +53,7 @@ instance Pretty PackageVersionConstraint where -- Just (PackageVersionConstraint (PackageName "foo") (ThisVersion (mkVersion [2,0]))) instance Parsec PackageVersionConstraint where parsec = do - PackageIdentifier name ver <- parsec + PackageIdentifier name ver comp <- parsec if ver == nullVersion then do P.spaces @@ -64,7 +64,7 @@ instance Parsec PackageVersionConstraint where -- | @since 3.4.0.0 thisPackageVersionConstraint :: PackageIdentifier -> PackageVersionConstraint -thisPackageVersionConstraint (PackageIdentifier pn vr) = +thisPackageVersionConstraint (PackageIdentifier pn vr comp) = PackageVersionConstraint pn (thisVersion vr) -- | @since 3.4.0.0 diff --git a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs index 0fba79bcb87..a72fe20f07f 100644 --- a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs +++ b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs @@ -71,9 +71,9 @@ instance HasMungedPackageId PreExistingComponent where mungedId = pc_munged_id instance Package PreExistingComponent where - packageId pec = PackageIdentifier (pc_pkgname pec) v + packageId pec = PackageIdentifier (pc_pkgname pec) v compid where - MungedPackageId _ v = pc_munged_id pec + MungedPackageId _ v compid = pc_munged_id pec instance HasUnitId PreExistingComponent where installedUnitId = pc_uid diff --git a/Cabal/src/Distribution/Backpack/ReadyComponent.hs b/Cabal/src/Distribution/Backpack/ReadyComponent.hs index 7a3523d5eab..b871ebff59f 100644 --- a/Cabal/src/Distribution/Backpack/ReadyComponent.hs +++ b/Cabal/src/Distribution/Backpack/ReadyComponent.hs @@ -300,6 +300,7 @@ toReadyComponents pid_map subst0 comps = MungedPackageId (MungedPackageName nonExistentPackageThisIsCabalBug LMainLibName) (mkVersion [0]) + Nothing instc = InstantiatedComponent { instc_insts = Map.toList insts diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index 925bc69d6e1..799e677af17 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -582,7 +582,7 @@ checkSetupBuildInfo (Just (SetupBuildInfo ds _)) = do checkPVPs (checkDependencyVersionRange hasGTLowerBound) gtlck ds checkPackageId :: Monad m => PackageIdentifier -> CheckM m () -checkPackageId (PackageIdentifier pkgName_ _pkgVersion_) = do +checkPackageId (PackageIdentifier pkgName_ _pkgVersion_ _compid) = do checkP (not . FilePath.Windows.isValid . prettyShow $ pkgName_) (PackageDistInexcusable $ InvalidNameWin pkgName_) diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 402f27467d2..008a270848f 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -821,7 +821,7 @@ testSuiteLibV09AsLibAndExe } -- This is, like, the one place where we use a CTestName for a library. -- Should NOT use library name, since that could conflict! - PackageIdentifier pkg_name pkg_ver = package pkg_descr + PackageIdentifier pkg_name pkg_ver _pkg_compid = package pkg_descr -- Note: we do make internal library from the test! compat_name = MungedPackageName pkg_name (LSubLibName (testName test)) compat_key = computeCompatPackageKey (compiler lbi) compat_name pkg_ver (componentUnitId clbi) diff --git a/Cabal/src/Distribution/Simple/Build/Macros.hs b/Cabal/src/Distribution/Simple/Build/Macros.hs index f3c51d71c96..e71d5a4a644 100644 --- a/Cabal/src/Distribution/Simple/Build/Macros.hs +++ b/Cabal/src/Distribution/Simple/Build/Macros.hs @@ -67,11 +67,11 @@ generateCabalMacrosHeader pkg_descr lbi clbi = , Z.zMangleStr = map fixchar } where - getPid (_, MungedPackageId (MungedPackageName pn _) v) = + getPid (_, MungedPackageId (MungedPackageName pn _) v compid) = -- NB: Drop the library name! We're just reporting package versions. -- This would have to be revisited if you are allowed to depend -- on different versions of the same package - PackageIdentifier pn v + PackageIdentifier pn v compid -- | Helper function that generates just the @VERSION_pkg@ and @MIN_VERSION_pkg@ -- macros for a list of package ids (usually used with the specific deps of @@ -91,7 +91,7 @@ generatePackageVersionMacros ver pkgids = } mkZPackage :: PackageId -> Z.ZPackage -mkZPackage (PackageIdentifier name ver) = +mkZPackage (PackageIdentifier name ver compid) = Z.ZPackage { Z.zpkgName = name , Z.zpkgVersion = ver diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 7c96efb33fc..a76b4359bc9 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -335,7 +335,7 @@ writePersistBuildConfig mbWorkDir distPref lbi = do -- | Identifier of the current Cabal package. currentCabalId :: PackageIdentifier -currentCabalId = PackageIdentifier (mkPackageName "Cabal") cabalVersion +currentCabalId = PackageIdentifier (mkPackageName "Cabal") cabalVersion Nothing -- | Identifier of the current compiler package. currentCompilerId :: PackageIdentifier @@ -343,6 +343,7 @@ currentCompilerId = PackageIdentifier (mkPackageName System.Info.compilerName) (mkVersion' System.Info.compilerVersion) + Nothing -- | Parse the @setup-config@ file header, returning the package identifiers -- for Cabal and the compiler. @@ -1987,7 +1988,7 @@ selectDependency -- It's an internal library, and we're not per-component build do_internal lib | Set.member lib internalIndex = - Right $ InternalDependency $ PackageIdentifier dep_pkgname $ packageVersion pkgid + Right $ InternalDependency $ PackageIdentifier dep_pkgname (packageVersion pkgid) (pkgCompiler pkgid) | otherwise = Left $ DependencyMissingInternal dep_pkgname lib diff --git a/Cabal/src/Distribution/Simple/PackageIndex.hs b/Cabal/src/Distribution/Simple/PackageIndex.hs index a7d23962b72..6e115ca65a5 100644 --- a/Cabal/src/Distribution/Simple/PackageIndex.hs +++ b/Cabal/src/Distribution/Simple/PackageIndex.hs @@ -169,7 +169,7 @@ instance Semigroup (PackageIndex IPI.InstalledPackageInfo) where {-# NOINLINE invariant #-} invariant :: WithCallStack (InstalledPackageIndex -> Bool) invariant (PackageIndex pids pnames) = - -- trace (show pids' ++ "\n" ++ show pnames') $ + trace (show pids' ++ "\n" ++ show pnames') $ pids' == pnames' where pids' = map installedUnitId (Map.elems pids) @@ -335,16 +335,21 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = Just pvers -> case Map.lookup (packageVersion pkgid) pvers of Nothing -> original Just pkgs -> - mkPackageIndex - (foldl' (flip (Map.delete . installedUnitId)) pids pkgs) + traceShow (pkgid, pkgs) $ mkPackageIndex + (Map.update deletePkgInstance (installedUnitId pkgid) pids) (deletePkgName pnames) where deletePkgName = Map.update deletePkgVersion (packageName pkgid, LMainLibName) + deletePkgVersion :: Map Version [IPI.InstalledPackageInfo] -> Maybe (Map Version [IPI.InstalledPackageInfo]) deletePkgVersion = (\m -> if Map.null m then Nothing else Just m) - . Map.delete (packageVersion pkgid) + . Map.update deletePkgInstance (packageVersion pkgid) + + deletePkgInstance :: [IPI.InstalledPackageInfo] -> Maybe [IPI.InstalledPackageInfo] + deletePkgInstance xs = if null xs' then Nothing else Just xs' + where xs' = [x | x <- xs, pkgCompiler pkgid /= pkgCompiler (IPI.sourcePackageId x)] -- | Removes all packages with this (case-sensitive) name from the index. -- diff --git a/Cabal/src/Distribution/Types/PackageName/Magic.hs b/Cabal/src/Distribution/Types/PackageName/Magic.hs index 022a62468b1..908e82bea6f 100644 --- a/Cabal/src/Distribution/Types/PackageName/Magic.hs +++ b/Cabal/src/Distribution/Types/PackageName/Magic.hs @@ -21,4 +21,4 @@ fakePackageCabalFileName = "fake-package.cabal" -- | 'fakePackageName' with 'version0'. fakePackageId :: PackageId -fakePackageId = PackageIdentifier fakePackageName version0 +fakePackageId = PackageIdentifier fakePackageName version0 Nothing diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index d391345d0eb..6ae45e569fc 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -39,7 +39,7 @@ convCP iidx sidx (CP qpi fa es ds) = } -- "In repo" i.e. a source package (PI qpn@(Q _path pn) (I stage v InRepo)) -> - let pi = PackageIdentifier pn v in + let pi = PackageIdentifier pn v Nothing {-# FIXME: should be COMPILERID #-} in Configured $ SolverPackage { solverPkgQPN = qpn, @@ -70,4 +70,4 @@ convConfId (PI (Q (PackagePath _ q) pn) (I _stage v loc)) = , pn == pn' -> Right (PlannedId sourceId) | otherwise -> Left (PlannedId sourceId) where - sourceId = PackageIdentifier pn v + sourceId = PackageIdentifier pn v Nothing -- FIXME: this should be the compiler id! diff --git a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs index 15fb9d510ec..868d1d9dfe2 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs @@ -31,8 +31,8 @@ instance Structured InstSolverPackage instance Package InstSolverPackage where packageId i = -- HACK! See Note [Index conversion with internal libraries] - let MungedPackageId mpn v = mungedId i - in PackageIdentifier (encodeCompatPackageName mpn) v + let MungedPackageId mpn v compid = mungedId i + in PackageIdentifier (encodeCompatPackageName mpn) v compid instance HasMungedPackageId InstSolverPackage where mungedId = mungedId . instSolverPkgIPI diff --git a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs index ce1d1665327..a6febfcca50 100644 --- a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs +++ b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs @@ -103,7 +103,7 @@ newBuildReport os' arch' comp pkgid flags deps result = cabalInstallID :: PackageIdentifier cabalInstallID = - PackageIdentifier (mkPackageName "cabal-install") cabalInstallVersion + PackageIdentifier (mkPackageName "cabal-install") cabalInstallVersion Nothing ------------------------------------------------------------------------------- -- FieldGrammar diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 65f8a06ac97..7f3812d69b4 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -1057,7 +1057,7 @@ configuredPackageProblems (sort $ map fst (PD.unFlagAssignment specifiedFlags)) -- TODO packageSatisfiesDependency :: PackageIdentifier -> Dependency -> Bool packageSatisfiesDependency - (PackageIdentifier name version) + (PackageIdentifier name version _compid) (Dependency name' versionRange _) = assert (name == name') $ version `withinRange` versionRange diff --git a/cabal-install/src/Distribution/Client/IndexUtils.hs b/cabal-install/src/Distribution/Client/IndexUtils.hs index 6027f5e53f3..0cd842d663e 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils.hs @@ -617,7 +617,7 @@ extractPkg verbosity entry blockNo = case Tar.entryContent entry of [pkgname, vers, _] -> case simpleParsec vers of Just ver -> Just . return $ Just (NormalPackage pkgid descr content blockNo) where - pkgid = PackageIdentifier (mkPackageName pkgname) ver + pkgid = PackageIdentifier (mkPackageName pkgname) ver Nothing parsed = parseGenericPackageDescriptionMaybe (BS.toStrict content) descr = case parsed of Just d -> d @@ -1269,10 +1269,10 @@ hashConsCache cache0 = go !pns !pvs (CachePackageId pid bno ts : rest) = CachePackageId pid' bno ts : go pns' pvs' rest where - !pid' = PackageIdentifier pn' pv' + !pid' = PackageIdentifier pn' pv' compid (!pn', !pns') = mapIntern pn pns (!pv', !pvs') = mapIntern pv pvs - PackageIdentifier pn pv = pid + PackageIdentifier pn pv compid = pid go pns pvs (x : xs) = x : go pns pvs xs mapIntern :: Ord k => k -> Map.Map k k -> (k, Map.Map k k) @@ -1395,7 +1395,7 @@ read00IndexCacheEntry = \line -> (Just pkgname, Just pkgver, Just blockno) -> Just ( CachePackageId - (PackageIdentifier pkgname pkgver) + (PackageIdentifier pkgname pkgver Nothing) blockno NoTimestamp ) diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 6c9a605c553..7f32d51ac3d 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -1101,7 +1101,7 @@ theSpecifiedPackage :: Package pkg => PackageSpecifier pkg -> Maybe PackageId theSpecifiedPackage pkgSpec = case pkgSpec of NamedPackage name [PackagePropertyVersion version] -> - PackageIdentifier name <$> trivialRange version + PackageIdentifier name <$> trivialRange version <*> Nothing NamedPackage _ _ -> Nothing SpecificSourcePackage pkg -> Just $ packageId pkg where diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index 38240c3888a..d99fc9ad250 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -133,7 +133,7 @@ hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = , showHashValue (truncateHash 20 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version = pkgHashPkgId + PackageIdentifier name version _compid = pkgHashPkgId -- Truncate a string, with a visual indication that it is truncated. truncateStr n s @@ -172,7 +172,7 @@ hashedInstalledPackageIdVeryShort pkghashinputs@PackageHashInputs{pkgHashPkgId} , showHashValue (truncateHash 4 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version = pkgHashPkgId + PackageIdentifier name version _compid = pkgHashPkgId -- | All the information that contributes to a package's hash, and thus its -- 'InstalledPackageId'. diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index 55042e212cd..d46045c849a 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -1068,7 +1068,7 @@ getExternalSetupMethod verbosity options pkg bt = do debug verbosity "Setup executable needs to be updated, compiling..." (compiler, progdb, options'') <- configureCompiler options' pkgDbs <- traverse (traverse (makeRelativeToDirS mbWorkDir)) (coercePackageDBStack (usePackageDB options'')) - let cabalPkgid = PackageIdentifier (mkPackageName "Cabal") cabalLibVersion + let cabalPkgid = PackageIdentifier (mkPackageName "Cabal") cabalLibVersion Nothing (program, extraOpts) = case compilerFlavor compiler of GHCJS -> (ghcjsProgram, ["-build-runner"]) @@ -1155,5 +1155,5 @@ getExternalSetupMethod verbosity options pkg bt = do return $ i setupProgFile isCabalPkgId, isBasePkgId :: PackageIdentifier -> Bool -isCabalPkgId (PackageIdentifier pname _) = pname == mkPackageName "Cabal" -isBasePkgId (PackageIdentifier pname _) = pname == mkPackageName "base" +isCabalPkgId (PackageIdentifier pname _ _compid) = pname == mkPackageName "Cabal" +isBasePkgId (PackageIdentifier pname _ _compid) = pname == mkPackageName "base" diff --git a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs index 17dcf6d9398..631dbde5afe 100644 --- a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs +++ b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs @@ -218,7 +218,7 @@ showPlanProblem (PackageInconsistency name inconsistencies) = [ " package " ++ prettyShow pkg ++ " requires " - ++ prettyShow (PackageIdentifier name ver) + ++ prettyShow (PackageIdentifier name ver Nothing) | (pkg, ver) <- inconsistencies ] showPlanProblem (PackageStateInvalid pkg pkg') = diff --git a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs index 0a5700174b8..6a6503aaf4c 100644 --- a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs +++ b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs @@ -109,7 +109,7 @@ relaxedDepStarP = -- continuation after package identifier relaxedDepPkgidP :: CabalParsing m => PackageIdentifier -> m RelaxedDep -relaxedDepPkgidP pid@(PackageIdentifier pn v) +relaxedDepPkgidP pid@(PackageIdentifier pn v _compid) | pn == mkPackageName "all" , v == nullVersion = RelaxedDep RelaxDepScopeAll <$ P.char ':' <*> modP <*> parsec From 328713ab2214d9098b97240f8d87cba807fc2f5c Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:52:36 +0900 Subject: [PATCH 51/82] Revert "Add compiler to PackageId" This reverts commit 79b31e10d39ee54e68e2055587728b4f92c49145. --- Cabal-syntax/src/Distribution/Compiler.hs | 2 +- .../PackageDescription/FieldGrammar.hs | 4 +--- .../Distribution/Types/InstalledPackageInfo.hs | 10 +++++----- .../Types/InstalledPackageInfo/FieldGrammar.hs | 13 +++++-------- .../src/Distribution/Types/MungedPackageId.hs | 17 +++++++---------- .../Distribution/Types/PackageDescription.hs | 1 - .../src/Distribution/Types/PackageId.hs | 12 ++++-------- .../src/Distribution/Types/PackageId/Lens.hs | 6 ------ .../Types/PackageVersionConstraint.hs | 4 ++-- .../Backpack/PreExistingComponent.hs | 4 ++-- .../src/Distribution/Backpack/ReadyComponent.hs | 1 - .../Distribution/PackageDescription/Check.hs | 2 +- Cabal/src/Distribution/Simple/Build.hs | 2 +- Cabal/src/Distribution/Simple/Build/Macros.hs | 6 +++--- Cabal/src/Distribution/Simple/Configure.hs | 5 ++--- Cabal/src/Distribution/Simple/PackageIndex.hs | 13 ++++--------- .../src/Distribution/Types/PackageName/Magic.hs | 2 +- .../Solver/Modular/ConfiguredConversion.hs | 4 ++-- .../Solver/Types/InstSolverPackage.hs | 4 ++-- .../Client/BuildReports/Anonymous.hs | 2 +- .../src/Distribution/Client/Dependency.hs | 2 +- .../src/Distribution/Client/IndexUtils.hs | 8 ++++---- .../src/Distribution/Client/Install.hs | 2 +- .../src/Distribution/Client/PackageHash.hs | 4 ++-- .../src/Distribution/Client/SetupWrapper.hs | 6 +++--- .../Distribution/Client/SolverInstallPlan.hs | 2 +- .../src/Distribution/Client/Types/AllowNewer.hs | 2 +- 27 files changed, 57 insertions(+), 83 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index a4ac948570f..cef915a25d3 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -174,7 +174,7 @@ instance (Semigroup a, Monoid a) => Monoid (PerCompilerFlavor a) where -- ------------------------------------------------------------ data CompilerId = CompilerId CompilerFlavor Version - deriving (Eq, Generic, Ord, Read, Show, Data) + deriving (Eq, Generic, Ord, Read, Show) instance Binary CompilerId instance Structured CompilerId diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index 27e98ee0a82..22912564e49 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -74,7 +74,7 @@ import Prelude () import Distribution.CabalSpecVersion import Distribution.Compat.Newtype (Newtype, pack', unpack') -import Distribution.Compiler (CompilerFlavor (..), PerCompilerFlavor (..), CompilerId) +import Distribution.Compiler (CompilerFlavor (..), PerCompilerFlavor (..)) import Distribution.FieldGrammar import Distribution.Fields import Distribution.ModuleName (ModuleName) @@ -101,7 +101,6 @@ packageDescriptionFieldGrammar , c (Identity BuildType) , c (Identity PackageName) , c (Identity Version) - , c (Identity CompilerId) , forall from to. c (List FSep (RelativePathNT from to) (RelativePath from to)) , forall from to. c (List VCat (RelativePathNT from to) (RelativePath from to)) , c (List FSep TestedWith (CompilerFlavor, VersionRange)) @@ -151,7 +150,6 @@ packageDescriptionFieldGrammar = PackageIdentifier <$> uniqueField "name" L.pkgName <*> uniqueField "version" L.pkgVersion - <*> optionalField "compiler" L.pkgCompiler licenseFilesGrammar = (++) diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs index ee1dfca5888..defb1922607 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs @@ -16,10 +16,10 @@ import Prelude () import Distribution.Backpack import Distribution.Compat.Graph (IsNode (..)) -import Distribution.Compiler (CompilerId, buildCompilerId) +import Distribution.Compiler (CompilerId) import Distribution.License import Distribution.ModuleName -import Distribution.Package hiding (installedUnitId, pkgCompiler) +import Distribution.Package hiding (installedUnitId) import Distribution.Types.AbiDependency import Distribution.Types.ExposedModule import Distribution.Types.LibraryName @@ -121,8 +121,8 @@ instance IsNode InstalledPackageInfo where nodeNeighbors = depends mungedPackageId :: InstalledPackageInfo -> MungedPackageId -mungedPackageId ipi@InstalledPackageInfo{pkgCompiler = comp} = - MungedPackageId (mungedPackageName ipi) (packageVersion ipi) comp +mungedPackageId ipi = + MungedPackageId (mungedPackageName ipi) (packageVersion ipi) -- | Returns the munged package name, which we write into @name@ for -- compatibility with old versions of GHC. @@ -132,7 +132,7 @@ mungedPackageName ipi = MungedPackageName (packageName ipi) (sourceLibName ipi) emptyInstalledPackageInfo :: InstalledPackageInfo emptyInstalledPackageInfo = InstalledPackageInfo - { sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion Nothing + { sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion , sourceLibName = LMainLibName , installedComponentId_ = mkComponentId "" , installedUnitId = mkUnitId "" diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index 151aaf4b119..c2e77292c07 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -20,7 +20,7 @@ import Distribution.FieldGrammar import Distribution.FieldGrammar.FieldDescrs import Distribution.License import Distribution.ModuleName -import Distribution.Package hiding (pkgCompiler) +import Distribution.Package import Distribution.Parsec import Distribution.Pretty import Distribution.Types.LibraryName @@ -38,7 +38,7 @@ import qualified Text.PrettyPrint as Disp import Distribution.Types.InstalledPackageInfo import qualified Distribution.Types.InstalledPackageInfo.Lens as L -import qualified Distribution.Types.PackageId.Lens as L hiding (pkgCompiler) +import qualified Distribution.Types.PackageId.Lens as L -- Note: GHC goes nuts and inlines everything, -- One can see e.g. in -ddump-simpl-stats: @@ -133,7 +133,7 @@ ipiFieldGrammar = InstalledPackageInfo -- _basicPkgName is not used -- setMaybePackageId says it can be no-op. - (PackageIdentifier pn _basicVersion _basicCompilerId) + (PackageIdentifier pn _basicVersion) (combineLibraryName ln _basicLibName) (mkComponentId "") -- installedComponentId_, not in use _basicLibVisibility @@ -256,7 +256,6 @@ data Basic = Basic , _basicPkgName :: Maybe PackageName , _basicLibName :: LibraryName , _basicLibVisibility :: LibraryVisibility - , _basicCompilerId :: Maybe CompilerId } basic :: Lens' InstalledPackageInfo Basic @@ -269,16 +268,14 @@ basic f ipi = g <$> f b (maybePackageName ipi) (sourceLibName ipi) (libVisibility ipi) - (pkgCompiler ipi) - g (Basic n v pn ln lv compid) = + g (Basic n v pn ln lv) = ipi & setMungedPackageName n & L.sourcePackageId . L.pkgVersion .~ v & setMaybePackageName pn & L.sourceLibName .~ ln & L.libVisibility .~ lv - & L.pkgCompiler .~ compid basicName :: Lens' Basic MungedPackageName basicName f b = (\x -> b{_basicName = x}) <$> f (_basicName b) @@ -322,7 +319,7 @@ basicFieldGrammar = <*> optionalField "lib-name" basicLibName <*> optionalFieldDef "visibility" basicLibVisibility LibraryVisibilityPrivate where - mkBasic n v pn ln lv = Basic n v pn ln' lv' Nothing + mkBasic n v pn ln lv = Basic n v pn ln' lv' where ln' = maybe LMainLibName LSubLibName ln -- Older GHCs (<8.8) always report installed libraries as private diff --git a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs index b0edcd99bf5..8e879620478 100644 --- a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs @@ -15,7 +15,6 @@ import Distribution.Types.LibraryName import Distribution.Types.MungedPackageName import Distribution.Types.PackageId import Distribution.Version (Version, nullVersion) -import Distribution.Compiler (CompilerId) import qualified Text.PrettyPrint as Disp @@ -28,7 +27,6 @@ data MungedPackageId = MungedPackageId -- 'MungedPackageName'. , mungedVersion :: Version -- ^ The version of this package / component, eg 1.2 - , mingledCompilerId :: Maybe CompilerId } deriving (Generic, Read, Show, Eq, Ord, Data) @@ -43,9 +41,8 @@ instance Structured MungedPackageId -- >>> prettyShow $ MungedPackageId (MungedPackageName "servant" (LSubLibName "lackey")) (mkVersion [0,1,2]) -- "z-servant-z-lackey-0.1.2" instance Pretty MungedPackageId where - pretty (MungedPackageId n v c) - | v == nullVersion = pretty c <<>> Disp.char '-' <<>> pretty n -- if no version, don't show version. - | Just c' <- c = pretty c' <<>> Disp.char '-' <<>> pretty n <<>> Disp.char '-' <<>> pretty v + pretty (MungedPackageId n v) + | v == nullVersion = pretty n -- if no version, don't show version. | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v -- | @@ -69,15 +66,15 @@ instance Pretty MungedPackageId where -- Nothing instance Parsec MungedPackageId where parsec = do - PackageIdentifier pn v comp <- parsec - return $ MungedPackageId (decodeCompatPackageName pn) v comp + PackageIdentifier pn v <- parsec + return $ MungedPackageId (decodeCompatPackageName pn) v instance NFData MungedPackageId where - rnf (MungedPackageId name version compiler) = rnf name `seq` rnf version `seq` rnf compiler + rnf (MungedPackageId name version) = rnf name `seq` rnf version computeCompatPackageId :: PackageId -> LibraryName -> MungedPackageId -computeCompatPackageId (PackageIdentifier pn vr comp) ln = - MungedPackageId (MungedPackageName pn ln) vr comp +computeCompatPackageId (PackageIdentifier pn vr) ln = + MungedPackageId (MungedPackageName pn ln) vr -- $setup -- >>> :seti -XOverloadedStrings diff --git a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs index 17f72e54c95..4b00a8ef526 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs @@ -207,7 +207,6 @@ emptyPackageDescription = PackageIdentifier (mkPackageName "") nullVersion - Nothing , licenseRaw = Right UnspecifiedLicense -- TODO: , licenseFiles = [] , specVersion = CabalSpecV1_0 diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index ca9bfbfc967..9cd88a2f810 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -13,7 +13,6 @@ import Distribution.Parsec (Parsec (..), simpleParsec) import Distribution.Pretty import Distribution.Types.PackageName import Distribution.Version (Version, nullVersion) -import Distribution.Compiler (CompilerId) import qualified Data.List.NonEmpty as NE import qualified Distribution.Compat.CharParsing as P @@ -28,7 +27,6 @@ data PackageIdentifier = PackageIdentifier -- ^ The name of this package, eg. foo , pkgVersion :: Version -- ^ the version of this package, eg 1.2 - , pkgCompiler :: Maybe CompilerId } deriving (Generic, Read, Show, Eq, Ord, Data) @@ -36,9 +34,8 @@ instance Binary PackageIdentifier instance Structured PackageIdentifier instance Pretty PackageIdentifier where - pretty (PackageIdentifier n v c) - | v == nullVersion = pretty c <<>> Disp.char '-' <<>> pretty n -- if no version, don't show version. - | Just c' <- c = pretty c' <<>> Disp.char '-' <<>> pretty n <<>> Disp.char '-' <<>> pretty v + pretty (PackageIdentifier n v) + | v == nullVersion = pretty n -- if no version, don't show version. | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v -- | @@ -64,16 +61,15 @@ instance Pretty PackageIdentifier where -- Nothing instance Parsec PackageIdentifier where parsec = do - comp <- parsec <* P.char '-' xs' <- P.sepByNonEmpty component (P.char '-') (v, xs) <- case simpleParsec (NE.last xs') of Nothing -> return (nullVersion, toList xs') -- all components are version Just v -> return (v, NE.init xs') if not (null xs) && all (\c -> all (/= '.') c && not (all isDigit c)) xs - then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v comp + then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v else fail "all digits or a dot in a portion of package name" where component = P.munch1 (\c -> isAlphaNum c || c == '.') instance NFData PackageIdentifier where - rnf (PackageIdentifier name version compiler) = rnf name `seq` rnf version `seq` rnf compiler + rnf (PackageIdentifier name version) = rnf name `seq` rnf version diff --git a/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs b/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs index 5a4682c7ed3..08305234fbd 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs @@ -10,7 +10,6 @@ import Prelude () import Distribution.Types.PackageId (PackageIdentifier) import Distribution.Types.PackageName (PackageName) import Distribution.Version (Version) -import Distribution.Compiler (CompilerId) import qualified Distribution.Types.PackageId as T @@ -21,8 +20,3 @@ pkgName f s = fmap (\x -> s{T.pkgName = x}) (f (T.pkgName s)) pkgVersion :: Lens' PackageIdentifier Version pkgVersion f s = fmap (\x -> s{T.pkgVersion = x}) (f (T.pkgVersion s)) {-# INLINE pkgVersion #-} - -pkgCompiler :: Lens' PackageIdentifier (Maybe CompilerId) -pkgCompiler f s = fmap (\x -> s{T.pkgCompiler = x}) (f (T.pkgCompiler s)) -{-# INLINE pkgCompiler #-} - diff --git a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs index 5c2b8d9b0b1..013226ca2d5 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs @@ -53,7 +53,7 @@ instance Pretty PackageVersionConstraint where -- Just (PackageVersionConstraint (PackageName "foo") (ThisVersion (mkVersion [2,0]))) instance Parsec PackageVersionConstraint where parsec = do - PackageIdentifier name ver comp <- parsec + PackageIdentifier name ver <- parsec if ver == nullVersion then do P.spaces @@ -64,7 +64,7 @@ instance Parsec PackageVersionConstraint where -- | @since 3.4.0.0 thisPackageVersionConstraint :: PackageIdentifier -> PackageVersionConstraint -thisPackageVersionConstraint (PackageIdentifier pn vr comp) = +thisPackageVersionConstraint (PackageIdentifier pn vr) = PackageVersionConstraint pn (thisVersion vr) -- | @since 3.4.0.0 diff --git a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs index a72fe20f07f..0fba79bcb87 100644 --- a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs +++ b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs @@ -71,9 +71,9 @@ instance HasMungedPackageId PreExistingComponent where mungedId = pc_munged_id instance Package PreExistingComponent where - packageId pec = PackageIdentifier (pc_pkgname pec) v compid + packageId pec = PackageIdentifier (pc_pkgname pec) v where - MungedPackageId _ v compid = pc_munged_id pec + MungedPackageId _ v = pc_munged_id pec instance HasUnitId PreExistingComponent where installedUnitId = pc_uid diff --git a/Cabal/src/Distribution/Backpack/ReadyComponent.hs b/Cabal/src/Distribution/Backpack/ReadyComponent.hs index b871ebff59f..7a3523d5eab 100644 --- a/Cabal/src/Distribution/Backpack/ReadyComponent.hs +++ b/Cabal/src/Distribution/Backpack/ReadyComponent.hs @@ -300,7 +300,6 @@ toReadyComponents pid_map subst0 comps = MungedPackageId (MungedPackageName nonExistentPackageThisIsCabalBug LMainLibName) (mkVersion [0]) - Nothing instc = InstantiatedComponent { instc_insts = Map.toList insts diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index 799e677af17..925bc69d6e1 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -582,7 +582,7 @@ checkSetupBuildInfo (Just (SetupBuildInfo ds _)) = do checkPVPs (checkDependencyVersionRange hasGTLowerBound) gtlck ds checkPackageId :: Monad m => PackageIdentifier -> CheckM m () -checkPackageId (PackageIdentifier pkgName_ _pkgVersion_ _compid) = do +checkPackageId (PackageIdentifier pkgName_ _pkgVersion_) = do checkP (not . FilePath.Windows.isValid . prettyShow $ pkgName_) (PackageDistInexcusable $ InvalidNameWin pkgName_) diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 008a270848f..402f27467d2 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -821,7 +821,7 @@ testSuiteLibV09AsLibAndExe } -- This is, like, the one place where we use a CTestName for a library. -- Should NOT use library name, since that could conflict! - PackageIdentifier pkg_name pkg_ver _pkg_compid = package pkg_descr + PackageIdentifier pkg_name pkg_ver = package pkg_descr -- Note: we do make internal library from the test! compat_name = MungedPackageName pkg_name (LSubLibName (testName test)) compat_key = computeCompatPackageKey (compiler lbi) compat_name pkg_ver (componentUnitId clbi) diff --git a/Cabal/src/Distribution/Simple/Build/Macros.hs b/Cabal/src/Distribution/Simple/Build/Macros.hs index e71d5a4a644..f3c51d71c96 100644 --- a/Cabal/src/Distribution/Simple/Build/Macros.hs +++ b/Cabal/src/Distribution/Simple/Build/Macros.hs @@ -67,11 +67,11 @@ generateCabalMacrosHeader pkg_descr lbi clbi = , Z.zMangleStr = map fixchar } where - getPid (_, MungedPackageId (MungedPackageName pn _) v compid) = + getPid (_, MungedPackageId (MungedPackageName pn _) v) = -- NB: Drop the library name! We're just reporting package versions. -- This would have to be revisited if you are allowed to depend -- on different versions of the same package - PackageIdentifier pn v compid + PackageIdentifier pn v -- | Helper function that generates just the @VERSION_pkg@ and @MIN_VERSION_pkg@ -- macros for a list of package ids (usually used with the specific deps of @@ -91,7 +91,7 @@ generatePackageVersionMacros ver pkgids = } mkZPackage :: PackageId -> Z.ZPackage -mkZPackage (PackageIdentifier name ver compid) = +mkZPackage (PackageIdentifier name ver) = Z.ZPackage { Z.zpkgName = name , Z.zpkgVersion = ver diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index a76b4359bc9..7c96efb33fc 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -335,7 +335,7 @@ writePersistBuildConfig mbWorkDir distPref lbi = do -- | Identifier of the current Cabal package. currentCabalId :: PackageIdentifier -currentCabalId = PackageIdentifier (mkPackageName "Cabal") cabalVersion Nothing +currentCabalId = PackageIdentifier (mkPackageName "Cabal") cabalVersion -- | Identifier of the current compiler package. currentCompilerId :: PackageIdentifier @@ -343,7 +343,6 @@ currentCompilerId = PackageIdentifier (mkPackageName System.Info.compilerName) (mkVersion' System.Info.compilerVersion) - Nothing -- | Parse the @setup-config@ file header, returning the package identifiers -- for Cabal and the compiler. @@ -1988,7 +1987,7 @@ selectDependency -- It's an internal library, and we're not per-component build do_internal lib | Set.member lib internalIndex = - Right $ InternalDependency $ PackageIdentifier dep_pkgname (packageVersion pkgid) (pkgCompiler pkgid) + Right $ InternalDependency $ PackageIdentifier dep_pkgname $ packageVersion pkgid | otherwise = Left $ DependencyMissingInternal dep_pkgname lib diff --git a/Cabal/src/Distribution/Simple/PackageIndex.hs b/Cabal/src/Distribution/Simple/PackageIndex.hs index 6e115ca65a5..a7d23962b72 100644 --- a/Cabal/src/Distribution/Simple/PackageIndex.hs +++ b/Cabal/src/Distribution/Simple/PackageIndex.hs @@ -169,7 +169,7 @@ instance Semigroup (PackageIndex IPI.InstalledPackageInfo) where {-# NOINLINE invariant #-} invariant :: WithCallStack (InstalledPackageIndex -> Bool) invariant (PackageIndex pids pnames) = - trace (show pids' ++ "\n" ++ show pnames') $ + -- trace (show pids' ++ "\n" ++ show pnames') $ pids' == pnames' where pids' = map installedUnitId (Map.elems pids) @@ -335,21 +335,16 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = Just pvers -> case Map.lookup (packageVersion pkgid) pvers of Nothing -> original Just pkgs -> - traceShow (pkgid, pkgs) $ mkPackageIndex - (Map.update deletePkgInstance (installedUnitId pkgid) pids) + mkPackageIndex + (foldl' (flip (Map.delete . installedUnitId)) pids pkgs) (deletePkgName pnames) where deletePkgName = Map.update deletePkgVersion (packageName pkgid, LMainLibName) - deletePkgVersion :: Map Version [IPI.InstalledPackageInfo] -> Maybe (Map Version [IPI.InstalledPackageInfo]) deletePkgVersion = (\m -> if Map.null m then Nothing else Just m) - . Map.update deletePkgInstance (packageVersion pkgid) - - deletePkgInstance :: [IPI.InstalledPackageInfo] -> Maybe [IPI.InstalledPackageInfo] - deletePkgInstance xs = if null xs' then Nothing else Just xs' - where xs' = [x | x <- xs, pkgCompiler pkgid /= pkgCompiler (IPI.sourcePackageId x)] + . Map.delete (packageVersion pkgid) -- | Removes all packages with this (case-sensitive) name from the index. -- diff --git a/Cabal/src/Distribution/Types/PackageName/Magic.hs b/Cabal/src/Distribution/Types/PackageName/Magic.hs index 908e82bea6f..022a62468b1 100644 --- a/Cabal/src/Distribution/Types/PackageName/Magic.hs +++ b/Cabal/src/Distribution/Types/PackageName/Magic.hs @@ -21,4 +21,4 @@ fakePackageCabalFileName = "fake-package.cabal" -- | 'fakePackageName' with 'version0'. fakePackageId :: PackageId -fakePackageId = PackageIdentifier fakePackageName version0 Nothing +fakePackageId = PackageIdentifier fakePackageName version0 diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index 6ae45e569fc..d391345d0eb 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -39,7 +39,7 @@ convCP iidx sidx (CP qpi fa es ds) = } -- "In repo" i.e. a source package (PI qpn@(Q _path pn) (I stage v InRepo)) -> - let pi = PackageIdentifier pn v Nothing {-# FIXME: should be COMPILERID #-} in + let pi = PackageIdentifier pn v in Configured $ SolverPackage { solverPkgQPN = qpn, @@ -70,4 +70,4 @@ convConfId (PI (Q (PackagePath _ q) pn) (I _stage v loc)) = , pn == pn' -> Right (PlannedId sourceId) | otherwise -> Left (PlannedId sourceId) where - sourceId = PackageIdentifier pn v Nothing -- FIXME: this should be the compiler id! + sourceId = PackageIdentifier pn v diff --git a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs index 868d1d9dfe2..15fb9d510ec 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs @@ -31,8 +31,8 @@ instance Structured InstSolverPackage instance Package InstSolverPackage where packageId i = -- HACK! See Note [Index conversion with internal libraries] - let MungedPackageId mpn v compid = mungedId i - in PackageIdentifier (encodeCompatPackageName mpn) v compid + let MungedPackageId mpn v = mungedId i + in PackageIdentifier (encodeCompatPackageName mpn) v instance HasMungedPackageId InstSolverPackage where mungedId = mungedId . instSolverPkgIPI diff --git a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs index a6febfcca50..ce1d1665327 100644 --- a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs +++ b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs @@ -103,7 +103,7 @@ newBuildReport os' arch' comp pkgid flags deps result = cabalInstallID :: PackageIdentifier cabalInstallID = - PackageIdentifier (mkPackageName "cabal-install") cabalInstallVersion Nothing + PackageIdentifier (mkPackageName "cabal-install") cabalInstallVersion ------------------------------------------------------------------------------- -- FieldGrammar diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 7f3812d69b4..65f8a06ac97 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -1057,7 +1057,7 @@ configuredPackageProblems (sort $ map fst (PD.unFlagAssignment specifiedFlags)) -- TODO packageSatisfiesDependency :: PackageIdentifier -> Dependency -> Bool packageSatisfiesDependency - (PackageIdentifier name version _compid) + (PackageIdentifier name version) (Dependency name' versionRange _) = assert (name == name') $ version `withinRange` versionRange diff --git a/cabal-install/src/Distribution/Client/IndexUtils.hs b/cabal-install/src/Distribution/Client/IndexUtils.hs index 0cd842d663e..6027f5e53f3 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils.hs @@ -617,7 +617,7 @@ extractPkg verbosity entry blockNo = case Tar.entryContent entry of [pkgname, vers, _] -> case simpleParsec vers of Just ver -> Just . return $ Just (NormalPackage pkgid descr content blockNo) where - pkgid = PackageIdentifier (mkPackageName pkgname) ver Nothing + pkgid = PackageIdentifier (mkPackageName pkgname) ver parsed = parseGenericPackageDescriptionMaybe (BS.toStrict content) descr = case parsed of Just d -> d @@ -1269,10 +1269,10 @@ hashConsCache cache0 = go !pns !pvs (CachePackageId pid bno ts : rest) = CachePackageId pid' bno ts : go pns' pvs' rest where - !pid' = PackageIdentifier pn' pv' compid + !pid' = PackageIdentifier pn' pv' (!pn', !pns') = mapIntern pn pns (!pv', !pvs') = mapIntern pv pvs - PackageIdentifier pn pv compid = pid + PackageIdentifier pn pv = pid go pns pvs (x : xs) = x : go pns pvs xs mapIntern :: Ord k => k -> Map.Map k k -> (k, Map.Map k k) @@ -1395,7 +1395,7 @@ read00IndexCacheEntry = \line -> (Just pkgname, Just pkgver, Just blockno) -> Just ( CachePackageId - (PackageIdentifier pkgname pkgver Nothing) + (PackageIdentifier pkgname pkgver) blockno NoTimestamp ) diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 7f32d51ac3d..6c9a605c553 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -1101,7 +1101,7 @@ theSpecifiedPackage :: Package pkg => PackageSpecifier pkg -> Maybe PackageId theSpecifiedPackage pkgSpec = case pkgSpec of NamedPackage name [PackagePropertyVersion version] -> - PackageIdentifier name <$> trivialRange version <*> Nothing + PackageIdentifier name <$> trivialRange version NamedPackage _ _ -> Nothing SpecificSourcePackage pkg -> Just $ packageId pkg where diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index d99fc9ad250..38240c3888a 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -133,7 +133,7 @@ hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = , showHashValue (truncateHash 20 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version _compid = pkgHashPkgId + PackageIdentifier name version = pkgHashPkgId -- Truncate a string, with a visual indication that it is truncated. truncateStr n s @@ -172,7 +172,7 @@ hashedInstalledPackageIdVeryShort pkghashinputs@PackageHashInputs{pkgHashPkgId} , showHashValue (truncateHash 4 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version _compid = pkgHashPkgId + PackageIdentifier name version = pkgHashPkgId -- | All the information that contributes to a package's hash, and thus its -- 'InstalledPackageId'. diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index d46045c849a..55042e212cd 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -1068,7 +1068,7 @@ getExternalSetupMethod verbosity options pkg bt = do debug verbosity "Setup executable needs to be updated, compiling..." (compiler, progdb, options'') <- configureCompiler options' pkgDbs <- traverse (traverse (makeRelativeToDirS mbWorkDir)) (coercePackageDBStack (usePackageDB options'')) - let cabalPkgid = PackageIdentifier (mkPackageName "Cabal") cabalLibVersion Nothing + let cabalPkgid = PackageIdentifier (mkPackageName "Cabal") cabalLibVersion (program, extraOpts) = case compilerFlavor compiler of GHCJS -> (ghcjsProgram, ["-build-runner"]) @@ -1155,5 +1155,5 @@ getExternalSetupMethod verbosity options pkg bt = do return $ i setupProgFile isCabalPkgId, isBasePkgId :: PackageIdentifier -> Bool -isCabalPkgId (PackageIdentifier pname _ _compid) = pname == mkPackageName "Cabal" -isBasePkgId (PackageIdentifier pname _ _compid) = pname == mkPackageName "base" +isCabalPkgId (PackageIdentifier pname _) = pname == mkPackageName "Cabal" +isBasePkgId (PackageIdentifier pname _) = pname == mkPackageName "base" diff --git a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs index 631dbde5afe..17dcf6d9398 100644 --- a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs +++ b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs @@ -218,7 +218,7 @@ showPlanProblem (PackageInconsistency name inconsistencies) = [ " package " ++ prettyShow pkg ++ " requires " - ++ prettyShow (PackageIdentifier name ver Nothing) + ++ prettyShow (PackageIdentifier name ver) | (pkg, ver) <- inconsistencies ] showPlanProblem (PackageStateInvalid pkg pkg') = diff --git a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs index 6a6503aaf4c..0a5700174b8 100644 --- a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs +++ b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs @@ -109,7 +109,7 @@ relaxedDepStarP = -- continuation after package identifier relaxedDepPkgidP :: CabalParsing m => PackageIdentifier -> m RelaxedDep -relaxedDepPkgidP pid@(PackageIdentifier pn v _compid) +relaxedDepPkgidP pid@(PackageIdentifier pn v) | pn == mkPackageName "all" , v == nullVersion = RelaxedDep RelaxDepScopeAll <$ P.char ':' <*> modP <*> parsec From f8600655624c8cc2cdd2fb16237ab115828e3754 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:54:49 +0900 Subject: [PATCH 52/82] fixup! Add compiler to PackageId --- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index a55f6bee2da..9590c2e010c 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1043,7 +1043,7 @@ reportPlanningFailure projectConfig Toolchain{toolchainCompiler = comp, toolchai theSpecifiedPackage pkgSpec = case pkgSpec of NamedPackage name [PackagePropertyVersion version] -> - PackageIdentifier name <$> trivialRange version + PackageIdentifier name <$> trivialRange version <*> Nothing NamedPackage _ _ -> Nothing SpecificSourcePackage pkg -> Just $ packageId pkg -- \| If a range includes only a single version, return Just that version. From ad675ad5be14e56d3443b64943b378b91647c29e Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:55:26 +0900 Subject: [PATCH 53/82] Revert "fixup! Add compiler to PackageId" This reverts commit f8600655624c8cc2cdd2fb16237ab115828e3754. --- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 9590c2e010c..a55f6bee2da 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1043,7 +1043,7 @@ reportPlanningFailure projectConfig Toolchain{toolchainCompiler = comp, toolchai theSpecifiedPackage pkgSpec = case pkgSpec of NamedPackage name [PackagePropertyVersion version] -> - PackageIdentifier name <$> trivialRange version <*> Nothing + PackageIdentifier name <$> trivialRange version NamedPackage _ _ -> Nothing SpecificSourcePackage pkg -> Just $ packageId pkg -- \| If a range includes only a single version, return Just that version. From 125921422d2cacef165db2a17c032db0d08ebcf6 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:57:16 +0900 Subject: [PATCH 54/82] fixup! Add compiler to PackageId --- .../Solver/Modular/IndexConversion.hs | 4 ++-- .../Distribution/Client/ProjectPlanning.hs | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index 9ab501e904a..a1a27b9bb33 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -85,7 +85,7 @@ convIPI' toolchains (ShadowPkgs sip) idx = -- | Extract/recover the package ID from an installed package info, and convert it to a solver's I. convId :: Toolchains -> IPI.InstalledPackageInfo -> (PN, I) convId toolchains ipi = (pn, I stage ver $ Inst $ IPI.installedUnitId ipi) - where MungedPackageId mpn ver = mungedId ipi + where MungedPackageId mpn ver compid = mungedId ipi -- HACK. See Note [Index conversion with internal libraries] pn = encodeCompatPackageName mpn stage = case IPI.pkgCompiler ipi of @@ -169,7 +169,7 @@ convSPI' toolchains constraints strfl solveExes = -- | Convert a single source package into the solver-specific format. convSP :: Toolchains -> Map PN [LabeledPackageConstraint] -> StrongFlags -> SolveExecutables -> SourcePackage loc -> [(PN, I, PInfo)] -convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) = +convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv _compid) gpd _ _pl) = let pkgConstraints = fromMaybe [] $ M.lookup pn constraints in [(pn, I Host pv InRepo, convGPD (hostToolchain toolchains) pkgConstraints strfl solveExes pn gpd) ,(pn, I Build pv InRepo, convGPD (buildToolchain toolchains) pkgConstraints strfl solveExes pn gpd)] diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index a55f6bee2da..c2d46bd188a 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -198,6 +198,7 @@ import Distribution.Types.GivenComponent import Distribution.Types.LibraryName import qualified Distribution.Types.LocalBuildConfig as LBC import Distribution.Types.PackageVersionConstraint +import qualified Distribution.Types.PackageId as PI import Distribution.Types.PkgconfigDependency import Distribution.Types.UnqualComponentName @@ -791,8 +792,21 @@ rebuildInstallPlan -- } -- deriving (Eq, Generic, Show, Read) -- - -- can probably use fromList $ Map.elems $ on it. + -- let mapPkgIdx f = PI.fromList . map f . PI.allPackages + -- let updateIPI :: IPI.InstalledPackageInfo -> IPI.InstalledPackageInfo + -- updateIPI ipi = ipi { + -- IPI.sourcePackageId = (IPI.sourcePackageId ipi){ PI.pkgCompiler = IPI.pkgCompiler ipi } + -- } + -- let addCompilerToSourcePkg :: CompilerId -> [PackageSpecifier UnresolvedSourcePackage] -> [PackageSpecifier UnresolvedSourcePackage] + -- addCompilerToSourcePkg compilerId = map (addCompilerId compilerId) + -- addCompilerId :: CompilerId -> PackageSpecifier UnresolvedSourcePackage -> PackageSpecifier UnresolvedSourcePackage + -- addCompilerId compilerId (NamedPackage name props) = NamedPackage name props + -- addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (f pkg) + -- where f :: SourcePackage UnresolvedPkgLoc -> SourcePackage UnresolvedPkgLoc + -- f pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} + hinstalledPkgIndex <- + -- mapPkgIdx updateIPI <$> getInstalledPackages verbosity (hostToolchain toolchains) @@ -802,6 +816,7 @@ rebuildInstallPlan -- for now. FIXME! -- let hinstalledPkgIndex' = PI.fromList $ PI.allPackages hinstalledPkgIndex binstalledPkgIndex <- + -- mapPkgIdx updateIPI <$> getInstalledPackages verbosity (buildToolchain toolchains) @@ -809,6 +824,8 @@ rebuildInstallPlan -- if host and build compiler are the same, we want to get -package-db in here. (corePackageDbs $ if buildIsHost toolchains then Host else Build) + -- let localPackages' = addCompilerToSourcePkg (compilerId . toolchainCompiler . hostToolchain $ toolchains) localPackages + (sourcePkgDb, tis, ar) <- getSourcePackages verbosity From 02f17b1951a1ddeb5f20fc41b16bb1b9bb709bab Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:57:33 +0900 Subject: [PATCH 55/82] Revert "fixup! Add compiler to PackageId" This reverts commit 125921422d2cacef165db2a17c032db0d08ebcf6. --- .../Solver/Modular/IndexConversion.hs | 4 ++-- .../Distribution/Client/ProjectPlanning.hs | 19 +------------------ 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index a1a27b9bb33..9ab501e904a 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -85,7 +85,7 @@ convIPI' toolchains (ShadowPkgs sip) idx = -- | Extract/recover the package ID from an installed package info, and convert it to a solver's I. convId :: Toolchains -> IPI.InstalledPackageInfo -> (PN, I) convId toolchains ipi = (pn, I stage ver $ Inst $ IPI.installedUnitId ipi) - where MungedPackageId mpn ver compid = mungedId ipi + where MungedPackageId mpn ver = mungedId ipi -- HACK. See Note [Index conversion with internal libraries] pn = encodeCompatPackageName mpn stage = case IPI.pkgCompiler ipi of @@ -169,7 +169,7 @@ convSPI' toolchains constraints strfl solveExes = -- | Convert a single source package into the solver-specific format. convSP :: Toolchains -> Map PN [LabeledPackageConstraint] -> StrongFlags -> SolveExecutables -> SourcePackage loc -> [(PN, I, PInfo)] -convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv _compid) gpd _ _pl) = +convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) = let pkgConstraints = fromMaybe [] $ M.lookup pn constraints in [(pn, I Host pv InRepo, convGPD (hostToolchain toolchains) pkgConstraints strfl solveExes pn gpd) ,(pn, I Build pv InRepo, convGPD (buildToolchain toolchains) pkgConstraints strfl solveExes pn gpd)] diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index c2d46bd188a..a55f6bee2da 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -198,7 +198,6 @@ import Distribution.Types.GivenComponent import Distribution.Types.LibraryName import qualified Distribution.Types.LocalBuildConfig as LBC import Distribution.Types.PackageVersionConstraint -import qualified Distribution.Types.PackageId as PI import Distribution.Types.PkgconfigDependency import Distribution.Types.UnqualComponentName @@ -792,21 +791,8 @@ rebuildInstallPlan -- } -- deriving (Eq, Generic, Show, Read) -- - -- let mapPkgIdx f = PI.fromList . map f . PI.allPackages - -- let updateIPI :: IPI.InstalledPackageInfo -> IPI.InstalledPackageInfo - -- updateIPI ipi = ipi { - -- IPI.sourcePackageId = (IPI.sourcePackageId ipi){ PI.pkgCompiler = IPI.pkgCompiler ipi } - -- } - -- let addCompilerToSourcePkg :: CompilerId -> [PackageSpecifier UnresolvedSourcePackage] -> [PackageSpecifier UnresolvedSourcePackage] - -- addCompilerToSourcePkg compilerId = map (addCompilerId compilerId) - -- addCompilerId :: CompilerId -> PackageSpecifier UnresolvedSourcePackage -> PackageSpecifier UnresolvedSourcePackage - -- addCompilerId compilerId (NamedPackage name props) = NamedPackage name props - -- addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (f pkg) - -- where f :: SourcePackage UnresolvedPkgLoc -> SourcePackage UnresolvedPkgLoc - -- f pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} - + -- can probably use fromList $ Map.elems $ on it. hinstalledPkgIndex <- - -- mapPkgIdx updateIPI <$> getInstalledPackages verbosity (hostToolchain toolchains) @@ -816,7 +802,6 @@ rebuildInstallPlan -- for now. FIXME! -- let hinstalledPkgIndex' = PI.fromList $ PI.allPackages hinstalledPkgIndex binstalledPkgIndex <- - -- mapPkgIdx updateIPI <$> getInstalledPackages verbosity (buildToolchain toolchains) @@ -824,8 +809,6 @@ rebuildInstallPlan -- if host and build compiler are the same, we want to get -package-db in here. (corePackageDbs $ if buildIsHost toolchains then Host else Build) - -- let localPackages' = addCompilerToSourcePkg (compilerId . toolchainCompiler . hostToolchain $ toolchains) localPackages - (sourcePkgDb, tis, ar) <- getSourcePackages verbosity From 7c321e32f5730929a3c95b95a7373907acd3dcd4 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 13:39:48 +0900 Subject: [PATCH 56/82] Add build package index --- .../src/Distribution/Solver/Modular.hs | 8 ++++---- .../Solver/Modular/ConfiguredConversion.hs | 12 +++++++----- .../Solver/Modular/IndexConversion.hs | 11 +++++++---- .../Solver/Types/DependencyResolver.hs | 3 ++- .../src/Distribution/Client/Configure.hs | 1 + .../src/Distribution/Client/Dependency.hs | 19 +++++++++++++++---- .../src/Distribution/Client/Fetch.hs | 2 +- .../src/Distribution/Client/Freeze.hs | 2 +- cabal-install/src/Distribution/Client/Get.hs | 2 +- .../src/Distribution/Client/Install.hs | 1 + .../Distribution/Client/ProjectPlanning.hs | 8 ++++++-- 11 files changed, 46 insertions(+), 23 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular.hs b/cabal-install-solver/src/Distribution/Solver/Modular.hs index 733cdc87aa0..f72a0bda371 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular.hs @@ -80,14 +80,14 @@ showCP (CP qpi fa es ds) = -- | Ties the two worlds together: classic cabal-install vs. the modular -- solver. Performs the necessary translations before and after. modularResolver :: SolverConfig -> DependencyResolver loc -modularResolver sc toolchains iidx sidx pkgConfigDB pprefs pcs pns = do - (assignment, revdepmap) <- solve' sc toolchains idx pkgConfigDB pprefs gcs pns +modularResolver sc toolchains biidx iidx sidx pkgConfigDB pprefs pcs pns = do + (assignment, revdepmap) <- solve' sc toolchains (trace (showIdx idx) idx) pkgConfigDB pprefs gcs pns let cp = toCPs assignment revdepmap Step (show (vcat (map showCP cp))) $ return $ postprocess assignment revdepmap where -- Indices have to be converted into solver-specific uniform index. - idx = convPIs toolchains gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) iidx sidx + idx = convPIs toolchains gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) biidx iidx sidx -- Constraints have to be converted into a finite map indexed by PN. gcs = M.fromListWith (++) (map pair pcs) where @@ -97,7 +97,7 @@ modularResolver sc toolchains iidx sidx pkgConfigDB pprefs pcs pns = do -- package qualifiers, which means that linked packages become duplicates -- and can be removed. postprocess a rdm = ordNubBy nodeKey $ - map (convCP iidx sidx) (toCPs a rdm) + map (convCP biidx iidx sidx) (toCPs a rdm) -- Helper function to extract the PN from a constraint. pcName :: PackageConstraint -> PN diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index d391345d0eb..69e41072547 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -19,21 +19,23 @@ import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SolverPackage import Distribution.Solver.Types.InstSolverPackage import Distribution.Solver.Types.SourcePackage +import Control.Applicative ((<|>)) -- | Converts from the solver specific result @CP QPN@ into -- a 'ResolverPackage', which can then be converted into -- the install plan. -convCP :: SI.InstalledPackageIndex -> - CI.PackageIndex (SourcePackage loc) -> - CP QPN -> ResolverPackage loc -convCP iidx sidx (CP qpi fa es ds) = +convCP :: SI.InstalledPackageIndex -- ^ build + -> SI.InstalledPackageIndex -- ^ host + -> CI.PackageIndex (SourcePackage loc) + -> CP QPN -> ResolverPackage loc +convCP biidx iidx sidx (CP qpi fa es ds) = case qpi of -- Installed (PI qpn (I _stage _ (Inst pi))) -> PreExisting $ InstSolverPackage { instSolverQPN = qpn, - instSolverPkgIPI = fromMaybe (error "convCP: lookupUnitId failed") $ SI.lookupUnitId iidx pi, + instSolverPkgIPI = fromMaybe (error "convCP: lookupUnitId failed") $ (SI.lookupUnitId iidx pi) <|> (SI.lookupUnitId biidx pi), instSolverPkgLibDeps = fmap fst ds', instSolverPkgExeDeps = fmap snd ds' } diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index 9ab501e904a..2fc84f84697 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -58,11 +58,14 @@ import Distribution.Solver.Modular.Version -- explicitly requested. convPIs :: Toolchains -> Map PN [LabeledPackageConstraint] -> ShadowPkgs -> StrongFlags -> SolveExecutables - -> SI.InstalledPackageIndex -> CI.PackageIndex (SourcePackage loc) + -> SI.InstalledPackageIndex -- ^ build + -> SI.InstalledPackageIndex -- ^ host + -> CI.PackageIndex (SourcePackage loc) -> Index -convPIs toolchains constraints sip strfl solveExes iidx sidx = - mkIndex $ - convIPI' toolchains sip iidx ++ convSPI' toolchains constraints strfl solveExes sidx + where bipis = convIPI' toolchains sip biidx + hipis = convIPI' toolchains sip iidx + ipis = bipis ++ hipis + spis = convSPI' toolchains constraints strfl solveExes sidx -- | Convert a Cabal installed package index to the simpler, -- more uniform index format of the solver. diff --git a/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs b/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs index d4e9c2ea707..3306ac620de 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs @@ -28,7 +28,8 @@ import Distribution.System ( Platform ) -- in alternatives. -- type DependencyResolver loc = Toolchains - -> InstalledPackageIndex + -> InstalledPackageIndex -- ^ build + -> InstalledPackageIndex -- ^ host -> PackageIndex (SourcePackage loc) -> Maybe PkgConfigDb -> (PackageName -> PackagePreferences) diff --git a/cabal-install/src/Distribution/Client/Configure.hs b/cabal-install/src/Distribution/Client/Configure.hs index f62ee83e61c..bc3c24f9245 100644 --- a/cabal-install/src/Distribution/Client/Configure.hs +++ b/cabal-install/src/Distribution/Client/Configure.hs @@ -464,6 +464,7 @@ planLocalPackage . setSolveExecutables (SolveExecutables False) . setSolverVerbosity verbosity $ standardInstallPolicy + mempty {- build pkgs -} installedPkgIndex -- NB: We pass in an *empty* source package database, -- because cabal configure assumes that all dependencies diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 65f8a06ac97..8bde68b8112 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -181,6 +181,7 @@ data DepResolverParams = DepResolverParams , depResolverPreferences :: [PackagePreference] , depResolverPreferenceDefault :: PackagesPreferenceDefault , depResolverInstalledPkgIndex :: InstalledPackageIndex + , depResolverBuildInstalledPkgIndex :: InstalledPackageIndex , depResolverSourcePkgIndex :: PackageIndex.PackageIndex UnresolvedSourcePackage , depResolverReorderGoals :: ReorderGoals , depResolverCountConflicts :: CountConflicts @@ -277,15 +278,17 @@ showPackagePreference (PackageStanzasPreference pn st) = basicDepResolverParams :: InstalledPackageIndex + -> InstalledPackageIndex -> PackageIndex.PackageIndex UnresolvedSourcePackage -> DepResolverParams -basicDepResolverParams installedPkgIndex sourcePkgIndex = +basicDepResolverParams buildInstalledPkgIndex installedPkgIndex sourcePkgIndex= DepResolverParams { depResolverTargets = Set.empty , depResolverConstraints = [] , depResolverPreferences = [] , depResolverPreferenceDefault = PreferLatestForSelected , depResolverInstalledPkgIndex = installedPkgIndex + , depResolverBuildInstalledPkgIndex = buildInstalledPkgIndex , depResolverSourcePkgIndex = sourcePkgIndex , depResolverReorderGoals = ReorderGoals False , depResolverCountConflicts = CountConflicts True @@ -702,11 +705,13 @@ reinstallTargets params = -- | A basic solver policy on which all others are built. basicInstallPolicy - :: InstalledPackageIndex + :: InstalledPackageIndex -- ^ Build + -> InstalledPackageIndex -- ^ Host -> SourcePackageDb -> [PackageSpecifier UnresolvedSourcePackage] -> DepResolverParams basicInstallPolicy + binstalledPkgIndex installedPkgIndex (SourcePackageDb sourcePkgIndex sourcePkgPrefs) pkgSpecifiers = @@ -723,6 +728,7 @@ basicInstallPolicy . addSourcePackages [pkg | SpecificSourcePackage pkg <- pkgSpecifiers] $ basicDepResolverParams + binstalledPkgIndex installedPkgIndex sourcePkgIndex @@ -731,13 +737,15 @@ basicInstallPolicy -- -- It extends the 'basicInstallPolicy' with a policy on setup deps. standardInstallPolicy - :: InstalledPackageIndex + :: InstalledPackageIndex -- ^ Build + -> InstalledPackageIndex -- ^ Host -> SourcePackageDb -> [PackageSpecifier UnresolvedSourcePackage] -> DepResolverParams -standardInstallPolicy installedPkgIndex sourcePkgDb pkgSpecifiers = +standardInstallPolicy binstalledPkgIndex installedPkgIndex sourcePkgDb pkgSpecifiers = addDefaultSetupDependencies mkDefaultSetupDeps $ basicInstallPolicy + binstalledPkgIndex installedPkgIndex sourcePkgDb pkgSpecifiers @@ -810,6 +818,7 @@ resolveDependencies toolchains pkgConfigDB params = (PruneAfterFirstSuccess False) ) toolchains + binstalledPkgIndex installedPkgIndex sourcePkgIndex pkgConfigDB @@ -823,6 +832,7 @@ resolveDependencies toolchains pkgConfigDB params = prefs defpref installedPkgIndex + binstalledPkgIndex sourcePkgIndex reordGoals cntConflicts @@ -1141,6 +1151,7 @@ resolveWithoutDependencies prefs defpref installedPkgIndex + binstalledPkgIndex sourcePkgIndex _reorderGoals _countConflicts diff --git a/cabal-install/src/Distribution/Client/Fetch.hs b/cabal-install/src/Distribution/Client/Fetch.hs index abe6d181a7f..e66acf66cc6 100644 --- a/cabal-install/src/Distribution/Client/Fetch.hs +++ b/cabal-install/src/Distribution/Client/Fetch.hs @@ -220,7 +220,7 @@ planPackages -- already installed. Since we want to get the source packages of -- things we might have installed (but not have the sources for). . reinstallTargets - $ standardInstallPolicy installedPkgIndex sourcePkgDb pkgSpecifiers + $ standardInstallPolicy mempty {-build-} installedPkgIndex sourcePkgDb pkgSpecifiers includeDependencies = fromFlag (fetchDeps fetchFlags) logMsg message rest = debug verbosity message >> rest diff --git a/cabal-install/src/Distribution/Client/Freeze.hs b/cabal-install/src/Distribution/Client/Freeze.hs index abcc69797f9..e6a5190260f 100644 --- a/cabal-install/src/Distribution/Client/Freeze.hs +++ b/cabal-install/src/Distribution/Client/Freeze.hs @@ -245,7 +245,7 @@ planPackages in LabeledPackageConstraint pc ConstraintSourceFreeze | pkgSpecifier <- pkgSpecifiers ] - $ standardInstallPolicy installedPkgIndex sourcePkgDb pkgSpecifiers + $ standardInstallPolicy mempty {- build -} installedPkgIndex sourcePkgDb pkgSpecifiers logMsg message rest = debug verbosity message >> rest diff --git a/cabal-install/src/Distribution/Client/Get.hs b/cabal-install/src/Distribution/Client/Get.hs index 39ace2f2652..08029a53b8d 100644 --- a/cabal-install/src/Distribution/Client/Get.hs +++ b/cabal-install/src/Distribution/Client/Get.hs @@ -148,7 +148,7 @@ get verbosity repoCtxt globalFlags getFlags userTargets = do resolverParams :: SourcePackageDb -> [PackageSpecifier UnresolvedSourcePackage] -> DepResolverParams resolverParams sourcePkgDb pkgSpecifiers = -- TODO: add command-line constraint and preference args for unpack - standardInstallPolicy mempty sourcePkgDb pkgSpecifiers + standardInstallPolicy mempty mempty sourcePkgDb pkgSpecifiers onlyPkgDescr = fromFlagOrDefault False (getOnlyPkgDescr getFlags) diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 6c9a605c553..2fb03562f24 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -650,6 +650,7 @@ planPackages -- doesn't understand how to install them . setSolveExecutables (SolveExecutables False) $ standardInstallPolicy + mempty {- build pkgs -} installedPkgIndex sourcePkgDb pkgSpecifiers diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index a55f6bee2da..76fcbf9bc21 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -837,7 +837,8 @@ rebuildInstallPlan verbosity toolchains solverSettings - (installedPackages <> hinstalledPkgIndex <> binstalledPkgIndex) + binstalledPkgIndex + (installedPackages <> hinstalledPkgIndex) sourcePkgDb pkgConfigDB localPackages @@ -1322,7 +1323,8 @@ planPackages :: Verbosity -> Toolchains -> SolverSettings - -> InstalledPackageIndex + -> InstalledPackageIndex -- ^ Build Installed Package Index + -> InstalledPackageIndex -- ^ Host Installed Package Index -> SourcePackageDb -> Maybe PkgConfigDb -> [PackageSpecifier UnresolvedSourcePackage] @@ -1332,6 +1334,7 @@ planPackages verbosity toolchains SolverSettings{..} + binstalledPkgIndex installedPkgIndex sourcePkgDb pkgConfigDB @@ -1461,6 +1464,7 @@ planPackages -- Note: we don't use the standardInstallPolicy here, since that uses -- its own addDefaultSetupDependencies that is not appropriate for us. basicInstallPolicy + binstalledPkgIndex installedPkgIndex sourcePkgDb localPackages From 409e01fc55aee741e7ab23c1d1ae1663e6760456 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 25 Mar 2025 12:52:54 +0900 Subject: [PATCH 57/82] Prevent NonReinstallable Packages from Setup dependencies. --- cabal-install/src/Distribution/Client/Dependency.hs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 8bde68b8112..645e81b1873 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -452,7 +452,16 @@ dontInstallNonReinstallablePackages params = ConstraintSourceNonReinstallablePackage | pkgname <- nonReinstallablePackages ] - +dontInstallNonReinstallablePackagesSetupOnly :: DepResolverParams -> DepResolverParams +dontInstallNonReinstallablePackagesSetupOnly params = + addConstraints extraConstraints params + where + extraConstraints = + [ LabeledPackageConstraint + (PackageConstraint (ScopeAnySetupQualifier pkgname) PackagePropertyInstalled) + ConstraintSourceNonReinstallablePackage + | pkgname <- nonReinstallablePackages + ] -- | The set of non-reinstallable packages includes those which cannot be -- rebuilt using a GHC installation and Hackage-published source distribution. -- There are a few reasons why this might be true: @@ -851,7 +860,7 @@ resolveDependencies toolchains pkgConfigDB params = verbosity ) = if asBool (depResolverAllowBootLibInstalls params) - then params + then dontInstallNonReinstallablePackagesSetupOnly params else dontInstallNonReinstallablePackages params preferences :: PackageName -> PackagePreferences From bb2f2e1000410e95b1d0067165ee1445806c9213 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:52:30 +0900 Subject: [PATCH 58/82] Add compiler to PackageId (cherry picked from commit 79b31e10d39ee54e68e2055587728b4f92c49145) --- Cabal-syntax/src/Distribution/Compiler.hs | 2 +- .../PackageDescription/FieldGrammar.hs | 4 +++- .../Distribution/Types/InstalledPackageInfo.hs | 10 +++++----- .../Types/InstalledPackageInfo/FieldGrammar.hs | 13 ++++++++----- .../src/Distribution/Types/MungedPackageId.hs | 17 ++++++++++------- .../Distribution/Types/PackageDescription.hs | 1 + .../src/Distribution/Types/PackageId.hs | 12 ++++++++---- .../src/Distribution/Types/PackageId/Lens.hs | 6 ++++++ .../Types/PackageVersionConstraint.hs | 4 ++-- .../Backpack/PreExistingComponent.hs | 4 ++-- .../src/Distribution/Backpack/ReadyComponent.hs | 1 + .../Distribution/PackageDescription/Check.hs | 2 +- Cabal/src/Distribution/Simple/Build.hs | 2 +- Cabal/src/Distribution/Simple/Build/Macros.hs | 6 +++--- Cabal/src/Distribution/Simple/Configure.hs | 5 +++-- Cabal/src/Distribution/Simple/PackageIndex.hs | 13 +++++++++---- .../src/Distribution/Types/PackageName/Magic.hs | 2 +- .../Solver/Modular/ConfiguredConversion.hs | 4 ++-- .../Solver/Types/InstSolverPackage.hs | 4 ++-- .../Client/BuildReports/Anonymous.hs | 2 +- .../src/Distribution/Client/Dependency.hs | 2 +- .../src/Distribution/Client/IndexUtils.hs | 8 ++++---- .../src/Distribution/Client/Install.hs | 2 +- .../src/Distribution/Client/PackageHash.hs | 4 ++-- .../src/Distribution/Client/SetupWrapper.hs | 6 +++--- .../Distribution/Client/SolverInstallPlan.hs | 2 +- .../src/Distribution/Client/Types/AllowNewer.hs | 2 +- 27 files changed, 83 insertions(+), 57 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index cef915a25d3..a4ac948570f 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -174,7 +174,7 @@ instance (Semigroup a, Monoid a) => Monoid (PerCompilerFlavor a) where -- ------------------------------------------------------------ data CompilerId = CompilerId CompilerFlavor Version - deriving (Eq, Generic, Ord, Read, Show) + deriving (Eq, Generic, Ord, Read, Show, Data) instance Binary CompilerId instance Structured CompilerId diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index 22912564e49..27e98ee0a82 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -74,7 +74,7 @@ import Prelude () import Distribution.CabalSpecVersion import Distribution.Compat.Newtype (Newtype, pack', unpack') -import Distribution.Compiler (CompilerFlavor (..), PerCompilerFlavor (..)) +import Distribution.Compiler (CompilerFlavor (..), PerCompilerFlavor (..), CompilerId) import Distribution.FieldGrammar import Distribution.Fields import Distribution.ModuleName (ModuleName) @@ -101,6 +101,7 @@ packageDescriptionFieldGrammar , c (Identity BuildType) , c (Identity PackageName) , c (Identity Version) + , c (Identity CompilerId) , forall from to. c (List FSep (RelativePathNT from to) (RelativePath from to)) , forall from to. c (List VCat (RelativePathNT from to) (RelativePath from to)) , c (List FSep TestedWith (CompilerFlavor, VersionRange)) @@ -150,6 +151,7 @@ packageDescriptionFieldGrammar = PackageIdentifier <$> uniqueField "name" L.pkgName <*> uniqueField "version" L.pkgVersion + <*> optionalField "compiler" L.pkgCompiler licenseFilesGrammar = (++) diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs index defb1922607..ee1dfca5888 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs @@ -16,10 +16,10 @@ import Prelude () import Distribution.Backpack import Distribution.Compat.Graph (IsNode (..)) -import Distribution.Compiler (CompilerId) +import Distribution.Compiler (CompilerId, buildCompilerId) import Distribution.License import Distribution.ModuleName -import Distribution.Package hiding (installedUnitId) +import Distribution.Package hiding (installedUnitId, pkgCompiler) import Distribution.Types.AbiDependency import Distribution.Types.ExposedModule import Distribution.Types.LibraryName @@ -121,8 +121,8 @@ instance IsNode InstalledPackageInfo where nodeNeighbors = depends mungedPackageId :: InstalledPackageInfo -> MungedPackageId -mungedPackageId ipi = - MungedPackageId (mungedPackageName ipi) (packageVersion ipi) +mungedPackageId ipi@InstalledPackageInfo{pkgCompiler = comp} = + MungedPackageId (mungedPackageName ipi) (packageVersion ipi) comp -- | Returns the munged package name, which we write into @name@ for -- compatibility with old versions of GHC. @@ -132,7 +132,7 @@ mungedPackageName ipi = MungedPackageName (packageName ipi) (sourceLibName ipi) emptyInstalledPackageInfo :: InstalledPackageInfo emptyInstalledPackageInfo = InstalledPackageInfo - { sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion + { sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion Nothing , sourceLibName = LMainLibName , installedComponentId_ = mkComponentId "" , installedUnitId = mkUnitId "" diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index c2e77292c07..151aaf4b119 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -20,7 +20,7 @@ import Distribution.FieldGrammar import Distribution.FieldGrammar.FieldDescrs import Distribution.License import Distribution.ModuleName -import Distribution.Package +import Distribution.Package hiding (pkgCompiler) import Distribution.Parsec import Distribution.Pretty import Distribution.Types.LibraryName @@ -38,7 +38,7 @@ import qualified Text.PrettyPrint as Disp import Distribution.Types.InstalledPackageInfo import qualified Distribution.Types.InstalledPackageInfo.Lens as L -import qualified Distribution.Types.PackageId.Lens as L +import qualified Distribution.Types.PackageId.Lens as L hiding (pkgCompiler) -- Note: GHC goes nuts and inlines everything, -- One can see e.g. in -ddump-simpl-stats: @@ -133,7 +133,7 @@ ipiFieldGrammar = InstalledPackageInfo -- _basicPkgName is not used -- setMaybePackageId says it can be no-op. - (PackageIdentifier pn _basicVersion) + (PackageIdentifier pn _basicVersion _basicCompilerId) (combineLibraryName ln _basicLibName) (mkComponentId "") -- installedComponentId_, not in use _basicLibVisibility @@ -256,6 +256,7 @@ data Basic = Basic , _basicPkgName :: Maybe PackageName , _basicLibName :: LibraryName , _basicLibVisibility :: LibraryVisibility + , _basicCompilerId :: Maybe CompilerId } basic :: Lens' InstalledPackageInfo Basic @@ -268,14 +269,16 @@ basic f ipi = g <$> f b (maybePackageName ipi) (sourceLibName ipi) (libVisibility ipi) + (pkgCompiler ipi) - g (Basic n v pn ln lv) = + g (Basic n v pn ln lv compid) = ipi & setMungedPackageName n & L.sourcePackageId . L.pkgVersion .~ v & setMaybePackageName pn & L.sourceLibName .~ ln & L.libVisibility .~ lv + & L.pkgCompiler .~ compid basicName :: Lens' Basic MungedPackageName basicName f b = (\x -> b{_basicName = x}) <$> f (_basicName b) @@ -319,7 +322,7 @@ basicFieldGrammar = <*> optionalField "lib-name" basicLibName <*> optionalFieldDef "visibility" basicLibVisibility LibraryVisibilityPrivate where - mkBasic n v pn ln lv = Basic n v pn ln' lv' + mkBasic n v pn ln lv = Basic n v pn ln' lv' Nothing where ln' = maybe LMainLibName LSubLibName ln -- Older GHCs (<8.8) always report installed libraries as private diff --git a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs index 8e879620478..b0edcd99bf5 100644 --- a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs @@ -15,6 +15,7 @@ import Distribution.Types.LibraryName import Distribution.Types.MungedPackageName import Distribution.Types.PackageId import Distribution.Version (Version, nullVersion) +import Distribution.Compiler (CompilerId) import qualified Text.PrettyPrint as Disp @@ -27,6 +28,7 @@ data MungedPackageId = MungedPackageId -- 'MungedPackageName'. , mungedVersion :: Version -- ^ The version of this package / component, eg 1.2 + , mingledCompilerId :: Maybe CompilerId } deriving (Generic, Read, Show, Eq, Ord, Data) @@ -41,8 +43,9 @@ instance Structured MungedPackageId -- >>> prettyShow $ MungedPackageId (MungedPackageName "servant" (LSubLibName "lackey")) (mkVersion [0,1,2]) -- "z-servant-z-lackey-0.1.2" instance Pretty MungedPackageId where - pretty (MungedPackageId n v) - | v == nullVersion = pretty n -- if no version, don't show version. + pretty (MungedPackageId n v c) + | v == nullVersion = pretty c <<>> Disp.char '-' <<>> pretty n -- if no version, don't show version. + | Just c' <- c = pretty c' <<>> Disp.char '-' <<>> pretty n <<>> Disp.char '-' <<>> pretty v | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v -- | @@ -66,15 +69,15 @@ instance Pretty MungedPackageId where -- Nothing instance Parsec MungedPackageId where parsec = do - PackageIdentifier pn v <- parsec - return $ MungedPackageId (decodeCompatPackageName pn) v + PackageIdentifier pn v comp <- parsec + return $ MungedPackageId (decodeCompatPackageName pn) v comp instance NFData MungedPackageId where - rnf (MungedPackageId name version) = rnf name `seq` rnf version + rnf (MungedPackageId name version compiler) = rnf name `seq` rnf version `seq` rnf compiler computeCompatPackageId :: PackageId -> LibraryName -> MungedPackageId -computeCompatPackageId (PackageIdentifier pn vr) ln = - MungedPackageId (MungedPackageName pn ln) vr +computeCompatPackageId (PackageIdentifier pn vr comp) ln = + MungedPackageId (MungedPackageName pn ln) vr comp -- $setup -- >>> :seti -XOverloadedStrings diff --git a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs index 4b00a8ef526..17f72e54c95 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs @@ -207,6 +207,7 @@ emptyPackageDescription = PackageIdentifier (mkPackageName "") nullVersion + Nothing , licenseRaw = Right UnspecifiedLicense -- TODO: , licenseFiles = [] , specVersion = CabalSpecV1_0 diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index 9cd88a2f810..ca9bfbfc967 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -13,6 +13,7 @@ import Distribution.Parsec (Parsec (..), simpleParsec) import Distribution.Pretty import Distribution.Types.PackageName import Distribution.Version (Version, nullVersion) +import Distribution.Compiler (CompilerId) import qualified Data.List.NonEmpty as NE import qualified Distribution.Compat.CharParsing as P @@ -27,6 +28,7 @@ data PackageIdentifier = PackageIdentifier -- ^ The name of this package, eg. foo , pkgVersion :: Version -- ^ the version of this package, eg 1.2 + , pkgCompiler :: Maybe CompilerId } deriving (Generic, Read, Show, Eq, Ord, Data) @@ -34,8 +36,9 @@ instance Binary PackageIdentifier instance Structured PackageIdentifier instance Pretty PackageIdentifier where - pretty (PackageIdentifier n v) - | v == nullVersion = pretty n -- if no version, don't show version. + pretty (PackageIdentifier n v c) + | v == nullVersion = pretty c <<>> Disp.char '-' <<>> pretty n -- if no version, don't show version. + | Just c' <- c = pretty c' <<>> Disp.char '-' <<>> pretty n <<>> Disp.char '-' <<>> pretty v | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v -- | @@ -61,15 +64,16 @@ instance Pretty PackageIdentifier where -- Nothing instance Parsec PackageIdentifier where parsec = do + comp <- parsec <* P.char '-' xs' <- P.sepByNonEmpty component (P.char '-') (v, xs) <- case simpleParsec (NE.last xs') of Nothing -> return (nullVersion, toList xs') -- all components are version Just v -> return (v, NE.init xs') if not (null xs) && all (\c -> all (/= '.') c && not (all isDigit c)) xs - then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v + then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v comp else fail "all digits or a dot in a portion of package name" where component = P.munch1 (\c -> isAlphaNum c || c == '.') instance NFData PackageIdentifier where - rnf (PackageIdentifier name version) = rnf name `seq` rnf version + rnf (PackageIdentifier name version compiler) = rnf name `seq` rnf version `seq` rnf compiler diff --git a/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs b/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs index 08305234fbd..5a4682c7ed3 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId/Lens.hs @@ -10,6 +10,7 @@ import Prelude () import Distribution.Types.PackageId (PackageIdentifier) import Distribution.Types.PackageName (PackageName) import Distribution.Version (Version) +import Distribution.Compiler (CompilerId) import qualified Distribution.Types.PackageId as T @@ -20,3 +21,8 @@ pkgName f s = fmap (\x -> s{T.pkgName = x}) (f (T.pkgName s)) pkgVersion :: Lens' PackageIdentifier Version pkgVersion f s = fmap (\x -> s{T.pkgVersion = x}) (f (T.pkgVersion s)) {-# INLINE pkgVersion #-} + +pkgCompiler :: Lens' PackageIdentifier (Maybe CompilerId) +pkgCompiler f s = fmap (\x -> s{T.pkgCompiler = x}) (f (T.pkgCompiler s)) +{-# INLINE pkgCompiler #-} + diff --git a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs index 013226ca2d5..5c2b8d9b0b1 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs @@ -53,7 +53,7 @@ instance Pretty PackageVersionConstraint where -- Just (PackageVersionConstraint (PackageName "foo") (ThisVersion (mkVersion [2,0]))) instance Parsec PackageVersionConstraint where parsec = do - PackageIdentifier name ver <- parsec + PackageIdentifier name ver comp <- parsec if ver == nullVersion then do P.spaces @@ -64,7 +64,7 @@ instance Parsec PackageVersionConstraint where -- | @since 3.4.0.0 thisPackageVersionConstraint :: PackageIdentifier -> PackageVersionConstraint -thisPackageVersionConstraint (PackageIdentifier pn vr) = +thisPackageVersionConstraint (PackageIdentifier pn vr comp) = PackageVersionConstraint pn (thisVersion vr) -- | @since 3.4.0.0 diff --git a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs index 0fba79bcb87..a72fe20f07f 100644 --- a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs +++ b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs @@ -71,9 +71,9 @@ instance HasMungedPackageId PreExistingComponent where mungedId = pc_munged_id instance Package PreExistingComponent where - packageId pec = PackageIdentifier (pc_pkgname pec) v + packageId pec = PackageIdentifier (pc_pkgname pec) v compid where - MungedPackageId _ v = pc_munged_id pec + MungedPackageId _ v compid = pc_munged_id pec instance HasUnitId PreExistingComponent where installedUnitId = pc_uid diff --git a/Cabal/src/Distribution/Backpack/ReadyComponent.hs b/Cabal/src/Distribution/Backpack/ReadyComponent.hs index 7a3523d5eab..b871ebff59f 100644 --- a/Cabal/src/Distribution/Backpack/ReadyComponent.hs +++ b/Cabal/src/Distribution/Backpack/ReadyComponent.hs @@ -300,6 +300,7 @@ toReadyComponents pid_map subst0 comps = MungedPackageId (MungedPackageName nonExistentPackageThisIsCabalBug LMainLibName) (mkVersion [0]) + Nothing instc = InstantiatedComponent { instc_insts = Map.toList insts diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index 925bc69d6e1..799e677af17 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -582,7 +582,7 @@ checkSetupBuildInfo (Just (SetupBuildInfo ds _)) = do checkPVPs (checkDependencyVersionRange hasGTLowerBound) gtlck ds checkPackageId :: Monad m => PackageIdentifier -> CheckM m () -checkPackageId (PackageIdentifier pkgName_ _pkgVersion_) = do +checkPackageId (PackageIdentifier pkgName_ _pkgVersion_ _compid) = do checkP (not . FilePath.Windows.isValid . prettyShow $ pkgName_) (PackageDistInexcusable $ InvalidNameWin pkgName_) diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 402f27467d2..008a270848f 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -821,7 +821,7 @@ testSuiteLibV09AsLibAndExe } -- This is, like, the one place where we use a CTestName for a library. -- Should NOT use library name, since that could conflict! - PackageIdentifier pkg_name pkg_ver = package pkg_descr + PackageIdentifier pkg_name pkg_ver _pkg_compid = package pkg_descr -- Note: we do make internal library from the test! compat_name = MungedPackageName pkg_name (LSubLibName (testName test)) compat_key = computeCompatPackageKey (compiler lbi) compat_name pkg_ver (componentUnitId clbi) diff --git a/Cabal/src/Distribution/Simple/Build/Macros.hs b/Cabal/src/Distribution/Simple/Build/Macros.hs index f3c51d71c96..e71d5a4a644 100644 --- a/Cabal/src/Distribution/Simple/Build/Macros.hs +++ b/Cabal/src/Distribution/Simple/Build/Macros.hs @@ -67,11 +67,11 @@ generateCabalMacrosHeader pkg_descr lbi clbi = , Z.zMangleStr = map fixchar } where - getPid (_, MungedPackageId (MungedPackageName pn _) v) = + getPid (_, MungedPackageId (MungedPackageName pn _) v compid) = -- NB: Drop the library name! We're just reporting package versions. -- This would have to be revisited if you are allowed to depend -- on different versions of the same package - PackageIdentifier pn v + PackageIdentifier pn v compid -- | Helper function that generates just the @VERSION_pkg@ and @MIN_VERSION_pkg@ -- macros for a list of package ids (usually used with the specific deps of @@ -91,7 +91,7 @@ generatePackageVersionMacros ver pkgids = } mkZPackage :: PackageId -> Z.ZPackage -mkZPackage (PackageIdentifier name ver) = +mkZPackage (PackageIdentifier name ver compid) = Z.ZPackage { Z.zpkgName = name , Z.zpkgVersion = ver diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 7c96efb33fc..a76b4359bc9 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -335,7 +335,7 @@ writePersistBuildConfig mbWorkDir distPref lbi = do -- | Identifier of the current Cabal package. currentCabalId :: PackageIdentifier -currentCabalId = PackageIdentifier (mkPackageName "Cabal") cabalVersion +currentCabalId = PackageIdentifier (mkPackageName "Cabal") cabalVersion Nothing -- | Identifier of the current compiler package. currentCompilerId :: PackageIdentifier @@ -343,6 +343,7 @@ currentCompilerId = PackageIdentifier (mkPackageName System.Info.compilerName) (mkVersion' System.Info.compilerVersion) + Nothing -- | Parse the @setup-config@ file header, returning the package identifiers -- for Cabal and the compiler. @@ -1987,7 +1988,7 @@ selectDependency -- It's an internal library, and we're not per-component build do_internal lib | Set.member lib internalIndex = - Right $ InternalDependency $ PackageIdentifier dep_pkgname $ packageVersion pkgid + Right $ InternalDependency $ PackageIdentifier dep_pkgname (packageVersion pkgid) (pkgCompiler pkgid) | otherwise = Left $ DependencyMissingInternal dep_pkgname lib diff --git a/Cabal/src/Distribution/Simple/PackageIndex.hs b/Cabal/src/Distribution/Simple/PackageIndex.hs index a7d23962b72..6e115ca65a5 100644 --- a/Cabal/src/Distribution/Simple/PackageIndex.hs +++ b/Cabal/src/Distribution/Simple/PackageIndex.hs @@ -169,7 +169,7 @@ instance Semigroup (PackageIndex IPI.InstalledPackageInfo) where {-# NOINLINE invariant #-} invariant :: WithCallStack (InstalledPackageIndex -> Bool) invariant (PackageIndex pids pnames) = - -- trace (show pids' ++ "\n" ++ show pnames') $ + trace (show pids' ++ "\n" ++ show pnames') $ pids' == pnames' where pids' = map installedUnitId (Map.elems pids) @@ -335,16 +335,21 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = Just pvers -> case Map.lookup (packageVersion pkgid) pvers of Nothing -> original Just pkgs -> - mkPackageIndex - (foldl' (flip (Map.delete . installedUnitId)) pids pkgs) + traceShow (pkgid, pkgs) $ mkPackageIndex + (Map.update deletePkgInstance (installedUnitId pkgid) pids) (deletePkgName pnames) where deletePkgName = Map.update deletePkgVersion (packageName pkgid, LMainLibName) + deletePkgVersion :: Map Version [IPI.InstalledPackageInfo] -> Maybe (Map Version [IPI.InstalledPackageInfo]) deletePkgVersion = (\m -> if Map.null m then Nothing else Just m) - . Map.delete (packageVersion pkgid) + . Map.update deletePkgInstance (packageVersion pkgid) + + deletePkgInstance :: [IPI.InstalledPackageInfo] -> Maybe [IPI.InstalledPackageInfo] + deletePkgInstance xs = if null xs' then Nothing else Just xs' + where xs' = [x | x <- xs, pkgCompiler pkgid /= pkgCompiler (IPI.sourcePackageId x)] -- | Removes all packages with this (case-sensitive) name from the index. -- diff --git a/Cabal/src/Distribution/Types/PackageName/Magic.hs b/Cabal/src/Distribution/Types/PackageName/Magic.hs index 022a62468b1..908e82bea6f 100644 --- a/Cabal/src/Distribution/Types/PackageName/Magic.hs +++ b/Cabal/src/Distribution/Types/PackageName/Magic.hs @@ -21,4 +21,4 @@ fakePackageCabalFileName = "fake-package.cabal" -- | 'fakePackageName' with 'version0'. fakePackageId :: PackageId -fakePackageId = PackageIdentifier fakePackageName version0 +fakePackageId = PackageIdentifier fakePackageName version0 Nothing diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index 69e41072547..e766957be1b 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -41,7 +41,7 @@ convCP biidx iidx sidx (CP qpi fa es ds) = } -- "In repo" i.e. a source package (PI qpn@(Q _path pn) (I stage v InRepo)) -> - let pi = PackageIdentifier pn v in + let pi = PackageIdentifier pn v Nothing {-# FIXME: should be COMPILERID #-} in Configured $ SolverPackage { solverPkgQPN = qpn, @@ -72,4 +72,4 @@ convConfId (PI (Q (PackagePath _ q) pn) (I _stage v loc)) = , pn == pn' -> Right (PlannedId sourceId) | otherwise -> Left (PlannedId sourceId) where - sourceId = PackageIdentifier pn v + sourceId = PackageIdentifier pn v Nothing -- FIXME: this should be the compiler id! diff --git a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs index 15fb9d510ec..868d1d9dfe2 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs @@ -31,8 +31,8 @@ instance Structured InstSolverPackage instance Package InstSolverPackage where packageId i = -- HACK! See Note [Index conversion with internal libraries] - let MungedPackageId mpn v = mungedId i - in PackageIdentifier (encodeCompatPackageName mpn) v + let MungedPackageId mpn v compid = mungedId i + in PackageIdentifier (encodeCompatPackageName mpn) v compid instance HasMungedPackageId InstSolverPackage where mungedId = mungedId . instSolverPkgIPI diff --git a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs index ce1d1665327..a6febfcca50 100644 --- a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs +++ b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs @@ -103,7 +103,7 @@ newBuildReport os' arch' comp pkgid flags deps result = cabalInstallID :: PackageIdentifier cabalInstallID = - PackageIdentifier (mkPackageName "cabal-install") cabalInstallVersion + PackageIdentifier (mkPackageName "cabal-install") cabalInstallVersion Nothing ------------------------------------------------------------------------------- -- FieldGrammar diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 645e81b1873..44309e069ef 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -1076,7 +1076,7 @@ configuredPackageProblems (sort $ map fst (PD.unFlagAssignment specifiedFlags)) -- TODO packageSatisfiesDependency :: PackageIdentifier -> Dependency -> Bool packageSatisfiesDependency - (PackageIdentifier name version) + (PackageIdentifier name version _compid) (Dependency name' versionRange _) = assert (name == name') $ version `withinRange` versionRange diff --git a/cabal-install/src/Distribution/Client/IndexUtils.hs b/cabal-install/src/Distribution/Client/IndexUtils.hs index 6027f5e53f3..0cd842d663e 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils.hs @@ -617,7 +617,7 @@ extractPkg verbosity entry blockNo = case Tar.entryContent entry of [pkgname, vers, _] -> case simpleParsec vers of Just ver -> Just . return $ Just (NormalPackage pkgid descr content blockNo) where - pkgid = PackageIdentifier (mkPackageName pkgname) ver + pkgid = PackageIdentifier (mkPackageName pkgname) ver Nothing parsed = parseGenericPackageDescriptionMaybe (BS.toStrict content) descr = case parsed of Just d -> d @@ -1269,10 +1269,10 @@ hashConsCache cache0 = go !pns !pvs (CachePackageId pid bno ts : rest) = CachePackageId pid' bno ts : go pns' pvs' rest where - !pid' = PackageIdentifier pn' pv' + !pid' = PackageIdentifier pn' pv' compid (!pn', !pns') = mapIntern pn pns (!pv', !pvs') = mapIntern pv pvs - PackageIdentifier pn pv = pid + PackageIdentifier pn pv compid = pid go pns pvs (x : xs) = x : go pns pvs xs mapIntern :: Ord k => k -> Map.Map k k -> (k, Map.Map k k) @@ -1395,7 +1395,7 @@ read00IndexCacheEntry = \line -> (Just pkgname, Just pkgver, Just blockno) -> Just ( CachePackageId - (PackageIdentifier pkgname pkgver) + (PackageIdentifier pkgname pkgver Nothing) blockno NoTimestamp ) diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 2fb03562f24..6f7d3bdd8a9 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -1102,7 +1102,7 @@ theSpecifiedPackage :: Package pkg => PackageSpecifier pkg -> Maybe PackageId theSpecifiedPackage pkgSpec = case pkgSpec of NamedPackage name [PackagePropertyVersion version] -> - PackageIdentifier name <$> trivialRange version + PackageIdentifier name <$> trivialRange version <*> Nothing NamedPackage _ _ -> Nothing SpecificSourcePackage pkg -> Just $ packageId pkg where diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index 38240c3888a..d99fc9ad250 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -133,7 +133,7 @@ hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = , showHashValue (truncateHash 20 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version = pkgHashPkgId + PackageIdentifier name version _compid = pkgHashPkgId -- Truncate a string, with a visual indication that it is truncated. truncateStr n s @@ -172,7 +172,7 @@ hashedInstalledPackageIdVeryShort pkghashinputs@PackageHashInputs{pkgHashPkgId} , showHashValue (truncateHash 4 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version = pkgHashPkgId + PackageIdentifier name version _compid = pkgHashPkgId -- | All the information that contributes to a package's hash, and thus its -- 'InstalledPackageId'. diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index 55042e212cd..d46045c849a 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -1068,7 +1068,7 @@ getExternalSetupMethod verbosity options pkg bt = do debug verbosity "Setup executable needs to be updated, compiling..." (compiler, progdb, options'') <- configureCompiler options' pkgDbs <- traverse (traverse (makeRelativeToDirS mbWorkDir)) (coercePackageDBStack (usePackageDB options'')) - let cabalPkgid = PackageIdentifier (mkPackageName "Cabal") cabalLibVersion + let cabalPkgid = PackageIdentifier (mkPackageName "Cabal") cabalLibVersion Nothing (program, extraOpts) = case compilerFlavor compiler of GHCJS -> (ghcjsProgram, ["-build-runner"]) @@ -1155,5 +1155,5 @@ getExternalSetupMethod verbosity options pkg bt = do return $ i setupProgFile isCabalPkgId, isBasePkgId :: PackageIdentifier -> Bool -isCabalPkgId (PackageIdentifier pname _) = pname == mkPackageName "Cabal" -isBasePkgId (PackageIdentifier pname _) = pname == mkPackageName "base" +isCabalPkgId (PackageIdentifier pname _ _compid) = pname == mkPackageName "Cabal" +isBasePkgId (PackageIdentifier pname _ _compid) = pname == mkPackageName "base" diff --git a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs index 17dcf6d9398..631dbde5afe 100644 --- a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs +++ b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs @@ -218,7 +218,7 @@ showPlanProblem (PackageInconsistency name inconsistencies) = [ " package " ++ prettyShow pkg ++ " requires " - ++ prettyShow (PackageIdentifier name ver) + ++ prettyShow (PackageIdentifier name ver Nothing) | (pkg, ver) <- inconsistencies ] showPlanProblem (PackageStateInvalid pkg pkg') = diff --git a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs index 0a5700174b8..6a6503aaf4c 100644 --- a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs +++ b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs @@ -109,7 +109,7 @@ relaxedDepStarP = -- continuation after package identifier relaxedDepPkgidP :: CabalParsing m => PackageIdentifier -> m RelaxedDep -relaxedDepPkgidP pid@(PackageIdentifier pn v) +relaxedDepPkgidP pid@(PackageIdentifier pn v _compid) | pn == mkPackageName "all" , v == nullVersion = RelaxedDep RelaxDepScopeAll <$ P.char ':' <*> modP <*> parsec From fa6d6d102430738d3642a183e77eb56ad1d040f9 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:54:49 +0900 Subject: [PATCH 59/82] fixup! Add compiler to PackageId (cherry picked from commit f8600655624c8cc2cdd2fb16237ab115828e3754) --- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 76fcbf9bc21..5ed709a2578 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1044,7 +1044,7 @@ reportPlanningFailure projectConfig Toolchain{toolchainCompiler = comp, toolchai theSpecifiedPackage pkgSpec = case pkgSpec of NamedPackage name [PackagePropertyVersion version] -> - PackageIdentifier name <$> trivialRange version + PackageIdentifier name <$> trivialRange version <*> Nothing NamedPackage _ _ -> Nothing SpecificSourcePackage pkg -> Just $ packageId pkg -- \| If a range includes only a single version, return Just that version. From 6939af82e142ab5ebcad5aa8930d8020ee5c090a Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 24 Mar 2025 12:57:16 +0900 Subject: [PATCH 60/82] fixup! Add compiler to PackageId (cherry picked from commit 125921422d2cacef165db2a17c032db0d08ebcf6) --- .../Solver/Modular/IndexConversion.hs | 4 ++-- .../Distribution/Client/ProjectPlanning.hs | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index 2fc84f84697..08583f537d1 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -88,7 +88,7 @@ convIPI' toolchains (ShadowPkgs sip) idx = -- | Extract/recover the package ID from an installed package info, and convert it to a solver's I. convId :: Toolchains -> IPI.InstalledPackageInfo -> (PN, I) convId toolchains ipi = (pn, I stage ver $ Inst $ IPI.installedUnitId ipi) - where MungedPackageId mpn ver = mungedId ipi + where MungedPackageId mpn ver compid = mungedId ipi -- HACK. See Note [Index conversion with internal libraries] pn = encodeCompatPackageName mpn stage = case IPI.pkgCompiler ipi of @@ -172,7 +172,7 @@ convSPI' toolchains constraints strfl solveExes = -- | Convert a single source package into the solver-specific format. convSP :: Toolchains -> Map PN [LabeledPackageConstraint] -> StrongFlags -> SolveExecutables -> SourcePackage loc -> [(PN, I, PInfo)] -convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) = +convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv _compid) gpd _ _pl) = let pkgConstraints = fromMaybe [] $ M.lookup pn constraints in [(pn, I Host pv InRepo, convGPD (hostToolchain toolchains) pkgConstraints strfl solveExes pn gpd) ,(pn, I Build pv InRepo, convGPD (buildToolchain toolchains) pkgConstraints strfl solveExes pn gpd)] diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 5ed709a2578..5e95e31d718 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -198,6 +198,7 @@ import Distribution.Types.GivenComponent import Distribution.Types.LibraryName import qualified Distribution.Types.LocalBuildConfig as LBC import Distribution.Types.PackageVersionConstraint +import qualified Distribution.Types.PackageId as PI import Distribution.Types.PkgconfigDependency import Distribution.Types.UnqualComponentName @@ -791,8 +792,21 @@ rebuildInstallPlan -- } -- deriving (Eq, Generic, Show, Read) -- - -- can probably use fromList $ Map.elems $ on it. + -- let mapPkgIdx f = PI.fromList . map f . PI.allPackages + -- let updateIPI :: IPI.InstalledPackageInfo -> IPI.InstalledPackageInfo + -- updateIPI ipi = ipi { + -- IPI.sourcePackageId = (IPI.sourcePackageId ipi){ PI.pkgCompiler = IPI.pkgCompiler ipi } + -- } + -- let addCompilerToSourcePkg :: CompilerId -> [PackageSpecifier UnresolvedSourcePackage] -> [PackageSpecifier UnresolvedSourcePackage] + -- addCompilerToSourcePkg compilerId = map (addCompilerId compilerId) + -- addCompilerId :: CompilerId -> PackageSpecifier UnresolvedSourcePackage -> PackageSpecifier UnresolvedSourcePackage + -- addCompilerId compilerId (NamedPackage name props) = NamedPackage name props + -- addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (f pkg) + -- where f :: SourcePackage UnresolvedPkgLoc -> SourcePackage UnresolvedPkgLoc + -- f pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} + hinstalledPkgIndex <- + -- mapPkgIdx updateIPI <$> getInstalledPackages verbosity (hostToolchain toolchains) @@ -802,6 +816,7 @@ rebuildInstallPlan -- for now. FIXME! -- let hinstalledPkgIndex' = PI.fromList $ PI.allPackages hinstalledPkgIndex binstalledPkgIndex <- + -- mapPkgIdx updateIPI <$> getInstalledPackages verbosity (buildToolchain toolchains) @@ -809,6 +824,8 @@ rebuildInstallPlan -- if host and build compiler are the same, we want to get -package-db in here. (corePackageDbs $ if buildIsHost toolchains then Host else Build) + -- let localPackages' = addCompilerToSourcePkg (compilerId . toolchainCompiler . hostToolchain $ toolchains) localPackages + (sourcePkgDb, tis, ar) <- getSourcePackages verbosity From 51d9f9513c69a4ce4f4cbce404e8722bb41ebd89 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 25 Mar 2025 20:38:08 +0900 Subject: [PATCH 61/82] Absolutely hacked nonsense, but ... it works?! --- Cabal/src/Distribution/Simple/PackageIndex.hs | 14 ++- .../src/Distribution/Solver/Modular.hs | 10 ++- .../Solver/Modular/ConfiguredConversion.hs | 16 ++-- .../Solver/Modular/IndexConversion.hs | 9 +- .../src/Distribution/Solver/Modular/Solver.hs | 5 +- .../Distribution/Solver/Types/Toolchain.hs | 4 + .../src/Distribution/Client/Dependency.hs | 24 ++++- .../src/Distribution/Client/ProjectConfig.hs | 8 ++ .../Client/ProjectOrchestration.hs | 18 +++- .../Distribution/Client/ProjectPlanning.hs | 87 +++++++++++++------ .../Distribution/Client/SolverInstallPlan.hs | 37 ++++++++ 11 files changed, 181 insertions(+), 51 deletions(-) diff --git a/Cabal/src/Distribution/Simple/PackageIndex.hs b/Cabal/src/Distribution/Simple/PackageIndex.hs index 6e115ca65a5..eb3e4a22cce 100644 --- a/Cabal/src/Distribution/Simple/PackageIndex.hs +++ b/Cabal/src/Distribution/Simple/PackageIndex.hs @@ -336,7 +336,8 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = Nothing -> original Just pkgs -> traceShow (pkgid, pkgs) $ mkPackageIndex - (Map.update deletePkgInstance (installedUnitId pkgid) pids) + (foldl' (flip (Map.delete . installedUnitId)) pids pkgs) +-- (Map.update deletePkgInstance (installedUnitId pkgid) pids) (deletePkgName pnames) where deletePkgName = @@ -345,10 +346,15 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = deletePkgVersion :: Map Version [IPI.InstalledPackageInfo] -> Maybe (Map Version [IPI.InstalledPackageInfo]) deletePkgVersion = (\m -> if Map.null m then Nothing else Just m) - . Map.update deletePkgInstance (packageVersion pkgid) + . Map.update deletePkgInstances (packageVersion pkgid) - deletePkgInstance :: [IPI.InstalledPackageInfo] -> Maybe [IPI.InstalledPackageInfo] - deletePkgInstance xs = if null xs' then Nothing else Just xs' + deletePkgInstance :: IPI.InstalledPackageInfo -> Maybe IPI.InstalledPackageInfo + deletePkgInstance ipi + | pkgCompiler pkgid /= pkgCompiler (IPI.sourcePackageId ipi) = Just ipi + | otherwise = Nothing + + deletePkgInstances :: [IPI.InstalledPackageInfo] -> Maybe [IPI.InstalledPackageInfo] + deletePkgInstances xs = if null xs' then Nothing else Just xs' where xs' = [x | x <- xs, pkgCompiler pkgid /= pkgCompiler (IPI.sourcePackageId x)] -- | Removes all packages with this (case-sensitive) name from the index. diff --git a/cabal-install-solver/src/Distribution/Solver/Modular.hs b/cabal-install-solver/src/Distribution/Solver/Modular.hs index f72a0bda371..a623d732703 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular.hs @@ -34,7 +34,7 @@ import Distribution.Solver.Modular.IndexConversion import Distribution.Solver.Modular.Log ( SolverFailure(..), displayLogMessages ) import Distribution.Solver.Modular.Package - ( PN, showPI ) + ( PN, showPI, I ) import Distribution.Solver.Modular.RetryLog import Distribution.Solver.Modular.Solver ( SolverConfig(..), PruneAfterFirstSuccess(..), solve ) @@ -56,7 +56,7 @@ import Distribution.Simple.Utils import Distribution.Verbosity import Distribution.Solver.Modular.Configured (CP (..)) import qualified Distribution.Solver.Types.ComponentDeps as ComponentDeps -import Distribution.Pretty (Pretty (..)) +import Distribution.Pretty (Pretty (..), prettyShow) import Text.PrettyPrint (text, vcat, Doc, nest, ($+$)) import Distribution.Solver.Types.OptionalStanza (showStanzas, optStanzaSetNull) import Distribution.Solver.Types.Toolchain ( Toolchains ) @@ -86,6 +86,10 @@ modularResolver sc toolchains biidx iidx sidx pkgConfigDB pprefs pcs pns = do Step (show (vcat (map showCP cp))) $ return $ postprocess assignment revdepmap where + showIdx :: Index -> String + showIdx idx = unlines [prettyShow pn ++ ": " ++ show i + | (pn, m) <- M.toList idx + , (i, _info) <- M.toList (m :: Map I PInfo)] -- Indices have to be converted into solver-specific uniform index. idx = convPIs toolchains gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) biidx iidx sidx -- Constraints have to be converted into a finite map indexed by PN. @@ -97,7 +101,7 @@ modularResolver sc toolchains biidx iidx sidx pkgConfigDB pprefs pcs pns = do -- package qualifiers, which means that linked packages become duplicates -- and can be removed. postprocess a rdm = ordNubBy nodeKey $ - map (convCP biidx iidx sidx) (toCPs a rdm) + map (convCP toolchains biidx iidx sidx) (toCPs a rdm) -- Helper function to extract the PN from a constraint. pcName :: PackageConstraint -> PN diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index e766957be1b..32148c4dce8 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -19,16 +19,18 @@ import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SolverPackage import Distribution.Solver.Types.InstSolverPackage import Distribution.Solver.Types.SourcePackage +import Distribution.Solver.Types.Toolchain import Control.Applicative ((<|>)) -- | Converts from the solver specific result @CP QPN@ into -- a 'ResolverPackage', which can then be converted into -- the install plan. -convCP :: SI.InstalledPackageIndex -- ^ build +convCP :: Toolchains + -> SI.InstalledPackageIndex -- ^ build -> SI.InstalledPackageIndex -- ^ host -> CI.PackageIndex (SourcePackage loc) -> CP QPN -> ResolverPackage loc -convCP biidx iidx sidx (CP qpi fa es ds) = +convCP toolchains biidx iidx sidx (CP qpi fa es ds) = case qpi of -- Installed (PI qpn (I _stage _ (Inst pi))) -> @@ -41,7 +43,7 @@ convCP biidx iidx sidx (CP qpi fa es ds) = } -- "In repo" i.e. a source package (PI qpn@(Q _path pn) (I stage v InRepo)) -> - let pi = PackageIdentifier pn v Nothing {-# FIXME: should be COMPILERID #-} in + let pi = PackageIdentifier pn v (Just $ compilerIdFor stage toolchains) in Configured $ SolverPackage { solverPkgQPN = qpn, @@ -54,10 +56,10 @@ convCP biidx iidx sidx (CP qpi fa es ds) = } where ds' :: ComponentDeps ([SolverId] {- lib -}, [SolverId] {- exe -}) - ds' = fmap (partitionEithers . map convConfId) ds + ds' = fmap (partitionEithers . map (convConfId toolchains)) ds -convConfId :: PI QPN -> Either SolverId {- is lib -} SolverId {- is exe -} -convConfId (PI (Q (PackagePath _ q) pn) (I _stage v loc)) = +convConfId :: Toolchains -> PI QPN -> Either SolverId {- is lib -} SolverId {- is exe -} +convConfId toolchains (PI (Q (PackagePath _ q) pn) (I stage v loc)) = case loc of Inst pi -> Left (PreExistingId sourceId pi) @@ -72,4 +74,4 @@ convConfId (PI (Q (PackagePath _ q) pn) (I _stage v loc)) = , pn == pn' -> Right (PlannedId sourceId) | otherwise -> Left (PlannedId sourceId) where - sourceId = PackageIdentifier pn v Nothing -- FIXME: this should be the compiler id! + sourceId = PackageIdentifier pn v (Just $ compilerIdFor stage toolchains) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index 08583f537d1..d6f008e153b 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -62,10 +62,14 @@ convPIs :: Toolchains -> Map PN [LabeledPackageConstraint] -> SI.InstalledPackageIndex -- ^ host -> CI.PackageIndex (SourcePackage loc) -> Index +convPIs toolchains constraints sip strfl solveExes biidx iidx sidx = + mkIndex $ (trace (pp "BIPIs" bipis) bipis) ++ (trace (pp "HIPIs" hipis) hipis) ++ (trace (pp "SPIs" spis) spis) where bipis = convIPI' toolchains sip biidx hipis = convIPI' toolchains sip iidx ipis = bipis ++ hipis spis = convSPI' toolchains constraints strfl solveExes sidx + pp :: String -> [(PN, I, PInfo)] -> String + pp label xs = unlines $ ("=== " ++ label ++ ":\n"):(map (\(pn, i, pi) -> show pn ++ " " ++ show i) xs) -- | Convert a Cabal installed package index to the simpler, -- more uniform index format of the solver. @@ -154,7 +158,7 @@ convIP toolchains idx ipi = convIPId :: Toolchains -> DependencyReason PN -> Component -> SI.InstalledPackageIndex -> UnitId -> Either UnitId (FlaggedDep PN) convIPId toolchains dr comp idx ipid = case SI.lookupUnitId idx ipid of - Nothing -> Left ipid + Nothing -> traceShow (show comp ++ ": Failed to find: " ++ show ipid ++ " in index.") $ Left ipid Just ipi -> let (pn, i) = convId toolchains ipi name = ExposedLib LMainLibName -- TODO: Handle sub-libraries. in Right (D.Simple (LDep dr (Dep (PkgComponent pn name) (Fixed i))) comp) @@ -175,7 +179,8 @@ convSP :: Toolchains -> Map PN [LabeledPackageConstraint] convSP toolchains constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv _compid) gpd _ _pl) = let pkgConstraints = fromMaybe [] $ M.lookup pn constraints in [(pn, I Host pv InRepo, convGPD (hostToolchain toolchains) pkgConstraints strfl solveExes pn gpd) - ,(pn, I Build pv InRepo, convGPD (buildToolchain toolchains) pkgConstraints strfl solveExes pn gpd)] + ,(pn, I Build pv InRepo, convGPD (buildToolchain toolchains) pkgConstraints strfl solveExes pn gpd) + ] -- We do not use 'flattenPackageDescription' or 'finalizePD' -- from 'Distribution.PackageDescription.Configuration' here, because we diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 89c7daa0223..0a6674ce9f5 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -105,6 +105,7 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = traceTree "cycles.json" id . detectCycles . traceTree "heuristics.json" id . + stageBuildDeps "post-pref: " . trav ( heuristicsPhase . preferencesPhase . @@ -114,9 +115,9 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = validationCata . traceTree "pruned.json" id . trav prunePhase . - -- stageBuildDeps "post-prune: " . + stageBuildDeps "post-prune: " . (if buildIsHost toolchains then id else trav P.pruneHostFromSetup) . - -- stageBuildDeps "build: " . + stageBuildDeps "build: " . traceTree "build.json" id $ buildPhase where diff --git a/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs index d7b9312520b..e965e54bee5 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/Toolchain.hs @@ -5,6 +5,7 @@ module Distribution.Solver.Types.Toolchain ( Toolchain (..) , Toolchains (..) , toolchainFor + , compilerIdFor , mkToolchainsWithHost , buildIsHost ) where @@ -48,6 +49,9 @@ toolchainFor :: Stage -> Toolchains -> Toolchain toolchainFor Build = buildToolchain toolchainFor Host = hostToolchain +compilerIdFor :: Stage -> Toolchains -> CompilerId +compilerIdFor stage = compilerId . toolchainCompiler . toolchainFor stage + instance Binary Toolchains instance Structured Toolchains diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 44309e069ef..51c66a9f691 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -166,6 +166,8 @@ import Data.List import qualified Data.Map as Map import qualified Data.Set as Set +import GHC.Stack (HasCallStack) + -- ------------------------------------------------------------ -- * High level planner policy @@ -836,13 +838,13 @@ resolveDependencies toolchains pkgConfigDB params = targets where finalparams@( DepResolverParams - targets + targets -- depResolverTargets constraints prefs defpref installedPkgIndex binstalledPkgIndex - sourcePkgIndex + sourcePkgIndex -- depResolverSourcePkgIndex reordGoals cntConflicts fineGrained @@ -928,17 +930,31 @@ interpretPackagesPreference selected defaultPref prefs = -- | Make an install plan from the output of the dep resolver. -- It checks that the plan is valid, or it's an error in the dep resolver. validateSolverResult - :: Toolchains + :: HasCallStack => Toolchains -> IndependentGoals -> [ResolverPackage UnresolvedPkgLoc] -> SolverInstallPlan validateSolverResult toolchains indepGoals pkgs = - case planPackagesProblems toolchains pkgs of + case planPackagesProblems toolchains (trace (dump pkgs) pkgs) of [] -> case SolverInstallPlan.new indepGoals graph of Right plan -> plan Left problems -> error (formatPlanProblems problems) problems -> error (formatPkgProblems problems) where + dump :: [ResolverPackage UnresolvedPkgLoc] -> String + dump xs = unlines $ + "=== DUMP ===":[unlines $ (resolverPkgHead x ++ show (packageId x)):[ "- "++ solverIdHead y ++ show (solverSrcId y) + | y <- CD.flatDeps (resolverPackageLibDeps x)] + | x <- xs ] + ++ ["=== /DUMP =="] + + solverIdHead :: SolverId -> String + solverIdHead (PreExistingId{}) = "[PE]" + solverIdHead (PlannedId {}) = "[PL]" + + resolverPkgHead (PreExisting _) = "[PE]" + resolverPkgHead (Configured _) = "[CF]" + graph :: Graph.Graph (ResolverPackage UnresolvedPkgLoc) graph = Graph.fromDistinctList pkgs diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index fd96eb4d2f3..c211f26abca 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -1091,6 +1091,14 @@ findProjectPackages let repoPkgs = map ProjectPackageRemoteRepo projectPackagesRepo namedPkgs = map ProjectPackageNamed projectPackagesNamed + -- FIXME: We should _REALLY_ Tag the packages here somehow. + -- Right now we just slam together requiredPkgs and buildPkgs, ... + -- Maybe we can carry the Build/Host distinction in the + -- ProjectPackageLocation. Because we later on really want to make + -- sure we consider only buildPkgs for building with the Build + -- compiler, and all others with the Host compiler. For now we just + -- Assume both for both compilers, but this is not god. + -- XXX: FIXME! return (concat [requiredPkgs, buildPkgs, optionalPkgs, repoPkgs, namedPkgs]) where findPackageLocations :: Bool -> [String] -> Rebuild [ProjectPackageLocation] diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 348eb031093..dd43c4298ab 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -659,7 +659,8 @@ resolveTargets checkTarget bt@(TargetPackage _ (ordNub -> [pkgid]) mkfilter) | Just ats <- fmap (maybe id filterTargetsKind mkfilter) $ - Map.lookup pkgid availableTargetsByPackageId = + (trace (unlines $ ("Failed to find " ++ prettyShow pkgid ++ " in "):[prettyShow k {-# ++ " -> " ++ show v #-} | (k,v) <- Map.toList availableTargetsByPackageId]) + (Map.lookup pkgid availableTargetsByPackageId)) = fmap (componentTargets WholeComponent) $ selectPackageTargets bt ats | otherwise = @@ -685,9 +686,18 @@ resolveTargets $ concat (Map.elems availableTargetsByPackageId) checkTarget (TargetComponent pkgid cname subtarget) | Just ats <- - Map.lookup - (pkgid, cname) - availableTargetsByPackageIdAndComponentName = + -- FIXME: this is stupid. We do not know what the target selectors HOST compiler is... + -- so we'll assume tere is only a _SINGLE_ match in the map if we ignore the pkgCompiler. + -- This lookup is now O(n) instead of O(log n). + (trace (unlines $ ("Failed to find " ++ prettyShow pkgid ++ ":" ++ show cname ++ " in "):[prettyShow k ++ ":" ++ show k' {-# ++ " -> " ++ show v #-} | ((k,k'),v) <- Map.toList availableTargetsByPackageIdAndComponentName]) + (case [v | ((k,k'),v) <- Map.toList availableTargetsByPackageIdAndComponentName + , k{pkgCompiler = Nothing} == pkgid + , k' == cname] of + [match] -> Just match)) + -- (Map.lookup + -- (pkgid, cname) + -- availableTargetsByPackageIdAndComponentName)) + = fmap (componentTargets subtarget) $ selectComponentTargets subtarget ats | Map.member pkgid availableTargetsByPackageId = diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 5e95e31d718..38e4d752f03 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -243,6 +243,8 @@ import Distribution.Solver.Types.ProjectConfigPath import System.FilePath import qualified Text.PrettyPrint as Disp +import GHC.Stack (HasCallStack) + -- | Check that an 'ElaboratedConfiguredPackage' actually makes -- sense under some 'ElaboratedSharedConfig'. sanityCheckElaboratedConfiguredPackage @@ -758,13 +760,13 @@ rebuildInstallPlan , projectConfigBuildOnly } toolchains - localPackages + localPackages_ installedPackages = rerunIfChanged verbosity fileMonitorSolverPlan ( solverSettings - , localPackages + , localPackages_ , localPackagesEnabledStanzas , toolchains , hookHashes @@ -797,13 +799,6 @@ rebuildInstallPlan -- updateIPI ipi = ipi { -- IPI.sourcePackageId = (IPI.sourcePackageId ipi){ PI.pkgCompiler = IPI.pkgCompiler ipi } -- } - -- let addCompilerToSourcePkg :: CompilerId -> [PackageSpecifier UnresolvedSourcePackage] -> [PackageSpecifier UnresolvedSourcePackage] - -- addCompilerToSourcePkg compilerId = map (addCompilerId compilerId) - -- addCompilerId :: CompilerId -> PackageSpecifier UnresolvedSourcePackage -> PackageSpecifier UnresolvedSourcePackage - -- addCompilerId compilerId (NamedPackage name props) = NamedPackage name props - -- addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (f pkg) - -- where f :: SourcePackage UnresolvedPkgLoc -> SourcePackage UnresolvedPkgLoc - -- f pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} hinstalledPkgIndex <- -- mapPkgIdx updateIPI <$> @@ -824,8 +819,20 @@ rebuildInstallPlan -- if host and build compiler are the same, we want to get -package-db in here. (corePackageDbs $ if buildIsHost toolchains then Host else Build) - -- let localPackages' = addCompilerToSourcePkg (compilerId . toolchainCompiler . hostToolchain $ toolchains) localPackages + -- getSourcePackages + -- :: Verbosity + -- -> (forall a. (RepoContext -> IO a) -> IO a) + -- -> Maybe IndexUtils.TotalIndexState + -- -> Maybe IndexUtils.ActiveRepos + -- -> Rebuild (SourcePackageDb, IndexUtils.TotalIndexState, IndexUtils.ActiveRepos) + + -- data SourcePackageDb = SourcePackageDb + -- { packageIndex :: PackageIndex UnresolvedSourcePackage + -- , packagePreferences :: Map PackageName VersionRange + -- } + -- NOTE: sourcePkgDbs is the stuff that we pull from Hackage + -- and similar Indices! (sourcePkgDb, tis, ar) <- getSourcePackages verbosity @@ -842,12 +849,14 @@ rebuildInstallPlan liftIO $ do notice verbosity "Resolving dependencies..." - -- putStrLn "== installedPackages" - -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages installedPackages - -- putStrLn "== binstalledPackages" - -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages binstalledPkgIndex - -- putStrLn "== hinstalledPackages" - -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages hinstalledPkgIndex + putStrLn "== installedPackages" + putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages installedPackages + putStrLn "== binstalledPackages" + putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages binstalledPkgIndex + putStrLn "== hinstalledPackages" + putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages hinstalledPkgIndex + putStrLn "== localPackages" + putStrLn $ unlines . map (prettyShow . srcpkgPackageId) $ [pkg | SpecificSourcePackage pkg <- localPackages] planOrError <- foldProgress logMsg (pure . Left) (pure . Right) $ planPackages @@ -866,6 +875,16 @@ rebuildInstallPlan dieWithException verbosity $ PhaseRunSolverErr msg Right plan -> return (plan, pkgConfigDB, tis, ar) where + -- FIXME: See FIXME in Distribution.Client.ProjectConfig wrt to buildPackages. + addCompilerToSourcePkg :: CompilerId -> [PackageSpecifier UnresolvedSourcePackage] -> [PackageSpecifier UnresolvedSourcePackage] + addCompilerToSourcePkg compilerId = map (addCompilerId compilerId) + addCompilerId :: CompilerId -> PackageSpecifier UnresolvedSourcePackage -> PackageSpecifier UnresolvedSourcePackage + addCompilerId compilerId (NamedPackage name props) = NamedPackage name props + addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (f pkg) + where f :: SourcePackage UnresolvedPkgLoc -> SourcePackage UnresolvedPkgLoc + f pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} + localPackages = (addCompilerToSourcePkg (compilerIdFor Build toolchains) localPackages_) + <> (addCompilerToSourcePkg (compilerIdFor Host toolchains) localPackages_) corePackageDbs :: Stage -> PackageDBStackCWD corePackageDbs stage = Cabal.interpretPackageDbFlags False (packageDBs stage) @@ -942,7 +961,7 @@ rebuildInstallPlan toolchains pkgConfigDB solverPlan - localPackages = do + localPackages_ = do liftIO $ debug verbosity "Elaborating the install plan..." sourcePackageHashes <- @@ -980,6 +999,17 @@ rebuildInstallPlan liftIO $ debugNoWrap verbosity (showElaboratedInstallPlan instantiatedPlan) return (instantiatedPlan, elaboratedShared) where + -- FIXME: See FIXME in Distribution.Client.ProjectConfig wrt to buildPackages. + addCompilerToSourcePkg :: CompilerId -> [PackageSpecifier (SourcePackage (PackageLocation loc))] -> [PackageSpecifier (SourcePackage (PackageLocation loc))] + addCompilerToSourcePkg compilerId = map (addCompilerId compilerId) + addCompilerId :: CompilerId -> PackageSpecifier (SourcePackage (PackageLocation loc)) -> PackageSpecifier (SourcePackage (PackageLocation loc)) + addCompilerId compilerId (NamedPackage name props) = NamedPackage name props + addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (f pkg) + where f :: SourcePackage (PackageLocation loc) -> SourcePackage (PackageLocation loc) + f pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} + localPackages = (addCompilerToSourcePkg (compilerIdFor Build toolchains) localPackages_) + <> (addCompilerToSourcePkg (compilerIdFor Host toolchains) localPackages_) + withRepoCtx :: (RepoContext -> IO a) -> IO a withRepoCtx = projectConfigWithSolverRepoContext @@ -1752,7 +1782,7 @@ elaborateInstallPlan let src_comps = componentsGraphToList g infoProgress $ hang - (text "Component graph for" <+> pretty pkgid <<>> colon) + (text "Component graph for" <+> pretty pkgid <+> text "at stage " <+> text (show $ elabStage elab0) <<>> colon) 4 (dispComponentsWithDeps src_comps) (_, comps) <- @@ -1943,7 +1973,7 @@ elaborateInstallPlan elab0 { elabPkgOrComp = ElabComponent $ elab_comp } - cid = case elabBuildStyle elab0 of + cid = case traceShow (elabBuildStyle elab0) (elabBuildStyle elab0) of BuildInplaceOnly{} -> mkComponentId $ prettyShow pkgid @@ -2331,7 +2361,9 @@ elaborateInstallPlan else cp elabPkgSourceLocation = srcloc - elabPkgSourceHash = Map.lookup pkgid sourcePackageHashes + elabPkgSourceHash = case Map.lookup pkgid sourcePackageHashes of + Just h -> Just h + Nothing -> trace (unlines $ ("failed to find " ++ prettyShow pkgid ++ " in "):[ prettyShow k ++ " -> " ++ show v | (k, v) <- Map.toList sourcePackageHashes]) Nothing elabLocalToProject = isLocalToProject pkg elabBuildStyle = if shouldBuildInplaceOnly pkg @@ -2519,15 +2551,20 @@ elaborateInstallPlan shouldBuildInplaceOnly pkg = Set.member (packageId pkg) - pkgsToBuildInplaceOnly + (traceShowId pkgsToBuildInplaceOnly) + + -- FIXME: This change is stupid, however the previous assumption is + -- that ALL pkgsLocalToProject somehow end up in the solverPlan. This + -- is not given, as we now have every local package listed twice. Once + -- for the Host, and once for the Build. Thus iterating over each individual + -- package _does_ work, but is rather idiotic. pkgsToBuildInplaceOnly :: Set PackageId pkgsToBuildInplaceOnly = Set.fromList $ map packageId $ - SolverInstallPlan.reverseDependencyClosure - solverPlan - (map PlannedId (Set.toList pkgsLocalToProject)) + concat [SolverInstallPlan.reverseDependencyClosure solverPlan [PlannedId p] + | p <- (Set.toList pkgsLocalToProject)] isLocalToProject :: Package pkg => pkg -> Bool isLocalToProject pkg = @@ -4474,7 +4511,7 @@ setupHsHaddockArgs elab = -- not replace installed packages with ghc-pkg. packageHashInputs - :: ElaboratedSharedConfig + :: HasCallStack => ElaboratedSharedConfig -> ElaboratedConfiguredPackage -> PackageHashInputs packageHashInputs diff --git a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs index 631dbde5afe..883f9f38a91 100644 --- a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs +++ b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs @@ -360,6 +360,43 @@ setupRoots = -- Each element in the result is a package name along with the packages that -- depend on it and the versions they require. These are guaranteed to be -- distinct. + +-- type SolverPlanIndex = Graph (ResolverPackage UnresolvedPkgLoc) +-- data ResolverPackage loc = PreExisting InstSolverPackage +-- | Configured (SolverPackage loc) +-- data InstSolverPackage = InstSolverPackage { +-- instSolverQPN :: QPN, +-- instSolverPkgIPI :: InstalledPackageInfo, +-- instSolverPkgLibDeps :: ComponentDeps [SolverId], +-- instSolverPkgExeDeps :: ComponentDeps [SolverId] +-- } +-- data SolverPackage loc = SolverPackage { +-- solverPkgQPN :: QPN, +-- solverPkgStage :: Stage, +-- solverPkgSource :: SourcePackage loc, +-- solverPkgFlags :: FlagAssignment, +-- solverPkgStanzas :: OptionalStanzaSet, +-- solverPkgLibDeps :: ComponentDeps [SolverId], +-- solverPkgExeDeps :: ComponentDeps [SolverId] +-- } +-- newtype ComponentDeps a = ComponentDeps { unComponentDeps :: Map Component a } +-- data SolverId = PreExistingId { solverSrcId :: PackageId, solverInstId :: UnitId } +-- | PlannedId { solverSrcId :: PackageId } +-- +-- flatDeps :: ComponentDeps a -> a + +-- instance Package (ResolverPackage loc) where +-- packageId (PreExisting ipkg) = packageId ipkg +-- packageId (Configured spkg) = packageId spkg + +-- resolverPackageLibDeps :: ResolverPackage loc -> CD.ComponentDeps [SolverId] +-- resolverPackageLibDeps (PreExisting ipkg) = instSolverPkgLibDeps ipkg +-- resolverPackageLibDeps (Configured spkg) = solverPkgLibDeps spkg + +-- resolverPackageExeDeps :: ResolverPackage loc -> CD.ComponentDeps [SolverId] +-- resolverPackageExeDeps (PreExisting ipkg) = instSolverPkgExeDeps ipkg +-- resolverPackageExeDeps (Configured spkg) = solverPkgExeDeps spkg + dependencyInconsistencies' :: SolverPlanIndex -> [(PackageName, [(PackageIdentifier, Version)])] From 78afc12dc80772fef4ce996713a8fcd7ea5df8ec Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 25 Mar 2025 20:45:04 +0900 Subject: [PATCH 62/82] Drop debug --- Cabal/src/Distribution/Simple/PackageIndex.hs | 3 +-- .../src/Distribution/Solver/Modular.hs | 2 +- .../Solver/Modular/IndexConversion.hs | 6 ++--- .../src/Distribution/Solver/Modular/Solver.hs | 6 ++--- .../src/Distribution/Client/Dependency.hs | 15 +----------- .../Client/ProjectOrchestration.hs | 6 ++--- .../Distribution/Client/ProjectPlanning.hs | 24 +++++++++---------- 7 files changed, 22 insertions(+), 40 deletions(-) diff --git a/Cabal/src/Distribution/Simple/PackageIndex.hs b/Cabal/src/Distribution/Simple/PackageIndex.hs index eb3e4a22cce..545811b5984 100644 --- a/Cabal/src/Distribution/Simple/PackageIndex.hs +++ b/Cabal/src/Distribution/Simple/PackageIndex.hs @@ -169,7 +169,6 @@ instance Semigroup (PackageIndex IPI.InstalledPackageInfo) where {-# NOINLINE invariant #-} invariant :: WithCallStack (InstalledPackageIndex -> Bool) invariant (PackageIndex pids pnames) = - trace (show pids' ++ "\n" ++ show pnames') $ pids' == pnames' where pids' = map installedUnitId (Map.elems pids) @@ -335,7 +334,7 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = Just pvers -> case Map.lookup (packageVersion pkgid) pvers of Nothing -> original Just pkgs -> - traceShow (pkgid, pkgs) $ mkPackageIndex + mkPackageIndex (foldl' (flip (Map.delete . installedUnitId)) pids pkgs) -- (Map.update deletePkgInstance (installedUnitId pkgid) pids) (deletePkgName pnames) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular.hs b/cabal-install-solver/src/Distribution/Solver/Modular.hs index a623d732703..73bb9c5b20b 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular.hs @@ -81,7 +81,7 @@ showCP (CP qpi fa es ds) = -- solver. Performs the necessary translations before and after. modularResolver :: SolverConfig -> DependencyResolver loc modularResolver sc toolchains biidx iidx sidx pkgConfigDB pprefs pcs pns = do - (assignment, revdepmap) <- solve' sc toolchains (trace (showIdx idx) idx) pkgConfigDB pprefs gcs pns + (assignment, revdepmap) <- solve' sc toolchains idx pkgConfigDB pprefs gcs pns let cp = toCPs assignment revdepmap Step (show (vcat (map showCP cp))) $ return $ postprocess assignment revdepmap diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index d6f008e153b..f91b425f593 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -63,13 +63,11 @@ convPIs :: Toolchains -> Map PN [LabeledPackageConstraint] -> CI.PackageIndex (SourcePackage loc) -> Index convPIs toolchains constraints sip strfl solveExes biidx iidx sidx = - mkIndex $ (trace (pp "BIPIs" bipis) bipis) ++ (trace (pp "HIPIs" hipis) hipis) ++ (trace (pp "SPIs" spis) spis) + mkIndex $ bipis ++ hipis ++ spis where bipis = convIPI' toolchains sip biidx hipis = convIPI' toolchains sip iidx ipis = bipis ++ hipis spis = convSPI' toolchains constraints strfl solveExes sidx - pp :: String -> [(PN, I, PInfo)] -> String - pp label xs = unlines $ ("=== " ++ label ++ ":\n"):(map (\(pn, i, pi) -> show pn ++ " " ++ show i) xs) -- | Convert a Cabal installed package index to the simpler, -- more uniform index format of the solver. @@ -158,7 +156,7 @@ convIP toolchains idx ipi = convIPId :: Toolchains -> DependencyReason PN -> Component -> SI.InstalledPackageIndex -> UnitId -> Either UnitId (FlaggedDep PN) convIPId toolchains dr comp idx ipid = case SI.lookupUnitId idx ipid of - Nothing -> traceShow (show comp ++ ": Failed to find: " ++ show ipid ++ " in index.") $ Left ipid + Nothing -> Left ipid Just ipi -> let (pn, i) = convId toolchains ipi name = ExposedLib LMainLibName -- TODO: Handle sub-libraries. in Right (D.Simple (LDep dr (Dep (PkgComponent pn name) (Fixed i))) comp) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 0a6674ce9f5..d519456143f 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -105,7 +105,7 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = traceTree "cycles.json" id . detectCycles . traceTree "heuristics.json" id . - stageBuildDeps "post-pref: " . + -- stageBuildDeps "post-pref: " . trav ( heuristicsPhase . preferencesPhase . @@ -115,9 +115,9 @@ solve sc toolchains idx pkgConfigDB userPrefs userConstraints userGoals = validationCata . traceTree "pruned.json" id . trav prunePhase . - stageBuildDeps "post-prune: " . + -- stageBuildDeps "post-prune: " . (if buildIsHost toolchains then id else trav P.pruneHostFromSetup) . - stageBuildDeps "build: " . + -- stageBuildDeps "build: " . traceTree "build.json" id $ buildPhase where diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 51c66a9f691..f3814917ace 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -935,25 +935,12 @@ validateSolverResult -> [ResolverPackage UnresolvedPkgLoc] -> SolverInstallPlan validateSolverResult toolchains indepGoals pkgs = - case planPackagesProblems toolchains (trace (dump pkgs) pkgs) of + case planPackagesProblems toolchains pkgs of [] -> case SolverInstallPlan.new indepGoals graph of Right plan -> plan Left problems -> error (formatPlanProblems problems) problems -> error (formatPkgProblems problems) where - dump :: [ResolverPackage UnresolvedPkgLoc] -> String - dump xs = unlines $ - "=== DUMP ===":[unlines $ (resolverPkgHead x ++ show (packageId x)):[ "- "++ solverIdHead y ++ show (solverSrcId y) - | y <- CD.flatDeps (resolverPackageLibDeps x)] - | x <- xs ] - ++ ["=== /DUMP =="] - - solverIdHead :: SolverId -> String - solverIdHead (PreExistingId{}) = "[PE]" - solverIdHead (PlannedId {}) = "[PL]" - - resolverPkgHead (PreExisting _) = "[PE]" - resolverPkgHead (Configured _) = "[CF]" graph :: Graph.Graph (ResolverPackage UnresolvedPkgLoc) graph = Graph.fromDistinctList pkgs diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index dd43c4298ab..6d91783326a 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -659,8 +659,7 @@ resolveTargets checkTarget bt@(TargetPackage _ (ordNub -> [pkgid]) mkfilter) | Just ats <- fmap (maybe id filterTargetsKind mkfilter) $ - (trace (unlines $ ("Failed to find " ++ prettyShow pkgid ++ " in "):[prettyShow k {-# ++ " -> " ++ show v #-} | (k,v) <- Map.toList availableTargetsByPackageId]) - (Map.lookup pkgid availableTargetsByPackageId)) = + (Map.lookup pkgid availableTargetsByPackageId) = fmap (componentTargets WholeComponent) $ selectPackageTargets bt ats | otherwise = @@ -689,11 +688,10 @@ resolveTargets -- FIXME: this is stupid. We do not know what the target selectors HOST compiler is... -- so we'll assume tere is only a _SINGLE_ match in the map if we ignore the pkgCompiler. -- This lookup is now O(n) instead of O(log n). - (trace (unlines $ ("Failed to find " ++ prettyShow pkgid ++ ":" ++ show cname ++ " in "):[prettyShow k ++ ":" ++ show k' {-# ++ " -> " ++ show v #-} | ((k,k'),v) <- Map.toList availableTargetsByPackageIdAndComponentName]) (case [v | ((k,k'),v) <- Map.toList availableTargetsByPackageIdAndComponentName , k{pkgCompiler = Nothing} == pkgid , k' == cname] of - [match] -> Just match)) + [match] -> Just match) -- (Map.lookup -- (pkgid, cname) -- availableTargetsByPackageIdAndComponentName)) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 38e4d752f03..91a319c83a4 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -849,14 +849,14 @@ rebuildInstallPlan liftIO $ do notice verbosity "Resolving dependencies..." - putStrLn "== installedPackages" - putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages installedPackages - putStrLn "== binstalledPackages" - putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages binstalledPkgIndex - putStrLn "== hinstalledPackages" - putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages hinstalledPkgIndex - putStrLn "== localPackages" - putStrLn $ unlines . map (prettyShow . srcpkgPackageId) $ [pkg | SpecificSourcePackage pkg <- localPackages] + -- putStrLn "== installedPackages" + -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages installedPackages + -- putStrLn "== binstalledPackages" + -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages binstalledPkgIndex + -- putStrLn "== hinstalledPackages" + -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages hinstalledPkgIndex + -- putStrLn "== localPackages" + -- putStrLn $ unlines . map (prettyShow . srcpkgPackageId) $ [pkg | SpecificSourcePackage pkg <- localPackages] planOrError <- foldProgress logMsg (pure . Left) (pure . Right) $ planPackages @@ -1782,7 +1782,7 @@ elaborateInstallPlan let src_comps = componentsGraphToList g infoProgress $ hang - (text "Component graph for" <+> pretty pkgid <+> text "at stage " <+> text (show $ elabStage elab0) <<>> colon) + (text "Component graph for" <+> pretty pkgid <<>> colon) 4 (dispComponentsWithDeps src_comps) (_, comps) <- @@ -1973,7 +1973,7 @@ elaborateInstallPlan elab0 { elabPkgOrComp = ElabComponent $ elab_comp } - cid = case traceShow (elabBuildStyle elab0) (elabBuildStyle elab0) of + cid = case elabBuildStyle elab0 of BuildInplaceOnly{} -> mkComponentId $ prettyShow pkgid @@ -2363,7 +2363,7 @@ elaborateInstallPlan elabPkgSourceLocation = srcloc elabPkgSourceHash = case Map.lookup pkgid sourcePackageHashes of Just h -> Just h - Nothing -> trace (unlines $ ("failed to find " ++ prettyShow pkgid ++ " in "):[ prettyShow k ++ " -> " ++ show v | (k, v) <- Map.toList sourcePackageHashes]) Nothing + Nothing -> Nothing elabLocalToProject = isLocalToProject pkg elabBuildStyle = if shouldBuildInplaceOnly pkg @@ -2551,7 +2551,7 @@ elaborateInstallPlan shouldBuildInplaceOnly pkg = Set.member (packageId pkg) - (traceShowId pkgsToBuildInplaceOnly) + pkgsToBuildInplaceOnly -- FIXME: This change is stupid, however the previous assumption is From 0532529f34d83ff9f95c4350ed1686bb6a315442 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 25 Mar 2025 21:31:17 +0900 Subject: [PATCH 63/82] Set source-dir witout compiler --- cabal-install/src/Distribution/Client/ProjectBuilding.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding.hs b/cabal-install/src/Distribution/Client/ProjectBuilding.hs index a2aa390e8a7..12bfd0df037 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding.hs @@ -220,7 +220,7 @@ rebuildTargetsDryRun distDirLayout@DistDirLayout{..} shared = else return (BuildStatusUnpack tarball) where srcdir :: FilePath - srcdir = distUnpackedSrcDirectory (packageId pkg) + srcdir = distUnpackedSrcDirectory ((packageId pkg){pkgCompiler = Nothing}) dryRunLocalPkg :: ElaboratedConfiguredPackage @@ -713,7 +713,7 @@ withTarballLocalDirectory let tmpdir = distTempDirectory builddir = relativeSymbolicPath $ makeRelativePathEx "dist" in withTempDirectory verbosity tmpdir "src" $ \unpackdir -> do - let srcdir = makeSymbolicPath $ unpackdir </> prettyShow pkgid + let srcdir = makeSymbolicPath $ unpackdir </> prettyShow (pkgid{pkgCompiler = Nothing}) unpackPackageTarball verbosity tarball @@ -727,7 +727,7 @@ withTarballLocalDirectory -- inplace there BuildInplaceOnly{} -> do let srcrootdir = distUnpackedSrcRootDirectory - srcdir = distUnpackedSrcDirectory pkgid + srcdir = distUnpackedSrcDirectory (pkgid{pkgCompiler = Nothing}) builddir = makeSymbolicPath $ makeRelative (normalise srcdir) $ @@ -791,7 +791,7 @@ unpackPackageTarball verbosity tarball parentdir pkgid pkgTextOverride = </> pkgsubdir </> prettyShow pkgname <.> "cabal" - pkgsubdir = prettyShow pkgid + pkgsubdir = prettyShow (pkgid{pkgCompiler = Nothing}) pkgname = packageName pkgid -- | This is a bit of a hacky workaround. A number of packages ship From 5b816930dbec0ea56e7b27067ea609d1eb7fb7c3 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Wed, 26 Mar 2025 11:32:33 +0900 Subject: [PATCH 64/82] BUG: Parsect PackageIdentifier is broken If we try to parse <flavour>-<version>-<pkg>-<version> for e.g. <pkg>-<version> this will break in -- | Parse the @setup-config@ file header, returning the package identifiers -- for Cabal and the compiler. parseHeader :: ByteString -- ^ The file contents. -> IO (PackageIdentifier, PackageIdentifier) The issue is that we I guess parse e.g. Cabal-x.y.z as compiler flavour + version, and then have nothing for the PackageIdentifier to parse. This code needs to be fixed properly to try and parse compier-version-pkg-version or only pkg-version (and set compiler to Nothing). --- Cabal-syntax/src/Distribution/Types/PackageId.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index ca9bfbfc967..2da6171fe6d 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -64,13 +64,13 @@ instance Pretty PackageIdentifier where -- Nothing instance Parsec PackageIdentifier where parsec = do - comp <- parsec <* P.char '-' + -- comp <- parsec <* P.char '-' xs' <- P.sepByNonEmpty component (P.char '-') (v, xs) <- case simpleParsec (NE.last xs') of Nothing -> return (nullVersion, toList xs') -- all components are version Just v -> return (v, NE.init xs') if not (null xs) && all (\c -> all (/= '.') c && not (all isDigit c)) xs - then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v comp + then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v Nothing else fail "all digits or a dot in a portion of package name" where component = P.munch1 (\c -> isAlphaNum c || c == '.') From 062f69e69237b53b0ba16e58c5108a05fd11e696 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Wed, 26 Mar 2025 11:47:03 +0900 Subject: [PATCH 65/82] Revert "BUG: Parsect PackageIdentifier is broken" This reverts commit 5b816930dbec0ea56e7b27067ea609d1eb7fb7c3. --- Cabal-syntax/src/Distribution/Types/PackageId.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index 2da6171fe6d..ca9bfbfc967 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -64,13 +64,13 @@ instance Pretty PackageIdentifier where -- Nothing instance Parsec PackageIdentifier where parsec = do - -- comp <- parsec <* P.char '-' + comp <- parsec <* P.char '-' xs' <- P.sepByNonEmpty component (P.char '-') (v, xs) <- case simpleParsec (NE.last xs') of Nothing -> return (nullVersion, toList xs') -- all components are version Just v -> return (v, NE.init xs') if not (null xs) && all (\c -> all (/= '.') c && not (all isDigit c)) xs - then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v Nothing + then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v comp else fail "all digits or a dot in a portion of package name" where component = P.munch1 (\c -> isAlphaNum c || c == '.') From 8aadca3ee2c43fa41ac7cac4f3de5fe927c69f17 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 27 Mar 2025 10:30:43 +0900 Subject: [PATCH 66/82] Add ScopeAnyBuildDepQualifier --- .../Distribution/Solver/Types/PackageConstraint.hs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs b/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs index 06c5ae169fa..37c0d7dd1d7 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs @@ -49,6 +49,9 @@ data ConstraintScope -- | The package with the specified name when it has a -- setup qualifier. | ScopeAnySetupQualifier PackageName + -- | The package with the specified name when it is a build-time + -- dependency. E.g. a Setup script or a build-depends. + | ScopeAnyBuildDepQualifier PackageName -- | The package with the specified name regardless of -- qualifier. | ScopeAnyQualifier PackageName @@ -65,6 +68,7 @@ scopeToPackageName :: ConstraintScope -> PackageName scopeToPackageName (ScopeTarget pn) = pn scopeToPackageName (ScopeQualified _ pn) = pn scopeToPackageName (ScopeAnySetupQualifier pn) = pn +scopeToPackageName (ScopeAnyBuildDepQualifier pn) = pn scopeToPackageName (ScopeAnyQualifier pn) = pn constraintScopeMatches :: ConstraintScope -> QPN -> Bool @@ -74,6 +78,12 @@ constraintScopeMatches (ScopeTarget pn) (Q (PackagePath ns q) pn') = in namespaceMatches ns && q == QualToplevel && pn == pn' constraintScopeMatches (ScopeQualified q pn) (Q (PackagePath _ q') pn') = q == q' && pn == pn' +constraintScopeMatches (ScopeAnyBuildDepQualifier pn) (Q pp pn') = + let setup (PackagePath _ (QualSetup _)) = True + setup _ = False + build (PackagePath _ (QualExe _ _)) = True + build _ = False + in (setup pp || build pp) && pn == pn' constraintScopeMatches (ScopeAnySetupQualifier pn) (Q pp pn') = let setup (PackagePath _ (QualSetup _)) = True setup _ = False @@ -83,6 +93,7 @@ constraintScopeMatches (ScopeAnyQualifier pn) (Q _ pn') = pn == pn' instance Pretty ConstraintScope where pretty (ScopeTarget pn) = pretty pn <<>> Disp.text "." <<>> pretty pn pretty (ScopeQualified q pn) = dispQualifier q <<>> pretty pn + pretty (ScopeAnyBuildDepQualifier pn) = Disp.text "build." <<>> pretty pn pretty (ScopeAnySetupQualifier pn) = Disp.text "setup." <<>> pretty pn pretty (ScopeAnyQualifier pn) = Disp.text "any." <<>> pretty pn From 2554a524e2b5ec9bd6f225ffbaa94db554b3274d Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 27 Mar 2025 10:31:30 +0900 Subject: [PATCH 67/82] Fix deleteSourcePackageId --- Cabal/src/Distribution/Simple/PackageIndex.hs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Cabal/src/Distribution/Simple/PackageIndex.hs b/Cabal/src/Distribution/Simple/PackageIndex.hs index 545811b5984..7cb606a0e93 100644 --- a/Cabal/src/Distribution/Simple/PackageIndex.hs +++ b/Cabal/src/Distribution/Simple/PackageIndex.hs @@ -323,6 +323,10 @@ deleteUnitId ipkgid original@(PackageIndex pids pnames) = . List.deleteBy (\_ pkg -> installedUnitId pkg == ipkgid) undefined -- | Removes all packages with this source 'PackageId' from the index. +-- +-- The Index maps unitids to instances, however we may have multiple unitids +-- for the same package. Especially if for multiple compilers, as such we need +-- to ensure we don't delete by name/version, but by name/version/compiler only. deleteSourcePackageId :: PackageId -> InstalledPackageIndex @@ -333,11 +337,13 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = Nothing -> original Just pvers -> case Map.lookup (packageVersion pkgid) pvers of Nothing -> original - Just pkgs -> - mkPackageIndex - (foldl' (flip (Map.delete . installedUnitId)) pids pkgs) --- (Map.update deletePkgInstance (installedUnitId pkgid) pids) - (deletePkgName pnames) + Just pkgs -> case [pkg | pkg <- pkgs, IPI.pkgCompiler pkg == pkgCompiler pkgid] of + [] -> original + pkgs' -> + mkPackageIndex + (foldl' (flip (Map.delete . installedUnitId)) pids pkgs') + (deletePkgName pnames) + where deletePkgName = Map.update deletePkgVersion (packageName pkgid, LMainLibName) @@ -354,7 +360,7 @@ deleteSourcePackageId pkgid original@(PackageIndex pids pnames) = deletePkgInstances :: [IPI.InstalledPackageInfo] -> Maybe [IPI.InstalledPackageInfo] deletePkgInstances xs = if null xs' then Nothing else Just xs' - where xs' = [x | x <- xs, pkgCompiler pkgid /= pkgCompiler (IPI.sourcePackageId x)] + where xs' = [x | x <- xs, pkgCompiler pkgid /= IPI.pkgCompiler x] -- | Removes all packages with this (case-sensitive) name from the index. -- From 1a3a0a01222426de4cb5ad8e7d680a6b5913e723 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 27 Mar 2025 10:33:17 +0900 Subject: [PATCH 68/82] Use ScopeAnyBuildDepQualifier --- cabal-install/src/Distribution/Client/Dependency.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index f3814917ace..939aabf2e4e 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -454,13 +454,13 @@ dontInstallNonReinstallablePackages params = ConstraintSourceNonReinstallablePackage | pkgname <- nonReinstallablePackages ] -dontInstallNonReinstallablePackagesSetupOnly :: DepResolverParams -> DepResolverParams -dontInstallNonReinstallablePackagesSetupOnly params = +dontInstallNonReinstallablePackagesForBuild :: DepResolverParams -> DepResolverParams +dontInstallNonReinstallablePackagesForBuild params = addConstraints extraConstraints params where extraConstraints = [ LabeledPackageConstraint - (PackageConstraint (ScopeAnySetupQualifier pkgname) PackagePropertyInstalled) + (PackageConstraint (ScopeAnyBuildDepQualifier pkgname) PackagePropertyInstalled) ConstraintSourceNonReinstallablePackage | pkgname <- nonReinstallablePackages ] @@ -862,7 +862,7 @@ resolveDependencies toolchains pkgConfigDB params = verbosity ) = if asBool (depResolverAllowBootLibInstalls params) - then dontInstallNonReinstallablePackagesSetupOnly params + then dontInstallNonReinstallablePackagesForBuild params else dontInstallNonReinstallablePackages params preferences :: PackageName -> PackagePreferences From 7f34ae9d24a90eaed0d781f4ee898412a5de0cf0 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 27 Mar 2025 12:32:03 +0900 Subject: [PATCH 69/82] If build is host, allow installing even for build. --- cabal-install/src/Distribution/Client/Dependency.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 939aabf2e4e..878a99ca5e9 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -862,7 +862,9 @@ resolveDependencies toolchains pkgConfigDB params = verbosity ) = if asBool (depResolverAllowBootLibInstalls params) - then dontInstallNonReinstallablePackagesForBuild params + then if buildIsHost toolchains + then params + else dontInstallNonReinstallablePackagesForBuild params else dontInstallNonReinstallablePackages params preferences :: PackageName -> PackagePreferences From 78342eee234e8cee14ab90f6935382ec98712b5e Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 27 Mar 2025 12:32:36 +0900 Subject: [PATCH 70/82] Better packageid --- Cabal-syntax/src/Distribution/Types/PackageId.hs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index ca9bfbfc967..486df97a146 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -29,6 +29,7 @@ data PackageIdentifier = PackageIdentifier , pkgVersion :: Version -- ^ the version of this package, eg 1.2 , pkgCompiler :: Maybe CompilerId + -- ^ the associated compiler id of the package, eg ghc-9.8.4 } deriving (Generic, Read, Show, Eq, Ord, Data) @@ -37,8 +38,9 @@ instance Structured PackageIdentifier instance Pretty PackageIdentifier where pretty (PackageIdentifier n v c) - | v == nullVersion = pretty c <<>> Disp.char '-' <<>> pretty n -- if no version, don't show version. - | Just c' <- c = pretty c' <<>> Disp.char '-' <<>> pretty n <<>> Disp.char '-' <<>> pretty v + | Just c' <- c, v == nullVersion = pretty c <<>> Disp.char ':' <<>> pretty n -- if no version, don't show version. + | Just c' <- c = pretty c' <<>> Disp.char ':' <<>> pretty n <<>> Disp.char '-' <<>> pretty v + | v == nullVersion = pretty n | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v -- | @@ -64,13 +66,13 @@ instance Pretty PackageIdentifier where -- Nothing instance Parsec PackageIdentifier where parsec = do - comp <- parsec <* P.char '-' + -- comp <- Just <$> (parsec <* P.char ':') <|> return Nothing xs' <- P.sepByNonEmpty component (P.char '-') (v, xs) <- case simpleParsec (NE.last xs') of Nothing -> return (nullVersion, toList xs') -- all components are version Just v -> return (v, NE.init xs') if not (null xs) && all (\c -> all (/= '.') c && not (all isDigit c)) xs - then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v comp + then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v Nothing --comp else fail "all digits or a dot in a portion of package name" where component = P.munch1 (\c -> isAlphaNum c || c == '.') From 35e6455674a53127eb74aaef3ff28c88360224d5 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Thu, 27 Mar 2025 12:33:05 +0900 Subject: [PATCH 71/82] Add support for Package Indices --- .../src/Distribution/Client/FetchUtils.hs | 3 ++- .../src/Distribution/Client/ProjectPlanning.hs | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cabal-install/src/Distribution/Client/FetchUtils.hs b/cabal-install/src/Distribution/Client/FetchUtils.hs index 62da386573d..6b29dd84bfc 100644 --- a/cabal-install/src/Distribution/Client/FetchUtils.hs +++ b/cabal-install/src/Distribution/Client/FetchUtils.hs @@ -60,6 +60,7 @@ import Distribution.Package ( PackageId , packageName , packageVersion + , pkgCompiler ) import Distribution.Simple.Utils ( debug @@ -395,7 +396,7 @@ waitAsyncFetchPackage verbosity downloadMap srcloc = packageFile :: Repo -> PackageId -> FilePath packageFile repo pkgid = packageDir repo pkgid - </> prettyShow pkgid + </> prettyShow pkgid{pkgCompiler = Nothing} <.> "tar.gz" -- | Generate the full path to the directory where the local cached copy of diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 91a319c83a4..d3e417966c0 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -244,6 +244,7 @@ import System.FilePath import qualified Text.PrettyPrint as Disp import GHC.Stack (HasCallStack) +-- import qualified Distribution.Solver.Types.PackageIndex as XXX -- | Check that an 'ElaboratedConfiguredPackage' actually makes -- sense under some 'ElaboratedSharedConfig'. @@ -833,13 +834,17 @@ rebuildInstallPlan -- NOTE: sourcePkgDbs is the stuff that we pull from Hackage -- and similar Indices! - (sourcePkgDb, tis, ar) <- + (sourcePkgDb_, tis, ar) <- getSourcePackages verbosity withRepoCtx (solverSettingIndexState solverSettings) (solverSettingActiveRepos solverSettings) + -- FIXME: we are duplicating the index here, bad for memory use :-/ + let sourcePkgDb = sourcePkgDb_{packageIndex = (addCompilerIdToSrcPkg (compilerIdFor Build toolchains) <$> packageIndex sourcePkgDb_) + <> (addCompilerIdToSrcPkg (compilerIdFor Host toolchains) <$> packageIndex sourcePkgDb_) } + pkgConfigDB <- getPkgConfigDb verbosity (toolchainProgramDb $ buildToolchain toolchains) -- TODO: [code cleanup] it'd be better if the Compiler contained the @@ -857,6 +862,7 @@ rebuildInstallPlan -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages hinstalledPkgIndex -- putStrLn "== localPackages" -- putStrLn $ unlines . map (prettyShow . srcpkgPackageId) $ [pkg | SpecificSourcePackage pkg <- localPackages] + -- putStrLn $ unlines . take 20 $ map (prettyShow . srcpkgPackageId) (XXX.allPackages (packageIndex sourcePkgDb)) planOrError <- foldProgress logMsg (pure . Left) (pure . Right) $ planPackages @@ -880,9 +886,9 @@ rebuildInstallPlan addCompilerToSourcePkg compilerId = map (addCompilerId compilerId) addCompilerId :: CompilerId -> PackageSpecifier UnresolvedSourcePackage -> PackageSpecifier UnresolvedSourcePackage addCompilerId compilerId (NamedPackage name props) = NamedPackage name props - addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (f pkg) - where f :: SourcePackage UnresolvedPkgLoc -> SourcePackage UnresolvedPkgLoc - f pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} + addCompilerId compilerId (SpecificSourcePackage pkg) = SpecificSourcePackage (addCompilerIdToSrcPkg compilerId pkg) + addCompilerIdToSrcPkg :: CompilerId -> SourcePackage UnresolvedPkgLoc -> SourcePackage UnresolvedPkgLoc + addCompilerIdToSrcPkg compilerId pkg = pkg{srcpkgPackageId = (srcpkgPackageId pkg){pkgCompiler = Just compilerId}} localPackages = (addCompilerToSourcePkg (compilerIdFor Build toolchains) localPackages_) <> (addCompilerToSourcePkg (compilerIdFor Host toolchains) localPackages_) corePackageDbs :: Stage -> PackageDBStackCWD From c52048294c408446ad9dea836cf3f48f0405693f Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 1 Apr 2025 20:34:37 +0900 Subject: [PATCH 72/82] UGLY! Forcing pkgCompiler to Nothing across the codebasy :cry: --- Cabal/src/Distribution/Backpack/Id.hs | 6 ++++-- Cabal/src/Distribution/Simple/InstallDirs.hs | 6 +++--- cabal-install/src/Distribution/Client/DistDirLayout.hs | 3 ++- cabal-install/src/Distribution/Client/FetchUtils.hs | 2 +- .../src/Distribution/Client/ProjectBuilding.hs | 2 +- .../src/Distribution/Client/ProjectPlanning.hs | 10 +++++----- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Cabal/src/Distribution/Backpack/Id.hs b/Cabal/src/Distribution/Backpack/Id.hs index 38e831acf17..7e94dc38008 100644 --- a/Cabal/src/Distribution/Backpack/Id.hs +++ b/Cabal/src/Distribution/Backpack/Id.hs @@ -39,12 +39,14 @@ computeComponentId -- This is used by cabal-install's legacy codepath -> Maybe ([ComponentId], FlagAssignment) -> ComponentId -computeComponentId deterministic mb_ipid mb_cid pid cname mb_details = +computeComponentId deterministic mb_ipid mb_cid pid0 cname mb_details = -- show is found to be faster than intercalate and then replacement of -- special character used in intercalating. We cannot simply hash by -- doubly concatenating list, as it just flatten out the nested list, so -- different sources can produce same hash - let hash_suffix + let -- we do not want the compiler to show up in the Id. + pid = pid0{pkgCompiler = Nothing} + hash_suffix | Just (dep_ipids, flags) <- mb_details = "-" ++ hashToBase62 diff --git a/Cabal/src/Distribution/Simple/InstallDirs.hs b/Cabal/src/Distribution/Simple/InstallDirs.hs index 86e6fa08777..c3f403a27de 100644 --- a/Cabal/src/Distribution/Simple/InstallDirs.hs +++ b/Cabal/src/Distribution/Simple/InstallDirs.hs @@ -209,7 +209,7 @@ defaultInstallDirs' False comp userInstall _hasLibs = do case buildOS of Windows -> return "$prefix" _ -> return ("$prefix" </> "lib") - return $ + return $ traceShowId $ fmap toPathTemplate $ InstallDirs { prefix = installPrefix @@ -267,7 +267,7 @@ substituteInstallDirTemplates :: PathTemplateEnv -> InstallDirTemplates -> InstallDirTemplates -substituteInstallDirTemplates env dirs = dirs' +substituteInstallDirTemplates env dirs = traceShow "BOOM" $ dirs' where dirs' = InstallDirs @@ -441,7 +441,7 @@ packageTemplateEnv pkgId uid = , -- Invariant: uid is actually a HashedUnitId. Hard to enforce because -- it's an API change. (LibNameVar, PathTemplate [Ordinary $ prettyShow uid]) - , (PkgIdVar, PathTemplate [Ordinary $ prettyShow pkgId]) + , (PkgIdVar, PathTemplate [Ordinary $ prettyShow (pkgId{pkgCompiler = Nothing})]) ] compilerTemplateEnv :: CompilerInfo -> PathTemplateEnv diff --git a/cabal-install/src/Distribution/Client/DistDirLayout.hs b/cabal-install/src/Distribution/Client/DistDirLayout.hs index 64140152453..152e077f105 100644 --- a/cabal-install/src/Distribution/Client/DistDirLayout.hs +++ b/cabal-install/src/Distribution/Client/DistDirLayout.hs @@ -39,6 +39,7 @@ import Distribution.Package , PackageId , PackageIdentifier , UnitId + , pkgCompiler ) import Distribution.Simple.Compiler ( Compiler (..) @@ -200,7 +201,7 @@ defaultDistDirLayout projectRoot mdistDirectory haddockOutputDir = distBuildRootDirectory </> prettyShow (distParamPlatform params) </> prettyShow (distParamCompilerId params) - </> prettyShow (distParamPackageId params) + </> prettyShow ((distParamPackageId params){pkgCompiler = Nothing}) </> ( case distParamComponentName params of Nothing -> "" Just (CLibName LMainLibName) -> "" diff --git a/cabal-install/src/Distribution/Client/FetchUtils.hs b/cabal-install/src/Distribution/Client/FetchUtils.hs index 6b29dd84bfc..fd6dbe6553b 100644 --- a/cabal-install/src/Distribution/Client/FetchUtils.hs +++ b/cabal-install/src/Distribution/Client/FetchUtils.hs @@ -201,7 +201,7 @@ verifyFetchedTarball verbosity file mCallbacks pkgid = let warnAndFail s = warn verbosity ("Fetched tarball " ++ file ++ " does not match server, will redownload: " ++ s) >> return False in -- the do block in parens is due to dealing with the checked exceptions mechanism. ( do - fileInfo <- Sec.indexLookupFileInfo callbacks pkgid + fileInfo <- Sec.indexLookupFileInfo callbacks (pkgid{pkgCompiler = Nothing}) sz <- Sec.FileLength . fromInteger <$> getFileSize file if sz /= Sec.fileInfoLength (Sec.trusted fileInfo) then warnAndFail "file length mismatch" diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding.hs b/cabal-install/src/Distribution/Client/ProjectBuilding.hs index 12bfd0df037..d58df79fe26 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding.hs @@ -718,7 +718,7 @@ withTarballLocalDirectory verbosity tarball unpackdir - pkgid + pkgid{pkgCompiler = Nothing} pkgTextOverride buildPkg srcdir builddir diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index d3e417966c0..4c175ca020e 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1211,7 +1211,7 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do -- let allPkgLocations :: [(PackageId, PackageLocation (Maybe FilePath))] allPkgLocations = - [ (packageId pkg, srcpkgSource pkg) + [ ((packageId pkg){pkgCompiler = Nothing}, srcpkgSource pkg) | SolverInstallPlan.Configured (SolverPackage{solverPkgSource = pkg}) <- SolverInstallPlan.toList solverPlan ] @@ -1982,7 +1982,7 @@ elaborateInstallPlan cid = case elabBuildStyle elab0 of BuildInplaceOnly{} -> mkComponentId $ - prettyShow pkgid + prettyShow (pkgid{pkgCompiler = Nothing}) ++ "-inplace" ++ ( case Cabal.componentNameString cname of Nothing -> "" @@ -2215,7 +2215,7 @@ elaborateInstallPlan pkgInstalledId | shouldBuildInplaceOnly pkg = - mkComponentId (prettyShow pkgid ++ "-inplace") + mkComponentId (prettyShow (pkgid{pkgCompiler = Nothing}) ++ "-inplace") | otherwise = assert (isJust elabPkgSourceHash) $ hashedInstalledPackageId @@ -2226,7 +2226,7 @@ elaborateInstallPlan -- Need to filter out internal dependencies, because they don't -- correspond to anything real anymore. - isExt confid = confSrcId confid /= pkgid + isExt confid = (confSrcId confid){pkgCompiler = Nothing} /= pkgid{pkgCompiler = Nothing} filterExt = filter isExt filterExt' :: [(ConfiguredId, a)] -> [(ConfiguredId, a)] @@ -2367,7 +2367,7 @@ elaborateInstallPlan else cp elabPkgSourceLocation = srcloc - elabPkgSourceHash = case Map.lookup pkgid sourcePackageHashes of + elabPkgSourceHash = case Map.lookup (pkgid{pkgCompiler = Nothing}) sourcePackageHashes of Just h -> Just h Nothing -> Nothing elabLocalToProject = isLocalToProject pkg From 6ed744155ba20ee7c26c02595fc061d05eb04e32 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 1 Apr 2025 20:34:49 +0900 Subject: [PATCH 73/82] Add build. constraint. --- cabal-install/src/Distribution/Client/Targets.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cabal-install/src/Distribution/Client/Targets.hs b/cabal-install/src/Distribution/Client/Targets.hs index bfa94b0da80..cef19b4d277 100644 --- a/cabal-install/src/Distribution/Client/Targets.hs +++ b/cabal-install/src/Distribution/Client/Targets.hs @@ -618,6 +618,8 @@ data UserConstraintScope UserQualified UserQualifier PackageName | -- | Scope that applies to the package when it has a setup qualifier. UserAnySetupQualifier PackageName + | -- | Scope that applies to all build packages only. + UserAnyBuildDepQualifier PackageName | -- | Scope that applies to the package when it has any qualifier. UserAnyQualifier PackageName deriving (Eq, Show, Generic) @@ -634,6 +636,7 @@ fromUserConstraintScope :: UserConstraintScope -> ConstraintScope fromUserConstraintScope (UserQualified q pn) = ScopeQualified (fromUserQualifier q) pn fromUserConstraintScope (UserAnySetupQualifier pn) = ScopeAnySetupQualifier pn +fromUserConstraintScope (UserAnyBuildDepQualifier pn) = ScopeAnyBuildDepQualifier pn fromUserConstraintScope (UserAnyQualifier pn) = ScopeAnyQualifier pn -- | Version of 'PackageConstraint' that the user can specify on @@ -650,6 +653,7 @@ userConstraintPackageName (UserConstraint scope _) = scopePN scope where scopePN (UserQualified _ pn) = pn scopePN (UserAnyQualifier pn) = pn + scopePN (UserAnyBuildDepQualifier pn) = pn scopePN (UserAnySetupQualifier pn) = pn userToPackageConstraint :: UserConstraint -> PackageConstraint @@ -698,6 +702,7 @@ instance Parsec UserConstraint where withDot :: PackageName -> m UserConstraintScope withDot pn | pn == mkPackageName "any" = UserAnyQualifier <$> parsec + | pn == mkPackageName "build" = UserAnyBuildDepQualifier <$> parsec | pn == mkPackageName "setup" = UserAnySetupQualifier <$> parsec | otherwise = P.unexpected $ "constraint scope: " ++ unPackageName pn From 9fe4d069bb1149b339af45d2ed51d1d002a5394e Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Tue, 1 Apr 2025 20:37:30 +0900 Subject: [PATCH 74/82] Drop erronous traces --- Cabal/src/Distribution/Simple/InstallDirs.hs | 4 ++-- cabal-install/src/Distribution/Client/ProjectBuilding.hs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cabal/src/Distribution/Simple/InstallDirs.hs b/Cabal/src/Distribution/Simple/InstallDirs.hs index c3f403a27de..0611d33071c 100644 --- a/Cabal/src/Distribution/Simple/InstallDirs.hs +++ b/Cabal/src/Distribution/Simple/InstallDirs.hs @@ -209,7 +209,7 @@ defaultInstallDirs' False comp userInstall _hasLibs = do case buildOS of Windows -> return "$prefix" _ -> return ("$prefix" </> "lib") - return $ traceShowId $ + return $ fmap toPathTemplate $ InstallDirs { prefix = installPrefix @@ -267,7 +267,7 @@ substituteInstallDirTemplates :: PathTemplateEnv -> InstallDirTemplates -> InstallDirTemplates -substituteInstallDirTemplates env dirs = traceShow "BOOM" $ dirs' +substituteInstallDirTemplates env dirs = dirs' where dirs' = InstallDirs diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding.hs b/cabal-install/src/Distribution/Client/ProjectBuilding.hs index d58df79fe26..87e9167736d 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding.hs @@ -214,7 +214,7 @@ rebuildTargetsDryRun distDirLayout@DistDirLayout{..} shared = BuildInplaceOnly{} -> do -- TODO: [nice to have] use a proper file monitor rather -- than this dir exists test - exists <- doesDirectoryExist (traceShowId srcdir) + exists <- doesDirectoryExist srcdir if exists then dryRunLocalPkg pkg depsBuildStatus srcdir else return (BuildStatusUnpack tarball) From a1494a8a03099027906b6862e15cc5b64479d463 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Wed, 2 Apr 2025 12:44:05 +0900 Subject: [PATCH 75/82] Revert "UGLY! Forcing pkgCompiler to Nothing across the codebasy :cry:" This reverts commit c52048294c408446ad9dea836cf3f48f0405693f. --- Cabal/src/Distribution/Backpack/Id.hs | 6 ++---- Cabal/src/Distribution/Simple/InstallDirs.hs | 2 +- cabal-install/src/Distribution/Client/DistDirLayout.hs | 3 +-- cabal-install/src/Distribution/Client/FetchUtils.hs | 2 +- .../src/Distribution/Client/ProjectBuilding.hs | 2 +- .../src/Distribution/Client/ProjectPlanning.hs | 10 +++++----- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Cabal/src/Distribution/Backpack/Id.hs b/Cabal/src/Distribution/Backpack/Id.hs index 7e94dc38008..38e831acf17 100644 --- a/Cabal/src/Distribution/Backpack/Id.hs +++ b/Cabal/src/Distribution/Backpack/Id.hs @@ -39,14 +39,12 @@ computeComponentId -- This is used by cabal-install's legacy codepath -> Maybe ([ComponentId], FlagAssignment) -> ComponentId -computeComponentId deterministic mb_ipid mb_cid pid0 cname mb_details = +computeComponentId deterministic mb_ipid mb_cid pid cname mb_details = -- show is found to be faster than intercalate and then replacement of -- special character used in intercalating. We cannot simply hash by -- doubly concatenating list, as it just flatten out the nested list, so -- different sources can produce same hash - let -- we do not want the compiler to show up in the Id. - pid = pid0{pkgCompiler = Nothing} - hash_suffix + let hash_suffix | Just (dep_ipids, flags) <- mb_details = "-" ++ hashToBase62 diff --git a/Cabal/src/Distribution/Simple/InstallDirs.hs b/Cabal/src/Distribution/Simple/InstallDirs.hs index 0611d33071c..86e6fa08777 100644 --- a/Cabal/src/Distribution/Simple/InstallDirs.hs +++ b/Cabal/src/Distribution/Simple/InstallDirs.hs @@ -441,7 +441,7 @@ packageTemplateEnv pkgId uid = , -- Invariant: uid is actually a HashedUnitId. Hard to enforce because -- it's an API change. (LibNameVar, PathTemplate [Ordinary $ prettyShow uid]) - , (PkgIdVar, PathTemplate [Ordinary $ prettyShow (pkgId{pkgCompiler = Nothing})]) + , (PkgIdVar, PathTemplate [Ordinary $ prettyShow pkgId]) ] compilerTemplateEnv :: CompilerInfo -> PathTemplateEnv diff --git a/cabal-install/src/Distribution/Client/DistDirLayout.hs b/cabal-install/src/Distribution/Client/DistDirLayout.hs index 152e077f105..64140152453 100644 --- a/cabal-install/src/Distribution/Client/DistDirLayout.hs +++ b/cabal-install/src/Distribution/Client/DistDirLayout.hs @@ -39,7 +39,6 @@ import Distribution.Package , PackageId , PackageIdentifier , UnitId - , pkgCompiler ) import Distribution.Simple.Compiler ( Compiler (..) @@ -201,7 +200,7 @@ defaultDistDirLayout projectRoot mdistDirectory haddockOutputDir = distBuildRootDirectory </> prettyShow (distParamPlatform params) </> prettyShow (distParamCompilerId params) - </> prettyShow ((distParamPackageId params){pkgCompiler = Nothing}) + </> prettyShow (distParamPackageId params) </> ( case distParamComponentName params of Nothing -> "" Just (CLibName LMainLibName) -> "" diff --git a/cabal-install/src/Distribution/Client/FetchUtils.hs b/cabal-install/src/Distribution/Client/FetchUtils.hs index fd6dbe6553b..6b29dd84bfc 100644 --- a/cabal-install/src/Distribution/Client/FetchUtils.hs +++ b/cabal-install/src/Distribution/Client/FetchUtils.hs @@ -201,7 +201,7 @@ verifyFetchedTarball verbosity file mCallbacks pkgid = let warnAndFail s = warn verbosity ("Fetched tarball " ++ file ++ " does not match server, will redownload: " ++ s) >> return False in -- the do block in parens is due to dealing with the checked exceptions mechanism. ( do - fileInfo <- Sec.indexLookupFileInfo callbacks (pkgid{pkgCompiler = Nothing}) + fileInfo <- Sec.indexLookupFileInfo callbacks pkgid sz <- Sec.FileLength . fromInteger <$> getFileSize file if sz /= Sec.fileInfoLength (Sec.trusted fileInfo) then warnAndFail "file length mismatch" diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding.hs b/cabal-install/src/Distribution/Client/ProjectBuilding.hs index 87e9167736d..c339d790880 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding.hs @@ -718,7 +718,7 @@ withTarballLocalDirectory verbosity tarball unpackdir - pkgid{pkgCompiler = Nothing} + pkgid pkgTextOverride buildPkg srcdir builddir diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 4c175ca020e..d3e417966c0 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -1211,7 +1211,7 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do -- let allPkgLocations :: [(PackageId, PackageLocation (Maybe FilePath))] allPkgLocations = - [ ((packageId pkg){pkgCompiler = Nothing}, srcpkgSource pkg) + [ (packageId pkg, srcpkgSource pkg) | SolverInstallPlan.Configured (SolverPackage{solverPkgSource = pkg}) <- SolverInstallPlan.toList solverPlan ] @@ -1982,7 +1982,7 @@ elaborateInstallPlan cid = case elabBuildStyle elab0 of BuildInplaceOnly{} -> mkComponentId $ - prettyShow (pkgid{pkgCompiler = Nothing}) + prettyShow pkgid ++ "-inplace" ++ ( case Cabal.componentNameString cname of Nothing -> "" @@ -2215,7 +2215,7 @@ elaborateInstallPlan pkgInstalledId | shouldBuildInplaceOnly pkg = - mkComponentId (prettyShow (pkgid{pkgCompiler = Nothing}) ++ "-inplace") + mkComponentId (prettyShow pkgid ++ "-inplace") | otherwise = assert (isJust elabPkgSourceHash) $ hashedInstalledPackageId @@ -2226,7 +2226,7 @@ elaborateInstallPlan -- Need to filter out internal dependencies, because they don't -- correspond to anything real anymore. - isExt confid = (confSrcId confid){pkgCompiler = Nothing} /= pkgid{pkgCompiler = Nothing} + isExt confid = confSrcId confid /= pkgid filterExt = filter isExt filterExt' :: [(ConfiguredId, a)] -> [(ConfiguredId, a)] @@ -2367,7 +2367,7 @@ elaborateInstallPlan else cp elabPkgSourceLocation = srcloc - elabPkgSourceHash = case Map.lookup (pkgid{pkgCompiler = Nothing}) sourcePackageHashes of + elabPkgSourceHash = case Map.lookup pkgid sourcePackageHashes of Just h -> Just h Nothing -> Nothing elabLocalToProject = isLocalToProject pkg From f140135758bafe9419b0acee200b895f38b692d0 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Fri, 4 Apr 2025 17:49:39 +0900 Subject: [PATCH 76/82] Update UnitId This patch is quite raw. - Effectively ComponentId and UnitId are very similar. I think UnitId should just be a newtype around ComponentId. - We have Partial IDs, which should really be called Legacy, as they deal with non-compiler-prefixed ids. - We need to modify the parsing of installed packages, to inject the compiler into unit-ids. - We also need to modify parsing configure flags (--dependency=...) to ensure the ids are aligned. Note: we need to support INTERNAL and EXTERNAL Setup.hs. (This shows up with --dependency=...) especially. --- Cabal-syntax/src/Distribution/Backpack.hs | 10 ++- .../src/Distribution/InstalledPackageInfo.hs | 18 +++-- .../src/Distribution/Types/ComponentId.hs | 43 +++++++++-- .../Types/InstalledPackageInfo.hs | 4 +- .../InstalledPackageInfo/FieldGrammar.hs | 11 ++- .../Types/InstalledPackageInfo/Lens.hs | 2 +- .../src/Distribution/Types/PackageId.hs | 5 +- Cabal-syntax/src/Distribution/Types/UnitId.hs | 75 ++++++++++++++++--- Cabal/src/Distribution/Backpack/Configure.hs | 62 +++++++-------- Cabal/src/Distribution/Simple/Configure.hs | 24 ++++-- Cabal/src/Distribution/Simple/Errors.hs | 4 +- Cabal/src/Distribution/Simple/GHC.hs | 13 +++- .../src/Distribution/Simple/Program/HcPkg.hs | 9 ++- Cabal/src/Distribution/Simple/Register.hs | 5 +- .../src/Distribution/Client/Errors.hs | 2 +- .../src/Distribution/Client/PackageHash.hs | 12 ++- .../Client/ProjectBuilding/UnpackedPackage.hs | 10 ++- .../Distribution/Client/ProjectPlanning.hs | 32 +++++--- .../src/Distribution/Client/Store.hs | 16 ++-- 19 files changed, 248 insertions(+), 109 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Backpack.hs b/Cabal-syntax/src/Distribution/Backpack.hs index e70b9ffc692..048abdc0239 100644 --- a/Cabal-syntax/src/Distribution/Backpack.hs +++ b/Cabal-syntax/src/Distribution/Backpack.hs @@ -53,6 +53,10 @@ import Distribution.Utils.Base62 import qualified Data.Map as Map import qualified Data.Set as Set +import GHC.Stack (HasCallStack) + +import Unsafe.Coerce (unsafeCoerce) + ----------------------------------------------------------------------- -- OpenUnitId @@ -147,9 +151,7 @@ mkOpenUnitId uid cid insts = mkDefUnitId :: ComponentId -> Map ModuleName Module -> DefUnitId mkDefUnitId cid insts = unsafeMkDefUnitId - ( mkUnitId - (unComponentId cid ++ maybe "" ("+" ++) (hashModuleSubst insts)) - ) + (addSuffixToUnitId (maybe "" ("+" ++) (hashModuleSubst insts)) (unsafeCoerce cid)) -- impose invariant! @@ -254,7 +256,7 @@ openModuleSubstFreeHoles insts = Set.unions (map openModuleFreeHoles (Map.elems -- | When typechecking, we don't demand that a freshly instantiated -- 'IndefFullUnitId' be compiled; instead, we just depend on the -- installed indefinite unit installed at the 'ComponentId'. -abstractUnitId :: OpenUnitId -> UnitId +abstractUnitId :: HasCallStack => OpenUnitId -> UnitId abstractUnitId (DefiniteUnitId def_uid) = unDefUnitId def_uid abstractUnitId (IndefFullUnitId cid _) = newSimpleUnitId cid diff --git a/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs index 2c15d678335..93000823a13 100644 --- a/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs @@ -62,11 +62,15 @@ import qualified Text.PrettyPrint as Disp import Distribution.Types.InstalledPackageInfo import Distribution.Types.InstalledPackageInfo.FieldGrammar -installedComponentId :: InstalledPackageInfo -> ComponentId +import GHC.Stack (HasCallStack) + +import Unsafe.Coerce (unsafeCoerce) + +installedComponentId :: HasCallStack => InstalledPackageInfo -> ComponentId installedComponentId ipi = - case unComponentId (installedComponentId_ ipi) of - "" -> mkComponentId (unUnitId (installedUnitId ipi)) - _ -> installedComponentId_ ipi + fromMaybe + (unsafeCoerce (installedUnitId ipi)) + (installedComponentId_ ipi) -- | Get the indefinite unit identity representing this package. -- This IS NOT guaranteed to give you a substitution; for @@ -117,12 +121,12 @@ parseInstalledPackageInfo s = case P.readFields s of -- | Pretty print 'InstalledPackageInfo'. -- -- @pkgRoot@ isn't printed, as ghc-pkg prints it manually (as GHC-8.4). -showInstalledPackageInfo :: InstalledPackageInfo -> String +showInstalledPackageInfo :: HasCallStack => InstalledPackageInfo -> String showInstalledPackageInfo ipi = showFullInstalledPackageInfo ipi{pkgRoot = Nothing} -- | The variant of 'showInstalledPackageInfo' which outputs @pkgroot@ field too. -showFullInstalledPackageInfo :: InstalledPackageInfo -> String +showFullInstalledPackageInfo :: HasCallStack => InstalledPackageInfo -> String showFullInstalledPackageInfo = P.showFields (const NoComment) . prettyFieldGrammar cabalSpecLatest ipiFieldGrammar -- | @@ -130,7 +134,7 @@ showFullInstalledPackageInfo = P.showFields (const NoComment) . prettyFieldGramm -- >>> let ipi = emptyInstalledPackageInfo { maintainer = fromString "Tester" } -- >>> fmap ($ ipi) $ showInstalledPackageInfoField "maintainer" -- Just "maintainer: Tester" -showInstalledPackageInfoField :: String -> Maybe (InstalledPackageInfo -> String) +showInstalledPackageInfoField :: HasCallStack => String -> Maybe (InstalledPackageInfo -> String) showInstalledPackageInfoField fn = fmap (\g -> Disp.render . ppField fn . g) $ fieldDescrPretty ipiFieldGrammar (toUTF8BS fn) diff --git a/Cabal-syntax/src/Distribution/Types/ComponentId.hs b/Cabal-syntax/src/Distribution/Types/ComponentId.hs index fa770448363..03820ad0631 100644 --- a/Cabal-syntax/src/Distribution/Types/ComponentId.hs +++ b/Cabal-syntax/src/Distribution/Types/ComponentId.hs @@ -17,6 +17,7 @@ import Distribution.Pretty import qualified Distribution.Compat.CharParsing as P import Text.PrettyPrint (text) +import GHC.Stack (HasCallStack) -- | A 'ComponentId' uniquely identifies the transitive source -- code closure of a component (i.e. libraries, executables). -- @@ -30,8 +31,21 @@ import Text.PrettyPrint (text) -- This type is opaque since @Cabal-2.0@ -- -- @since 2.0.0.2 -newtype ComponentId = ComponentId ShortText - deriving (Generic, Read, Show, Eq, Ord, Data) +data ComponentId = ComponentId ShortText ShortText Bool + | PartialComponentId ShortText + deriving (Generic, Read, Show, Data) + +instance Eq ComponentId where + (ComponentId c1 s1 _) == (ComponentId c2 s2 _) = c1 == c2 && s1 == s2 + (PartialComponentId s1) == (PartialComponentId s2) = s1 == s2 + _ == _ = False + +instance Ord ComponentId where + compare (ComponentId c1 s1 _) (ComponentId c2 s2 _) = compare (c1, s1) (c2, s2) + compare (PartialComponentId s1) (PartialComponentId s2) = compare s1 s2 + compare (PartialComponentId _) _ = LT + compare _ (PartialComponentId _) = GT + -- | Construct a 'ComponentId' from a 'String' -- @@ -41,14 +55,25 @@ newtype ComponentId = ComponentId ShortText -- 'ComponentId' is valid -- -- @since 2.0.0.2 -mkComponentId :: String -> ComponentId -mkComponentId = ComponentId . toShortText +mkComponentId :: HasCallStack => String -> ComponentId +mkComponentId s = case (simpleParsec s) of + Just cid@ComponentId{} -> cid + Just cid@PartialComponentId{} -> error $ "mkPartialComponentId: `" ++ s ++ "' is a partial component id, not a full one." + _ -> error $ "Unable to parse PartialComponentId: `" ++ s ++ "'." + +mkComponentId' :: HasCallStack => String -> String -> Bool -> ComponentId +mkComponentId' c i b = ComponentId (toShortText c) (toShortText i) b + +mkPartialComponentId :: HasCallStack => String -> ComponentId +mkPartialComponentId s = PartialComponentId (toShortText s) -- | Convert 'ComponentId' to 'String' -- -- @since 2.0.0.2 -unComponentId :: ComponentId -> String -unComponentId (ComponentId s) = fromShortText s +unComponentId :: HasCallStack => ComponentId -> String +unComponentId (ComponentId c s False) = fromShortText c ++ '_':fromShortText s +unComponentId (ComponentId c s True) = fromShortText s +unComponentId (PartialComponentId s) = fromShortText s -- | 'mkComponentId' -- @@ -63,8 +88,12 @@ instance Pretty ComponentId where pretty = text . unComponentId instance Parsec ComponentId where - parsec = mkComponentId `fmap` P.munch1 abi_char + parsec = P.try (mkComponentId' <$> compid <* P.char '_' <*> P.munch1 abi_char <*> return False) + <|> mkPartialComponentId <$> P.munch1 abi_char where + compid = (\f v -> f ++ "-" ++ v) <$> P.munch1 isAlpha <* P.char '-' <*> P.munch1 isVerChar + isVerChar :: Char -> Bool + isVerChar c = c `elem` '.':['0'..'9'] abi_char c = isAlphaNum c || c `elem` "-_." instance NFData ComponentId where diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs index ee1dfca5888..e5733d158a4 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs @@ -42,7 +42,7 @@ data InstalledPackageInfo = InstalledPackageInfo -- exactly the same as PackageDescription sourcePackageId :: PackageId , sourceLibName :: LibraryName - , installedComponentId_ :: ComponentId + , installedComponentId_ :: Maybe ComponentId , libVisibility :: LibraryVisibility , installedUnitId :: UnitId , -- INVARIANT: if this package is definite, OpenModule's @@ -134,7 +134,7 @@ emptyInstalledPackageInfo = InstalledPackageInfo { sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion Nothing , sourceLibName = LMainLibName - , installedComponentId_ = mkComponentId "" + , installedComponentId_ = Nothing , installedUnitId = mkUnitId "" , instantiatedWith = [] , compatPackageKey = "" diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index 151aaf4b119..b6be432a6ff 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -40,6 +40,8 @@ import Distribution.Types.InstalledPackageInfo import qualified Distribution.Types.InstalledPackageInfo.Lens as L import qualified Distribution.Types.PackageId.Lens as L hiding (pkgCompiler) +import GHC.Stack (HasCallStack) + -- Note: GHC goes nuts and inlines everything, -- One can see e.g. in -ddump-simpl-stats: -- @@ -75,7 +77,7 @@ ipiFieldGrammar , c InstWith , c SpecLicenseLenient , c (Identity (Maybe CompilerId)) - ) + , HasCallStack ) => g InstalledPackageInfo InstalledPackageInfo ipiFieldGrammar = mkInstalledPackageInfo @@ -86,7 +88,10 @@ ipiFieldGrammar = -- Very basic fields: name, version, package-name, lib-name and visibility <@> blurFieldGrammar basic basicFieldGrammar -- Basic fields - <@> optionalFieldDef "id" L.installedUnitId (mkUnitId "") + -- [note: forced default values] + -- Observe optionalFieldDef fn l x = optionalFieldDefAla fn Identity l x + -- and optionalFieldDefAla will force x. + <@> optionalFieldDef "id" L.installedUnitId (mkUnitId "invalid-invalid") <@> optionalFieldDefAla "instantiated-with" InstWith L.instantiatedWith [] <@> optionalFieldDefAla "key" CompatPackageKey L.compatPackageKey "" <@> optionalFieldDefAla "license" SpecLicenseLenient L.license (Left SPDX.NONE) @@ -135,7 +140,7 @@ ipiFieldGrammar = -- setMaybePackageId says it can be no-op. (PackageIdentifier pn _basicVersion _basicCompilerId) (combineLibraryName ln _basicLibName) - (mkComponentId "") -- installedComponentId_, not in use + Nothing _basicLibVisibility where MungedPackageName pn ln = _basicName diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs index 9e7798e443d..c34e885fa01 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs @@ -28,7 +28,7 @@ installedUnitId :: Lens' InstalledPackageInfo UnitId installedUnitId f s = fmap (\x -> s{T.installedUnitId = x}) (f (T.installedUnitId s)) {-# INLINE installedUnitId #-} -installedComponentId_ :: Lens' InstalledPackageInfo ComponentId +installedComponentId_ :: Lens' InstalledPackageInfo (Maybe ComponentId) installedComponentId_ f s = fmap (\x -> s{T.installedComponentId_ = x}) (f (T.installedComponentId_ s)) {-# INLINE installedComponentId_ #-} diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index 486df97a146..bc366716216 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -38,8 +38,9 @@ instance Structured PackageIdentifier instance Pretty PackageIdentifier where pretty (PackageIdentifier n v c) - | Just c' <- c, v == nullVersion = pretty c <<>> Disp.char ':' <<>> pretty n -- if no version, don't show version. - | Just c' <- c = pretty c' <<>> Disp.char ':' <<>> pretty n <<>> Disp.char '-' <<>> pretty v + -- we must never print the compiler, as other tools like hackage-security rely on the Pretty instance + -- | Just c' <- c, v == nullVersion = pretty c <<>> Disp.char ':' <<>> pretty n -- if no version, don't show version. + -- | Just c' <- c = pretty c' <<>> Disp.char ':' <<>> pretty n <<>> Disp.char '-' <<>> pretty v | v == nullVersion = pretty n | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v diff --git a/Cabal-syntax/src/Distribution/Types/UnitId.hs b/Cabal-syntax/src/Distribution/Types/UnitId.hs index 0b5ca4bdf7b..d6a403a04c9 100644 --- a/Cabal-syntax/src/Distribution/Types/UnitId.hs +++ b/Cabal-syntax/src/Distribution/Types/UnitId.hs @@ -7,6 +7,9 @@ module Distribution.Types.UnitId ( UnitId , unUnitId , mkUnitId + , isPartialUnitId + , addPrefixToUnitId + , addSuffixToUnitId , DefUnitId , unsafeMkDefUnitId , unDefUnitId @@ -27,6 +30,11 @@ import Distribution.Types.PackageId import Text.PrettyPrint (text) +import GHC.Stack (HasCallStack) +import Data.List (isInfixOf) + +import Unsafe.Coerce (unsafeCoerce) + -- | A unit identifier identifies a (possibly instantiated) -- package/component that can be installed the installed package -- database. There are several types of components that can be @@ -63,11 +71,24 @@ import Text.PrettyPrint (text) -- representation of a UnitId to pass, e.g., as a @-package-id@ -- flag, use the 'display' function, which will work on all -- versions of Cabal. -newtype UnitId = UnitId ShortText - deriving (Generic, Read, Show, Eq, Ord, Data, NFData) +data UnitId = UnitId ShortText ShortText Bool + | PartialUnitId ShortText + deriving (Generic, Read, Show, Data) + +instance Eq UnitId where + (UnitId c1 s1 _) == (UnitId c2 s2 _) = c1 == c2 && s1 == s2 + (PartialUnitId s1) == (PartialUnitId s2) = s1 == s2 + _ == _ = False + +instance Ord UnitId where + compare (UnitId c1 s1 _) (UnitId c2 s2 _) = compare (c1, s1) (c2, s2) + compare (PartialUnitId s1) (PartialUnitId s2) = compare s1 s2 + compare (PartialUnitId _) _ = LT + compare _ (PartialUnitId _) = GT instance Binary UnitId instance Structured UnitId +instance NFData UnitId -- | The textual format for 'UnitId' coincides with the format -- GHC accepts for @-package-id@. @@ -77,8 +98,12 @@ instance Pretty UnitId where -- | The textual format for 'UnitId' coincides with the format -- GHC accepts for @-package-id@. instance Parsec UnitId where - parsec = mkUnitId <$> P.munch1 isUnitChar + parsec = P.try (mkUnitId' <$> compid <* P.char '_' <*> P.munch1 isUnitChar <*> return False) + <|> (mkPartialUnitId <$> P.munch1 isUnitChar) where + compid = (\f v -> f ++ "-" ++ v) <$> P.munch1 isAlpha <* P.char '-' <*> P.munch1 isVerChar + isVerChar :: Char -> Bool + isVerChar c = c `elem` '.':['0'..'9'] -- https://gitlab.haskell.org/ghc/ghc/issues/17752 isUnitChar '-' = True isUnitChar '_' = True @@ -86,13 +111,41 @@ instance Parsec UnitId where isUnitChar '+' = True isUnitChar c = isAlphaNum c +isPartialUnitId :: HasCallStack => UnitId -> Bool +isPartialUnitId (PartialUnitId _) = True +isPartialUnitId _ = False + +addPrefixToUnitId :: HasCallStack => String -> UnitId -> UnitId +addPrefixToUnitId prefix (PartialUnitId s) = UnitId (toShortText prefix) s True +addPrefixToUnitId prefix uid@(UnitId _ _ _) = error $ "addPrefixToUnitId: UnitId " ++ show uid ++ " already has a prefix; can't add: " ++ prefix + +addSuffixToUnitId :: HasCallStack => String -> UnitId -> UnitId +addSuffixToUnitId suffix (UnitId c s fromPartial) = UnitId c (s <> toShortText suffix) fromPartial +addSuffixToUnitId suffix (PartialUnitId s) = PartialUnitId (s <> toShortText suffix) + + +dropPrefixFromUnitId :: HasCallStack => UnitId -> UnitId +dropPrefixFromUnitId (PartialUnitId s) = PartialUnitId s +dropPrefixFromUnitId (UnitId _c s _fromPartial) = PartialUnitId s + -- | If you need backwards compatibility, consider using 'display' -- instead, which is supported by all versions of Cabal. -unUnitId :: UnitId -> String -unUnitId (UnitId s) = fromShortText s +unUnitId :: HasCallStack => UnitId -> String +unUnitId (UnitId c s False) = fromShortText c ++ '_':fromShortText s +unUnitId (UnitId c s True) = fromShortText s +unUnitId (PartialUnitId s) = fromShortText s + +mkUnitId :: HasCallStack => String -> UnitId +mkUnitId s = case (simpleParsec s) of + Just uid@UnitId{} -> uid + Just uid@PartialUnitId{} -> uid -- error $ "mkUnitId: `" ++ s ++ "' is a partial unit id, not a full one." + _ -> error $ "Unable to parse UnitId: `" ++ s ++ "'." + +mkUnitId' :: HasCallStack => String -> String -> Bool -> UnitId +mkUnitId' c i b = UnitId (toShortText c) (toShortText i) b -mkUnitId :: String -> UnitId -mkUnitId = UnitId . toShortText +mkPartialUnitId :: HasCallStack => String -> UnitId +mkPartialUnitId s = PartialUnitId (toShortText s) -- | 'mkUnitId' -- @@ -102,17 +155,17 @@ instance IsString UnitId where -- | Create a unit identity with no associated hash directly -- from a 'ComponentId'. -newSimpleUnitId :: ComponentId -> UnitId -newSimpleUnitId = mkUnitId . unComponentId +newSimpleUnitId :: HasCallStack => ComponentId -> UnitId +newSimpleUnitId = unsafeCoerce -- | Make an old-style UnitId from a package identifier. -- Assumed to be for the public library -mkLegacyUnitId :: PackageId -> UnitId +mkLegacyUnitId :: HasCallStack => PackageId -> UnitId mkLegacyUnitId = newSimpleUnitId . mkComponentId . prettyShow -- | Returns library name prefixed with HS, suitable for filenames getHSLibraryName :: UnitId -> String -getHSLibraryName uid = "HS" ++ prettyShow uid +getHSLibraryName uid = "HS" ++ prettyShow (dropPrefixFromUnitId uid) -- | A 'UnitId' for a definite package. The 'DefUnitId' invariant says -- that a 'UnitId' identified this way is definite; i.e., it has no diff --git a/Cabal/src/Distribution/Backpack/Configure.hs b/Cabal/src/Distribution/Backpack/Configure.hs index d4c00b75c7b..41bf7929bc3 100644 --- a/Cabal/src/Distribution/Backpack/Configure.hs +++ b/Cabal/src/Distribution/Backpack/Configure.hs @@ -56,6 +56,8 @@ import qualified Data.Set as Set import Distribution.Pretty import Text.PrettyPrint +import Unsafe.Coerce (unsafeCoerce) + ------------------------------------------------------------------------------ -- Pipeline ------------------------------------------------------------------------------ @@ -144,7 +146,7 @@ configureComponentLocalBuildInfos , ( DefiniteUnitId ( unsafeMkDefUnitId - (mkUnitId (unComponentId (ann_id aid))) + (unsafeCoerce (ann_id aid)) ) , emptyModuleShape ) @@ -303,35 +305,35 @@ toComponentLocalBuildInfos -- TODO: Move this into a helper function -- -- TODO: This is probably wrong for Backpack - let pseudoTopPkg :: InstalledPackageInfo - pseudoTopPkg = - emptyInstalledPackageInfo - { Installed.installedUnitId = mkLegacyUnitId (packageId pkg_descr) - , Installed.sourcePackageId = packageId pkg_descr - , Installed.depends = map pc_uid externalPkgDeps - } - case PackageIndex.dependencyInconsistencies - . PackageIndex.insert pseudoTopPkg - $ packageDependsIndex of - [] -> return () - inconsistencies -> - warnProgress $ - hang - ( text "This package indirectly depends on multiple versions of the same" - <+> text "package. This is very likely to cause a compile failure." - ) - 2 - ( vcat - [ text "package" - <+> pretty (packageName user) - <+> parens (pretty (installedUnitId user)) - <+> text "requires" - <+> pretty inst - | (_dep_key, insts) <- inconsistencies - , (inst, users) <- insts - , user <- users - ] - ) + -- let pseudoTopPkg :: InstalledPackageInfo + -- pseudoTopPkg = + -- emptyInstalledPackageInfo + -- { Installed.installedUnitId = mkLegacyUnitId (packageId pkg_descr) + -- , Installed.sourcePackageId = packageId pkg_descr + -- , Installed.depends = map pc_uid externalPkgDeps + -- } + -- case PackageIndex.dependencyInconsistencies + -- . PackageIndex.insert pseudoTopPkg + -- $ packageDependsIndex of + -- [] -> return () + -- inconsistencies -> + -- warnProgress $ + -- hang + -- ( text "This package indirectly depends on multiple versions of the same" + -- <+> text "package. This is very likely to cause a compile failure." + -- ) + -- 2 + -- ( vcat + -- [ text "package" + -- <+> pretty (packageName user) + -- <+> parens (pretty (installedUnitId user)) + -- <+> text "requires" + -- <+> pretty inst + -- | (_dep_key, insts) <- inconsistencies + -- , (inst, users) <- insts + -- , user <- users + -- ] + -- ) let clbis = mkLinkedComponentsLocalBuildInfo comp graph -- forM clbis $ \(clbi,deps) -> info verbosity $ "UNIT" ++ hashUnitId (componentUnitId clbi) ++ "\n" ++ intercalate "\n" (map hashUnitId deps) return (clbis, packageDependsIndex) diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index a76b4359bc9..44bce682c5f 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -183,6 +183,10 @@ import qualified Data.Maybe as M import qualified Data.Set as Set import qualified Distribution.Compat.NonEmptySet as NES +import GHC.Stack (HasCallStack) + +import Unsafe.Coerce (unsafeCoerce) + type UseExternalInternalDeps = Bool -- | The errors that can be thrown when reading the @setup-config@ file. @@ -937,7 +941,8 @@ configurePackage cfg lbc0 pkg_descr00 flags enabled comp platform programDb0 pac return (lbc, pbd) finalizeAndConfigurePackage - :: ConfigFlags + :: HasCallStack + => ConfigFlags -> LBC.LocalBuildConfig -> GenericPackageDescription -> Compiler @@ -992,9 +997,17 @@ finalizeAndConfigurePackage cfg lbc0 g_pkg_descr comp platform enabled = do , requiredDepsMap :: Map (PackageName, ComponentName) InstalledPackageInfo ) <- either (dieWithException verbosity) return $ - combinedConstraints + -- why do we need this? We internally now treat everything as properly + -- qualified Component/UnitIds. Thus we need to turn Partial ones into + -- fully qualified ones. Otherwise any lookup internally will fail. + -- installedPackageSet will already contain properly qualified ones. + let updCompId :: GivenComponent -> GivenComponent + updCompId (GivenComponent pn ln cid) | isPartialUnitId (unsafeCoerce cid) = + GivenComponent pn ln (unsafeCoerce (addPrefixToUnitId (prettyShow (compilerId comp)) (unsafeCoerce cid))) + updCompId (GivenComponent pn ln cid) = GivenComponent pn ln cid + in combinedConstraints (configConstraints cfg) - (configDependencies cfg) + (map updCompId (configDependencies cfg)) installedPackageSet let @@ -2185,7 +2198,8 @@ interpretPackageDbFlags userInstall specificDBs = -- deps in the end. So we still need to remember which installed packages to -- pick. combinedConstraints - :: [PackageVersionConstraint] + :: HasCallStack + => [PackageVersionConstraint] -> [GivenComponent] -- ^ installed dependencies -> InstalledPackageIndex @@ -2220,7 +2234,7 @@ combinedConstraints constraints dependencies installedPackages = do ] -- The dependencies along with the installed package info, if it exists - dependenciesPkgInfo :: [(PackageName, ComponentName, ComponentId, Maybe InstalledPackageInfo)] + dependenciesPkgInfo :: HasCallStack => [(PackageName, ComponentName, ComponentId, Maybe InstalledPackageInfo)] dependenciesPkgInfo = [ (pkgname, CLibName lname, cid, mpkg) | GivenComponent pkgname lname cid <- dependencies diff --git a/Cabal/src/Distribution/Simple/Errors.hs b/Cabal/src/Distribution/Simple/Errors.hs index 1ce4f7ca06a..0d9062cbe08 100644 --- a/Cabal/src/Distribution/Simple/Errors.hs +++ b/Cabal/src/Distribution/Simple/Errors.hs @@ -60,7 +60,7 @@ data CabalException | OnlySupportSpecificPackageDb | FailedToParseOutputDescribe String PackageId | DumpFailed String String - | FailedToParseOutputDump String + | FailedToParseOutputDump String String | ListFailed String | FailedToParseOutputList String | ProgramNotFound String @@ -336,7 +336,7 @@ exceptionMessage e = case e of OnlySupportSpecificPackageDb -> "HcPkg.writeRegistrationFileDirectly: only supports SpecificPackageDB for now" FailedToParseOutputDescribe programId pkgId -> "failed to parse output of '" ++ programId ++ " describe " ++ prettyShow pkgId ++ "'" DumpFailed programId exception -> programId ++ " dump failed: " ++ exception - FailedToParseOutputDump programId -> "failed to parse output of '" ++ programId ++ " dump'" + FailedToParseOutputDump programId err -> "failed to parse output of '" ++ programId ++ " dump': " ++ err ListFailed programId -> programId ++ " list failed" FailedToParseOutputList programId -> "failed to parse output of '" ++ programId ++ " list'" ProgramNotFound progName -> "The program '" ++ progName ++ "' is required but it could not be found" diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 8a7bad44b38..427d605949d 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -421,13 +421,22 @@ getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do checkPackageDbEnvVar verbosity checkPackageDbStack verbosity comp packagedbs pkgss <- getInstalledPackages' verbosity mbWorkDir packagedbs progdb - let pkgss' = [ (packagedb, (\pkg -> pkg{ InstalledPackageInfo.pkgCompiler = Just (compilerId comp) }) - <$> pkgs) + let pkgss' = [ (packagedb, updDependsUnitIds . updUnitId . setPkgCompiler <$> pkgs) | (packagedb, pkgs) <- pkgss ] index <- toPackageIndex verbosity pkgss' progdb return $! hackRtsPackage index where + setPkgCompiler pkg = pkg{ InstalledPackageInfo.pkgCompiler = Just (compilerId comp) } + updUnitId pkg | isPartialUnitId (installedUnitId pkg) = + pkg { InstalledPackageInfo.installedUnitId = + addPrefixToUnitId (prettyShow (compilerId comp)) (InstalledPackageInfo.installedUnitId pkg) + } + updUnitId pkg = pkg + updDependsUnitIds pkg = + pkg { InstalledPackageInfo.depends = + map (\x -> if isPartialUnitId x then addPrefixToUnitId (prettyShow (compilerId comp)) x else x) (InstalledPackageInfo.depends pkg) + } hackRtsPackage index = case PackageIndex.lookupPackageName index (mkPackageName "rts") of [(_, [rts])] -> diff --git a/Cabal/src/Distribution/Simple/Program/HcPkg.hs b/Cabal/src/Distribution/Simple/Program/HcPkg.hs index a494bc63f02..024d21542f6 100644 --- a/Cabal/src/Distribution/Simple/Program/HcPkg.hs +++ b/Cabal/src/Distribution/Simple/Program/HcPkg.hs @@ -74,6 +74,7 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as LBS import qualified Data.List.NonEmpty as NE import qualified System.FilePath.Posix as FilePath.Posix +import GHC.Stack (HasCallStack) -- | Information about the features and capabilities of an @hc-pkg@ -- program. @@ -292,9 +293,9 @@ dump hpi verbosity mbWorkDir packagedb = do case parsePackages output of Left ok -> return ok - _ -> dieWithException verbosity $ FailedToParseOutputDump (programId (hcPkgProgram hpi)) + Right e -> dieWithException verbosity $ FailedToParseOutputDump (programId (hcPkgProgram hpi)) (unwords e) -parsePackages :: LBS.ByteString -> Either [InstalledPackageInfo] [String] +parsePackages :: HasCallStack => LBS.ByteString -> Either [InstalledPackageInfo] [String] parsePackages lbs0 = case traverse parseInstalledPackageInfo $ splitPkgs lbs0 of Right ok -> Left [setUnitId . maybe id mungePackagePaths (pkgRoot pkg) $ pkg | (_, pkg) <- ok] @@ -380,7 +381,7 @@ mungePackagePaths pkgroot pkginfo = -- Older installed package info files did not have the installedUnitId -- field, so if it is missing then we fill it as the source package ID. -- NB: Internal libraries not supported. -setUnitId :: InstalledPackageInfo -> InstalledPackageInfo +setUnitId :: HasCallStack => InstalledPackageInfo -> InstalledPackageInfo setUnitId pkginfo@InstalledPackageInfo { installedUnitId = uid @@ -389,7 +390,7 @@ setUnitId | unUnitId uid == "" = pkginfo { installedUnitId = mkLegacyUnitId pid - , installedComponentId_ = mkComponentId (prettyShow pid) + , installedComponentId_ = Just (mkComponentId (prettyShow pid)) } setUnitId pkginfo = pkginfo diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index f5078f69f3d..10ea7f0e94e 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -90,6 +90,7 @@ import System.FilePath (isAbsolute) import qualified Data.ByteString.Lazy.Char8 as BS.Char8 +import GHC.Stack (HasCallStack) -- ----------------------------------------------------------------------------- -- Registration @@ -163,7 +164,7 @@ generateOne pkg lib lbi clbi regFlags = mbWorkDir = flagToMaybe $ setupWorkingDir common registerAll - :: PackageDescription + :: HasCallStack => PackageDescription -> LocalBuildInfo -> RegisterFlags -> [InstalledPackageInfo] @@ -496,7 +497,7 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi IPI.InstalledPackageInfo { IPI.sourcePackageId = packageId pkg , IPI.installedUnitId = componentUnitId clbi - , IPI.installedComponentId_ = componentComponentId clbi + , IPI.installedComponentId_ = Just (componentComponentId clbi) , IPI.instantiatedWith = expectLibraryComponent (maybeComponentInstantiatedWith clbi) , IPI.sourceLibName = libName lib , IPI.compatPackageKey = expectLibraryComponent (maybeComponentCompatPackageKey clbi) diff --git a/cabal-install/src/Distribution/Client/Errors.hs b/cabal-install/src/Distribution/Client/Errors.hs index 493ce2fc98b..9d750b1548d 100644 --- a/cabal-install/src/Distribution/Client/Errors.hs +++ b/cabal-install/src/Distribution/Client/Errors.hs @@ -385,7 +385,7 @@ exceptionMessageCabalInstall e = case e of FindOpenProgramLocationErr err -> err PkgConfParseFailed perror -> "Couldn't parse the output of 'setup register --gen-pkg-config':" - ++ show perror + ++ perror ErrorPackingSdist err -> "Error packing sdist: " ++ err SdistException pkgIdentifier -> "sdist of " ++ prettyShow pkgIdentifier SpecifyAnExecutable -> "Please specify an executable to run" diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index d99fc9ad250..0fa147669d9 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -66,6 +66,8 @@ import qualified Data.ByteString.Lazy.Char8 as LBS import qualified Data.Map as Map import qualified Data.Set as Set +import GHC.Stack (HasCallStack) + ------------------------------- -- Calculating package hashes -- @@ -76,7 +78,7 @@ import qualified Data.Set as Set -- Note that due to path length limitations on Windows, this function uses -- a different method on Windows that produces shorted package ids. -- See 'hashedInstalledPackageIdLong' vs 'hashedInstalledPackageIdShort'. -hashedInstalledPackageId :: PackageHashInputs -> InstalledPackageId +hashedInstalledPackageId :: HasCallStack => PackageHashInputs -> InstalledPackageId hashedInstalledPackageId | buildOS == Windows = hashedInstalledPackageIdShort | buildOS == OSX = hashedInstalledPackageIdVeryShort @@ -122,7 +124,7 @@ hashedInstalledPackageIdLong -- Truncating the hash size is disappointing but also technically ok. We -- rely on the hash primarily for collision avoidance not for any security -- properties (at least for now). -hashedInstalledPackageIdShort :: PackageHashInputs -> InstalledPackageId +hashedInstalledPackageIdShort :: HasCallStack => PackageHashInputs -> InstalledPackageId hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = mkComponentId $ intercalate @@ -162,10 +164,12 @@ hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = -- libraries on macOS, such that the proxy libraries and the linked libraries -- stay under the load command limit, and the recursive linker is still able -- to link all of them. -hashedInstalledPackageIdVeryShort :: PackageHashInputs -> InstalledPackageId +hashedInstalledPackageIdVeryShort :: HasCallStack => PackageHashInputs -> InstalledPackageId hashedInstalledPackageIdVeryShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = mkComponentId $ - intercalate + prettyShow (pkgHashCompilerId . pkgHashOtherConfig $ pkghashinputs) + ++ + '_':intercalate "-" [ prettyShow name , prettyShow version diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index 1a1e286596b..8fd229b61fa 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -120,6 +120,8 @@ import Distribution.Compat.Directory (listDirectory) import Distribution.Client.ProjectBuilding.PackageFileMonitor +import GHC.Stack (HasCallStack) + -- | Each unpacked package is processed in the following phases: -- -- * Configure phase @@ -995,7 +997,7 @@ hasValidHaddockTargets ElaboratedConfiguredPackage{..} hasHaddocks = not (null (elabPkgDescription ^. componentModules name)) withTempInstalledPackageInfoFile - :: Verbosity + :: HasCallStack => Verbosity -> FilePath -> (FilePath -> IO ()) -> IO InstalledPackageInfo @@ -1009,15 +1011,15 @@ withTempInstalledPackageInfoFile verbosity tempdir action = readPkgConf "." pkgConfDest where - pkgConfParseFailed :: String -> IO a + pkgConfParseFailed :: HasCallStack => String -> IO a pkgConfParseFailed perror = dieWithException verbosity $ PkgConfParseFailed perror - readPkgConf :: FilePath -> FilePath -> IO InstalledPackageInfo + readPkgConf :: HasCallStack => FilePath -> FilePath -> IO InstalledPackageInfo readPkgConf pkgConfDir pkgConfFile = do pkgConfStr <- BS.readFile (pkgConfDir </> pkgConfFile) (warns, ipkg) <- case Installed.parseInstalledPackageInfo pkgConfStr of - Left perrors -> pkgConfParseFailed $ unlines $ NE.toList perrors + Left perrors -> pkgConfParseFailed $ unlines $ "While parsing:":LBS.Char8.unpack (LBS.Char8.fromStrict pkgConfStr):"encountered:":NE.toList perrors Right (warns, ipkg) -> return (warns, ipkg) unless (null warns) $ diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index d3e417966c0..8df269624f4 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -855,11 +855,11 @@ rebuildInstallPlan liftIO $ do notice verbosity "Resolving dependencies..." -- putStrLn "== installedPackages" - -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages installedPackages + -- putStrLn $ unlines $ map (prettyShow . IPI.installedUnitId) $ PI.allPackages installedPackages -- putStrLn "== binstalledPackages" - -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages binstalledPkgIndex + -- putStrLn $ unlines $ map (prettyShow . IPI.installedUnitId) $ PI.allPackages binstalledPkgIndex -- putStrLn "== hinstalledPackages" - -- putStrLn $ unlines $ map (prettyShow . IPI.sourcePackageId) $ PI.allPackages hinstalledPkgIndex + -- putStrLn $ unlines $ map (prettyShow . IPI.installedUnitId) $ PI.allPackages hinstalledPkgIndex -- putStrLn "== localPackages" -- putStrLn $ unlines . map (prettyShow . srcpkgPackageId) $ [pkg | SpecificSourcePackage pkg <- localPackages] -- putStrLn $ unlines . take 20 $ map (prettyShow . srcpkgPackageId) (XXX.allPackages (packageIndex sourcePkgDb)) @@ -1701,7 +1701,7 @@ planPackages -- In theory should be able to make an elaborated install plan with a policy -- matching that of the classic @cabal install --user@ or @--global@ elaborateInstallPlan - :: Verbosity + :: HasCallStack => Verbosity -> Map FilePath HookAccept -> Toolchains -> Maybe PkgConfigDb @@ -1758,7 +1758,7 @@ elaborateInstallPlan f _ = Nothing elaboratedInstallPlan - :: LogProgress (InstallPlan.GenericInstallPlan IPI.InstalledPackageInfo ElaboratedConfiguredPackage) + :: HasCallStack => LogProgress (InstallPlan.GenericInstallPlan IPI.InstalledPackageInfo ElaboratedConfiguredPackage) elaboratedInstallPlan = flip InstallPlan.fromSolverInstallPlanWithProgress solverPlan $ \mapDep planpkg -> case planpkg of @@ -1779,7 +1779,7 @@ elaborateInstallPlan -- NB: We don't INSTANTIATE packages at this point. That's -- a post-pass. This makes it simpler to compute dependencies. elaborateSolverToComponents - :: (SolverId -> [ElaboratedPlanPackage]) + :: HasCallStack => (SolverId -> [ElaboratedPlanPackage]) -> SolverPackage UnresolvedPkgLoc -> LogProgress [ElaboratedConfiguredPackage] elaborateSolverToComponents mapDep spkg@(SolverPackage _qpn _stage _ _ _ deps0 exe_deps0) = @@ -1922,7 +1922,7 @@ elaborateInstallPlan ++ " not implemented yet" buildComponent - :: ( ConfiguredComponentMap + :: HasCallStack => ( ConfiguredComponentMap , LinkedComponentMap , Map ComponentId FilePath ) @@ -1979,10 +1979,14 @@ elaborateInstallPlan elab0 { elabPkgOrComp = ElabComponent $ elab_comp } + elabCompiler = toolchainCompiler (toolchainFor (elabStage elab0) toolchains) + cid = case elabBuildStyle elab0 of BuildInplaceOnly{} -> mkComponentId $ - prettyShow pkgid + prettyShow (compilerId elabCompiler) + ++ + '_':prettyShow pkgid ++ "-inplace" ++ ( case Cabal.componentNameString cname of Nothing -> "" @@ -2213,9 +2217,13 @@ elaborateInstallPlan Nothing -> emptyModuleShape Just e -> Ty.elabModuleShape e + elabCompiler = toolchainCompiler (toolchainFor elabStage toolchains) + pkgInstalledId - | shouldBuildInplaceOnly pkg = - mkComponentId (prettyShow pkgid ++ "-inplace") + | shouldBuildInplaceOnly pkg = mkComponentId $ + prettyShow (compilerId elabCompiler) + ++ + '_':prettyShow pkgid ++ "-inplace" | otherwise = assert (isJust elabPkgSourceHash) $ hashedInstalledPackageId @@ -2226,7 +2234,7 @@ elaborateInstallPlan -- Need to filter out internal dependencies, because they don't -- correspond to anything real anymore. - isExt confid = confSrcId confid /= pkgid + isExt confid = (confSrcId confid){pkgCompiler = Nothing} /= pkgid{pkgCompiler = Nothing} filterExt = filter isExt filterExt' :: [(ConfiguredId, a)] -> [(ConfiguredId, a)] @@ -2765,7 +2773,7 @@ matchElabPkg p elab = -- and 'ComponentName' to the 'ComponentId' that should be used -- in this case. mkCCMapping - :: ElaboratedPlanPackage + :: HasCallStack => ElaboratedPlanPackage -> (PackageName, Map ComponentName (AnnotatedId ComponentId)) mkCCMapping = InstallPlan.foldPlanPackage diff --git a/cabal-install/src/Distribution/Client/Store.hs b/cabal-install/src/Distribution/Client/Store.hs index dcf4c78d02c..5b82712b963 100644 --- a/cabal-install/src/Distribution/Client/Store.hs +++ b/cabal-install/src/Distribution/Client/Store.hs @@ -26,9 +26,11 @@ import Prelude () import Distribution.Client.DistDirLayout import Distribution.Client.RebuildMonad -import Distribution.Package (UnitId, mkUnitId) +import Distribution.Package (UnitId, mkUnitId, addPrefixToUnitId, isPartialUnitId) import Distribution.Simple.Compiler (Compiler (..)) +import GHC.Stack (HasCallStack) + import Distribution.Simple.Utils ( debug , info @@ -132,18 +134,20 @@ doesStoreEntryExist StoreDirLayout{storePackageDirectory} compiler unitid = -- | Return the 'UnitId's of all packages\/components already installed in the -- store. -getStoreEntries :: StoreDirLayout -> Compiler -> Rebuild (Set UnitId) +getStoreEntries :: HasCallStack => StoreDirLayout -> Compiler -> Rebuild (Set UnitId) getStoreEntries StoreDirLayout{storeDirectory} compiler = do paths <- getDirectoryContentsMonitored (storeDirectory compiler) return $! mkEntries paths where mkEntries = - Set.delete (mkUnitId "package.db") - . Set.delete (mkUnitId "incoming") - . Set.fromList - . map mkUnitId + Set.fromList + . map (\pkg -> case mkUnitId pkg of + uid | isPartialUnitId uid -> addPrefixToUnitId (prettyShow (compilerId compiler)) uid + | otherwise -> uid) . filter valid valid ('.' : _) = False + valid "incoming" = False + valid "package.db" = False valid _ = True -- | The outcome of 'newStoreEntry': either the store entry was newly created From 8a629931bb7cee318214c12d87439216939e7812 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sat, 5 Apr 2025 11:48:39 +0900 Subject: [PATCH 77/82] Fixup AbiTag logic to deal with <build>_<host>-<abitag>. --- Cabal-syntax/src/Distribution/Compiler.hs | 1 + Cabal-syntax/src/Distribution/Types/UnitId.hs | 15 +++++++++++++++ Cabal/src/Distribution/Simple/GHC.hs | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index a4ac948570f..e79b18e846f 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -229,6 +229,7 @@ instance Binary CompilerInfo instance Structured CompilerInfo instance NFData CompilerInfo where rnf = genericRnf +-- | AbiTag logic data AbiTag = NoAbiTag | AbiTag String diff --git a/Cabal-syntax/src/Distribution/Types/UnitId.hs b/Cabal-syntax/src/Distribution/Types/UnitId.hs index d6a403a04c9..a57211a8663 100644 --- a/Cabal-syntax/src/Distribution/Types/UnitId.hs +++ b/Cabal-syntax/src/Distribution/Types/UnitId.hs @@ -16,6 +16,7 @@ module Distribution.Types.UnitId , newSimpleUnitId , mkLegacyUnitId , getHSLibraryName + , getAbiTag ) where import Distribution.Compat.Prelude @@ -184,3 +185,17 @@ instance Parsec DefUnitId where -- is to ensure that the 'DefUnitId' invariant holds. unsafeMkDefUnitId :: UnitId -> DefUnitId unsafeMkDefUnitId = DefUnitId + +-- | The ABI tag is the part of the unit id that comes after the +-- last hyphen. It is used to distinguish between different +-- versions of the same package that are ABI compatible. +-- +-- FIXME: ideally this would be part of the proper structure of the +-- datatype, instead of some heuristic of the string. +getAbiTag :: HasCallStack => UnitId -> AbiTag +getAbiTag (UnitId _c s _) = case takeWhile (/= '-') . reverse . fromShortText $ s of + [] -> NoAbiTag + xs -> AbiTag . reverse $ xs +getAbiTag (PartialUnitId s) = case takeWhile (/= '-') . reverse . fromShortText $ s of + [] -> NoAbiTag + xs -> AbiTag . reverse $ xs \ No newline at end of file diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 427d605949d..8d56a4ffd46 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -249,7 +249,7 @@ configure verbosity hcPath hcPkgPath conf0 = do compilerId = CompilerId GHC ghcVersion compilerAbiTag :: AbiTag - compilerAbiTag = maybe NoAbiTag AbiTag (Map.lookup "Project Unit Id" ghcInfoMap >>= stripPrefix (prettyShow compilerId <> "-")) + compilerAbiTag = fromMaybe NoAbiTag (getAbiTag . fromString <$> Map.lookup "Project Unit Id" ghcInfoMap) let comp = Compiler From 4e2e0601c8a43389bdd6152482c186c21343830c Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sat, 5 Apr 2025 15:51:36 +0900 Subject: [PATCH 78/82] +HasCallStack --- Cabal-syntax/src/Distribution/Compat/Graph.hs | 4 +- .../src/Distribution/FieldGrammar/Class.hs | 44 ++++++++++--------- .../src/Distribution/InstalledPackageInfo.hs | 2 +- Cabal-syntax/src/Distribution/Parsec.hs | 4 +- Cabal/src/Distribution/Simple/Configure.hs | 4 +- Cabal/src/Distribution/Simple/GHC.hs | 8 ++-- .../src/Distribution/Simple/Program/HcPkg.hs | 2 +- .../src/Distribution/Client/IndexUtils.hs | 4 +- 8 files changed, 41 insertions(+), 31 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Compat/Graph.hs b/Cabal-syntax/src/Distribution/Compat/Graph.hs index c716563f52a..60eeee53631 100644 --- a/Cabal-syntax/src/Distribution/Compat/Graph.hs +++ b/Cabal-syntax/src/Distribution/Compat/Graph.hs @@ -105,6 +105,8 @@ 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'. data Graph a = Graph @@ -377,7 +379,7 @@ fromMap m = 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) diff --git a/Cabal-syntax/src/Distribution/FieldGrammar/Class.hs b/Cabal-syntax/src/Distribution/FieldGrammar/Class.hs index fa815a49a5e..f439f9d2b01 100644 --- a/Cabal-syntax/src/Distribution/FieldGrammar/Class.hs +++ b/Cabal-syntax/src/Distribution/FieldGrammar/Class.hs @@ -23,6 +23,8 @@ import Distribution.FieldGrammar.Newtypes import Distribution.Fields.Field import Distribution.Utils.ShortText +import GHC.Stack (HasCallStack) + -- | 'FieldGrammar' is parametrised by -- -- * @s@ which is a structure we are parsing. We need this to provide prettyprinter @@ -43,11 +45,11 @@ class | g -> c where -- | Unfocus, zoom out, /blur/ 'FieldGrammar'. - blurFieldGrammar :: ALens' a b -> g b d -> g a d + blurFieldGrammar :: HasCallStack => ALens' a b -> g b d -> g a d -- | Field which should be defined, exactly once. uniqueFieldAla - :: (c b, Newtype a b) + :: (c b, Newtype a b, HasCallStack) => FieldName -- ^ field name -> (a -> b) @@ -58,7 +60,7 @@ class -- | Boolean field with a default value. booleanFieldDef - :: FieldName + :: HasCallStack => FieldName -- ^ field name -> ALens' s Bool -- ^ lens into the field @@ -68,7 +70,7 @@ class -- | Optional field. optionalFieldAla - :: (c b, Newtype a b) + :: (c b, Newtype a b, HasCallStack) => FieldName -- ^ field name -> (a -> b) @@ -79,7 +81,7 @@ class -- | Optional field with default value. optionalFieldDefAla - :: (c b, Newtype a b, Eq a) + :: (c b, Newtype a b, Eq a, HasCallStack) => FieldName -- ^ field name -> (a -> b) @@ -95,7 +97,7 @@ class -- -- @since 3.0.0.0 freeTextField - :: FieldName + :: HasCallStack => FieldName -> ALens' s (Maybe String) -- ^ lens into the field -> g s (Maybe String) @@ -105,14 +107,14 @@ class -- -- @since 3.0.0.0 freeTextFieldDef - :: FieldName + :: HasCallStack => FieldName -> ALens' s String -- ^ lens into the field -> g s String -- | @since 3.2.0.0 freeTextFieldDefST - :: FieldName + :: HasCallStack => FieldName -> ALens' s ShortText -- ^ lens into the field -> g s ShortText @@ -123,7 +125,7 @@ class -- -- /Note:/ 'optionalFieldAla' is a @monoidalField@ with 'Last' monoid. monoidalFieldAla - :: (c b, Monoid a, Newtype a b) + :: (c b, Monoid a, Newtype a b, HasCallStack) => FieldName -- ^ field name -> (a -> b) @@ -134,21 +136,21 @@ class -- | Parser matching all fields with a name starting with a prefix. prefixedFields - :: FieldName + :: HasCallStack => FieldName -- ^ field name prefix -> ALens' s [(String, String)] -- ^ lens into the field -> g s [(String, String)] -- | Known field, which we don't parse, nor pretty print. - knownField :: FieldName -> g s () + knownField :: HasCallStack => FieldName -> g s () -- | Field which is parsed but not pretty printed. - hiddenField :: g s a -> g s a + hiddenField :: HasCallStack => g s a -> g s a -- | Deprecated since deprecatedSince - :: CabalSpecVersion + :: HasCallStack => CabalSpecVersion -- ^ version -> String -- ^ deprecation message @@ -157,7 +159,7 @@ class -- | Removed in. If we encounter removed field, parsing fails. removedIn - :: CabalSpecVersion + :: HasCallStack => CabalSpecVersion -- ^ version -> String -- ^ removal message @@ -166,7 +168,7 @@ class -- | Annotate field with since spec-version. availableSince - :: CabalSpecVersion + :: HasCallStack => CabalSpecVersion -- ^ spec version -> a -- ^ default value @@ -181,7 +183,7 @@ class -- -- @since 3.4.0.0 availableSinceWarn - :: CabalSpecVersion + :: HasCallStack => CabalSpecVersion -- ^ spec version -> g s a -> g s a @@ -189,7 +191,7 @@ class -- | Field which can be defined at most once. uniqueField - :: (FieldGrammar c g, c (Identity a)) + :: (FieldGrammar c g, c (Identity a), HasCallStack) => FieldName -- ^ field name -> ALens' s a @@ -199,7 +201,7 @@ uniqueField fn l = uniqueFieldAla fn Identity l -- | Field which can be defined at most once. optionalField - :: (FieldGrammar c g, c (Identity a)) + :: (FieldGrammar c g, c (Identity a), HasCallStack) => FieldName -- ^ field name -> ALens' s (Maybe a) @@ -209,7 +211,7 @@ optionalField fn l = optionalFieldAla fn Identity l -- | Optional field with default value. optionalFieldDef - :: (FieldGrammar c g, Functor (g s), c (Identity a), Eq a) + :: (FieldGrammar c g, Functor (g s), c (Identity a), Eq a, HasCallStack) => FieldName -- ^ field name -> ALens' s a @@ -221,7 +223,7 @@ optionalFieldDef fn l x = optionalFieldDefAla fn Identity l x -- | Field which can be define multiple times, and the results are @mappend@ed. monoidalField - :: (FieldGrammar c g, c (Identity a), Monoid a) + :: (FieldGrammar c g, c (Identity a), Monoid a, HasCallStack) => FieldName -- ^ field name -> ALens' s a @@ -231,7 +233,7 @@ monoidalField fn l = monoidalFieldAla fn Identity l -- | Default implementation for 'freeTextFieldDefST'. defaultFreeTextFieldDefST - :: (Functor (g s), FieldGrammar c g) + :: (Functor (g s), FieldGrammar c g, HasCallStack) => FieldName -> ALens' s ShortText -- ^ lens into the field diff --git a/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs index 93000823a13..dc2499f7a38 100644 --- a/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs @@ -97,7 +97,7 @@ sourceComponentName = CLibName . sourceLibName -- | Return either errors, or IPI with list of warnings parseInstalledPackageInfo - :: ByteString + :: HasCallStack => ByteString -> Either (NonEmpty String) ([String], InstalledPackageInfo) parseInstalledPackageInfo s = case P.readFields s of Left err -> Left (show err :| []) diff --git a/Cabal-syntax/src/Distribution/Parsec.hs b/Cabal-syntax/src/Distribution/Parsec.hs index d0197616fd6..bac02a8a63a 100644 --- a/Cabal-syntax/src/Distribution/Parsec.hs +++ b/Cabal-syntax/src/Distribution/Parsec.hs @@ -70,6 +70,8 @@ import qualified Distribution.Compat.DList as DList import qualified Distribution.Compat.MonadFail as Fail import qualified Text.Parsec as Parsec +import GHC.Stack (HasCallStack) + ------------------------------------------------------------------------------- -- Class ------------------------------------------------------------------------------- @@ -78,7 +80,7 @@ import qualified Text.Parsec as Parsec -- -- For parsing @.cabal@ like file structure, see "Distribution.Fields". class Parsec a where - parsec :: CabalParsing m => m a + parsec :: (HasCallStack, CabalParsing m) => m a -- | Parsing class which -- diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 44bce682c5f..1ed13020f82 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -2065,7 +2065,7 @@ reportFailedDependencies verbosity failed = -- with a warning and treated as empty ones, since technically they do not -- contain any package. getInstalledPackages - :: Verbosity + :: HasCallStack => Verbosity -> Compiler -> Maybe (SymbolicPath CWD (Dir from)) -> PackageDBStackX (SymbolicPath from (Dir PkgDB)) @@ -2108,7 +2108,7 @@ getInstalledPackages verbosity comp mbWorkDir packageDBs progdb = do -- on the package database stack in question. However, when sandboxes -- are involved these sanity checks are not desirable. getPackageDBContents - :: Verbosity + :: HasCallStack => Verbosity -> Compiler -> Maybe (SymbolicPath CWD (Dir Pkg)) -> PackageDB diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 8d56a4ffd46..e865fe436d2 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -150,6 +150,8 @@ import System.Directory import Distribution.Simple.Setup (BuildingWhat (..)) import Distribution.Simple.Setup.Build +import GHC.Stack (HasCallStack) + -- ----------------------------------------------------------------------------- -- Configuring @@ -400,7 +402,7 @@ getGhcInfo verbosity ghcProg = Internal.getGhcInfo verbosity implInfo ghcProg -- | Given a single package DB, return all installed packages. getPackageDBContents - :: Verbosity + :: HasCallStack => Verbosity -> Maybe (SymbolicPath CWD (Dir from)) -> PackageDBX (SymbolicPath from (Dir PkgDB)) -> ProgramDb @@ -411,7 +413,7 @@ getPackageDBContents verbosity mbWorkDir packagedb progdb = do -- | Given a package DB stack, return all installed packages. getInstalledPackages - :: Verbosity + :: HasCallStack => Verbosity -> Compiler -> Maybe (SymbolicPath CWD (Dir from)) -> PackageDBStackX (SymbolicPath from (Dir PkgDB)) @@ -548,7 +550,7 @@ removeMingwIncludeDir pkg = -- | Get the packages from specific PackageDBs, not cumulative. getInstalledPackages' - :: Verbosity + :: HasCallStack => Verbosity -> Maybe (SymbolicPath CWD (Dir from)) -> [PackageDBX (SymbolicPath from (Dir PkgDB))] -> ProgramDb diff --git a/Cabal/src/Distribution/Simple/Program/HcPkg.hs b/Cabal/src/Distribution/Simple/Program/HcPkg.hs index 024d21542f6..8017850d16e 100644 --- a/Cabal/src/Distribution/Simple/Program/HcPkg.hs +++ b/Cabal/src/Distribution/Simple/Program/HcPkg.hs @@ -278,7 +278,7 @@ hide hpi verbosity mbWorkDir packagedb pkgid = -- | Call @hc-pkg@ to get all the details of all the packages in the given -- package database. dump - :: HcPkgInfo + :: HasCallStack => HcPkgInfo -> Verbosity -> Maybe (SymbolicPath CWD (Dir from)) -> PackageDBX (SymbolicPath from (Dir PkgDB)) diff --git a/cabal-install/src/Distribution/Client/IndexUtils.hs b/cabal-install/src/Distribution/Client/IndexUtils.hs index 0cd842d663e..489f8acfdb1 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils.hs @@ -156,9 +156,11 @@ import Distribution.Client.Errors import qualified Hackage.Security.Client as Sec import qualified Hackage.Security.Util.Some as Sec +import GHC.Stack (HasCallStack) + -- | Reduced-verbosity version of 'Configure.getInstalledPackages' getInstalledPackages - :: Verbosity + :: HasCallStack => Verbosity -> Compiler -> PackageDBStackCWD -> ProgramDb From 6744f1a35050928086251f4b665183c258cfefb2 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sat, 5 Apr 2025 15:51:45 +0900 Subject: [PATCH 79/82] +Debug --- Cabal-syntax/src/Distribution/Compat/Graph.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Compat/Graph.hs b/Cabal-syntax/src/Distribution/Compat/Graph.hs index 60eeee53631..6fe6bb3bfec 100644 --- a/Cabal-syntax/src/Distribution/Compat/Graph.hs +++ b/Cabal-syntax/src/Distribution/Compat/Graph.hs @@ -380,15 +380,17 @@ fromMap m = -- | /O(V log V)/. Convert a list of nodes (with distinct keys) into a graph. fromDistinctList :: (HasCallStack, IsNode a, Show (Key a)) => [a] -> Graph a -fromDistinctList = +fromDistinctList xs = fromMap . Map.fromListWith (\_ -> duplicateError) - . map (\n -> n `seq` (nodeKey n, n)) + . map (\n -> n `seq` (nodeKey n, n)) $ xs where duplicateError n = error $ "Graph.fromDistinctList: duplicate key: " ++ show (nodeKey n) + ++ " in " + ++ unlines (map (show . nodeKey) xs) -- Map-like operations From 3de93d045e35fd84797f80689555c41eabc32de4 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Sat, 5 Apr 2025 15:52:09 +0900 Subject: [PATCH 80/82] +Debug: UnitId --- Cabal-syntax/src/Distribution/Types/UnitId.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Cabal-syntax/src/Distribution/Types/UnitId.hs b/Cabal-syntax/src/Distribution/Types/UnitId.hs index a57211a8663..5c765cee65c 100644 --- a/Cabal-syntax/src/Distribution/Types/UnitId.hs +++ b/Cabal-syntax/src/Distribution/Types/UnitId.hs @@ -19,6 +19,7 @@ module Distribution.Types.UnitId , getAbiTag ) where +import Distribution.Compiler (AbiTag (..)) import Distribution.Compat.Prelude import Distribution.Utils.ShortText import Prelude () @@ -31,7 +32,7 @@ import Distribution.Types.PackageId import Text.PrettyPrint (text) -import GHC.Stack (HasCallStack) +import GHC.Stack (HasCallStack, prettyCallStack, callStack) import Data.List (isInfixOf) import Unsafe.Coerce (unsafeCoerce) @@ -117,6 +118,7 @@ isPartialUnitId (PartialUnitId _) = True isPartialUnitId _ = False addPrefixToUnitId :: HasCallStack => String -> UnitId -> UnitId +-- addPrefixToUnitId prefix (PartialUnitId s) | s == toShortText "process-1.6.25.0-inplace" = trace ("### addPrefixToUnitId': `" ++ prefix ++ "' `" ++ (fromShortText s) ++ "'.\n" ++ prettyCallStack callStack) $ UnitId (toShortText prefix) s True addPrefixToUnitId prefix (PartialUnitId s) = UnitId (toShortText prefix) s True addPrefixToUnitId prefix uid@(UnitId _ _ _) = error $ "addPrefixToUnitId: UnitId " ++ show uid ++ " already has a prefix; can't add: " ++ prefix @@ -143,9 +145,11 @@ mkUnitId s = case (simpleParsec s) of _ -> error $ "Unable to parse UnitId: `" ++ s ++ "'." mkUnitId' :: HasCallStack => String -> String -> Bool -> UnitId +-- mkUnitId' c i b | c == "ghc-9.8.4", i == "process-1.6.25.0-inplace" = trace ("### mkUnitId': `" ++ c ++ "' `" ++ i ++ "' is a full one.\n" ++ prettyCallStack callStack) (UnitId (toShortText c) (toShortText i) b) mkUnitId' c i b = UnitId (toShortText c) (toShortText i) b mkPartialUnitId :: HasCallStack => String -> UnitId +-- mkPartialUnitId s | s == "process-1.6.25.0-inplace" = trace ("### mkPartialUnitId: `" ++ s ++ "' is a partial unit id, not a full one.\n" ++ prettyCallStack callStack) (PartialUnitId (toShortText s)) mkPartialUnitId s = PartialUnitId (toShortText s) -- | 'mkUnitId' From df70cef4be330f156e54231254ab7a9583c944e8 Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 7 Apr 2025 17:36:15 +0900 Subject: [PATCH 81/82] Add "flags:" to ipi --- Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs | 5 ++++- .../Distribution/Types/InstalledPackageInfo/FieldGrammar.hs | 3 +++ .../src/Distribution/Types/InstalledPackageInfo/Lens.hs | 5 +++++ Cabal/src/Distribution/Simple/Register.hs | 1 + 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs index e5733d158a4..49893ab1462 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs @@ -22,6 +22,7 @@ import Distribution.ModuleName import Distribution.Package hiding (installedUnitId, pkgCompiler) import Distribution.Types.AbiDependency import Distribution.Types.ExposedModule +import Distribution.Types.Flag (FlagAssignment) import Distribution.Types.LibraryName import Distribution.Types.LibraryVisibility import Distribution.Types.MungedPackageId @@ -62,7 +63,8 @@ data InstalledPackageInfo = InstalledPackageInfo , description :: !ShortText , category :: !ShortText , -- these parts are required by an installed package only: - abiHash :: AbiHash + unitFlags :: FlagAssignment + , abiHash :: AbiHash , indefinite :: Bool , exposed :: Bool , -- INVARIANT: if the package is definite, OpenModule's @@ -148,6 +150,7 @@ emptyInstalledPackageInfo = , synopsis = "" , description = "" , category = "" + , unitFlags = mempty , abiHash = mkAbiHash "" , indefinite = False , exposed = False diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index b6be432a6ff..9853efc287b 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -23,6 +23,7 @@ import Distribution.ModuleName import Distribution.Package hiding (pkgCompiler) import Distribution.Parsec import Distribution.Pretty +import Distribution.Types.Flag (FlagAssignment) import Distribution.Types.LibraryName import Distribution.Types.LibraryVisibility import Distribution.Types.MungedPackageName @@ -61,6 +62,7 @@ ipiFieldGrammar , Applicative (g InstalledPackageInfo) , Applicative (g Basic) , c (Identity AbiHash) + , c (Identity FlagAssignment) , c (Identity LibraryVisibility) , c (Identity PackageName) , c (Identity UnitId) @@ -105,6 +107,7 @@ ipiFieldGrammar = <@> freeTextFieldDefST "description" L.description <@> freeTextFieldDefST "category" L.category -- Installed fields + <@> optionalFieldDef "flags" L.unitFlags mempty <@> optionalFieldDef "abi" L.abiHash (mkAbiHash "") <@> booleanFieldDef "indefinite" L.indefinite False <@> booleanFieldDef "exposed" L.exposed False diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs index c34e885fa01..9a35a03816e 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/Lens.hs @@ -12,6 +12,7 @@ import Distribution.Backpack (OpenModule) import Distribution.License (License) import Distribution.ModuleName (ModuleName) import Distribution.Package (AbiHash, ComponentId, PackageIdentifier, UnitId) +import Distribution.Types.Flag (FlagAssignment) import Distribution.Types.InstalledPackageInfo (AbiDependency, ExposedModule, InstalledPackageInfo) import Distribution.Types.LibraryName (LibraryName) import Distribution.Types.LibraryVisibility (LibraryVisibility) @@ -28,6 +29,10 @@ installedUnitId :: Lens' InstalledPackageInfo UnitId installedUnitId f s = fmap (\x -> s{T.installedUnitId = x}) (f (T.installedUnitId s)) {-# INLINE installedUnitId #-} +unitFlags :: Lens' InstalledPackageInfo FlagAssignment +unitFlags f s = fmap (\x -> s{T.unitFlags = x}) (f (T.unitFlags s)) +{-# INLINE unitFlags #-} + installedComponentId_ :: Lens' InstalledPackageInfo (Maybe ComponentId) installedComponentId_ f s = fmap (\x -> s{T.installedComponentId_ = x}) (f (T.installedComponentId_ s)) {-# INLINE installedComponentId_ #-} diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index 10ea7f0e94e..9a9b313d994 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -500,6 +500,7 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi , IPI.installedComponentId_ = Just (componentComponentId clbi) , IPI.instantiatedWith = expectLibraryComponent (maybeComponentInstantiatedWith clbi) , IPI.sourceLibName = libName lib + , IPI.unitFlags = flagAssignment lbi , IPI.compatPackageKey = expectLibraryComponent (maybeComponentCompatPackageKey clbi) , -- If GHC >= 8.4 we register with SDPX, otherwise with legacy license IPI.license = From 7e50837ade188504d1401bad932a5b8b3769661e Mon Sep 17 00:00:00 2001 From: Moritz Angermann <moritz.angermann@gmail.com> Date: Mon, 7 Apr 2025 17:36:32 +0900 Subject: [PATCH 82/82] Fixup compiler id in pkgid --- Cabal-syntax/src/Distribution/Parsec.hs | 10 +++++----- .../src/Distribution/Types/ComponentId.hs | 6 ++++-- Cabal-syntax/src/Distribution/Types/UnitId.hs | 5 +++-- .../src/Distribution/Client/PackageHash.hs | 15 ++++++++++----- .../Client/ProjectBuilding/UnpackedPackage.hs | 4 ++++ 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Parsec.hs b/Cabal-syntax/src/Distribution/Parsec.hs index bac02a8a63a..dcc236b840f 100644 --- a/Cabal-syntax/src/Distribution/Parsec.hs +++ b/Cabal-syntax/src/Distribution/Parsec.hs @@ -96,7 +96,7 @@ class (P.CharParsing m, MonadPlus m, Fail.MonadFail m) => CabalParsing m where askCabalSpecVersion :: m CabalSpecVersion -- | 'parsec' /could/ consume trailing spaces, this function /will/ consume. -lexemeParsec :: (CabalParsing m, Parsec a) => m a +lexemeParsec :: (HasCallStack, CabalParsing m, Parsec a) => m a lexemeParsec = parsec <* P.spaces newtype ParsecParser a = PP @@ -177,14 +177,14 @@ instance CabalParsing ParsecParser where askCabalSpecVersion = PP pure -- | Parse a 'String' with 'lexemeParsec'. -simpleParsec :: Parsec a => String -> Maybe a +simpleParsec :: (HasCallStack, Parsec a) => String -> Maybe a simpleParsec = either (const Nothing) Just . runParsecParser lexemeParsec "<simpleParsec>" . fieldLineStreamFromString -- | Like 'simpleParsec' but for 'ByteString' -simpleParsecBS :: Parsec a => ByteString -> Maybe a +simpleParsecBS :: (HasCallStack, Parsec a) => ByteString -> Maybe a simpleParsecBS = either (const Nothing) Just . runParsecParser lexemeParsec "<simpleParsec>" @@ -193,7 +193,7 @@ simpleParsecBS = -- | Parse a 'String' with 'lexemeParsec' using specific 'CabalSpecVersion'. -- -- @since 3.4.0.0 -simpleParsec' :: Parsec a => CabalSpecVersion -> String -> Maybe a +simpleParsec' :: (HasCallStack, Parsec a) => CabalSpecVersion -> String -> Maybe a simpleParsec' spec = either (const Nothing) Just . runParsecParser' spec lexemeParsec "<simpleParsec>" @@ -203,7 +203,7 @@ simpleParsec' spec = -- Fail if there are any warnings. -- -- @since 3.4.0.0 -simpleParsecW' :: Parsec a => CabalSpecVersion -> String -> Maybe a +simpleParsecW' :: (HasCallStack, Parsec a) => CabalSpecVersion -> String -> Maybe a simpleParsecW' spec = either (const Nothing) (\(x, ws) -> if null ws then Just x else Nothing) . runParsecParser' spec ((,) <$> lexemeParsec <*> liftParsec Parsec.getState) "<simpleParsec>" diff --git a/Cabal-syntax/src/Distribution/Types/ComponentId.hs b/Cabal-syntax/src/Distribution/Types/ComponentId.hs index 03820ad0631..fd2467972e9 100644 --- a/Cabal-syntax/src/Distribution/Types/ComponentId.hs +++ b/Cabal-syntax/src/Distribution/Types/ComponentId.hs @@ -17,7 +17,7 @@ import Distribution.Pretty import qualified Distribution.Compat.CharParsing as P import Text.PrettyPrint (text) -import GHC.Stack (HasCallStack) +import GHC.Stack (HasCallStack, prettyCallStack, callStack) -- | A 'ComponentId' uniquely identifies the transitive source -- code closure of a component (i.e. libraries, executables). -- @@ -31,7 +31,7 @@ import GHC.Stack (HasCallStack) -- This type is opaque since @Cabal-2.0@ -- -- @since 2.0.0.2 -data ComponentId = ComponentId ShortText ShortText Bool +data ComponentId = ComponentId {unitComp :: ShortText, unitId :: ShortText, wasPartial :: Bool } | PartialComponentId ShortText deriving (Generic, Read, Show, Data) @@ -57,11 +57,13 @@ instance Ord ComponentId where -- @since 2.0.0.2 mkComponentId :: HasCallStack => String -> ComponentId mkComponentId s = case (simpleParsec s) of + -- Just cid@ComponentId{ unitComp = c, unitId = i } | (fromShortText c) == "ghc-9.8.4", (fromShortText i) == "rts-1.0.3-cec100dd" -> trace ("### ComponentId: `" ++ (fromShortText c) ++ "' `" ++ (fromShortText i) ++ "' is a full one.\n" ++ prettyCallStack callStack) cid Just cid@ComponentId{} -> cid Just cid@PartialComponentId{} -> error $ "mkPartialComponentId: `" ++ s ++ "' is a partial component id, not a full one." _ -> error $ "Unable to parse PartialComponentId: `" ++ s ++ "'." mkComponentId' :: HasCallStack => String -> String -> Bool -> ComponentId +-- mkComponentId' c i b | c == "ghc-9.8.4", i == "rts-1.0.3-cec100dd" = trace ("### mkComponentId': `" ++ c ++ "' `" ++ i ++ "' is a full one.\n" ++ prettyCallStack callStack) (ComponentId (toShortText c) (toShortText i) b) mkComponentId' c i b = ComponentId (toShortText c) (toShortText i) b mkPartialComponentId :: HasCallStack => String -> ComponentId diff --git a/Cabal-syntax/src/Distribution/Types/UnitId.hs b/Cabal-syntax/src/Distribution/Types/UnitId.hs index 5c765cee65c..a5aae2a38bd 100644 --- a/Cabal-syntax/src/Distribution/Types/UnitId.hs +++ b/Cabal-syntax/src/Distribution/Types/UnitId.hs @@ -73,7 +73,7 @@ import Unsafe.Coerce (unsafeCoerce) -- representation of a UnitId to pass, e.g., as a @-package-id@ -- flag, use the 'display' function, which will work on all -- versions of Cabal. -data UnitId = UnitId ShortText ShortText Bool +data UnitId = UnitId {unitComp :: ShortText, unitId :: ShortText, wasPartial :: Bool } | PartialUnitId ShortText deriving (Generic, Read, Show, Data) @@ -140,12 +140,13 @@ unUnitId (PartialUnitId s) = fromShortText s mkUnitId :: HasCallStack => String -> UnitId mkUnitId s = case (simpleParsec s) of + -- Just uid@UnitId{ unitComp = c, unitId = i } | (fromShortText c) == "ghc-9.8.4", (fromShortText i) == "rts-1.0.3-cec100dd" -> trace ("### mkUnitId: `" ++ (fromShortText c) ++ "' `" ++ (fromShortText i) ++ "' is a full one.\n" ++ prettyCallStack callStack) uid Just uid@UnitId{} -> uid Just uid@PartialUnitId{} -> uid -- error $ "mkUnitId: `" ++ s ++ "' is a partial unit id, not a full one." _ -> error $ "Unable to parse UnitId: `" ++ s ++ "'." mkUnitId' :: HasCallStack => String -> String -> Bool -> UnitId --- mkUnitId' c i b | c == "ghc-9.8.4", i == "process-1.6.25.0-inplace" = trace ("### mkUnitId': `" ++ c ++ "' `" ++ i ++ "' is a full one.\n" ++ prettyCallStack callStack) (UnitId (toShortText c) (toShortText i) b) +-- mkUnitId' c i b | c == "ghc-9.8.4", i == "rts-1.0.3-cec100dd" = trace ("### mkUnitId': `" ++ c ++ "' `" ++ i ++ "' is a full one.\n" ++ prettyCallStack callStack) (UnitId (toShortText c) (toShortText i) b) mkUnitId' c i b = UnitId (toShortText c) (toShortText i) b mkPartialUnitId :: HasCallStack => String -> UnitId diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index 0fa147669d9..0be2753dcf5 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -93,11 +93,14 @@ hashedInstalledPackageIdLong :: PackageHashInputs -> InstalledPackageId hashedInstalledPackageIdLong pkghashinputs@PackageHashInputs{pkgHashPkgId, pkgHashComponent} = mkComponentId $ - prettyShow pkgHashPkgId -- to be a bit user friendly + prettyShow compid + ++ "_" + ++ prettyShow pkgHashPkgId -- to be a bit user friendly ++ maybe "" displayComponent pkgHashComponent ++ "-" ++ showHashValue (hashPackageHashInputs pkghashinputs) where + PackageIdentifier name version (Just compid) = pkgHashPkgId displayComponent :: CD.Component -> String displayComponent CD.ComponentLib = "" displayComponent (CD.ComponentSubLib s) = "-l-" ++ prettyShow s @@ -127,7 +130,9 @@ hashedInstalledPackageIdLong hashedInstalledPackageIdShort :: HasCallStack => PackageHashInputs -> InstalledPackageId hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = mkComponentId $ - intercalate + prettyShow compid + ++ + '_':intercalate "-" -- max length now 64 [ truncateStr 14 (prettyShow name) @@ -135,7 +140,7 @@ hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = , showHashValue (truncateHash 20 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version _compid = pkgHashPkgId + PackageIdentifier name version (Just compid) = pkgHashPkgId -- Truncate a string, with a visual indication that it is truncated. truncateStr n s @@ -167,7 +172,7 @@ hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = hashedInstalledPackageIdVeryShort :: HasCallStack => PackageHashInputs -> InstalledPackageId hashedInstalledPackageIdVeryShort pkghashinputs@PackageHashInputs{pkgHashPkgId} = mkComponentId $ - prettyShow (pkgHashCompilerId . pkgHashOtherConfig $ pkghashinputs) + prettyShow compid ++ '_':intercalate "-" @@ -176,7 +181,7 @@ hashedInstalledPackageIdVeryShort pkghashinputs@PackageHashInputs{pkgHashPkgId} , showHashValue (truncateHash 4 (hashPackageHashInputs pkghashinputs)) ] where - PackageIdentifier name version _compid = pkgHashPkgId + PackageIdentifier name version (Just compid) = pkgHashPkgId -- | All the information that contributes to a package's hash, and thus its -- 'InstalledPackageId'. diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index 8fd229b61fa..c0bad4bc39f 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -834,6 +834,8 @@ buildAndInstallUnpackedPackage ++ unwords (map whyNotPerComponent $ NE.toList pkgWhyNotPerComponent) ++ ", " ++ dispcompiler (elabStage pkg) + -- ++ ", " + -- ++ show uid ++ ")" -- Packages built per component ElabComponent comp -> @@ -842,6 +844,8 @@ buildAndInstallUnpackedPackage ++ maybe "custom" prettyShow (compComponentName comp) ++ ", " ++ dispcompiler (elabStage pkg) + -- ++ ", " + -- ++ show uid ++ ")" dispcompiler :: Stage -> String dispcompiler Host = showCompilerId (toolchainCompiler (hostToolchain toolchains))