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

[GSoC2018] Add support for multiple public libraries in a single package #5526

Merged
merged 14 commits into from
Nov 4, 2018
Merged
3 changes: 3 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,8 @@ library
Distribution.Types.Version
Distribution.Types.VersionRange
Distribution.Types.VersionInterval
Distribution.Types.GivenComponent
Distribution.Types.PackageVersionConstraint
Distribution.Utils.Generic
Distribution.Utils.NubList
Distribution.Utils.ShortText
Expand Down
6 changes: 3 additions & 3 deletions Cabal/Distribution/Backpack/ComponentsGraph.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ mkComponentsGraph enabled pkg_descr =
(CExeName <$> getAllInternalToolDependencies pkg_descr bi)

++ [ 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
39 changes: 27 additions & 12 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,28 @@ 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
let (pn, cn) = fixFakePkgName pkg_descr name
value <- case Map.lookup cn =<< Map.lookup pn lib_dep_map of
then fmap concat $ forM (targetBuildDepends bi) $ \(Dependency name _ sublibs) -> do
-- The package name still needs fixing in case of legacy
-- sublibrary dependency syntax
let (pn, _) = fixFakePkgName pkg_descr name
pkg <- case Map.lookup pn lib_dep_map of
Nothing ->
dieProgress $
text "Dependency on unbuildable (i.e. 'buildable: False')" <+>
text (showComponentName cn) <+>
text "from" <+> disp pn
Just v -> return v
return value
text "Dependency on unbuildable" <+>
text "package" <+> disp pn
Just p -> return p
-- Return all library components
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
Just v -> return v
else return old_style_lib_deps
mkConfiguredComponent
pkg_descr this_cid
Expand All @@ -192,7 +205,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 @@ -293,11 +306,13 @@ newPackageDepsBehaviour pkg =
-- and internal libraries are specified the same. For now, we assume internal
-- libraries shadow, and this function disambiguates accordingly, but soon the
-- underlying ambiguity will be addressed.
-- Multiple public libraries (cabal 3.0) added an unambiguous way of specifying
-- sublibraries, but we still have to support the old syntax for bc reasons.
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
14 changes: 13 additions & 1 deletion Cabal/Distribution/CabalSpecVersion.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ data CabalSpecVersion
| CabalSpecV2_0
| CabalSpecV2_2
| CabalSpecV2_4
| CabalSpecV3_0
deriving (Eq, Ord, Show, Read, Enum, Bounded, Typeable, Data, Generic)

cabalSpecLatest :: CabalSpecVersion
cabalSpecLatest = CabalSpecV2_4
cabalSpecLatest = CabalSpecV3_0

cabalSpecFeatures :: CabalSpecVersion -> Set.Set CabalFeature
cabalSpecFeatures CabalSpecOld = Set.empty
Expand All @@ -36,6 +37,12 @@ cabalSpecFeatures CabalSpecV2_4 = Set.fromList
, CommonStanzas
, Globstar
]
cabalSpecFeatures CabalSpecV3_0 = Set.fromList
[ Elif
, CommonStanzas
, Globstar
, MultipleLibraries
]

cabalSpecSupports :: CabalSpecVersion -> [Int] -> Bool
cabalSpecSupports CabalSpecOld v = v < [1,21]
Expand All @@ -44,15 +51,18 @@ cabalSpecSupports CabalSpecV1_24 v = v < [1,25]
cabalSpecSupports CabalSpecV2_0 v = v < [2,1]
cabalSpecSupports CabalSpecV2_2 v = v < [2,3]
cabalSpecSupports CabalSpecV2_4 _ = True
cabalSpecSupports CabalSpecV3_0 _ = True

specHasCommonStanzas :: CabalSpecVersion -> HasCommonStanzas
specHasCommonStanzas CabalSpecV2_2 = HasCommonStanzas
specHasCommonStanzas CabalSpecV2_4 = HasCommonStanzas
specHasCommonStanzas CabalSpecV3_0 = HasCommonStanzas
specHasCommonStanzas _ = NoCommonStanzas

specHasElif :: CabalSpecVersion -> HasElif
specHasElif CabalSpecV2_2 = HasElif
specHasElif CabalSpecV2_4 = HasElif
specHasElif CabalSpecV3_0 = HasElif
specHasElif _ = NoElif

-------------------------------------------------------------------------------
Expand All @@ -65,6 +75,8 @@ data CabalFeature
| Globstar
-- ^ Implemented in #5284. Not actually a change to the parser,
-- as filename patterns are opaque to it currently.
| MultipleLibraries
-- ^ Multiple public libraries in a package. Implemented in #5526.
deriving (Eq, Ord, Show, Read, Enum, Bounded, Typeable, Data, Generic)

-------------------------------------------------------------------------------
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
34 changes: 17 additions & 17 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,7 +1493,7 @@ checkCabalVersion pkg =
allModuleNamesAutogen = concatMap autogenModules (allBuildInfo pkg)

displayRawDependency :: Dependency -> String
displayRawDependency (Dependency pkg vr) =
displayRawDependency (Dependency pkg vr _sublibs) =
display pkg ++ " " ++ display vr


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
Loading