Skip to content

[GSoC2018] [FREEZED on 2018-08-14] Add support for multiple public libraries in a single package #5528

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

Closed
wants to merge 22 commits into from
Closed
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
2 changes: 2 additions & 0 deletions Cabal/Cabal.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ library
Distribution.Types.ModuleReexport
Distribution.Types.ModuleRenaming
Distribution.Types.ComponentName
Distribution.Types.LibraryName
Distribution.Types.MungedPackageName
Distribution.Types.PackageName
Distribution.Types.PkgconfigName
Expand All @@ -367,6 +368,7 @@ library
Distribution.Types.Version
Distribution.Types.VersionRange
Distribution.Types.VersionInterval
Distribution.Types.GivenComponent
Distribution.Utils.Generic
Distribution.Utils.NubList
Distribution.Utils.ShortText
Expand Down
7 changes: 4 additions & 3 deletions Cabal/Distribution/Backpack/ComponentsGraph.hs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ mkComponentsGraph enabled pkg_descr =
componentDeps component =
(CExeName <$> getAllInternalToolDependencies pkg_descr bi)

--TODO check this
++ [ if pkgname == packageName pkg_descr
then CLibName
else CSubLibName toolname
| Dependency pkgname _ <- targetBuildDepends bi
then CLibName LMainLibName
else CLibName (LSubLibName toolname)
| Dependency pkgname _ _ <- targetBuildDepends bi
, let toolname = packageNameToUnqualComponentName pkgname
, toolname `elem` internalPkgDeps ]
where
Expand Down
40 changes: 33 additions & 7 deletions Cabal/Distribution/Backpack/ConfiguredComponent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import Distribution.Types.PackageId
import Distribution.Types.PackageName
import Distribution.Types.Mixin
import Distribution.Types.ComponentName
import Distribution.Types.LibraryName
import Distribution.Types.UnqualComponentName
import Distribution.Types.ComponentInclude
import Distribution.Package
Expand Down Expand Up @@ -150,7 +151,7 @@ mkConfiguredComponent pkg_descr this_cid lib_deps exe_deps component = do
bi = componentBuildInfo component
deps_map = Map.fromList [ ((packageName dep, ann_cname dep), dep)
| dep <- lib_deps ]
is_public = componentName component == CLibName
is_public = componentName component == CLibName LMainLibName

type ConfiguredComponentMap =
Map PackageName (Map ComponentName (AnnotatedId ComponentId))
Expand All @@ -165,16 +166,41 @@ toConfiguredComponent
toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do
lib_deps <-
if newPackageDepsBehaviour pkg_descr
then forM (targetBuildDepends bi) $ \(Dependency name _) -> do
then fmap concat $ forM (targetBuildDepends bi) $ \(Dependency name _ sublibs) -> do
let (pn, cn) = fixFakePkgName pkg_descr name
value <- case Map.lookup cn =<< Map.lookup pn lib_dep_map of
pkg <- case Map.lookup pn lib_dep_map of
Nothing ->
dieProgress $
text "Dependency on unbuildable" <+>
text "package" <+> disp pn
Just p -> return p
mainLibraryComponent <-
if sublibs /= Set.singleton LMainLibName
then pure Nothing
-- No sublibraries were specified, so we may be in the
-- legacy case where the package name is used as library
-- name
else Just <$>
case Map.lookup cn pkg of
Nothing ->
dieProgress $
text "Dependency on unbuildable (i.e. 'buildable: False')" <+>
text (showComponentName cn) <+>
text "from" <+> disp pn
Just v -> return v
return value
subLibrariesComponents <- forM (Set.toList sublibs) $ \lib ->
let comp = CLibName lib in
case Map.lookup (CLibName $ LSubLibName $ packageNameToUnqualComponentName name) pkg
<|> Map.lookup comp pkg
of
Nothing ->
dieProgress $
text "Dependency on unbuildable" <+>
text (showLibraryName lib) <+>
text "from" <+> disp pn
<+> text "available:" <+> text (show pkg)
Just v -> return v
return (maybeToList mainLibraryComponent ++ subLibrariesComponents)
else return old_style_lib_deps
mkConfiguredComponent
pkg_descr this_cid
Expand All @@ -192,7 +218,7 @@ toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do
| (pn, comp_map) <- Map.toList lib_dep_map
, pn /= packageName pkg_descr
, (cn, e) <- Map.toList comp_map
, cn == CLibName ]
, cn == CLibName LMainLibName ]
-- We have to nub here, because 'getAllToolDependencies' may return
-- duplicates (see #4986). (NB: This is not needed for lib_deps,
-- since those elaborate into includes, for which there explicitly
Expand Down Expand Up @@ -296,8 +322,8 @@ newPackageDepsBehaviour pkg =
fixFakePkgName :: PackageDescription -> PackageName -> (PackageName, ComponentName)
fixFakePkgName pkg_descr pn =
if subLibName `elem` internalLibraries
then (packageName pkg_descr, CSubLibName subLibName)
else (pn, CLibName)
then (packageName pkg_descr, CLibName (LSubLibName subLibName))
else (pn, CLibName LMainLibName )
where
subLibName = packageNameToUnqualComponentName pn
internalLibraries = mapMaybe libName (allLibraries pkg_descr)
5 changes: 3 additions & 2 deletions Cabal/Distribution/Backpack/ModuleScope.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Distribution.ModuleName
import Distribution.Types.IncludeRenaming
import Distribution.Types.PackageName
import Distribution.Types.ComponentName
import Distribution.Types.LibraryName

import Distribution.Backpack
import Distribution.Backpack.ModSubst
Expand Down Expand Up @@ -113,8 +114,8 @@ dispComponent pn cn =
-- should be clear enough. To do source syntax, we'd
-- need to know what the package we're linking is.
case cn of
CLibName -> disp pn
CSubLibName ucn -> disp pn <<>> colon <<>> disp ucn
CLibName LMainLibName -> disp pn
CLibName (LSubLibName ucn) -> disp pn <<>> colon <<>> disp ucn
-- Case below shouldn't happen
_ -> disp pn <+> parens (disp cn)

Expand Down
5 changes: 3 additions & 2 deletions Cabal/Distribution/Backpack/ReadyComponent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Distribution.Types.Component
import Distribution.Types.ComponentInclude
import Distribution.Types.ComponentId
import Distribution.Types.ComponentName
import Distribution.Types.LibraryName
import Distribution.Types.PackageId
import Distribution.Types.UnitId
import Distribution.Compat.Graph (IsNode(..))
Expand Down Expand Up @@ -139,8 +140,8 @@ rc_depends rc = ordNub $
computeCompatPackageId
(ci_pkgid ci)
(case ci_cname ci of
CLibName -> Nothing
CSubLibName uqn -> Just uqn
CLibName LMainLibName -> Nothing
CLibName (LSubLibName uqn) -> Just uqn
_ -> error $ display (rc_cid rc) ++
" depends on non-library " ++ display (ci_id ci))

Expand Down
4 changes: 2 additions & 2 deletions Cabal/Distribution/Backpack/UnifyM.hs
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ ci_msg ci
pn = pkgName (ci_pkgid ci)
pp_pn =
case ci_cname ci of
CLibName -> disp pn
CSubLibName cn -> disp pn <<>> colon <<>> disp cn
CLibName LMainLibName -> disp pn
CLibName (LSubLibName cn) -> disp pn <<>> colon <<>> disp cn
-- Shouldn't happen
cn -> disp pn <+> parens (disp cn)

Expand Down
5 changes: 3 additions & 2 deletions Cabal/Distribution/InstalledPackageInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import Distribution.ModuleName
import Distribution.Package hiding (installedPackageId, installedUnitId)
import Distribution.ParseUtils
import Distribution.Types.ComponentName
import Distribution.Types.LibraryName
import Distribution.Utils.Generic (toUTF8BS)

import qualified Data.Map as Map
Expand Down Expand Up @@ -104,8 +105,8 @@ installedPackageId = installedUnitId
sourceComponentName :: InstalledPackageInfo -> ComponentName
sourceComponentName ipi =
case sourceLibName ipi of
Nothing -> CLibName
Just qn -> CSubLibName qn
Nothing -> CLibName LMainLibName
Just qn -> CLibName $ LSubLibName qn

-- -----------------------------------------------------------------------------
-- Parsing
Expand Down
2 changes: 2 additions & 0 deletions Cabal/Distribution/PackageDescription.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ module Distribution.PackageDescription (
allBuildDepends,
enabledBuildDepends,
ComponentName(..),
LibraryName(..),
defaultLibName,
HookedBuildInfo,
emptyHookedBuildInfo,
Expand Down Expand Up @@ -135,5 +136,6 @@ import Distribution.Types.CondTree
import Distribution.Types.Condition
import Distribution.Types.PackageDescription
import Distribution.Types.ComponentName
import Distribution.Types.LibraryName
import Distribution.Types.HookedBuildInfo
import Distribution.Types.SourceRepo
36 changes: 18 additions & 18 deletions Cabal/Distribution/PackageDescription/Check.hs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ checkFields pkg =
, name `elem` map display knownLanguages ]

testedWithImpossibleRanges =
[ Dependency (mkPackageName (display compiler)) vr
[ Dependency (mkPackageName (display compiler)) vr Set.empty
| (compiler, vr) <- testedWith pkg
, isNoVersion vr ]

Expand All @@ -598,7 +598,7 @@ checkFields pkg =
internalLibDeps =
[ dep
| bi <- allBuildInfo pkg
, dep@(Dependency name _) <- targetBuildDepends bi
, dep@(Dependency name _ _) <- targetBuildDepends bi
, name `elem` internalLibraries
]

Expand All @@ -611,14 +611,14 @@ checkFields pkg =

depInternalLibraryWithExtraVersion =
[ dep
| dep@(Dependency _ versionRange) <- internalLibDeps
| dep@(Dependency _ versionRange _) <- internalLibDeps
, not $ isAnyVersion versionRange
, packageVersion pkg `withinRange` versionRange
]

depInternalLibraryWithImpossibleVersion =
[ dep
| dep@(Dependency _ versionRange) <- internalLibDeps
| dep@(Dependency _ versionRange _) <- internalLibDeps
, not $ packageVersion pkg `withinRange` versionRange
]

Expand Down Expand Up @@ -1243,8 +1243,8 @@ checkCabalVersion pkg =
++ ". To use this new syntax the package need to specify at least "
++ "'cabal-version: >= 1.6'. Alternatively, if broader compatibility "
++ "is important then use: " ++ commaSep
[ display (Dependency name (eliminateWildcardSyntax versionRange))
| Dependency name versionRange <- depsUsingWildcardSyntax ]
[ display (Dependency name (eliminateWildcardSyntax versionRange) Set.empty)
| Dependency name versionRange _ <- depsUsingWildcardSyntax ]

-- check use of "build-depends: foo ^>= 1.2.3" syntax
, checkVersion [2,0] (not (null depsUsingMajorBoundSyntax)) $
Expand All @@ -1255,8 +1255,8 @@ checkCabalVersion pkg =
++ ". To use this new syntax the package need to specify at least "
++ "'cabal-version: 2.0'. Alternatively, if broader compatibility "
++ "is important then use: " ++ commaSep
[ display (Dependency name (eliminateMajorBoundSyntax versionRange))
| Dependency name versionRange <- depsUsingMajorBoundSyntax ]
[ display (Dependency name (eliminateMajorBoundSyntax versionRange) Set.empty)
| Dependency name versionRange _ <- depsUsingMajorBoundSyntax ]

, checkVersion [2,1] (any (not . null)
(concatMap buildInfoField
Expand Down Expand Up @@ -1292,8 +1292,8 @@ checkCabalVersion pkg =
++ ". To use this new syntax the package need to specify at least "
++ "'cabal-version: >= 1.6'. Alternatively, if broader compatibility "
++ "is important then use: " ++ commaSep
[ display (Dependency name (eliminateWildcardSyntax versionRange))
| Dependency name versionRange <- testedWithUsingWildcardSyntax ]
[ display (Dependency name (eliminateWildcardSyntax versionRange) Set.empty)
| Dependency name versionRange _ <- testedWithUsingWildcardSyntax ]

-- check use of "source-repository" section
, checkVersion [1,6] (not (null (sourceRepos pkg))) $
Expand Down Expand Up @@ -1367,11 +1367,11 @@ checkCabalVersion pkg =
buildInfoField field = map field (allBuildInfo pkg)

versionRangeExpressions =
[ dep | dep@(Dependency _ vr) <- allBuildDepends pkg
[ dep | dep@(Dependency _ vr _) <- allBuildDepends pkg
, usesNewVersionRangeSyntax vr ]

testedWithVersionRangeExpressions =
[ Dependency (mkPackageName (display compiler)) vr
[ Dependency (mkPackageName (display compiler)) vr Set.empty
| (compiler, vr) <- testedWith pkg
, usesNewVersionRangeSyntax vr ]

Expand All @@ -1395,16 +1395,16 @@ checkCabalVersion pkg =
alg (VersionRangeParensF _) = 3
alg _ = 1 :: Int

depsUsingWildcardSyntax = [ dep | dep@(Dependency _ vr) <- allBuildDepends pkg
depsUsingWildcardSyntax = [ dep | dep@(Dependency _ vr _) <- allBuildDepends pkg
, usesWildcardSyntax vr ]

depsUsingMajorBoundSyntax = [ dep | dep@(Dependency _ vr) <- allBuildDepends pkg
depsUsingMajorBoundSyntax = [ dep | dep@(Dependency _ vr _) <- allBuildDepends pkg
, usesMajorBoundSyntax vr ]

usesBackpackIncludes = any (not . null . mixins) (allBuildInfo pkg)

testedWithUsingWildcardSyntax =
[ Dependency (mkPackageName (display compiler)) vr
[ Dependency (mkPackageName (display compiler)) vr Set.empty
| (compiler, vr) <- testedWith pkg
, usesWildcardSyntax vr ]

Expand Down Expand Up @@ -1493,8 +1493,8 @@ checkCabalVersion pkg =
allModuleNamesAutogen = concatMap autogenModules (allBuildInfo pkg)

displayRawDependency :: Dependency -> String
displayRawDependency (Dependency pkg vr) =
display pkg ++ " " ++ display vr
displayRawDependency (Dependency pkg vr cs) =
display pkg ++ " " ++ display vr ++ " " ++ (unwords . fmap display . Set.toList $ cs) --MAYBE maybe drop cs entirely


-- ------------------------------------------------------------
Expand Down Expand Up @@ -1545,7 +1545,7 @@ checkPackageVersions pkg =
foldr intersectVersionRanges anyVersion baseDeps
where
baseDeps =
[ vr | Dependency pname vr <- allBuildDepends pkg'
[ vr | Dependency pname vr _ <- allBuildDepends pkg'
, pname == mkPackageName "base" ]

-- Just in case finalizePD fails for any reason,
Expand Down
24 changes: 18 additions & 6 deletions Cabal/Distribution/PackageDescription/Configuration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ import Distribution.Types.DependencyMap

import qualified Data.Map.Strict as Map.Strict
import qualified Data.Map.Lazy as Map
import Data.Set ( Set )
import qualified Data.Set as Set
import Data.Tree ( Tree(Node) )

------------------------------------------------------------------------------
Expand Down Expand Up @@ -229,7 +231,7 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps =
mp (Left xs) (Left ys) =
let union = Map.foldrWithKey (Map.Strict.insertWith combine)
(unDepMapUnion xs) (unDepMapUnion ys)
combine x y = simplifyVersionRange $ unionVersionRanges x y
combine x y = (\(vr, cs) -> (simplifyVersionRange vr,cs)) $ unionVersionRangesAndIntersectionLibraries x y
in union `seq` Left (DepMapUnion union)

-- `mzero'
Expand Down Expand Up @@ -307,14 +309,22 @@ extractConditions f gpkg =


-- | A map of dependencies that combines version ranges using 'unionVersionRanges'.
newtype DepMapUnion = DepMapUnion { unDepMapUnion :: Map PackageName VersionRange }
newtype DepMapUnion = DepMapUnion { unDepMapUnion :: Map PackageName (VersionRange, Set LibraryName) }

-- TODO is this right? an union of versions should correspond to an intersection
-- of the components, but I'll have to check how this module actually works
unionVersionRangesAndIntersectionLibraries :: (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
unionVersionRangesAndIntersectionLibraries (vra, csa) (vrb, csb) =
(unionVersionRanges vra vrb, Set.intersection csa csb)

toDepMapUnion :: [Dependency] -> DepMapUnion
toDepMapUnion ds =
DepMapUnion $ Map.fromListWith unionVersionRanges [ (p,vr) | Dependency p vr <- ds ]
DepMapUnion $ Map.fromListWith unionVersionRangesAndIntersectionLibraries [ (p,(vr,cs)) | Dependency p vr cs <- ds ]

fromDepMapUnion :: DepMapUnion -> [Dependency]
fromDepMapUnion m = [ Dependency p vr | (p,vr) <- Map.toList (unDepMapUnion m) ]
fromDepMapUnion m = [ Dependency p vr cs | (p,(vr,cs)) <- Map.toList (unDepMapUnion m) ]

freeVars :: CondTree ConfVar c a -> [FlagName]
freeVars t = [ f | Flag f <- freeVars' t ]
Expand Down Expand Up @@ -344,12 +354,14 @@ overallDependencies enabled (TargetSet targets) = mconcat depss
-- UGH. The embedded componentName in the 'Component's here is
-- BLANK. I don't know whose fault this is but I'll use the tag
-- instead. -- ezyang
removeDisabledSections (Lib _) = componentNameRequested enabled CLibName
removeDisabledSections (Lib _) = componentNameRequested
enabled
(CLibName LMainLibName)
removeDisabledSections (SubComp t c)
-- Do NOT use componentName
= componentNameRequested enabled
$ case c of
CLib _ -> CSubLibName t
CLib _ -> CLibName (LSubLibName t)
CFLib _ -> CFLibName t
CExe _ -> CExeName t
CTest _ -> CTestName t
Expand Down
2 changes: 1 addition & 1 deletion Cabal/Distribution/Simple/Build.hs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ testSuiteLibV09AsLibAndExe pkg_descr
, componentInternalDeps = componentInternalDeps clbi
, componentIsIndefinite_ = False
, componentExeDeps = componentExeDeps clbi
, componentLocalName = CSubLibName (testName test)
, componentLocalName = CLibName $ LSubLibName $ testName test
, componentIsPublic = False
, componentIncludes = componentIncludes clbi
, componentUnitId = componentUnitId clbi
Expand Down
Loading