Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track static vs. dynamic dependencies #8624

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Cabal-syntax/src/Distribution/Types/InstalledPackageInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ data InstalledPackageInfo
frameworks :: [String],
haddockInterfaces :: [FilePath],
haddockHTMLs :: [FilePath],
pkgRoot :: Maybe FilePath
pkgRoot :: Maybe FilePath,
-- Artifacts included in this package:
providesStaticArtifacts :: Bool,
providesDynamicArtifacts :: Bool
}
deriving (Eq, Generic, Typeable, Read, Show)

Expand Down Expand Up @@ -173,5 +176,7 @@ emptyInstalledPackageInfo
haddockInterfaces = [],
haddockHTMLs = [],
pkgRoot = Nothing,
libVisibility = LibraryVisibilityPrivate
libVisibility = LibraryVisibilityPrivate,
providesStaticArtifacts = True,
providesDynamicArtifacts = True
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ ipiFieldGrammar = mkInstalledPackageInfo
<@> monoidalFieldAla "haddock-interfaces" (alaList' FSep FilePathNT) L.haddockInterfaces
<@> monoidalFieldAla "haddock-html" (alaList' FSep FilePathNT) L.haddockHTMLs
<@> optionalFieldAla "pkgroot" FilePathNT L.pkgRoot
<@> booleanFieldDef "provides-static-artifacts" L.providesStaticArtifacts True
<@> booleanFieldDef "provides-dynamic-artifacts" L.providesDynamicArtifacts True
where
mkInstalledPackageInfo _ Basic {..} = InstalledPackageInfo
-- _basicPkgName is not used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,11 @@ libVisibility :: Lens' InstalledPackageInfo LibraryVisibility
libVisibility f s = fmap (\x -> s { T.libVisibility = x }) (f (T.libVisibility s))
{-# INLINE libVisibility #-}

providesStaticArtifacts :: Lens' InstalledPackageInfo Bool
providesStaticArtifacts f s = fmap (\x -> s { T.providesStaticArtifacts = x }) (f (T.providesStaticArtifacts s))
{-# INLINE providesStaticArtifacts #-}

providesDynamicArtifacts :: Lens' InstalledPackageInfo Bool
providesDynamicArtifacts f s = fmap (\x -> s { T.providesDynamicArtifacts = x }) (f (T.providesDynamicArtifacts s))
{-# INLINE providesDynamicArtifacts #-}

4 changes: 3 additions & 1 deletion Cabal-tests/tests/ParserTests/ipi/Includes2.expr
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,6 @@ InstalledPackageInfo {
haddockHTMLs =
[
"/home/travis/build/haskell/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.dist/work/./dist/build/x86_64-linux/ghc-8.2.2/Includes2-0.1.0.0/l/mylib/Includes2-0.1.0.0-inplace-mylib+3gY9SyjX86dBypHcOaev1n/doc/html/Includes2"],
pkgRoot = Nothing}
pkgRoot = Nothing,
providesStaticArtifacts = True,
providesDynamicArtifacts = True}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ InstalledPackageInfo {
"/home/ogre/Documents/other-haskell/cabal/cabal-testsuite/PackageTests/CustomPreProcess/setup.dist/work/dist/doc/html/internal-preprocessor-test"],
pkgRoot =
Just
"/home/ogre/Documents/other-haskell/cabal/cabal-testsuite/PackageTests/CustomPreProcess/setup.dist/work/dist"}
"/home/ogre/Documents/other-haskell/cabal/cabal-testsuite/PackageTests/CustomPreProcess/setup.dist/work/dist",
providesStaticArtifacts = True,
providesDynamicArtifacts = True}
4 changes: 3 additions & 1 deletion Cabal-tests/tests/ParserTests/ipi/issue-2276-ghc-9885.expr
Original file line number Diff line number Diff line change
Expand Up @@ -2181,4 +2181,6 @@ InstalledPackageInfo {
"/opt/ghc/8.2.2/share/doc/ghc-8.2.2/html/libraries/transformers-0.5.2.0/transformers.haddock"],
haddockHTMLs = [
"/opt/ghc/8.2.2/share/doc/ghc-8.2.2/html/libraries/transformers-0.5.2.0"],
pkgRoot = Nothing}
pkgRoot = Nothing,
providesStaticArtifacts = True,
providesDynamicArtifacts = True}
4 changes: 3 additions & 1 deletion Cabal-tests/tests/ParserTests/ipi/transformers.expr
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,6 @@ InstalledPackageInfo {
haddockHTMLs = [
"/opt/ghc/8.2.2/share/doc/ghc-8.2.2/html/libraries/transformers-0.5.2.0"],
pkgRoot = Just
"/opt/ghc/8.2.2/lib/ghc-8.2.2"}
"/opt/ghc/8.2.2/lib/ghc-8.2.2",
providesStaticArtifacts = True,
providesDynamicArtifacts = True}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ tests = testGroup "Distribution.Utils.Structured"
, testCase "GenericPackageDescription" $
md5Check (Proxy :: Proxy GenericPackageDescription) 0xa3e9433662ecf0c7a3c26f6d75a53ba1
, testCase "LocalBuildInfo" $
md5Check (Proxy :: Proxy LocalBuildInfo) 0x91ffcd61bbd83525e8edba877435a031
md5Check (Proxy :: Proxy LocalBuildInfo) 0x89eabee921ae834a5222e4a10ce68439
#endif
]

