Skip to content
Merged
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
20 changes: 11 additions & 9 deletions cabal-install/src/Distribution/Client/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ import Distribution.Client.Setup
, filterConfigureFlags
)
import Distribution.Client.SetupWrapper
( SetupRunnerArgs (NotInLibrary)
( SetupDependencies (..)
, SetupRunnerArgs (NotInLibrary)
, SetupScriptOptions (..)
, defaultSetupScriptOptions
, setupWrapper
Expand Down Expand Up @@ -288,14 +289,15 @@ configureSetupScript
, useExtraEnvOverrides = []
, setupCacheLock = lock
, useWin32CleanHack = False
, -- If we have explicit setup dependencies, list them; otherwise, we give
-- the empty list of dependencies; ideally, we would fix the version of
-- Cabal here, so that we no longer need the special case for that in
-- `compileSetupExecutable` in `externalSetupMethod`, but we don't yet
-- know the version of Cabal at this point, but only find this there.
-- Therefore, for now, we just leave this blank.
useDependencies = fromMaybe [] explicitSetupDeps
, useDependenciesExclusive = not defaultSetupDeps && isJust explicitSetupDeps
, -- If the @custom-setup@ stanza has an explicit list of dependencies,
-- use those exclusively. Otherwise, the list is not exhaustive, and
-- we have a special case in 'SetupWrapper' to go looking for a Cabal
-- library. We don't yet know its version, so for now we leave the list
-- of implicit dependencies blank.
useSetupDependencies =
case explicitSetupDeps of
Just deps | not defaultSetupDeps -> ExplicitSetupDeps deps
_ -> ImplicitSetupDeps (fromMaybe [] explicitSetupDeps)
, useVersionMacros = not defaultSetupDeps && isJust explicitSetupDeps
, isInteractive = False
, isMainLibOrExeComponent = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ buildInplaceUnpackedPackage
Simple -> listSimple
Hooks -> listSdist `ifNullThen` listSimple
_
| elabSetupScriptCliVersion pkg >= mkVersion [1, 17] ->
| setupCliVersion (elabSetupScriptCliVersion pkg) >= mkVersion [1, 17] ->
listSdist `ifNullThen` listSimple
| otherwise ->
listSimple
Expand All @@ -689,18 +689,19 @@ buildInplaceUnpackedPackage
buildResult

whenReconfigure :: IO InLibraryLBI -> IO InLibraryLBI
whenReconfigure action =
whenReconfigure configure_action =
case buildStatus of
BuildStatusConfigure _ -> action
BuildStatusConfigure _ -> configure_action
_ -> do
-- We are skipping reconfiguration, so we recover the
-- 'LocalBuildInfo' persisted by the previous 'configure'.
mbOldLBI <- Cabal.tryGetPersistBuildConfig (Just srcdir) builddir
case mbOldLBI of
-- #11942: if the previous LocalBuildInfo was written by an
-- external Setup.hs with an incompatible Cabal library version,
-- then we must continue to use the external setup method.
Left Cabal.ConfigStateFileBadVersion{} -> return NotInLibraryNoLBI
-- #11942: the previous 'LocalBuildInfo' was written by an
-- incompatible Cabal (either an external Setup.hs or a different
-- version of cabal-install). We can't use it at all, so we must
-- re-configure.
Left Cabal.ConfigStateFileBadVersion{} -> configure_action
-- Other errors reflect genuine problems: re-throw them.
Left err -> throwIO err
Right lbi_wo_programs -> do
Expand Down
2 changes: 1 addition & 1 deletion cabal-install/src/Distribution/Client/ProjectPlanOutput.hs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ encodePlanAsJson distDirLayout elaboratedInstallPlan elaboratedSharedConfig =
-- with an old lib:Cabal version.
buildInfoFileLocation :: J.Pair
buildInfoFileLocation
| elabSetupScriptCliVersion elab < mkVersion [3, 7, 0, 0] =
| setupCliVersion (elabSetupScriptCliVersion elab) < mkVersion [3, 7, 0, 0] =
"build-info" J..= J.Null
| otherwise =
"build-info" J..= J.String (getSymbolicPath $ buildInfoPref $ makeSymbolicPath dist_dir)
Expand Down
33 changes: 17 additions & 16 deletions cabal-install/src/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3917,25 +3917,24 @@ setupHsScriptOptions
builddir
cacheLock =
SetupScriptOptions
{ useCabalVersion = thisVersion elabSetupScriptCliVersion
, useCabalSpecVersion =
{ useCabalVersion = thisVersion cliVersion
, -- NB: for build-type: Hooks we don't want to commit to a Cabal
-- version, as all that should matter is the version of Cabal-hooks,
-- not of Cabal.
useCabalSpecVersion =
if PD.buildType elabPkgDescription == PD.Hooks
then -- NB: we don't want to commit to a Cabal version here:
-- - all that should matter for Hooks build-type is the
-- version of Cabal-hooks, not of Cabal,
-- - if we commit to a Cabal version, the logic in
Nothing
else Just elabSetupScriptCliVersion
then Nothing
else Just cliVersion
, useCompiler = Just pkgConfigCompiler
, usePlatform = Just pkgConfigPlatform
, usePackageDB = elabSetupPackageDBStack
, usePackageIndex = Nothing
, useDependencies =
[ (uid, srcid)
| (ConfiguredId srcid (Just (CLibName LMainLibName)) uid, _) <-
elabSetupDependencies elab
]
, useDependenciesExclusive = True
, useSetupDependencies =
ExplicitSetupDeps
[ (uid, srcid)
| (ConfiguredId srcid (Just (CLibName LMainLibName)) uid, _) <-
elabSetupDependencies elab
]
, useVersionMacros = elabSetupScriptStyle == SetupCustomExplicitDeps
, useProgramDb = pkgConfigCompilerProgs
, useDistPref = builddir
Expand All @@ -3960,6 +3959,8 @@ setupHsScriptOptions
-- everything else is not a main lib or exe component
ElabComponent _ -> False
}
where
cliVersion = setupCliVersion elabSetupScriptCliVersion

-- | To be used for the input for elaborateInstallPlan.
--
Expand Down Expand Up @@ -4241,7 +4242,7 @@ setupHsBuildFlags par_strat elab _ common =
, buildProgramArgs = mempty -- unused, set at configure time
, buildNumJobs = mempty -- TODO: [nice to have] sometimes want to use toFlag (Just numBuildJobs),
, buildUseSemaphore =
if elabSetupScriptCliVersion elab >= mkVersion [3, 11, 0, 0]
if setupCliVersion (elabSetupScriptCliVersion elab) >= mkVersion [3, 11, 0, 0]
then -- Cabal 3.11 is the first version that supports parallelism semaphores
par_strat
else mempty
Expand All @@ -4250,7 +4251,7 @@ setupHsBuildFlags par_strat elab _ common =
setupHsBuildArgs :: ElaboratedConfiguredPackage -> [String]
setupHsBuildArgs elab@(ElaboratedConfiguredPackage{elabPkgOrComp = ElabPackage _})
-- Fix for #3335, don't pass build arguments if it's not supported
| elabSetupScriptCliVersion elab >= mkVersion [1, 17] =
| setupCliVersion (elabSetupScriptCliVersion elab) >= mkVersion [1, 17] =
map (showComponentTarget (packageId elab)) (elabBuildTargets elab)
| otherwise =
[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,8 @@
-- functions for both phases together here so at least you can see all of it
-- in one place.
--
-- There are four major cases for Setup.hs handling:
--
-- 1. @build-type@ Custom with a @custom-setup@ section
-- 2. @build-type@ Custom without a @custom-setup@ section
-- 3. @build-type@ not Custom with @cabal-version > $our-cabal-version@
-- 4. @build-type@ not Custom with @cabal-version <= $our-cabal-version@
--
-- It's also worth noting that packages specifying @cabal-version: >= 1.23@
-- or later that have @build-type@ Custom will always have a @custom-setup@
-- section. Therefore in case 2, the specified @cabal-version@ will always be
-- less than 1.23.
--
-- In cases 1 and 2 we obviously have to build an external Setup.hs script,
-- while in case 4 we can use the internal library API.
-- There are four major cases for Setup.hs handling; see the documentation of
-- 'SetupScriptStyle' in Distribution.Client.ProjectPlanning.Types.
--
-- @since 3.12.0.0
module Distribution.Client.ProjectPlanning.SetupPolicy
Expand All @@ -34,7 +22,10 @@ where
import Distribution.Client.Compat.Prelude
import Prelude ()

import Distribution.Client.ProjectPlanning.Types (SetupScriptStyle (..))
import Distribution.Client.ProjectPlanning.Types
( SetupCliVersion (..)
, SetupScriptStyle (..)
)
import Distribution.Client.SolverInstallPlan (SolverPlanPackage)
import Distribution.Solver.Types.ComponentDeps (ComponentDeps)
import qualified Distribution.Solver.Types.ComponentDeps as CD
Expand Down Expand Up @@ -192,24 +183,25 @@ packageSetupScriptSpecVersion
-> PackageDescription
-> Graph.Graph NonSetupLibDepSolverPlanPackage
-> ComponentDeps [SolverId]
-> Version
-> SetupCliVersion
-- We're going to be using the internal Cabal library, so the spec version of
-- that is simply the version of the Cabal library that cabal-install has been
-- built with.
packageSetupScriptSpecVersion SetupNonCustomInternalLib _ _ _ =
cabalVersion
InternalCabalLib
-- If we happen to be building the Cabal lib itself then because that
-- bootstraps itself then we use the version of the lib we're building.
packageSetupScriptSpecVersion SetupCustomImplicitDeps pkg _ _
| packageName pkg == cabalPkgname =
packageVersion pkg
ExternalCabalLib $ packageVersion pkg
-- In all other cases we have a look at what version of the Cabal lib the
-- solver picked. Or if it didn't depend on Cabal at all (which is very rare)
-- then we look at the .cabal file to see what spec version it declares.
packageSetupScriptSpecVersion _ pkg libDepGraph deps =
case find ((cabalPkgname ==) . packageName) setupLibDeps of
Just dep -> packageVersion dep
Nothing -> mkVersion (cabalSpecMinimumLibraryVersion (specVersion pkg))
ExternalCabalLib $
case find ((cabalPkgname ==) . packageName) setupLibDeps of
Just dep -> packageVersion dep
Nothing -> mkVersion (cabalSpecMinimumLibraryVersion (specVersion pkg))
where
setupLibDeps =
maybe [] (map packageId) (Graph.closure libDepGraph (CD.setupDeps deps))
Expand Down
75 changes: 54 additions & 21 deletions cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ module Distribution.Client.ProjectPlanning.Types

-- * Setup script
, SetupScriptStyle (..)
, SetupCliVersion (..)
, setupCliVersion
) where

import Distribution.Client.Compat.Prelude
Expand Down Expand Up @@ -102,7 +104,7 @@ import Distribution.Simple.Setup
, ReplOptions
, TestShowDetails
)
import Distribution.Simple.Utils (ordNub)
import Distribution.Simple.Utils (cabalVersion, ordNub)
import Distribution.Solver.Types.ComponentDeps (ComponentDeps)
import qualified Distribution.Solver.Types.ComponentDeps as CD
import Distribution.Solver.Types.OptionalStanza
Expand Down Expand Up @@ -313,15 +315,10 @@ data ElaboratedConfiguredPackage = ElaboratedConfiguredPackage

elabSetupScriptStyle :: SetupScriptStyle
-- ^ One of four modes for how we build and interact with the Setup.hs
-- script, based on whether it's a build-type Custom, with or without
-- explicit deps and the cabal spec version the .cabal file needs.
, elabSetupScriptCliVersion :: Version
-- ^ The version of the Cabal command line interface that we are using
-- for this package. This is typically the version of the Cabal lib
-- that the Setup.hs is built against.
--
-- TODO: We might want to turn this into a enum,
-- yet different enum than 'CabalSpecVersion'.
-- script, based on whether it's a build-type Custom or Hooks, with or
-- without explicit deps, and the cabal spec version the .cabal file needs.
, elabSetupScriptCliVersion :: SetupCliVersion
-- ^ The Cabal library version used to provide the Setup CLI.
, -- Build time related:
elabConfigureTargets :: [ComponentTarget]
, elabBuildTargets :: [ComponentTarget]
Expand Down Expand Up @@ -914,26 +911,62 @@ componentOptionalStanza _ = Nothing

-- | There are four major cases for Setup.hs handling:
--
-- 1. @build-type@ Custom with a @custom-setup@ section
-- 1. @build-type@ Custom or Hooks with a @custom-setup@ section
-- 2. @build-type@ Custom without a @custom-setup@ section
-- 3. @build-type@ not Custom with @cabal-version > $our-cabal-version@
-- 4. @build-type@ not Custom with @cabal-version <= $our-cabal-version@
-- 3. @build-type@ neither Custom nor Hooks, with
-- @cabal-version > $our-cabal-version@
-- 4. @build-type@ neither Custom nor Hooks, with
-- @cabal-version <= $our-cabal-version@
--
-- It's also worth noting that packages specifying @cabal-version: >= 1.23@
-- or later that have @build-type@ Custom will always have a @custom-setup@
-- section. Therefore in case 2, the specified @cabal-version@ will always be
-- less than 1.23.
--
-- In cases 1 and 2 we obviously have to build an external Setup.hs script,
-- while in case 4 we can use the internal library API. In case 3 we also have
-- to build an external Setup.hs script because the package needs a later
-- Cabal lib version than we can support internally.
-- In cases 1 and 2 we obviously have to compile an external program: a
-- Setup.hs script for build-type Custom, and the hooks executable for
-- build-type Hooks (with a possible fallback to a Setup.hs).
-- In case 3 we also have to build an external Setup.hs script, because the
-- package needs a later Cabal lib version than we can support internally.
-- Only in case 4 can we use the internal library API alone.
data SetupScriptStyle
= SetupCustomExplicitDeps
| SetupCustomImplicitDeps
| SetupNonCustomExternalLib
| SetupNonCustomInternalLib
= -- | @build-type: Custom@ (or @Hooks@) with explicit @setup-depends@
SetupCustomExplicitDeps
| -- | @build-type: Custom@ without an explicit @setup-depends@
SetupCustomImplicitDeps
| -- | Non-Custom/Hooks build-type, but we fall back to an external @Setup.hs@
-- in order to satisfy Cabal version constraints.
SetupNonCustomExternalLib
| -- | Non-Custom/Hooks build type: Cabal provides the Setup.hs CLI internally.
SetupNonCustomInternalLib
deriving (Eq, Show, Generic)

instance Binary SetupScriptStyle
instance Structured SetupScriptStyle

-- | The version of the Cabal library used to provide the Setup CLI.
--
-- The version corresponds to the 'SetupScriptStyle' we use: for
-- 'SetupNonCustomInternalLib' we use the Cabal library that @cabal-install@ was
-- built against, and for every other 'SetupScripStyle' we pick the version
-- chosen by the solver to compile the Setup script.
data SetupCliVersion
= -- | Use the Cabal library version that @cabal-install@ was linked against
-- to provide the Setup CLI.
InternalCabalLib -- NB: this very carefully __does not__ store a version number.
--
-- This is because of #11416: the install plan is cached across @cabal-install@
-- invocations, so we should not pin a Cabal library version which would
-- go stale when doing a minor @cabal-install@ upgrade.
| -- | Use the Cabal library version picked by the solver to provide
-- the Setup CLI.
ExternalCabalLib !Version
deriving (Eq, Show, Generic)

instance Binary SetupCliVersion
instance Structured SetupCliVersion

-- | The version of the Cabal library used to provide the Setup CLI.
setupCliVersion :: SetupCliVersion -> Version
setupCliVersion InternalCabalLib = cabalVersion
setupCliVersion (ExternalCabalLib version) = version
Loading
Loading