Skip to content

Commit 9756b4c

Browse files
authored
Merge pull request #5848 from fgaz/prevent-dep-on-private-lib
Prevent dependency on private library
2 parents 7a02cda + 3e31042 commit 9756b4c

File tree

20 files changed

+128
-27
lines changed

20 files changed

+128
-27
lines changed

Cabal/Distribution/Simple/Configure.hs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ import Distribution.Types.PkgconfigDependency
8383
import Distribution.Types.PkgconfigVersionRange
8484
import Distribution.Types.LocalBuildInfo
8585
import Distribution.Types.LibraryName
86+
import Distribution.Types.LibraryVisibility
8687
import Distribution.Types.ComponentRequestedSpec
8788
import Distribution.Types.ForeignLib
8889
import Distribution.Types.ForeignLibType
@@ -476,6 +477,7 @@ configure (pkg_descr0, pbi) cfg = do
476477
(dependencySatisfiable
477478
use_external_internal_deps
478479
(fromFlagOrDefault False (configExactConfiguration cfg))
480+
(fromFlagOrDefault False (configAllowDependingOnPrivateLibs cfg))
479481
(packageName pkg_descr0)
480482
installedPackageSet
481483
internalPackageSet
@@ -881,6 +883,7 @@ getInternalPackages pkg_descr0 =
881883
dependencySatisfiable
882884
:: Bool -- ^ use external internal deps?
883885
-> Bool -- ^ exact configuration?
886+
-> Bool -- ^ allow depending on private libs?
884887
-> PackageName
885888
-> InstalledPackageIndex -- ^ installed set
886889
-> Map PackageName (Maybe UnqualComponentName) -- ^ internal set
@@ -889,7 +892,9 @@ dependencySatisfiable
889892
-> (Dependency -> Bool)
890893
dependencySatisfiable
891894
use_external_internal_deps
892-
exact_config pn installedPackageSet internalPackageSet requiredDepsMap
895+
exact_config
896+
allow_private_deps
897+
pn installedPackageSet internalPackageSet requiredDepsMap
893898
(Dependency depName vr sublibs)
894899

895900
| exact_config
@@ -913,12 +918,7 @@ dependencySatisfiable
913918
packageNameToUnqualComponentName depName)
914919
requiredDepsMap)
915920

916-
|| all
917-
(\lib ->
918-
(depName, CLibName lib)
919-
`Map.member`
920-
requiredDepsMap)
921-
sublibs
921+
|| all visible sublibs
922922

923923
| isInternalDep
924924
= if use_external_internal_deps
@@ -949,6 +949,23 @@ dependencySatisfiable
949949
-- Reinterpret the "package name" as an unqualified component
950950
-- name
951951
= LSubLibName $ packageNameToUnqualComponentName depName
952+
-- Check whether a libray exists and is visible.
953+
-- We don't disambiguate between dependency on non-existent or private
954+
-- library yet, so we just return a bool and later report a generic error.
955+
visible lib = maybe
956+
False -- Does not even exist (wasn't in the depsMap)
957+
(\ipi -> Installed.libVisibility ipi == LibraryVisibilityPublic
958+
-- If the override is enabled, the visibility does
959+
-- not matter (it's handled externally)
960+
|| allow_private_deps
961+
-- If it's a library of the same package then it's
962+
-- always visible.
963+
-- This is only triggered when passing a component
964+
-- of the same package as --dependency, such as in:
965+
-- cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit.test.hs
966+
|| pkgName (Installed.sourcePackageId ipi) == pn)
967+
maybeIPI
968+
where maybeIPI = Map.lookup (depName, CLibName lib) requiredDepsMap
952969

953970
-- | Finalize a generic package description. The workhorse is
954971
-- 'finalizePD' but there's a bit of other nattering
@@ -981,7 +998,7 @@ configureFinalizedPackage verbosity cfg enabled
981998
pkg_descr0
982999
of Right r -> return r
9831000
Left missing ->
984-
die' verbosity $ "Encountered missing dependencies:\n"
1001+
die' verbosity $ "Encountered missing or private dependencies:\n"
9851002
++ (render . nest 4 . sep . punctuate comma
9861003
. map (pretty . simplifyDependency)
9871004
$ missing)

Cabal/Distribution/Simple/Setup.hs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,13 @@ data ConfigFlags = ConfigFlags {
274274
-- ^Halt and show an error message indicating an error in flag assignment
275275
configRelocatable :: Flag Bool, -- ^ Enable relocatable package built
276276
configDebugInfo :: Flag DebugInfoLevel, -- ^ Emit debug info.
277-
configUseResponseFiles :: Flag Bool
277+
configUseResponseFiles :: Flag Bool,
278278
-- ^ Whether to use response files at all. They're used for such tools
279279
-- as haddock, or or ld.
280+
configAllowDependingOnPrivateLibs :: Flag Bool
281+
-- ^ Allow depending on private sublibraries. This is used by external
282+
-- tools (like cabal-install) so they can add multiple-public-libraries
283+
-- compatibility to older ghcs by checking visibility externally.
280284
}
281285
deriving (Generic, Read, Show)
282286

@@ -704,6 +708,13 @@ configureOptions showOrParseArgs =
704708
configUseResponseFiles
705709
(\v flags -> flags { configUseResponseFiles = v })
706710
(boolOpt' ([], ["disable-response-files"]) ([], []))
711+
712+
,option "" ["allow-depending-on-private-libs"]
713+
( "Allow depending on private libraries. "
714+
++ "If set, the library visibility check MUST be done externally." )
715+
configAllowDependingOnPrivateLibs
716+
(\v flags -> flags { configAllowDependingOnPrivateLibs = v })
717+
trueArg
707718
]
708719
where
709720
liftInstallDirs =

Cabal/Distribution/Types/InstalledPackageInfo.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ data InstalledPackageInfo
4141
sourcePackageId :: PackageId,
4242
sourceLibName :: LibraryName,
4343
installedComponentId_ :: ComponentId,
44+
libVisibility :: LibraryVisibility,
4445
installedUnitId :: UnitId,
4546
-- INVARIANT: if this package is definite, OpenModule's
4647
-- OpenUnitId directly records UnitId. If it is
@@ -87,8 +88,7 @@ data InstalledPackageInfo
8788
frameworks :: [String],
8889
haddockInterfaces :: [FilePath],
8990
haddockHTMLs :: [FilePath],
90-
pkgRoot :: Maybe FilePath,
91-
libVisibility :: LibraryVisibility
91+
pkgRoot :: Maybe FilePath
9292
}
9393
deriving (Eq, Generic, Typeable, Read, Show)
9494

Cabal/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ ipiFieldGrammar = mkInstalledPackageInfo
6060
<$> monoidalFieldAla "hugs-options" (alaList' FSep Token) unitedList
6161
--- https://github.com/haskell/cabal/commit/40f3601e17024f07e0da8e64d3dd390177ce908b
6262
^^^ deprecatedSince CabalSpecV1_22 "hugs isn't supported anymore"
63-
-- Very basic fields: name, version, package-name and lib-name
63+
-- Very basic fields: name, version, package-name, lib-name and visibility
6464
<+> blurFieldGrammar basic basicFieldGrammar
6565
-- Basic fields
6666
<+> optionalFieldDef "id" L.installedUnitId (mkUnitId "")
@@ -102,14 +102,14 @@ ipiFieldGrammar = mkInstalledPackageInfo
102102
<+> monoidalFieldAla "haddock-interfaces" (alaList' FSep FilePathNT) L.haddockInterfaces
103103
<+> monoidalFieldAla "haddock-html" (alaList' FSep FilePathNT) L.haddockHTMLs
104104
<+> optionalFieldAla "pkgroot" FilePathNT L.pkgRoot
105-
<+> optionalFieldDef "visibility" L.libVisibility LibraryVisibilityPrivate
106105
where
107106
mkInstalledPackageInfo _ Basic {..} = InstalledPackageInfo
108107
-- _basicPkgName is not used
109108
-- setMaybePackageId says it can be no-op.
110109
(PackageIdentifier pn _basicVersion)
111110
(combineLibraryName ln _basicLibName)
112111
(mkComponentId "") -- installedComponentId_, not in use
112+
_basicLibVisibility
113113
where
114114
MungedPackageName pn ln = _basicName
115115
{-# SPECIALIZE ipiFieldGrammar :: FieldDescrs InstalledPackageInfo InstalledPackageInfo #-}
@@ -223,10 +223,11 @@ instance Pretty SpecLicenseLenient where
223223
-- in serialised textual representation
224224
-- to the actual 'InstalledPackageInfo' fields.
225225
data Basic = Basic
226-
{ _basicName :: MungedPackageName
227-
, _basicVersion :: Version
228-
, _basicPkgName :: Maybe PackageName
229-
, _basicLibName :: LibraryName
226+
{ _basicName :: MungedPackageName
227+
, _basicVersion :: Version
228+
, _basicPkgName :: Maybe PackageName
229+
, _basicLibName :: LibraryName
230+
, _basicLibVisibility :: LibraryVisibility
230231
}
231232

232233
basic :: Lens' InstalledPackageInfo Basic
@@ -237,12 +238,14 @@ basic f ipi = g <$> f b
237238
(packageVersion ipi)
238239
(maybePackageName ipi)
239240
(sourceLibName ipi)
241+
(libVisibility ipi)
240242

241-
g (Basic n v pn ln) = ipi
243+
g (Basic n v pn ln lv) = ipi
242244
& setMungedPackageName n
243245
& L.sourcePackageId . L.pkgVersion .~ v
244246
& setMaybePackageName pn
245247
& L.sourceLibName .~ ln
248+
& L.libVisibility .~ lv
246249

247250
basicName :: Lens' Basic MungedPackageName
248251
basicName f b = (\x -> b { _basicName = x }) <$> f (_basicName b)
@@ -261,6 +264,11 @@ basicLibName f b = (\x -> b { _basicLibName = maybeToLibraryName x }) <$>
261264
f (libraryNameString (_basicLibName b))
262265
{-# INLINE basicLibName #-}
263266

267+
basicLibVisibility :: Lens' Basic LibraryVisibility
268+
basicLibVisibility f b = (\x -> b { _basicLibVisibility = x }) <$>
269+
f (_basicLibVisibility b)
270+
{-# INLINE basicLibVisibility #-}
271+
264272
basicFieldGrammar
265273
:: (FieldGrammar g, Applicative (g Basic))
266274
=> g Basic Basic
@@ -269,5 +277,21 @@ basicFieldGrammar = mkBasic
269277
<*> optionalFieldDefAla "version" MQuoted basicVersion nullVersion
270278
<*> optionalField "package-name" basicPkgName
271279
<*> optionalField "lib-name" basicLibName
280+
<+> optionalFieldDef "visibility" basicLibVisibility LibraryVisibilityPrivate
272281
where
273-
mkBasic n v pn ln = Basic n v pn (maybe LMainLibName LSubLibName ln)
282+
mkBasic n v pn ln lv = Basic n v pn ln' lv'
283+
where
284+
ln' = maybe LMainLibName LSubLibName ln
285+
-- Older GHCs (<8.8) always report installed libraries as private
286+
-- because their ghc-pkg builds with an older Cabal.
287+
-- So we always set LibraryVisibilityPublic for main (unnamed) libs.
288+
-- This can be removed once we stop supporting GHC<8.8, at the
289+
-- condition that we keep marking main libraries as public when
290+
-- registering them.
291+
lv' = if
292+
let MungedPackageName _ mln = n in
293+
-- We need to check both because on ghc<8.2 ln' will always
294+
-- be LMainLibName
295+
ln' == LMainLibName && mln == LMainLibName
296+
then LibraryVisibilityPublic
297+
else lv

Cabal/tests/ParserTests/ipi/internal-preprocessor-test.expr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ InstalledPackageInfo
2929
installedUnitId = `UnitId "internal-preprocessor-test-0.1.0.0"`,
3030
instantiatedWith = [],
3131
ldOptions = [],
32-
libVisibility = LibraryVisibilityPrivate,
32+
libVisibility = LibraryVisibilityPublic,
3333
libraryDirs = ["/home/ogre/Documents/other-haskell/cabal/cabal-testsuite/PackageTests/CustomPreProcess/setup.dist/work/dist/build",
3434
"/home/ogre/Documents/other-haskell/cabal/cabal-testsuite/PackageTests/CustomPreProcess/setup.dist/work/dist/build"],
3535
libraryDynDirs = [],

Cabal/tests/ParserTests/ipi/internal-preprocessor-test.format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: internal-preprocessor-test
22
version: 0.1.0.0
3+
visibility: public
34
id: internal-preprocessor-test-0.1.0.0
45
key: internal-preprocessor-test-0.1.0.0
56
license: GPL-3

Cabal/tests/ParserTests/ipi/issue-2276-ghc-9885.expr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2071,7 +2071,7 @@ InstalledPackageInfo
20712071
"-lm",
20722072
"-lm",
20732073
"-lm"],
2074-
libVisibility = LibraryVisibilityPrivate,
2074+
libVisibility = LibraryVisibilityPublic,
20752075
libraryDirs = ["/opt/ghc/8.2.2/lib/ghc-8.2.2/transformers-0.5.2.0"],
20762076
libraryDynDirs = ["/opt/ghc/8.2.2/lib/ghc-8.2.2/transformers-0.5.2.0"],
20772077
license = Right BSD3,

Cabal/tests/ParserTests/ipi/issue-2276-ghc-9885.format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: transformers
22
version: 0.5.2.0
3+
visibility: public
34
id: transformers-0.5.2.0
45
key: transformers-0.5.2.0
56
license: BSD3

Cabal/tests/ParserTests/ipi/transformers.expr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ InstalledPackageInfo
7171
installedUnitId = `UnitId "transformers-0.5.2.0"`,
7272
instantiatedWith = [],
7373
ldOptions = [],
74-
libVisibility = LibraryVisibilityPrivate,
74+
libVisibility = LibraryVisibilityPublic,
7575
libraryDirs = ["/opt/ghc/8.2.2/lib/ghc-8.2.2/transformers-0.5.2.0"],
7676
libraryDynDirs = ["/opt/ghc/8.2.2/lib/ghc-8.2.2/transformers-0.5.2.0"],
7777
license = Right BSD3,

Cabal/tests/ParserTests/ipi/transformers.format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: transformers
22
version: 0.5.2.0
3+
visibility: public
34
id: transformers-0.5.2.0
45
key: transformers-0.5.2.0
56
license: BSD3

cabal-install/Distribution/Client/Config.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,8 @@ instance Semigroup SavedConfig where
413413
configExactConfiguration = combine configExactConfiguration,
414414
configFlagError = combine configFlagError,
415415
configRelocatable = combine configRelocatable,
416-
configUseResponseFiles = combine configUseResponseFiles
416+
configUseResponseFiles = combine configUseResponseFiles,
417+
configAllowDependingOnPrivateLibs = combine configAllowDependingOnPrivateLibs
417418
}
418419
where
419420
combine = combine' savedConfigureFlags

cabal-install/Distribution/Client/ProjectConfig/Legacy.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,8 @@ convertToLegacyAllPackageConfig
687687
configFlagError = mempty, --TODO: ???
688688
configRelocatable = mempty,
689689
configDebugInfo = mempty,
690-
configUseResponseFiles = mempty
690+
configUseResponseFiles = mempty,
691+
configAllowDependingOnPrivateLibs = mempty
691692
}
692693

693694
haddockFlags = mempty {
@@ -757,7 +758,8 @@ convertToLegacyPerPackageConfig PackageConfig {..} =
757758
configFlagError = mempty, --TODO: ???
758759
configRelocatable = packageConfigRelocatable,
759760
configDebugInfo = packageConfigDebugInfo,
760-
configUseResponseFiles = mempty
761+
configUseResponseFiles = mempty,
762+
configAllowDependingOnPrivateLibs = mempty
761763
}
762764

763765
installFlags = mempty {

cabal-install/Distribution/Client/ProjectPlanning.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3390,6 +3390,9 @@ setupHsConfigureFlags (ReadyPackage elab@ElaboratedConfiguredPackage{..})
33903390
configUserInstall = mempty -- don't rely on defaults
33913391
configPrograms_ = mempty -- never use, shouldn't exist
33923392
configUseResponseFiles = mempty
3393+
-- TODO set to true when the solver can prevent private-library-deps by itself
3394+
-- (issue #6039)
3395+
configAllowDependingOnPrivateLibs = mempty
33933396

33943397
setupHsConfigureArgs :: ElaboratedConfiguredPackage
33953398
-> [String]

cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit-fail.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ Installing internal library sublib in <PATH>
99
Registering library 'sublib' for Lib-0.1.0.0..
1010
# Setup configure
1111
Configuring executable 'exe' for Lib-0.1.0.0..
12-
setup: Encountered missing dependencies:
12+
setup: Encountered missing or private dependencies:
1313
sublib -any

cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit.test.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ main = setupTest $ do
55
base_id <- getIPID "base"
66
setup_install ["sublib", "--cid", "sublib-0.1-abc"]
77
setup_install [ "exe", "--exact-configuration"
8-
, "--dependency", "sublib=sublib-0.1-abc"
8+
, "--dependency", "sublib:sublib=sublib-0.1-abc"
99
, "--dependency", "base=" ++ base_id ]
1010
runExe' "exe" [] >>= assertOutputContains "OK"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# cabal v2-build
2+
Resolving dependencies...
3+
Build profile: -w ghc-<GHCVER> -O1
4+
In order, the following will be built:
5+
- d-0.1.0.0 (lib:privatelib) (first run)
6+
- p-0.1.0.0 (lib) (first run)
7+
Configuring library 'privatelib' for d-0.1.0.0..
8+
Preprocessing library 'privatelib' for d-0.1.0.0..
9+
Building library 'privatelib' for d-0.1.0.0..
10+
Configuring library for p-0.1.0.0..
11+
cabal: Encountered missing or private dependencies:
12+
d : {privatelib} ==0.1.0.0
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
packages:
2+
d
3+
p
4+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Test.Cabal.Prelude
2+
main = cabalTest $
3+
void $ fails (cabal' "v2-build" ["p"])
4+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
cabal-version: 3.0
2+
name: d
3+
version: 0.1.0.0
4+
5+
-- See issue #6038
6+
library
7+
default-language: Haskell2010
8+
9+
library privatelib
10+
visibility: private
11+
default-language: Haskell2010
12+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cabal-version: 3.0
2+
name: p
3+
version: 0.1.0.0
4+
5+
library
6+
build-depends: d:privatelib
7+
default-language: Haskell2010
8+

0 commit comments

Comments
 (0)