Expand Down
13 changes: 12 additions & 1 deletion Cabal/src/Distribution/Simple/Register.hs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,9 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi
IPI.haddockInterfaces = [haddockdir installDirs </> haddockName pkg],
IPI.haddockHTMLs = [htmldir installDirs],
IPI.pkgRoot = Nothing,
IPI.libVisibility = libVisibility lib
IPI.libVisibility = libVisibility lib,
IPI.providesStaticArtifacts = providesStaticArtifacts,
IPI.providesDynamicArtifacts = providesDynamicArtifacts
}
where
ghc84 = case compilerId $ compiler lbi of
Expand Down Expand Up @@ -492,6 +494,15 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi
= (libdir installDirs : dynlibdir installDirs : extraLibDirs bi, [])
-- the compiler doesn't understand the dynamic-library-dirs field so we
-- add the dyn directory to the "normal" list in the library-dirs field
(providesStaticArtifacts, providesDynamicArtifacts) = case compilerFlavor comp of
GHC ->
let
none f t = all (not . f) t
libDefaults = none ($ lbi) [withVanillaLib, withSharedLib] && hasLibrary
statics = libDefaults || any ($ lbi) [withVanillaLib]
dynamics = any ($ lbi) [withSharedLib]
in (statics, dynamics)
_ -> (True, True) -- Assume nothing is missing.

