{-# LANGUAGE DeriveDataTypeable #-}
{-# 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
  ) where

import Distribution.Compat.Prelude
import Prelude ()

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

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

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

-- | 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 -> Map (PackageName, ComponentName) ComponentId
promisedPkgs :: Map (PackageName, ComponentName) ComponentId
  -- ^ The packages we were promised, but aren't already installed.
  -- MP: Perhaps this just needs to be a Set UnitId at this stage.
  , 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 with 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
$cfrom :: forall x. LocalBuildInfo -> Rep LocalBuildInfo x
from :: forall x. LocalBuildInfo -> Rep LocalBuildInfo x
$cto :: forall x. Rep LocalBuildInfo x -> LocalBuildInfo
to :: forall x. Rep LocalBuildInfo x -> LocalBuildInfo
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
$creadsPrec :: Int -> ReadS LocalBuildInfo
readsPrec :: Int -> ReadS LocalBuildInfo
$creadList :: ReadS [LocalBuildInfo]
readList :: ReadS [LocalBuildInfo]
$creadPrec :: ReadPrec LocalBuildInfo
readPrec :: ReadPrec LocalBuildInfo
$creadListPrec :: ReadPrec [LocalBuildInfo]
readListPrec :: ReadPrec [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
$cshowsPrec :: Int -> LocalBuildInfo -> ShowS
showsPrec :: Int -> LocalBuildInfo -> ShowS
$cshow :: LocalBuildInfo -> String
show :: LocalBuildInfo -> String
$cshowList :: [LocalBuildInfo] -> ShowS
showList :: [LocalBuildInfo] -> ShowS
Show, Typeable)

instance Binary LocalBuildInfo
instance Structured 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 LocalBuildInfo
lbi =
  case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
    [LibComponentLocalBuildInfo{componentComponentId :: ComponentLocalBuildInfo -> ComponentId
componentComponentId = ComponentId
cid}] ->
      ComponentId
cid
    [ComponentLocalBuildInfo]
_ -> 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 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 LocalBuildInfo
lbi =
  case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
    [LibComponentLocalBuildInfo{componentUnitId :: ComponentLocalBuildInfo -> UnitId
componentUnitId = UnitId
uid}] ->
      UnitId
uid
    [ComponentLocalBuildInfo]
_ -> 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 LocalBuildInfo
lbi =
  case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
    [LibComponentLocalBuildInfo{componentCompatPackageKey :: ComponentLocalBuildInfo -> String
componentCompatPackageKey = String
pk}] ->
      String
pk
    [ComponentLocalBuildInfo]
_ -> 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 PackageDescription
pkg_descr LocalBuildInfo
_lbi ComponentLocalBuildInfo
clbi =
  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' PackageDescription
pkg_descr LocalBuildInfo
lbi 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 [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
    Maybe [ComponentLocalBuildInfo]
Nothing -> []

unitIdTarget' :: PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' :: PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' PackageDescription
pkg_descr LocalBuildInfo
lbi 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 ComponentLocalBuildInfo
clbi -> TargetInfo -> Maybe TargetInfo
forall a. a -> Maybe a
Just (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi)
    Maybe ComponentLocalBuildInfo
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 LocalBuildInfo
lbi 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 [ComponentLocalBuildInfo]
clbis -> [ComponentLocalBuildInfo]
clbis
    Maybe [ComponentLocalBuildInfo]
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' PackageDescription
pkg_descr 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' PackageDescription
pkg_descr LocalBuildInfo
lbi 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' PackageDescription
pkg_descr LocalBuildInfo
lbi [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
    Maybe [ComponentLocalBuildInfo]
Nothing -> String -> [TargetInfo]
forall a. HasCallStack => String -> a
error (String -> [TargetInfo]) -> String -> [TargetInfo]
forall a b. (a -> b) -> a -> b
$ String
"localBuildPlan: missing uids " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((UnitId -> String) -> [UnitId] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map UnitId -> String
forall a. Pretty a => a -> String
prettyShow [UnitId]
uids)
    Just [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' PackageDescription
pkg_descr LocalBuildInfo
lbi [UnitId]
uids 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 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 'PackageDescription' 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 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 LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi
allTargetsInBuildOrder :: LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder :: LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi
withAllTargetsInBuildOrder :: LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder :: LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi
neededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder 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 LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi