{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}

module Distribution.Types.LocalBuildInfo (
    -- * The type

    LocalBuildInfo(..),

    -- * Convenience accessors

    localComponentId,
    localUnitId,
    localCompatPackageKey,
    localPackage,

    -- * Build targets of the 'LocalBuildInfo'.

    componentNameCLBIs,

    -- NB: the primes mean that they take a 'PackageDescription'
    -- which may not match 'localPkgDescr' in 'LocalBuildInfo'.
    -- More logical types would drop this argument, but
    -- at the moment, this is the ONLY supported function, because
    -- 'localPkgDescr' is not guaranteed to match.  At some point
    -- we will fix it and then we can use the (free) unprimed
    -- namespace for the correct commands.
    --
    -- See https://github.com/haskell/cabal/issues/3606 for more
    -- details.

    componentNameTargets',
    unitIdTarget',
    allTargetsInBuildOrder',
    withAllTargetsInBuildOrder',
    neededTargetsInBuildOrder',
    withNeededTargetsInBuildOrder',
    testCoverage,

    -- * Functions you SHOULD NOT USE (yet), but are defined here to
    -- prevent someone from accidentally defining them

    componentNameTargets,
    unitIdTarget,
    allTargetsInBuildOrder,
    withAllTargetsInBuildOrder,
    neededTargetsInBuildOrder,
    withNeededTargetsInBuildOrder,

    -- * Backwards compatibility.

    componentsConfigs,
    externalPackageDeps,
  ) where

import Prelude ()
import Distribution.Compat.Prelude

import Distribution.Types.PackageDescription
import Distribution.Types.ComponentLocalBuildInfo
import Distribution.Types.ComponentRequestedSpec
import Distribution.Types.ComponentId
import Distribution.Types.MungedPackageId
import Distribution.Types.PackageId
import Distribution.Types.UnitId
import Distribution.Types.TargetInfo

import Distribution.Simple.InstallDirs hiding (absoluteInstallDirs,
                                               prefixRelativeInstallDirs,
                                               substPathTemplate, )
import Distribution.Simple.Program
import Distribution.PackageDescription
import Distribution.Simple.Compiler
import Distribution.Simple.PackageIndex
import Distribution.Simple.Setup
import Distribution.System
import Distribution.Pretty

import Distribution.Compat.Graph (Graph)
import qualified Distribution.Compat.Graph as Graph
import qualified Data.Map as Map

-- | Data cached after configuration step.  See also
-- 'Distribution.Simple.Setup.ConfigFlags'.
data LocalBuildInfo = LocalBuildInfo {
        LocalBuildInfo -> ConfigFlags
configFlags   :: ConfigFlags,
        -- ^ Options passed to the configuration step.
        -- Needed to re-run configuration when .cabal is out of date
        LocalBuildInfo -> FlagAssignment
flagAssignment :: FlagAssignment,
        -- ^ The final set of flags which were picked for this package
        LocalBuildInfo -> ComponentRequestedSpec
componentEnabledSpec :: ComponentRequestedSpec,
        -- ^ What components were enabled during configuration, and why.
        LocalBuildInfo -> [String]
extraConfigArgs     :: [String],
        -- ^ Extra args on the command line for the configuration step.
        -- Needed to re-run configuration when .cabal is out of date
        LocalBuildInfo -> InstallDirTemplates
installDirTemplates :: InstallDirTemplates,
                -- ^ The installation directories for the various different
                -- kinds of files
        --TODO: inplaceDirTemplates :: InstallDirs FilePath
        LocalBuildInfo -> Compiler
compiler      :: Compiler,
                -- ^ The compiler we're building with
        LocalBuildInfo -> Platform
hostPlatform  :: Platform,
                -- ^ The platform we're building for
        LocalBuildInfo -> String
buildDir      :: FilePath,
                -- ^ Where to build the package.
        LocalBuildInfo -> Maybe String
cabalFilePath :: Maybe FilePath,
                -- ^ Path to the cabal file, if given during configuration.
        LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph :: Graph ComponentLocalBuildInfo,
                -- ^ All the components to build, ordered by topological
                -- sort, and with their INTERNAL dependencies over the
                -- intrapackage dependency graph.
                -- TODO: this is assumed to be short; otherwise we want
                -- some sort of ordered map.
        LocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo]