-- | Construct 'InstalledPackageInfo' for a library that is in place in the
-- build tree.
Expand Down
1 change: 1 addition & 0 deletions cabal-install-solver/cabal-install-solver.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ library
Distribution.Solver.Modular.Var
Distribution.Solver.Modular.Version
Distribution.Solver.Modular.WeightedPSQ
Distribution.Solver.Types.ArtifactSelection
Distribution.Solver.Types.ComponentDeps
Distribution.Solver.Types.ConstraintSource
Distribution.Solver.Types.DependencyResolver
Expand Down
2 changes: 1 addition & 1 deletion cabal-install-solver/src/Distribution/Solver/Modular.hs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns
solve' sc cinfo idx pkgConfigDB pprefs gcs pns
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 os arch cinfo gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) (sourceArtifacts sc) iidx sidx
-- Constraints have to be converted into a finite map indexed by PN.
gcs = M.fromListWith (++) (map pair pcs)
where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ addChildren bs@(BS { rdeps = rdm, next = OneGoal (StanzaGoal qsn@(SN qpn _) t gr
-- and furthermore we update the set of goals.
--
-- TODO: We could inline this above.
addChildren bs@(BS { next = Instance qpn (PInfo fdeps _ fdefs _) }) =
addChildren bs@(BS { next = Instance qpn (PInfo fdeps _ fdefs _ _) }) =
addChildren ((scopedExtendOpen qpn fdeps fdefs bs)
{ next = Goals })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ exploreLog mbj enableBj fineGrainedConflicts (CountConflicts countConflicts) idx
-- 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 =
let (PInfo deps _ _ _) = idx M.! pn M.! i
let (PInfo deps _ _ _ _) = idx M.! pn M.! i
qdeps = qualifyDeps (defaultQualifyOptions idx) currentQPN deps

couldBeResolved :: CS.Conflict -> Maybe ConflictSet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Distribution.Solver.Modular.Dependency
import Distribution.Solver.Modular.Flag
import Distribution.Solver.Modular.Package
import Distribution.Solver.Modular.Tree
import Distribution.Solver.Types.ArtifactSelection

-- | An index contains information about package instances. This is a nested
-- dictionary. Package names are mapped to instances, which in turn is mapped
Expand All @@ -32,10 +33,13 @@ type Index = Map PN (Map I PInfo)
-- globally, for reasons external to the solver. We currently use this
-- for shadowing which essentially is a GHC limitation, and for
-- installed packages that are broken.
--
-- Additionally, track build artifacts provided and build artifacts required.
data PInfo = PInfo (FlaggedDeps PN)
(Map ExposedComponent ComponentInfo)
FlagInfo
(Maybe FailReason)
(ArtifactSelection, ArtifactSelection)

-- | Info associated with each library and executable in a package instance.
data ComponentInfo = ComponentInfo {
Expand Down Expand Up @@ -64,7 +68,7 @@ defaultQualifyOptions idx = QO {
| -- 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
, (I _ver (Inst _), PInfo deps _comps _flagNfo _fr _arts) <- M.toList is
-- .. and flatten all their dependencies ..
, (LDep _ (Dep (PkgComponent dep _) _ci), _comp) <- flattenFlaggedDeps deps
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import Distribution.PackageDescription.Configuration
import qualified Distribution.Simple.PackageIndex as SI
import Distribution.System

import Distribution.Solver.Types.ArtifactSelection
( ArtifactSelection(..), allArtifacts, staticOutsOnly, dynOutsOnly, noOuts )
import Distribution.Solver.Types.ComponentDeps
( Component(..), componentNameToComponent )
import Distribution.Solver.Types.Flag
Expand Down Expand Up @@ -55,11 +57,12 @@ import Distribution.Solver.Modular.Version
-- explicitly requested.
convPIs :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
-> ShadowPkgs -> StrongFlags -> SolveExecutables
-> Maybe (ArtifactSelection, ArtifactSelection)
-> SI.InstalledPackageIndex -> CI.PackageIndex (SourcePackage loc)
-> Index
convPIs os arch comp constraints sip strfl solveExes iidx sidx =
convPIs os arch comp constraints sip strfl solveExes srcArts iidx sidx =
mkIndex $
convIPI' sip iidx ++ convSPI' os arch comp constraints strfl solveExes sidx
convIPI' sip iidx ++ convSPI' os arch comp constraints strfl solveExes srcArts sidx

-- | Convert a Cabal installed package index to the simpler,
-- more uniform index format of the solver.
Expand All @@ -75,8 +78,8 @@ convIPI' (ShadowPkgs sip) idx =
where

-- shadowing is recorded in the package info
shadow (pn, i, PInfo fdeps comps fds _)
| sip = (pn, i, PInfo fdeps comps fds (Just Shadowed))
shadow (pn, i, PInfo fdeps comps fds _ arts)
| sip = (pn, i, PInfo fdeps comps fds (Just Shadowed) arts)
shadow x = x

-- | Extract/recover the package ID from an installed package info, and convert it to a solver's I.
Expand All @@ -90,8 +93,8 @@ convId ipi = (pn, I ver $ Inst $ IPI.installedUnitId ipi)
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
Left u -> (pn, i, PInfo [] M.empty M.empty (Just (Broken u)))
Right fds -> (pn, i, PInfo fds components M.empty Nothing)
Left u -> (pn, i, PInfo [] M.empty M.empty (Just (Broken u)) mempty)
Right fds -> (pn, i, PInfo fds components M.empty Nothing (ipiToAS ipi))
where
-- TODO: Handle sub-libraries and visibility.
components =
Expand Down Expand Up @@ -151,31 +154,44 @@ convIPId dr comp idx ipid =
-- NB: something we pick up from the
-- InstalledPackageIndex is NEVER an executable

-- | Extract the 'ArtifactSelection's representing which artifacts are
-- available in this installed package and which artifacts this installed
-- package requires. Assume both are the same.
ipiToAS :: IPI.InstalledPackageInfo -> (ArtifactSelection, ArtifactSelection)
ipiToAS ipi = (\x -> (x, x)) $ mconcat [statics, dynamics]
where
statics | IPI.providesStaticArtifacts ipi = staticOutsOnly | otherwise = mempty
dynamics | IPI.providesDynamicArtifacts ipi = dynOutsOnly | otherwise = mempty

-- | Convert a cabal-install source package index to the simpler,
-- more uniform index format of the solver.
convSPI' :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
-> StrongFlags -> SolveExecutables
-> StrongFlags -> SolveExecutables -> Maybe (ArtifactSelection, ArtifactSelection)
-> 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' os arch cinfo constraints strfl solveExes srcArts =
L.map (convSP os arch cinfo constraints strfl solveExes srcArts) . 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) =
-> StrongFlags -> SolveExecutables -> Maybe (ArtifactSelection, ArtifactSelection)
-> SourcePackage loc
-> (PN, I, PInfo)
convSP os arch cinfo constraints strfl solveExes srcArts (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) =
let i = I pv InRepo
pkgConstraints = fromMaybe [] $ M.lookup pn constraints
in (pn, i, convGPD os arch cinfo pkgConstraints strfl solveExes pn gpd)
in (pn, i, convGPD os arch cinfo pkgConstraints strfl solveExes srcArts 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]
-> StrongFlags -> SolveExecutables -> PN -> GenericPackageDescription
-> StrongFlags -> SolveExecutables
-> Maybe (ArtifactSelection, ArtifactSelection)
-> PN -> GenericPackageDescription
-> PInfo
convGPD os arch cinfo constraints strfl solveExes pn
convGPD os arch cinfo constraints strfl solveExes srcArts pn
(GenericPackageDescription pkg scannedVersion flags mlib sub_libs flibs exes tests benchs) =
let
fds = flagInfo strfl flags
Expand Down Expand Up @@ -238,7 +254,7 @@ convGPD os arch cinfo constraints strfl solveExes pn
isPrivate LibraryVisibilityPrivate = True
isPrivate LibraryVisibilityPublic = False

in PInfo flagged_deps components fds fr
in PInfo flagged_deps components fds fr (fromMaybe (allArtifacts, noOuts) srcArts)

-- | Applies the given predicate (for example, testing buildability or
-- visibility) to the given component and environment. Values are combined with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ validateLinking index = (`runReader` initVS) . go
goP :: QPN -> POption -> Validate (Tree d c) -> Validate (Tree d c)
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
newSaved = M.insert qpn qdeps (vsSaved vs)
let PInfo deps _ _ _ _ = vsIndex vs ! pn ! i
qdeps = qualifyDeps (vsQualifyOptions vs) 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)
Right vs' -> local (const vs' { vsSaved = newSaved }) r
Expand Down Expand Up @@ -349,7 +349,7 @@ verifyLinkGroup lg =
-- if a constructor is added to the datatype we won't notice it here
Just i -> do
vs <- get
let PInfo _deps _exes finfo _ = vsIndex vs ! lgPackage lg ! i
let PInfo _deps _exes finfo _ _ = vsIndex vs ! lgPackage lg ! i
flags = M.keys finfo
stanzas = [TestStanzas, BenchStanzas]
forM_ flags $ \fn -> do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ showFR _ MultipleInstances = " (multiple instances)"
showFR c (DependenciesNotLinked msg) = " (dependencies not linked: " ++ msg ++ "; conflict set: " ++ showConflictSet c ++ ")"
showFR c CyclicDependencies = " (cyclic dependencies; conflict set: " ++ showConflictSet c ++ ")"
showFR _ (UnsupportedSpecVer ver) = " (unsupported spec-version " ++ prettyShow ver ++ ")"
showFR _ (MissingArtifacts arts) = " (missing build artifacts: " ++ prettyShow arts ++ ")"
-- The following are internal failures. They should not occur. In the
-- interest of not crashing unnecessarily, we still just print an error
-- message though.
Expand Down
Loading