Skip to content

Commit 58b4a65

Browse files
committed
Force Cabal >= 1.24 dep when there's no custom-setup stanza.
Fixes #3199. (cherry picked from commit 2f97657)
1 parent 3784e1f commit 58b4a65

File tree

7 files changed

+156
-68
lines changed

7 files changed

+156
-68
lines changed

Cabal/Distribution/PackageDescription.hs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ module Distribution.PackageDescription (
100100
GenericPackageDescription(..),
101101
Flag(..), FlagName(..), FlagAssignment,
102102
CondTree(..), ConfVar(..), Condition(..),
103-
cNot,
103+
cNot, cAnd, cOr,
104104

105105
-- * Source repositories
106106
SourceRepo(..),
@@ -114,7 +114,7 @@ module Distribution.PackageDescription (
114114

115115
import Distribution.Compat.Binary
116116
import qualified Distribution.Compat.Semigroup as Semi ((<>))
117-
import Distribution.Compat.Semigroup as Semi (Monoid(..), Semigroup, gmempty, gmappend)
117+
import Distribution.Compat.Semigroup as Semi (Monoid(..), Semigroup, gmempty)
118118
import qualified Distribution.Compat.ReadP as Parse
119119
import Distribution.Compat.ReadP ((<++))
120120
import Distribution.Package
@@ -310,18 +310,24 @@ instance Text BuildType where
310310
-- options authors can specify to just Haskell package dependencies.
311311

312312
data SetupBuildInfo = SetupBuildInfo {
313-
setupDepends :: [Dependency]
313+
setupDepends :: [Dependency],
314+
defaultSetupDepends :: Bool
315+
-- ^ Is this a default 'custom-setup' section added by the cabal-install
316+
-- code (as opposed to user-provided)? This field is only used
317+
-- internally, and doesn't correspond to anything in the .cabal
318+
-- file. See #3199.
314319
}
315320
deriving (Generic, Show, Eq, Read, Typeable, Data)
316321

317322
instance Binary SetupBuildInfo
318323

319324
instance Semi.Monoid SetupBuildInfo where
320-
mempty = gmempty
325+
mempty = SetupBuildInfo [] False
321326
mappend = (Semi.<>)
322327

323328
instance Semigroup SetupBuildInfo where
324-
(<>) = gmappend
329+
a <> b = SetupBuildInfo (setupDepends a Semi.<> setupDepends b)
330+
(defaultSetupDepends a || defaultSetupDepends b)
325331

326332
-- ---------------------------------------------------------------------------
327333
-- Module renaming
@@ -1225,11 +1231,32 @@ data Condition c = Var c
12251231
| CAnd (Condition c) (Condition c)
12261232
deriving (Show, Eq, Typeable, Data, Generic)
12271233

1234+
-- | Boolean negation of a 'Condition' value.
12281235
cNot :: Condition a -> Condition a
12291236
cNot (Lit b) = Lit (not b)
12301237
cNot (CNot c) = c
12311238
cNot c = CNot c
12321239

1240+
-- | Boolean AND of two 'Condtion' values.
1241+
cAnd :: Condition a -> Condition a -> Condition a
1242+
cAnd (Lit False) _ = Lit False
1243+
cAnd _ (Lit False) = Lit False
1244+
cAnd (Lit True) x = x
1245+
cAnd x (Lit True) = x
1246+
cAnd x y = CAnd x y
1247+
1248+
-- | Boolean OR of two 'Condition' values.
1249+
cOr :: Eq v => Condition v -> Condition v -> Condition v
1250+
cOr (Lit True) _ = Lit True
1251+
cOr _ (Lit True) = Lit True
1252+
cOr (Lit False) x = x
1253+
cOr x (Lit False) = x
1254+
cOr c (CNot d)
1255+
| c == d = Lit True
1256+
cOr (CNot c) d
1257+
| c == d = Lit True
1258+
cOr x y = COr x y
1259+
12331260
instance Functor Condition where
12341261
f `fmap` Var c = Var (f c)
12351262
_ `fmap` Lit c = Lit c

Cabal/Distribution/PackageDescription/Configuration.hs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE CPP #-}
12
-- -fno-warn-deprecations for use of Map.foldWithKey
23
{-# OPTIONS_GHC -fno-warn-deprecations #-}
34
-----------------------------------------------------------------------------
@@ -23,6 +24,7 @@ module Distribution.PackageDescription.Configuration (
2324
parseCondition,
2425
freeVars,
2526
extractCondition,
27+
extractConditions,
2628
addBuildableCondition,
2729
mapCondTree,
2830
mapTreeData,
@@ -32,6 +34,9 @@ module Distribution.PackageDescription.Configuration (
3234
transformAllBuildDepends,
3335
) where
3436

37+
import Control.Applicative -- 7.10 -Werror workaround.
38+
import Prelude
39+
3540
import Distribution.Package
3641
import Distribution.PackageDescription
3742
import Distribution.PackageDescription.Utils
@@ -293,17 +298,24 @@ addBuildableCondition getInfo t =
293298
Lit False -> CondNode mempty mempty []
294299
c -> CondNode mempty mempty [(c, t, Nothing)]
295300

296-
-- | Extract buildable condition from a cond tree.
301+
-- Note: extracting buildable conditions.
302+
-- --------------------------------------
297303
--
298-
-- Background: If the conditions in a cond tree lead to Buildable being set to False,
299-
-- then none of the dependencies for this cond tree should actually be taken into
300-
-- account. On the other hand, some of the flags may only be decided in the solver,
301-
-- so we cannot necessarily make the decision whether a component is Buildable or not
302-
-- prior to solving.
304+
-- If the conditions in a cond tree lead to Buildable being set to False, then
305+
-- none of the dependencies for this cond tree should actually be taken into
306+
-- account. On the other hand, some of the flags may only be decided in the
307+
-- solver, so we cannot necessarily make the decision whether a component is
308+
-- Buildable or not prior to solving.
303309
--
304-
-- What we are doing here is to partially evaluate a condition tree in order to extract
305-
-- the condition under which Buildable is True. The predicate determines whether data
306-
-- under a 'CondTree' is buildable.
310+
-- What we are doing here is to partially evaluate a condition tree in order to
311+
-- extract the condition under which Buildable is True. The predicate determines
312+
-- whether data under a 'CondTree' is buildable.
313+
314+
315+
-- | Extract the condition matched by the given predicate from a cond tree.
316+
--
317+
-- We use this mainly for extracting buildable conditions (see the Note above),
318+
-- but the function is in fact more general.
307319
extractCondition :: Eq v => (a -> Bool) -> CondTree v c a -> Condition v
308320
extractCondition p = go
309321
where
@@ -316,21 +328,20 @@ extractCondition p = go
316328
ct = go t
317329
ce = maybe (Lit True) go e
318330
in
319-
((c `cand` ct) `cor` (CNot c `cand` ce)) `cand` goList cs
320-
321-
cand (Lit False) _ = Lit False
322-
cand _ (Lit False) = Lit False
323-
cand (Lit True) x = x
324-
cand x (Lit True) = x
325-
cand x y = CAnd x y
326-
327-
cor (Lit True) _ = Lit True
328-
cor _ (Lit True) = Lit True
329-
cor (Lit False) x = x
330-
cor x (Lit False) = x
331-
cor c (CNot d)
332-
| c == d = Lit True
333-
cor x y = COr x y
331+
((c `cAnd` ct) `cOr` (CNot c `cAnd` ce)) `cAnd` goList cs
332+
333+
-- | Extract conditions matched by the given predicate from all cond trees in a
334+
-- 'GenericPackageDescription'.
335+
extractConditions :: (BuildInfo -> Bool) -> GenericPackageDescription
336+
-> [Condition ConfVar]
337+
extractConditions f gpkg =
338+
concat [
339+
extractCondition (f . libBuildInfo) . snd <$> condLibraries gpkg
340+
, extractCondition (f . buildInfo) . snd <$> condExecutables gpkg
341+
, extractCondition (f . testBuildInfo) . snd <$> condTestSuites gpkg
342+
, extractCondition (f . benchmarkBuildInfo) . snd <$> condBenchmarks gpkg
343+
]
344+
334345

335346
-- | A map of dependencies that combines version ranges using 'unionVersionRanges'.
336347
newtype DepMapUnion = DepMapUnion { unDepMapUnion :: Map PackageName VersionRange }

cabal-install/Distribution/Client/Configure.hs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -187,18 +187,18 @@ configureSetupScript packageDBs
187187
index
188188
mpkg
189189
= SetupScriptOptions {
190-
useCabalVersion = cabalVersion
191-
, useCabalSpecVersion = Nothing
192-
, useCompiler = Just comp
193-
, usePlatform = Just platform
194-
, usePackageDB = packageDBs'
195-
, usePackageIndex = index'
196-
, useProgramConfig = conf
197-
, useDistPref = distPref
198-
, useLoggingHandle = Nothing
199-
, useWorkingDir = Nothing
200-
, setupCacheLock = lock
201-
, useWin32CleanHack = False
190+
useCabalVersion = cabalVersion
191+
, useCabalSpecVersion = Nothing
192+
, useCompiler = Just comp
193+
, usePlatform = Just platform
194+
, usePackageDB = packageDBs'
195+
, usePackageIndex = index'
196+
, useProgramConfig = conf
197+
, useDistPref = distPref
198+
, useLoggingHandle = Nothing
199+
, useWorkingDir = Nothing
200+
, setupCacheLock = lock
201+
, useWin32CleanHack = False
202202
, forceExternalSetupMethod = forceExternal
203203
-- If we have explicit setup dependencies, list them; otherwise, we give
204204
-- the empty list of dependencies; ideally, we would fix the version of
@@ -207,8 +207,8 @@ configureSetupScript packageDBs
207207
-- know the version of Cabal at this point, but only find this there.
208208
-- Therefore, for now, we just leave this blank.
209209
, useDependencies = fromMaybe [] explicitSetupDeps
210-
, useDependenciesExclusive = isJust explicitSetupDeps
211-
, useVersionMacros = isJust explicitSetupDeps
210+
, useDependenciesExclusive = not defaultSetupDeps && isJust explicitSetupDeps
211+
, useVersionMacros = not defaultSetupDeps && isJust explicitSetupDeps
212212
}
213213
where
214214
-- When we are compiling a legacy setup script without an explicit
@@ -226,13 +226,24 @@ configureSetupScript packageDBs
226226
-- but if the user is using an odd db stack, don't touch it
227227
_otherwise -> (packageDBs, Just index)
228228

229-
explicitSetupDeps :: Maybe [(UnitId, PackageId)]
230-
explicitSetupDeps = do
229+
maybeSetupBuildInfo :: Maybe PkgDesc.SetupBuildInfo
230+
maybeSetupBuildInfo = do
231231
ReadyPackage cpkg <- mpkg
232232
let gpkg = packageDescription (confPkgSource cpkg)
233-
-- Check if there is an explicit setup stanza
234-
_buildInfo <- PkgDesc.setupBuildInfo (PkgDesc.packageDescription gpkg)
233+
PkgDesc.setupBuildInfo (PkgDesc.packageDescription gpkg)
234+
235+
-- Was a default 'custom-setup' stanza added by 'cabal-install' itself? If
236+
-- so, 'setup-depends' must not be exclusive. See #3199.
237+
defaultSetupDeps :: Bool
238+
defaultSetupDeps = maybe False PkgDesc.defaultSetupDepends
239+
maybeSetupBuildInfo
240+
241+
explicitSetupDeps :: Maybe [(UnitId, PackageId)]
242+
explicitSetupDeps = do
243+
-- Check if there is an explicit setup stanza.
244+
_buildInfo <- maybeSetupBuildInfo
235245
-- Return the setup dependencies computed by the solver
246+
ReadyPackage cpkg <- mpkg
236247
return [ ( uid, srcid )
237248
| ConfiguredId srcid uid <- CD.setupDeps (confPkgDeps cpkg)
238249
]

cabal-install/Distribution/Client/Dependency.hs

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,14 @@ import Distribution.Package
9494
, Package(..), packageName, packageVersion
9595
, UnitId, Dependency(Dependency))
9696
import qualified Distribution.PackageDescription as PD
97-
( PackageDescription(..), SetupBuildInfo(..)
98-
, GenericPackageDescription(..)
99-
, Flag(flagName), FlagName(..) )
97+
import qualified Distribution.PackageDescription.Configuration as PD
10098
import Distribution.PackageDescription.Configuration
10199
( finalizePackageDescription )
102100
import Distribution.Client.PackageUtils
103101
( externalBuildDepends )
104102
import Distribution.Version
105-
( VersionRange, anyVersion, thisVersion, withinRange
106-
, simplifyVersionRange )
103+
( Version(..), VersionRange, anyVersion, thisVersion, orLaterVersion
104+
, withinRange, simplifyVersionRange )
107105
import Distribution.Compiler
108106
( CompilerInfo(..) )
109107
import Distribution.System
@@ -394,7 +392,7 @@ removeUpperBounds allowNewer params =
394392
-- 'addSourcePackages'. Otherwise, the packages inserted by
395393
-- 'addSourcePackages' won't have upper bounds in dependencies relaxed.
396394
--
397-
addDefaultSetupDependencies :: (UnresolvedSourcePackage -> [Dependency])
395+
addDefaultSetupDependencies :: (UnresolvedSourcePackage -> Maybe [Dependency])
398396
-> DepResolverParams -> DepResolverParams
399397
addDefaultSetupDependencies defaultSetupDeps params =
400398
params {
@@ -410,9 +408,12 @@ addDefaultSetupDependencies defaultSetupDeps params =
410408
PD.setupBuildInfo =
411409
case PD.setupBuildInfo pkgdesc of
412410
Just sbi -> Just sbi
413-
Nothing -> Just PD.SetupBuildInfo {
414-
PD.setupDepends = defaultSetupDeps srcpkg
415-
}
411+
Nothing -> case defaultSetupDeps srcpkg of
412+
Nothing -> Nothing
413+
Just deps -> Just PD.SetupBuildInfo {
414+
PD.defaultSetupDepends = True,
415+
PD.setupDepends = deps
416+
}
416417
}
417418
}
418419
}
@@ -451,12 +452,41 @@ standardInstallPolicy
451452
. hideInstalledPackagesSpecificBySourcePackageId
452453
[ packageId pkg | SpecificSourcePackage pkg <- pkgSpecifiers ]
453454

455+
. addDefaultSetupDependencies mkDefaultSetupDeps
456+
454457
. addSourcePackages
455458
[ pkg | SpecificSourcePackage pkg <- pkgSpecifiers ]
456459

457460
$ basicDepResolverParams
458461
installedPkgIndex sourcePkgIndex
459462

463+
where
464+
-- Force Cabal >= 1.24 dep when the package is affected by #3199.
465+
mkDefaultSetupDeps :: UnresolvedSourcePackage -> Maybe [Dependency]
466+
mkDefaultSetupDeps srcpkg | affected =
467+
Just [Dependency (PackageName "Cabal")
468+
(orLaterVersion $ Version [1,24] [])]
469+
| otherwise = Nothing
470+
where
471+
gpkgdesc = packageDescription srcpkg
472+
pkgdesc = PD.packageDescription gpkgdesc
473+
bt = fromMaybe PD.Custom (PD.buildType pkgdesc)
474+
affected = bt == PD.Custom && hasBuildableFalse gpkgdesc
475+
476+
-- Does this package contain any components with non-empty 'build-depends'
477+
-- and a 'buildable' field that could potentially be set to 'False'? False
478+
-- positives are possible.
479+
hasBuildableFalse :: PD.GenericPackageDescription -> Bool
480+
hasBuildableFalse gpkg =
481+
not (all alwaysTrue (zipWith PD.cOr buildableConditions noDepConditions))
482+
where
483+
buildableConditions = PD.extractConditions PD.buildable gpkg
484+
noDepConditions = PD.extractConditions
485+
(null . PD.targetBuildDepends) gpkg
486+
alwaysTrue (PD.Lit True) = True
487+
alwaysTrue _ = False
488+
489+
460490
applySandboxInstallPolicy :: SandboxPackageInfo
461491
-> DepResolverParams
462492
-> DepResolverParams

cabal-install/Distribution/Client/ProjectPlanning.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,14 +1629,15 @@ packageSetupScriptStylePreSolver pkg
16291629
-- we still need to distinguish the case of explicit and implict setup deps.
16301630
-- See 'rememberImplicitSetupDeps'.
16311631
--
1632-
defaultSetupDeps :: Platform -> PD.PackageDescription -> [Dependency]
1632+
defaultSetupDeps :: Platform -> PD.PackageDescription -> Maybe [Dependency]
16331633
defaultSetupDeps platform pkg =
16341634
case packageSetupScriptStylePreSolver pkg of
16351635

16361636
-- For packages with build type custom that do not specify explicit
16371637
-- setup dependencies, we add a dependency on Cabal and a number
16381638
-- of other packages.
16391639
SetupCustomImplicitDeps ->
1640+
Just $
16401641
[ Dependency depPkgname anyVersion
16411642
| depPkgname <- legacyCustomSetupPkgs platform ] ++
16421643
-- The Cabal dep is slightly special:
@@ -1663,13 +1664,13 @@ defaultSetupDeps platform pkg =
16631664
-- external Setup.hs, it'll be one of the simple ones that only depends
16641665
-- on Cabal and base.
16651666
SetupNonCustomExternalLib ->
1666-
[ Dependency cabalPkgname cabalConstraint
1667-
, Dependency basePkgname anyVersion ]
1667+
Just [ Dependency cabalPkgname cabalConstraint
1668+
, Dependency basePkgname anyVersion ]
16681669
where
16691670
cabalConstraint = orLaterVersion (PD.specVersion pkg)
16701671

16711672
-- The internal setup wrapper method has no deps at all.
1672-
SetupNonCustomInternalLib -> []
1673+
SetupNonCustomInternalLib -> Just []
16731674

16741675
SetupCustomExplicitDeps ->
16751676
error $ "defaultSetupDeps: called for a package with explicit "

0 commit comments

Comments
 (0)