componentNameMap :: Map ComponentName [ComponentLocalBuildInfo],
                -- ^ A map from component name to all matching
                -- components.  These coincide with 'componentGraph'
        LocalBuildInfo -> InstalledPackageIndex
installedPkgs :: InstalledPackageIndex,
                -- ^ All the info about the installed packages that the
                -- current package depends on (directly or indirectly).
                -- The copy saved on disk does NOT include internal
                -- dependencies (because we just don't have enough
                -- information at this point to have an
                -- 'InstalledPackageInfo' for an internal dep), but we
                -- will often update it with the internal dependencies;
                -- see for example 'Distribution.Simple.Build.build'.
                -- (This admonition doesn't apply for per-component builds.)
        LocalBuildInfo -> Maybe String
pkgDescrFile  :: Maybe FilePath,
                -- ^ the filename containing the .cabal file, if available
        LocalBuildInfo -> PackageDescription
localPkgDescr :: PackageDescription,
                -- ^ WARNING WARNING WARNING Be VERY careful about using
                -- this function; we haven't deprecated it but using it
                -- could introduce subtle bugs related to
                -- 'HookedBuildInfo'.
                --
                -- In principle, this is supposed to contain the
                -- resolved package description, that does not contain
                -- any conditionals.  However, it MAY NOT contain
                -- the description wtih a 'HookedBuildInfo' applied
                -- to it; see 'HookedBuildInfo' for the whole sordid saga.
                -- As much as possible, Cabal library should avoid using
                -- this parameter.
        LocalBuildInfo -> ProgramDb
withPrograms  :: ProgramDb, -- ^Location and args for all programs
        LocalBuildInfo -> PackageDBStack
withPackageDB :: PackageDBStack,  -- ^What package database to use, global\/user
        LocalBuildInfo -> Bool
withVanillaLib:: Bool,  -- ^Whether to build normal libs.
        LocalBuildInfo -> Bool
withProfLib   :: Bool,  -- ^Whether to build profiling versions of libs.
        LocalBuildInfo -> Bool
withSharedLib :: Bool,  -- ^Whether to build shared versions of libs.
        LocalBuildInfo -> Bool
withStaticLib :: Bool,  -- ^Whether to build static versions of libs (with all other libs rolled in)
        LocalBuildInfo -> Bool
withDynExe    :: Bool,  -- ^Whether to link executables dynamically
        LocalBuildInfo -> Bool
withFullyStaticExe :: Bool,  -- ^Whether to link executables fully statically
        LocalBuildInfo -> Bool
withProfExe   :: Bool,  -- ^Whether to build executables for profiling.
        LocalBuildInfo -> ProfDetailLevel
withProfLibDetail :: ProfDetailLevel, -- ^Level of automatic profile detail.
        LocalBuildInfo -> ProfDetailLevel
withProfExeDetail :: ProfDetailLevel, -- ^Level of automatic profile detail.
        LocalBuildInfo -> OptimisationLevel
withOptimization :: OptimisationLevel, -- ^Whether to build with optimization (if available).
        LocalBuildInfo -> DebugInfoLevel
withDebugInfo :: DebugInfoLevel, -- ^Whether to emit debug info (if available).
        LocalBuildInfo -> Bool
withGHCiLib   :: Bool,  -- ^Whether to build libs suitable for use with GHCi.
        LocalBuildInfo -> Bool
splitSections :: Bool,  -- ^Use -split-sections with GHC, if available
        LocalBuildInfo -> Bool
splitObjs     :: Bool,  -- ^Use -split-objs with GHC, if available
        LocalBuildInfo -> Bool
stripExes     :: Bool,  -- ^Whether to strip executables during install
        LocalBuildInfo -> Bool
stripLibs     :: Bool,  -- ^Whether to strip libraries during install
        LocalBuildInfo -> Bool
exeCoverage :: Bool,  -- ^Whether to enable executable program coverage
        LocalBuildInfo -> Bool
libCoverage :: Bool,  -- ^Whether to enable library program coverage
        LocalBuildInfo -> PathTemplate
progPrefix    :: PathTemplate, -- ^Prefix to be prepended to installed executables
        LocalBuildInfo -> PathTemplate
progSuffix    :: PathTemplate, -- ^Suffix to be appended to installed executables
        LocalBuildInfo -> Bool
relocatable   :: Bool --  ^Whether to build a relocatable package
  } deriving ((forall x. LocalBuildInfo -> Rep LocalBuildInfo x)
-> (forall x. Rep LocalBuildInfo x -> LocalBuildInfo)
-> Generic LocalBuildInfo
forall x. Rep LocalBuildInfo x -> LocalBuildInfo
forall x. LocalBuildInfo -> Rep LocalBuildInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LocalBuildInfo x -> LocalBuildInfo
$cfrom :: forall x. LocalBuildInfo -> Rep LocalBuildInfo x
Generic, ReadPrec [LocalBuildInfo]
ReadPrec LocalBuildInfo
Int -> ReadS LocalBuildInfo
ReadS [LocalBuildInfo]
(Int -> ReadS LocalBuildInfo)
-> ReadS [LocalBuildInfo]
-> ReadPrec LocalBuildInfo
-> ReadPrec [LocalBuildInfo]
-> Read LocalBuildInfo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [LocalBuildInfo]
$creadListPrec :: ReadPrec [LocalBuildInfo]
readPrec :: ReadPrec LocalBuildInfo
$creadPrec :: ReadPrec LocalBuildInfo
readList :: ReadS [LocalBuildInfo]
$creadList :: ReadS [LocalBuildInfo]
readsPrec :: Int -> ReadS LocalBuildInfo
$creadsPrec :: Int -> ReadS LocalBuildInfo
Read, Int -> LocalBuildInfo -> ShowS
[LocalBuildInfo] -> ShowS
LocalBuildInfo -> String
(Int -> LocalBuildInfo -> ShowS)
-> (LocalBuildInfo -> String)
-> ([LocalBuildInfo] -> ShowS)
-> Show LocalBuildInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LocalBuildInfo] -> ShowS
$cshowList :: [LocalBuildInfo] -> ShowS
show :: LocalBuildInfo -> String
$cshow :: LocalBuildInfo -> String
showsPrec :: Int -> LocalBuildInfo -> ShowS
$cshowsPrec :: Int -> LocalBuildInfo -> ShowS
Show)

instance Binary LocalBuildInfo

-------------------------------------------------------------------------------
-- Accessor functions

-- TODO: Get rid of these functions, as much as possible.  They are
-- a bit useful in some cases, but you should be very careful!

-- | Extract the 'ComponentId' from the public library component of a
-- 'LocalBuildInfo' if it exists, or make a fake component ID based
-- on the package ID.
localComponentId :: LocalBuildInfo -> ComponentId
localComponentId :: LocalBuildInfo -> ComponentId
localComponentId lbi :: LocalBuildInfo
lbi =
    case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
        [LibComponentLocalBuildInfo { componentComponentId :: ComponentLocalBuildInfo -> ComponentId
componentComponentId = ComponentId
cid }]
          -> ComponentId
cid
        _ -> String -> ComponentId
mkComponentId (PackageId -> String
forall a. Pretty a => a -> String
prettyShow (LocalBuildInfo -> PackageId
localPackage LocalBuildInfo
lbi))

-- | Extract the 'PackageIdentifier' of a 'LocalBuildInfo'.
-- This is a "safe" use of 'localPkgDescr'
localPackage :: LocalBuildInfo -> PackageId
localPackage :: LocalBuildInfo -> PackageId
localPackage lbi :: LocalBuildInfo
lbi = PackageDescription -> PackageId
package (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi)

-- | Extract the 'UnitId' from the library component of a
-- 'LocalBuildInfo' if it exists, or make a fake unit ID based on
-- the package ID.
localUnitId :: LocalBuildInfo -> UnitId
localUnitId :: LocalBuildInfo -> UnitId
localUnitId lbi :: LocalBuildInfo
lbi =
    case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
        [LibComponentLocalBuildInfo { componentUnitId :: ComponentLocalBuildInfo -> UnitId
componentUnitId = UnitId
uid }]
          -> UnitId
uid
        _ -> PackageId -> UnitId
mkLegacyUnitId (PackageId -> UnitId) -> PackageId -> UnitId
forall a b. (a -> b) -> a -> b
$ LocalBuildInfo -> PackageId
localPackage LocalBuildInfo
lbi

-- | Extract the compatibility package key from the public library component of a
-- 'LocalBuildInfo' if it exists, or make a fake package key based
-- on the package ID.
localCompatPackageKey :: LocalBuildInfo -> String
localCompatPackageKey :: LocalBuildInfo -> String
localCompatPackageKey lbi :: LocalBuildInfo
lbi =
    case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
        [LibComponentLocalBuildInfo { componentCompatPackageKey :: ComponentLocalBuildInfo -> String
componentCompatPackageKey = String
pk }]
          -> String
pk
        _ -> PackageId -> String
forall a. Pretty a => a -> String
prettyShow (LocalBuildInfo -> PackageId
localPackage LocalBuildInfo
lbi)

-- | Convenience function to generate a default 'TargetInfo' from a
-- 'ComponentLocalBuildInfo'.  The idea is to call this once, and then
-- use 'TargetInfo' everywhere else.  Private to this module.
mkTargetInfo :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo :: PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo pkg_descr :: PackageDescription
pkg_descr _lbi :: LocalBuildInfo
_lbi clbi :: ComponentLocalBuildInfo
clbi =
    TargetInfo :: ComponentLocalBuildInfo -> Component -> TargetInfo
TargetInfo {
        targetCLBI :: ComponentLocalBuildInfo
targetCLBI = ComponentLocalBuildInfo
clbi,
        -- NB: @pkg_descr@, not @localPkgDescr lbi@!
        targetComponent :: Component
targetComponent = PackageDescription -> ComponentName -> Component
getComponent PackageDescription
pkg_descr
                                       (ComponentLocalBuildInfo -> ComponentName
componentLocalName ComponentLocalBuildInfo
clbi)
     }

-- | Return all 'TargetInfo's associated with 'ComponentName'.
-- In the presence of Backpack there may be more than one!
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
componentNameTargets' :: PackageDescription -> LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets' :: PackageDescription
-> LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets' pkg_descr :: PackageDescription
pkg_descr lbi :: LocalBuildInfo
lbi cname :: ComponentName
cname =
    case ComponentName
-> Map ComponentName [ComponentLocalBuildInfo]
-> Maybe [ComponentLocalBuildInfo]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ComponentName
cname (LocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo]
componentNameMap LocalBuildInfo
lbi) of
        Just clbis :: [ComponentLocalBuildInfo]
clbis -> (ComponentLocalBuildInfo -> TargetInfo)
-> [ComponentLocalBuildInfo] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi) [ComponentLocalBuildInfo]
clbis
        Nothing -> []

unitIdTarget' :: PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' :: PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' pkg_descr :: PackageDescription
pkg_descr lbi :: LocalBuildInfo
lbi uid :: UnitId
uid =
    case Key ComponentLocalBuildInfo
-> Graph ComponentLocalBuildInfo -> Maybe ComponentLocalBuildInfo
forall a. IsNode a => Key a -> Graph a -> Maybe a
Graph.lookup Key ComponentLocalBuildInfo
UnitId
uid (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi) of
        Just clbi :: ComponentLocalBuildInfo
clbi -> TargetInfo -> Maybe TargetInfo
forall a. a -> Maybe a
Just (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi)
        Nothing -> Maybe TargetInfo
forall a. Maybe a
Nothing

-- | Return all 'ComponentLocalBuildInfo's associated with 'ComponentName'.
-- In the presence of Backpack there may be more than one!
componentNameCLBIs :: LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs :: LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs lbi :: LocalBuildInfo
lbi cname :: ComponentName
cname =
    case ComponentName
-> Map ComponentName [ComponentLocalBuildInfo]
-> Maybe [ComponentLocalBuildInfo]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ComponentName
cname (LocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo]
componentNameMap LocalBuildInfo
lbi) of
        Just clbis :: [ComponentLocalBuildInfo]
clbis -> [ComponentLocalBuildInfo]
clbis
        Nothing -> []

-- TODO: Maybe cache topsort (Graph can do this)

-- | Return the list of default 'TargetInfo's associated with a
-- configured package, in the order they need to be built.
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
allTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' pkg_descr :: PackageDescription
pkg_descr lbi :: LocalBuildInfo
lbi
    = (ComponentLocalBuildInfo -> TargetInfo)
-> [ComponentLocalBuildInfo] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi) (Graph ComponentLocalBuildInfo -> [ComponentLocalBuildInfo]
forall a. Graph a -> [a]
Graph.revTopSort (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi))

-- | Execute @f@ for every 'TargetInfo' in the package, respecting the
-- build dependency order.  (TODO: We should use Shake!)
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
withAllTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' :: PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' pkg_descr :: PackageDescription
pkg_descr lbi :: LocalBuildInfo
lbi f :: TargetInfo -> IO ()
f
    = [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [ TargetInfo -> IO ()
f TargetInfo
target | TargetInfo
target <- PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi ]

-- | Return the list of all targets needed to build the @uids@, in
-- the order they need to be built.
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
neededTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' pkg_descr :: PackageDescription
pkg_descr lbi :: LocalBuildInfo
lbi uids :: [UnitId]
uids =
  case Graph ComponentLocalBuildInfo
-> [Key ComponentLocalBuildInfo] -> Maybe [ComponentLocalBuildInfo]
forall a. Graph a -> [Key a] -> Maybe [a]
Graph.closure (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi) [Key ComponentLocalBuildInfo]
[UnitId]
uids of
    Nothing -> String -> [TargetInfo]
forall a. HasCallStack => String -> a
error (String -> [TargetInfo]) -> String -> [TargetInfo]
forall a b. (a -> b) -> a -> b
$ "localBuildPlan: missing uids " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate ", " ((UnitId -> String) -> [UnitId] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map UnitId -> String
forall a. Pretty a => a -> String
prettyShow [UnitId]
uids)
    Just clos :: [ComponentLocalBuildInfo]
clos -> (ComponentLocalBuildInfo -> TargetInfo)
-> [ComponentLocalBuildInfo] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi) (Graph ComponentLocalBuildInfo -> [ComponentLocalBuildInfo]
forall a. Graph a -> [a]
Graph.revTopSort ([ComponentLocalBuildInfo] -> Graph ComponentLocalBuildInfo
forall a. (IsNode a, Show (Key a)) => [a] -> Graph a
Graph.fromDistinctList [ComponentLocalBuildInfo]
clos))

