Unverified Commit 9b380e2a authored by Oleg Grenrus's avatar Oleg Grenrus Committed by GitHub

Merge pull request #6907 from phadej/issue-6083-qualified-syntax-dep

Fix #6083: allow depending on public sublibrary with pkg:lib qualified syntax
parents 6001bc94 67479396
......@@ -91,8 +91,6 @@ import qualified Distribution.PackageDescription as PD
import qualified Distribution.PackageDescription.Configuration as PD
import Distribution.PackageDescription.Configuration
( finalizePD )
import Distribution.Client.PackageUtils
( externalBuildDepends )
import Distribution.Compiler
( CompilerInfo(..) )
import Distribution.System
......@@ -890,22 +888,27 @@ showPackageProblem (InvalidDep dep pkgid) =
configuredPackageProblems :: Platform -> CompilerInfo
-> SolverPackage UnresolvedPkgLoc -> [PackageProblem]
configuredPackageProblems platform cinfo
(SolverPackage pkg specifiedFlags stanzas specifiedDeps' _specifiedExeDeps') =
(SolverPackage pkg specifiedFlags stanzas specifiedDeps0 _specifiedExeDeps') =
[ DuplicateFlag flag
| flag <- PD.findDuplicateFlagAssignments specifiedFlags ]
++ [ MissingFlag flag | OnlyInLeft flag <- mergedFlags ]
++ [ ExtraFlag flag | OnlyInRight flag <- mergedFlags ]
++ [ DuplicateDeps pkgs
| pkgs <- CD.nonSetupDeps (fmap (duplicatesBy (comparing packageName))
specifiedDeps) ]
specifiedDeps1) ]
++ [ MissingDep dep | OnlyInLeft dep <- mergedDeps ]
++ [ ExtraDep pkgid | OnlyInRight pkgid <- mergedDeps ]
++ [ InvalidDep dep pkgid | InBoth dep pkgid <- mergedDeps
, not (packageSatisfiesDependency pkgid dep) ]
-- TODO: sanity tests on executable deps
where
specifiedDeps :: ComponentDeps [PackageId]
specifiedDeps = fmap (map solverSrcId) specifiedDeps'
thisPkgName = packageName (packageDescription pkg)
specifiedDeps1 :: ComponentDeps [PackageId]
specifiedDeps1 = fmap (map solverSrcId) specifiedDeps0
specifiedDeps :: [PackageId]
specifiedDeps = CD.flatDeps specifiedDeps1
mergedFlags = mergeBy compare
(sort $ map PD.flagName (PD.genPackageFlags (packageDescription pkg)))
......@@ -919,7 +922,7 @@ configuredPackageProblems platform cinfo
dependencyName (Dependency name _ _) = name
mergedDeps :: [MergeResult Dependency PackageId]
mergedDeps = mergeDeps requiredDeps (CD.flatDeps specifiedDeps)
mergedDeps = mergeDeps requiredDeps specifiedDeps
mergeDeps :: [Dependency] -> [PackageId]
-> [MergeResult Dependency PackageId]
......@@ -947,7 +950,15 @@ configuredPackageProblems platform cinfo
[]
(packageDescription pkg) of
Right (resolvedPkg, _) ->
externalBuildDepends resolvedPkg compSpec
-- we filter self/internal dependencies. They are still there.
-- This is INCORRECT.
--
-- If we had per-component solver, it would make this unnecessary,
-- but no finalizePDs picks components we are not building, eg. exes.
-- See #3775
--
filter ((/= thisPkgName) . dependencyName)
(PD.enabledBuildDepends resolvedPkg compSpec)
++ maybe [] PD.setupDepends (PD.setupBuildInfo resolvedPkg)
Left _ ->
error "configuredPackageInvalidDeps internal error"
......
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Client.PackageUtils
-- Copyright : (c) Duncan Coutts 2010
-- License : BSD-like
--
-- Maintainer : cabal-devel@gmail.com
-- Stability : provisional
-- Portability : portable
--
-- Various package description utils that should be in the Cabal lib
-----------------------------------------------------------------------------
module Distribution.Client.PackageUtils (
externalBuildDepends,
) where
import Distribution.Client.Compat.Prelude
import Prelude ()
import Distribution.Package (packageName, packageVersion)
import Distribution.PackageDescription
(PackageDescription (..), enabledBuildDepends, libName)
import Distribution.Types.ComponentRequestedSpec (ComponentRequestedSpec)
import Distribution.Types.Dependency
import Distribution.Types.LibraryName
import Distribution.Types.UnqualComponentName
import Distribution.Version (isAnyVersion, withinRange)
-- | The list of dependencies that refer to external packages
-- rather than internal package components.
--
externalBuildDepends :: PackageDescription -> ComponentRequestedSpec -> [Dependency]
externalBuildDepends pkg spec = filter (not . internal) (enabledBuildDepends pkg spec)
where
-- True if this dependency is an internal one (depends on a library
-- defined in the same package).
internal (Dependency depName versionRange _) =
(depName == packageName pkg &&
packageVersion pkg `withinRange` versionRange) ||
(LSubLibName (packageNameToUnqualComponentName depName) `elem` map libName (subLibraries pkg) &&
isAnyVersion versionRange)
......@@ -17,7 +17,6 @@ import Distribution.Simple.BuildToolDepends -- from Cabal
import Distribution.Types.ExeDependency -- from Cabal
import Distribution.Types.PkgconfigDependency -- from Cabal
import Distribution.Types.ComponentName -- from Cabal
import Distribution.Types.UnqualComponentName -- from Cabal
import Distribution.Types.CondTree -- from Cabal
import Distribution.Types.MungedPackageId -- from Cabal
import Distribution.Types.MungedPackageName -- from Cabal
......@@ -181,19 +180,11 @@ convGPD os arch cinfo constraints strfl solveExes pn
let
fds = flagInfo strfl flags
-- | We have to be careful to filter out dependencies on
-- internal libraries, since they don't refer to real packages
-- and thus cannot actually be solved over. We'll do this
-- by creating a set of package names which are "internal"
-- and dropping them as we convert.
ipns = S.fromList $ [ unqualComponentNameToPackageName nm
| (nm, _) <- sub_libs ]
conv :: Monoid a => Component -> (a -> BuildInfo) -> DependencyReason PN ->
CondTree ConfVar [Dependency] a -> FlaggedDeps PN
conv comp getInfo dr =
convCondTree M.empty dr pkg os arch cinfo pn fds comp getInfo ipns solveExes .
convCondTree M.empty dr pkg os arch cinfo pn fds comp getInfo solveExes .
addBuildableCondition getInfo
initDR = DependencyReason pn M.empty S.empty
......@@ -331,27 +322,15 @@ flagInfo (StrongFlags strfl) =
weak m = WeakOrTrivial $ not (strfl || m)
flagType m = if m then Manual else Automatic
-- | Internal package names, which should not be interpreted as true
-- dependencies.
type IPNs = S.Set PN
-- | Convenience function to delete a 'Dependency' if it's
-- for a 'PN' that isn't actually real.
filterIPNs :: IPNs -> Dependency -> Maybe Dependency
filterIPNs ipns d@(Dependency pn _ _)
| S.notMember pn ipns = Just d
| otherwise = Nothing
-- | Convert condition trees to flagged dependencies. Mutually
-- recursive with 'convBranch'. See 'convBranch' for an explanation
-- of all arguments preceding the input 'CondTree'.
convCondTree :: Map FlagName Bool -> DependencyReason PN -> PackageDescription -> OS -> Arch -> CompilerInfo -> PN -> FlagInfo ->
Component ->
(a -> BuildInfo) ->
IPNs ->
SolveExecutables ->
CondTree ConfVar [Dependency] a -> FlaggedDeps PN
convCondTree flags dr pkg os arch cinfo pn fds comp getInfo ipns solveExes@(SolveExecutables solveExes') (CondNode info ds branches) =
convCondTree flags dr pkg os arch cinfo pn fds comp getInfo solveExes@(SolveExecutables solveExes') (CondNode info ds branches) =
-- Merge all library and build-tool dependencies at every level in
-- the tree of flagged dependencies. Otherwise 'extractCommon'
-- could create duplicate dependencies, and the number of
......@@ -359,13 +338,13 @@ convCondTree flags dr pkg os arch cinfo pn fds comp getInfo ipns solveExes@(Solv
-- of the tree.
mergeSimpleDeps $
[ D.Simple singleDep comp
| dep <- mapMaybe (filterIPNs ipns) ds
| dep <- ds
, singleDep <- convLibDeps dr dep ] -- unconditional package dependencies
++ L.map (\e -> D.Simple (LDep dr (Ext e)) comp) (allExtensions bi) -- unconditional extension dependencies
++ L.map (\l -> D.Simple (LDep dr (Lang l)) comp) (allLanguages bi) -- unconditional language dependencies
++ L.map (\(PkgconfigDependency pkn vr) -> D.Simple (LDep dr (Pkg pkn vr)) comp) (pkgconfigDepends bi) -- unconditional pkg-config dependencies
++ concatMap (convBranch flags dr pkg os arch cinfo pn fds comp getInfo ipns solveExes) branches
++ concatMap (convBranch flags dr pkg os arch cinfo pn fds comp getInfo solveExes) branches
-- build-tools dependencies
-- NB: Only include these dependencies if SolveExecutables
-- is True. It might be false in the legacy solver
......@@ -481,14 +460,13 @@ convBranch :: Map FlagName Bool
-> FlagInfo
-> Component
-> (a -> BuildInfo)
-> IPNs
-> SolveExecutables
-> CondBranch ConfVar [Dependency] a
-> FlaggedDeps PN
convBranch flags dr pkg os arch cinfo pn fds comp getInfo ipns solveExes (CondBranch c' t' mf') =
convBranch flags dr pkg os arch cinfo pn fds comp getInfo solveExes (CondBranch c' t' mf') =
go c'
(\flags' dr' -> convCondTree flags' dr' pkg os arch cinfo pn fds comp getInfo ipns solveExes t')
(\flags' dr' -> maybe [] (convCondTree flags' dr' pkg os arch cinfo pn fds comp getInfo ipns solveExes) mf')
(\flags' dr' -> convCondTree flags' dr' pkg os arch cinfo pn fds comp getInfo solveExes t')
(\flags' dr' -> maybe [] (convCondTree flags' dr' pkg os arch cinfo pn fds comp getInfo solveExes) mf')
flags dr
where
go :: Condition ConfVar
......
......@@ -225,7 +225,6 @@ executable cabal
Distribution.Client.NixStyleOptions
Distribution.Client.Outdated
Distribution.Client.PackageHash
Distribution.Client.PackageUtils
Distribution.Client.ParseUtils
Distribution.Client.ProjectBuilding
Distribution.Client.ProjectBuilding.Types
......
......@@ -217,7 +217,6 @@ library cabal-lib-client
Distribution.Client.NixStyleOptions
Distribution.Client.Outdated
Distribution.Client.PackageHash
Distribution.Client.PackageUtils
Distribution.Client.ParseUtils
Distribution.Client.ProjectBuilding
Distribution.Client.ProjectBuilding.Types
......
......@@ -225,7 +225,6 @@ executable cabal
Distribution.Client.NixStyleOptions
Distribution.Client.Outdated
Distribution.Client.PackageHash
Distribution.Client.PackageUtils
Distribution.Client.ParseUtils
Distribution.Client.ProjectBuilding
Distribution.Client.ProjectBuilding.Types
......
......@@ -161,7 +161,6 @@ Version: 3.3.0.0
Distribution.Client.NixStyleOptions
Distribution.Client.Outdated
Distribution.Client.PackageHash
Distribution.Client.PackageUtils
Distribution.Client.ParseUtils
Distribution.Client.ProjectBuilding
Distribution.Client.ProjectBuilding.Types
......
# cabal v2-run
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- pkg-def-0.1.0.0 (lib) (first run)
- pkg-abc-0.1.0.0 (exe:program) (first run)
Warning: pkg-def.cabal:13:27: visibility is experimental feature (issue #5660)
Configuring library for pkg-def-0.1.0.0..
Preprocessing library for pkg-def-0.1.0.0..
Building library for pkg-def-0.1.0.0..
Warning: pkg-abc.cabal:19:15: colon specifier is experimental feature (issue #5660)
Configuring executable 'program' for pkg-abc-0.1.0.0..
Warning: The package has an extraneous version range for a dependency on an internal library: pkg-def >=0 && ==0.1.0.0. This version range includes the current package but isn't needed as the current package's library will always be used.
Preprocessing executable 'program' for pkg-abc-0.1.0.0..
Building executable 'program' for pkg-abc-0.1.0.0..
import Test.Cabal.Prelude
-- https://github.com/haskell/cabal/issues/6083
-- see pkg-abc.cabal
main = cabalTest $
cabal' "v2-run" ["pkg-abc:program"] >>= assertOutputContains "pkg-def:pkg-def"
module Main (main) where
import PkgDef (defValue)
main :: IO ()
main = print defValue
cabal-version: 3.4
name: pkg-abc
version: 0.1.0.0
library pkg-def
default-language: Haskell2010
hs-source-dirs: pkg-def
build-depends: base
exposed-modules: PkgDef
executable program
default-language: Haskell2010
hs-source-dirs: exe
main-is: Main.hs
-- we want that to resolve to pkg-def main library.
build-depends:
, base
, pkg-def:pkg-def
module PkgDef (defValue) where
defValue :: String
defValue = "pkg-abc:pkg-def"
cabal-version: 3.0
name: pkg-def
version: 0.1.0.0
library
default-language: Haskell2010
hs-source-dirs: src
build-depends: base
exposed-modules: PkgDef
library publib
default-language: Haskell2010
visibility: public
hs-source-dirs: publib
build-depends: base
exposed-modules: PkgDef
module PkgDef (defValue) where
defValue :: String
defValue = "pkg-def:publib"
module PkgDef (defValue) where
defValue :: String
defValue = "pkg-def:pkg-def"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment