@@ -204,7 +204,7 @@ import Distribution.Types.PackageVersionConstraint
204204import Distribution.Types.PkgconfigDependency
205205import Distribution.Types.UnqualComponentName
206206
207- import Distribution.Backpack
207+ import Distribution.Backpack hiding ( mkDefUnitId )
208208import Distribution.Backpack.ComponentsGraph
209209import Distribution.Backpack.ConfiguredComponent
210210import Distribution.Backpack.FullUnitId
@@ -229,7 +229,7 @@ import qualified Distribution.Compat.Graph as Graph
229229import Control.Exception (assert )
230230import Control.Monad (sequence )
231231import Control.Monad.IO.Class (liftIO )
232- import Control.Monad.State as State (State , execState , runState , state )
232+ import Control.Monad.State (State , execState , gets , modify )
233233import Data.Foldable (fold )
234234import Data.List (deleteBy , groupBy )
235235import qualified Data.List.NonEmpty as NE
@@ -2791,7 +2791,7 @@ binDirectories layout config package = case elabBuildStyle package of
27912791 distBuildDirectory layout (elabDistDirParams config package)
27922792 </> " build"
27932793
2794- type InstS = Map UnitId ElaboratedPlanPackage
2794+ type InstS = Map ( WithStage UnitId ) ElaboratedPlanPackage
27952795type InstM a = State InstS a
27962796
27972797getComponentId
@@ -2875,67 +2875,75 @@ instantiateInstallPlan storeDirLayout defaultInstallDirs elaboratedShared plan =
28752875 where
28762876 pkgs = InstallPlan. toList plan
28772877
2878- cmap = Map. fromList [(getComponentId pkg, pkg) | pkg <- pkgs]
2878+ cmap = Map. fromList [(WithStage (stageOf pkg) ( getComponentId pkg) , pkg) | pkg <- pkgs]
28792879
28802880 instantiateUnitId
2881- :: ComponentId
2881+ :: Stage
2882+ -> ComponentId
2883+ -- \^ The id of the component being instantiated
28822884 -> Map ModuleName (Module , BuildStyle )
2885+ -- \^ A mapping from module names (the "holes" or signatures in Backpack)
2886+ -- to the concrete modules (and their build styles) that should fill those
2887+ -- holes.
28832888 -> InstM (DefUnitId , BuildStyle )
2884- instantiateUnitId cid insts = state $ \ s ->
2885- case Map. lookup uid s of
2886- Nothing ->
2887- -- Knot tied
2888- -- TODO: I don't think the knot tying actually does
2889- -- anything useful
2890- let (r, s') =
2891- runState
2892- (instantiateComponent uid cid insts)
2893- (Map. insert uid r s)
2894- in ((def_uid, extractElabBuildStyle r), Map. insert uid r s')
2895- Just r -> ((def_uid, extractElabBuildStyle r), s)
2889+ instantiateUnitId stage cid insts =
2890+ gets (Map. lookup (WithStage stage uid)) >>= \ case
2891+ Nothing -> do
2892+ r <- instantiateComponent uid (WithStage stage cid) insts
2893+ modify (Map. insert (WithStage stage uid) r)
2894+ return (unsafeMkDefUnitId uid, extractElabBuildStyle r)
2895+ Just r ->
2896+ return (unsafeMkDefUnitId uid, extractElabBuildStyle r)
28962897 where
2897- def_uid = mkDefUnitId cid (fmap fst insts)
2898- uid = unDefUnitId def_uid
2898+ uid = mkDefUnitId cid (fmap fst insts)
28992899
29002900 -- No need to InplaceT; the inplace-ness is properly computed for
29012901 -- the ElaboratedPlanPackage, so that will implicitly pass it on
29022902 instantiateComponent
29032903 :: UnitId
2904- -> ComponentId
2904+ -- \^ The unit id to assign to the instantiated component
2905+ -> WithStage ComponentId
2906+ -- \^ The id of the component being instantiated
29052907 -> Map ModuleName (Module , BuildStyle )
2908+ -- \^ A mapping from module names (the "holes" or signatures in Backpack)
2909+ -- to the concrete modules (and their build styles) that should fill those
2910+ -- holes.
29062911 -> InstM ElaboratedPlanPackage
2907- instantiateComponent uid cid insts
2908- | Just planpkg <- Map. lookup cid cmap =
2912+ instantiateComponent uid cidws@ (WithStage stage cid) insts =
2913+ case Map. lookup cidws cmap of
2914+ Nothing -> error (" instantiateComponent: " ++ prettyShow cid)
2915+ Just planpkg ->
29092916 case planpkg of
2910- InstallPlan. Configured
2911- ( elab0@ ElaboratedConfiguredPackage
2912- { elabPkgOrComp = ElabComponent comp
2913- }
2914- ) -> do
2915- deps <-
2916- traverse (fmap fst . substUnitId insts) (compLinkedLibDependencies comp)
2917- let build_style = fold (fmap snd insts)
2918- let getDep (Module dep_uid _) = [dep_uid]
2919- elab1 =
2920- fixupBuildStyle build_style $
2921- elab0
2922- { elabUnitId = uid
2923- , elabComponentId = cid
2924- , elabIsCanonical = Map. null (fmap fst insts)
2925- , elabPkgOrComp =
2926- ElabComponent
2927- comp
2928- { compOrderLibDependencies =
2929- (if Map. null insts then [] else [newSimpleUnitId cid])
2930- ++ ordNub
2931- ( map
2932- unDefUnitId
2933- (deps ++ concatMap (getDep . fst ) (Map. elems insts))
2934- )
2935- , compInstantiatedWith = fmap fst insts
2936- }
2937- }
2938- elab =
2917+ InstallPlan. Installed {} -> return planpkg
2918+ InstallPlan. PreExisting {} -> return planpkg
2919+ InstallPlan. Configured elab0 ->
2920+ case elabPkgOrComp elab0 of
2921+ ElabPackage {} -> return planpkg
2922+ ElabComponent comp -> do
2923+ deps <- traverse (fmap fst . instantiateUnit stage insts) (compLinkedLibDependencies comp)
2924+ let build_style = fold (fmap snd insts)
2925+ let getDep (Module dep_uid _) = [dep_uid]
2926+ elab1 =
2927+ fixupBuildStyle build_style $
2928+ elab0
2929+ { elabUnitId = uid
2930+ , elabComponentId = cid
2931+ , elabIsCanonical = Map. null (fmap fst insts)
2932+ , elabPkgOrComp =
2933+ ElabComponent
2934+ comp
2935+ { compOrderLibDependencies =
2936+ (if Map. null insts then [] else [newSimpleUnitId cid])
2937+ ++ ordNub
2938+ ( map
2939+ unDefUnitId
2940+ (deps ++ concatMap (getDep . fst ) (Map. elems insts))
2941+ )
2942+ , compInstantiatedWith = fmap fst insts
2943+ }
2944+ }
2945+ return $
2946+ InstallPlan. Configured
29392947 elab1
29402948 { elabInstallDirs =
29412949 computeInstallDirs
@@ -2944,112 +2952,135 @@ instantiateInstallPlan storeDirLayout defaultInstallDirs elaboratedShared plan =
29442952 elaboratedShared
29452953 elab1
29462954 }
2947- return $ InstallPlan. Configured elab
2948- _ -> return planpkg
2949- | otherwise = error (" instantiateComponent: " ++ prettyShow cid)
29502955
2951- substUnitId :: Map ModuleName (Module , BuildStyle ) -> OpenUnitId -> InstM (DefUnitId , BuildStyle )
2952- substUnitId _ (DefiniteUnitId uid) =
2956+ -- \| Instantiates an OpenUnitId into a concrete UnitId, producing a concrete UnitId and its associated BuildStyle.
2957+ --
2958+ -- This function recursively applies a module substitution to an OpenUnitId, producing a fully instantiated
2959+ -- (definite) unit and its build style. This is a key step in Backpack-style instantiation, where "holes" in
2960+ -- a package are filled with concrete modules.
2961+ --
2962+ -- Behavior
2963+ --
2964+ -- If given a DefiniteUnitId, it returns the id and a default build style (BuildAndInstall).
2965+ --
2966+ -- If given an IndefFullUnitId, it:
2967+ -- Recursively applies the substitution to each module in the instantiation map using substSubst.
2968+ -- Calls instantiateUnitId to create or retrieve the fully instantiated unit id and build style for this instantiation.
2969+ --
2970+ instantiateUnit
2971+ :: Stage
2972+ -> Map ModuleName (Module , BuildStyle )
2973+ -- \^ A mapping from module names to their corresponding modules and build styles.
2974+ -> OpenUnitId
2975+ -- \^ The unit to instantiate. This can be:
2976+ -- DefiniteUnitId uid: already fully instantiated (no holes).
2977+ -- IndefFullUnitId cid insts: an indefinite unit (with holes), described by a component id and a mapping of holes to modules.
2978+ -> InstM (DefUnitId , BuildStyle )
2979+ instantiateUnit _stage _subst (DefiniteUnitId def_uid) =
29532980 -- This COULD actually, secretly, be an inplace package, but in
29542981 -- that case it doesn't matter as it's already been recorded
29552982 -- in the package that depends on this
2956- return (uid, BuildAndInstall )
2957- substUnitId subst (IndefFullUnitId cid insts) = do
2958- insts' <- substSubst subst insts
2959- instantiateUnitId cid insts'
2960-
2961- -- NB: NOT composition
2962- substSubst
2963- :: Map ModuleName (Module , BuildStyle )
2964- -> Map ModuleName OpenModule
2965- -> InstM (Map ModuleName (Module , BuildStyle ))
2966- substSubst subst insts = traverse (substModule subst) insts
2967-
2968- substModule :: Map ModuleName (Module , BuildStyle ) -> OpenModule -> InstM (Module , BuildStyle )
2969- substModule subst (OpenModuleVar mod_name)
2983+ return (def_uid, BuildAndInstall )
2984+ instantiateUnit stage subst (IndefFullUnitId cid insts) = do
2985+ insts' <- traverse (instantiateModule stage subst) insts
2986+ instantiateUnitId stage cid insts'
2987+
2988+ -- \| Instantiates an OpenModule into a concrete Module producing a concrete Module
2989+ -- and its associated BuildStyle.
2990+ instantiateModule
2991+ :: Stage
2992+ -> Map ModuleName (Module , BuildStyle )
2993+ -- \^ A mapping from module names to their corresponding modules and build styles.
2994+ -> OpenModule
2995+ -- \^ The module to substitute, which can be:
2996+ -- OpenModuleVar mod_name: a hole (variable) named mod_name
2997+ -- OpenModule uid mod_name: a module from a specific unit (uid).
2998+ -> InstM (Module , BuildStyle )
2999+ instantiateModule _stage subst (OpenModuleVar mod_name)
29703000 | Just m <- Map. lookup mod_name subst = return m
29713001 | otherwise = error " substModule: non-closing substitution"
2972- substModule subst (OpenModule uid mod_name) = do
2973- (uid', build_style) <- substUnitId subst uid
3002+ instantiateModule stage subst (OpenModule uid mod_name) = do
3003+ (uid', build_style) <- instantiateUnit stage subst uid
29743004 return (Module uid' mod_name, build_style)
29753005
2976- indefiniteUnitId :: ComponentId -> InstM UnitId
2977- indefiniteUnitId cid = do
2978- let uid = newSimpleUnitId cid
2979- r <- indefiniteComponent uid cid
2980- state $ \ s -> (uid, Map. insert uid r s)
2981-
2982- indefiniteComponent :: UnitId -> ComponentId -> InstM ElaboratedPlanPackage
2983- indefiniteComponent _uid cid
2984- -- Only need Configured; this phase happens before improvement, so
2985- -- there shouldn't be any Installed packages here.
2986- | Just (InstallPlan. Configured epkg) <- Map. lookup cid cmap
2987- , ElabComponent elab_comp <- elabPkgOrComp epkg =
2988- do
2989- -- We need to do a little more processing of the includes: some
2990- -- of them are fully definite even without substitution. We
2991- -- want to build those too; see #5634.
2992- --
2993- -- This code mimics similar code in Distribution.Backpack.ReadyComponent;
2994- -- however, unlike the conversion from LinkedComponent to
2995- -- ReadyComponent, this transformation is done *without*
2996- -- changing the type in question; and what we are simply
2997- -- doing is enforcing tighter invariants on the data
2998- -- structure in question. The new invariant is that there
2999- -- is no IndefFullUnitId in compLinkedLibDependencies that actually
3000- -- has no holes. We couldn't specify this invariant when
3001- -- we initially created the ElaboratedPlanPackage because
3002- -- we have no way of actually reifying the UnitId into a
3003- -- DefiniteUnitId (that's what substUnitId does!)
3004- new_deps <- for (compLinkedLibDependencies elab_comp) $ \ uid ->
3005- if Set. null (openUnitIdFreeHoles uid)
3006- then fmap (DefiniteUnitId . fst ) (substUnitId Map. empty uid)
3007- else return uid
3008- -- NB: no fixupBuildStyle needed here, as if the indefinite
3009- -- component depends on any inplace packages, it itself must
3010- -- be indefinite! There is no substitution here, we can't
3011- -- post facto add inplace deps
3012- return . InstallPlan. Configured $
3013- epkg
3014- { elabPkgOrComp =
3015- ElabComponent
3016- elab_comp
3017- { compLinkedLibDependencies = new_deps
3018- , -- I think this is right: any new definite unit ids we
3019- -- minted in the phase above need to be built before us.
3020- -- Add 'em in. This doesn't remove any old dependencies
3021- -- on the indefinite package; they're harmless.
3022- compOrderLibDependencies =
3023- ordNub $
3024- compOrderLibDependencies elab_comp
3025- ++ [unDefUnitId d | DefiniteUnitId d <- new_deps]
3026- }
3027- }
3028- | Just planpkg <- Map. lookup cid cmap =
3029- return planpkg
3030- | otherwise = error (" indefiniteComponent: " ++ prettyShow cid)
3006+ indefiniteComponent
3007+ :: ElaboratedConfiguredPackage
3008+ -> InstM ElaboratedConfiguredPackage
3009+ indefiniteComponent epkg =
3010+ case elabPkgOrComp epkg of
3011+ ElabPackage {} -> return epkg
3012+ ElabComponent elab_comp -> do
3013+ -- We need to do a little more processing of the includes: some
3014+ -- of them are fully definite even without substitution. We
3015+ -- want to build those too; see #5634.
3016+ --
3017+ -- This code mimics similar code in Distribution.Backpack.ReadyComponent;
3018+ -- however, unlike the conversion from LinkedComponent to
3019+ -- ReadyComponent, this transformation is done *without*
3020+ -- changing the type in question; and what we are simply
3021+ -- doing is enforcing tighter invariants on the data
3022+ -- structure in question. The new invariant is that there
3023+ -- is no IndefFullUnitId in compLinkedLibDependencies that actually
3024+ -- has no holes. We couldn't specify this invariant when
3025+ -- we initially created the ElaboratedPlanPackage because
3026+ -- we have no way of actually reifying the UnitId into a
3027+ -- DefiniteUnitId (that's what substUnitId does!)
3028+ new_deps <- for (compLinkedLibDependencies elab_comp) $ \ uid ->
3029+ if Set. null (openUnitIdFreeHoles uid)
3030+ then fmap (DefiniteUnitId . fst ) (instantiateUnit (elabStage epkg) Map. empty uid)
3031+ else return uid
3032+ -- NB: no fixupBuildStyle needed here, as if the indefinite
3033+ -- component depends on any inplace packages, it itself must
3034+ -- be indefinite! There is no substitution here, we can't
3035+ -- post facto add inplace deps
3036+ return
3037+ epkg
3038+ { elabPkgOrComp =
3039+ ElabComponent
3040+ elab_comp
3041+ { compLinkedLibDependencies = new_deps
3042+ , -- I think this is right: any new definite unit ids we
3043+ -- minted in the phase above need to be built before us.
3044+ -- Add 'em in. This doesn't remove any old dependencies
3045+ -- on the indefinite package; they're harmless.
3046+ compOrderLibDependencies =
3047+ ordNub $
3048+ compOrderLibDependencies elab_comp
3049+ ++ [unDefUnitId d | DefiniteUnitId d <- new_deps]
3050+ }
3051+ }
30313052
30323053 fixupBuildStyle BuildAndInstall elab = elab
3033- fixupBuildStyle _ (elab@ ElaboratedConfiguredPackage {elabBuildStyle = BuildInplaceOnly {}}) = elab
3034- fixupBuildStyle t @ (BuildInplaceOnly {}) elab =
3054+ fixupBuildStyle _buildStyle (elab@ ElaboratedConfiguredPackage {elabBuildStyle = BuildInplaceOnly {}}) = elab
3055+ fixupBuildStyle buildStyle @ (BuildInplaceOnly {}) elab =
30353056 elab
3036- { elabBuildStyle = t
3057+ { elabBuildStyle = buildStyle
30373058 , elabBuildPackageDBStack = elabInplaceBuildPackageDBStack elab
30383059 , elabRegisterPackageDBStack = elabInplaceRegisterPackageDBStack elab
30393060 , elabSetupPackageDBStack = elabInplaceSetupPackageDBStack elab
30403061 }
30413062
30423063 ready_map = execState work Map. empty
3043-
30443064 work = for_ pkgs $ \ pkg ->
30453065 case pkg of
30463066 InstallPlan. Configured (elab@ ElaboratedConfiguredPackage {elabPkgOrComp = ElabComponent comp})
3047- | not (Map. null (compLinkedInstantiatedWith comp)) ->
3048- indefiniteUnitId (elabComponentId elab)
3049- >> return ( )
3067+ | not (Map. null (compLinkedInstantiatedWith comp)) -> do
3068+ r <- indefiniteComponent elab
3069+ modify ( Map. insert ( WithStage (elabStage elab) (elabUnitId elab)) ( InstallPlan. Configured r) )
30503070 _ ->
3051- instantiateUnitId (getComponentId pkg) Map. empty
3052- >> return ()
3071+ void $ instantiateUnitId (stageOf pkg) (getComponentId pkg) Map. empty
3072+
3073+ -- | Create a 'DefUnitId' from a 'ComponentId' and an instantiation
3074+ -- with no holes.
3075+ --
3076+ -- This function is defined in Cabal-syntax but only cabal-install
3077+ -- cares about it so I am putting it here.
3078+ --
3079+ -- I am also not using the DefUnitId newtype since I believe it
3080+ -- provides little value in the code above.
3081+ mkDefUnitId :: ComponentId -> Map ModuleName Module -> UnitId
3082+ mkDefUnitId cid insts =
3083+ mkUnitId (unComponentId cid ++ maybe " " (" +" ++ ) (hashModuleSubst insts))
30533084
30543085---------------------------
30553086-- Build targets
0 commit comments