-- | Execute @f@ for every 'TargetInfo' needed to build @uid@s, respecting
-- the build dependency order.
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
withNeededTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder' :: PackageDescription
-> LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder' pkg_descr :: PackageDescription
pkg_descr lbi :: LocalBuildInfo
lbi uids :: [UnitId]
uids f :: TargetInfo -> IO ()
f
    = [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [ TargetInfo -> IO ()
f TargetInfo
target | TargetInfo
target <- PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi [UnitId]
uids ]

-- | Is coverage enabled for test suites? In practice, this requires library
-- and executable profiling to be enabled.
testCoverage :: LocalBuildInfo -> Bool
testCoverage :: LocalBuildInfo -> Bool
testCoverage lbi :: LocalBuildInfo
lbi = LocalBuildInfo -> Bool
exeCoverage LocalBuildInfo
lbi Bool -> Bool -> Bool
&& LocalBuildInfo -> Bool
libCoverage LocalBuildInfo
lbi

-------------------------------------------------------------------------------
-- Stub functions to prevent someone from accidentally defining them

{-# WARNING componentNameTargets, unitIdTarget, allTargetsInBuildOrder, withAllTargetsInBuildOrder, neededTargetsInBuildOrder, withNeededTargetsInBuildOrder "By using this function, you may be introducing a bug where you retrieve a 'Component' which does not have 'HookedBuildInfo' applied to it.  See the documentation for 'HookedBuildInfo' for an explanation of the issue.  If you have a 'PakcageDescription' handy (NOT from the 'LocalBuildInfo'), try using the primed version of the function, which takes it as an extra argument." #-}

componentNameTargets :: LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets :: LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets lbi :: LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

unitIdTarget :: LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget :: LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget lbi :: LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

allTargetsInBuildOrder :: LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder :: LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder lbi :: LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

withAllTargetsInBuildOrder :: LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder :: LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder lbi :: LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

neededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder lbi :: LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

withNeededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder lbi :: LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

-------------------------------------------------------------------------------
-- Backwards compatibility

{-# DEPRECATED componentsConfigs "Use 'componentGraph' instead; you can get a list of 'ComponentLocalBuildInfo' with 'Distribution.Compat.Graph.toList'. There's not a good way to get the list of 'ComponentName's the 'ComponentLocalBuildInfo' depends on because this query doesn't make sense; the graph is indexed by 'UnitId' not 'ComponentName'.  Given a 'UnitId' you can lookup the 'ComponentLocalBuildInfo' ('getCLBI') and then get the 'ComponentName' ('componentLocalName]). To be removed in Cabal 3.0" #-}
componentsConfigs :: LocalBuildInfo -> [(ComponentName, ComponentLocalBuildInfo, [ComponentName])]
componentsConfigs :: LocalBuildInfo
-> [(ComponentName, ComponentLocalBuildInfo, [ComponentName])]
componentsConfigs lbi :: LocalBuildInfo
lbi =
    [ (ComponentLocalBuildInfo -> ComponentName
componentLocalName ComponentLocalBuildInfo
clbi,
       ComponentLocalBuildInfo
clbi,
       (UnitId -> Maybe ComponentName) -> [UnitId] -> [ComponentName]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((ComponentLocalBuildInfo -> ComponentName)
-> Maybe ComponentLocalBuildInfo -> Maybe ComponentName
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ComponentLocalBuildInfo -> ComponentName
componentLocalName (Maybe ComponentLocalBuildInfo -> Maybe ComponentName)
-> (UnitId -> Maybe ComponentLocalBuildInfo)
-> UnitId
-> Maybe ComponentName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnitId
 -> Graph ComponentLocalBuildInfo -> Maybe ComponentLocalBuildInfo)
-> Graph ComponentLocalBuildInfo
-> UnitId
-> Maybe ComponentLocalBuildInfo
forall a b c. (a -> b -> c) -> b -> a -> c
flip UnitId
-> Graph ComponentLocalBuildInfo -> Maybe ComponentLocalBuildInfo
forall a. IsNode a => Key a -> Graph a -> Maybe a
Graph.lookup Graph ComponentLocalBuildInfo
g)
                (ComponentLocalBuildInfo -> [UnitId]
componentInternalDeps ComponentLocalBuildInfo
clbi))
    | ComponentLocalBuildInfo
clbi <- Graph ComponentLocalBuildInfo -> [ComponentLocalBuildInfo]
forall a. Graph a -> [a]
Graph.toList Graph ComponentLocalBuildInfo
g ]
  where
    g :: Graph ComponentLocalBuildInfo
g = LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi

-- | External package dependencies for the package as a whole. This is the
-- union of the individual 'componentPackageDeps', less any internal deps.
{-# DEPRECATED externalPackageDeps "You almost certainly don't want this function, which agglomerates the dependencies of ALL enabled components.  If you're using this to write out information on your dependencies, read off the dependencies directly from the actual component in question.  To be removed in Cabal 3.0" #-}
externalPackageDeps :: LocalBuildInfo -> [(UnitId, MungedPackageId)]
externalPackageDeps :: LocalBuildInfo -> [(UnitId, MungedPackageId)]
externalPackageDeps lbi :: LocalBuildInfo
lbi =
    -- TODO:  what about non-buildable components?
    [(UnitId, MungedPackageId)] -> [(UnitId, MungedPackageId)]
forall a. Eq a => [a] -> [a]
nub [ (UnitId
ipkgid, MungedPackageId
pkgid)
        | ComponentLocalBuildInfo
clbi            <- Graph ComponentLocalBuildInfo -> [ComponentLocalBuildInfo]
forall a. Graph a -> [a]
Graph.toList (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi)
        , (ipkgid :: UnitId
ipkgid, pkgid :: MungedPackageId
pkgid) <- ComponentLocalBuildInfo -> [(UnitId, MungedPackageId)]
componentPackageDeps ComponentLocalBuildInfo
clbi
        , Bool -> Bool
not (UnitId -> Bool
internal UnitId
ipkgid) ]
  where
    -- True if this dependency is an internal one (depends on the library
    -- defined in the same package).
    internal :: UnitId -> Bool
internal ipkgid :: UnitId
ipkgid = (ComponentLocalBuildInfo -> Bool)
-> [ComponentLocalBuildInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
==UnitId
ipkgid) (UnitId -> Bool)
-> (ComponentLocalBuildInfo -> UnitId)
-> ComponentLocalBuildInfo
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ComponentLocalBuildInfo -> UnitId
componentUnitId) (Graph ComponentLocalBuildInfo -> [ComponentLocalBuildInfo]
forall a. Graph a -> [a]
Graph.toList (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi))