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

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Distribution.Simple.Build
    -- Copyright   :  Isaac Jones 2003-2005,
    --                Ross Paterson 2006,
    --                Duncan Coutts 2007-2008, 2012
    -- License     :  BSD3
    --
    -- Maintainer  :  cabal-devel@haskell.org
    -- Portability :  portable
    --
    -- This is the entry point to actually building the modules in a package. It
    -- doesn't actually do much itself, most of the work is delegated to
    -- compiler-specific actions. It does do some non-compiler specific bits like
    -- running pre-processors.
    --

    module Distribution.Simple.Build (
        build, repl,
        startInterpreter,

        initialBuildSteps,
        createInternalPackageDB,
        componentInitialBuildSteps,
        writeAutogenFiles,
      ) where

    import Prelude ()
    import Distribution.Compat.Prelude
    import Distribution.Utils.Generic

    import Distribution.Types.ComponentLocalBuildInfo
    import Distribution.Types.ComponentRequestedSpec
    import Distribution.Types.Dependency
    import Distribution.Types.ExecutableScope
    import Distribution.Types.ForeignLib
    import Distribution.Types.LibraryVisibility
    import Distribution.Types.LocalBuildInfo
    import Distribution.Types.MungedPackageId
    import Distribution.Types.MungedPackageName
    import Distribution.Types.ModuleRenaming
    import Distribution.Types.TargetInfo
    import Distribution.Utils.Path

    import Distribution.Package
    import Distribution.Backpack
    import Distribution.Backpack.DescribeUnitId
    import qualified Distribution.Simple.GHC   as GHC
    import qualified Distribution.Simple.GHCJS as GHCJS
    import qualified Distribution.Simple.UHC   as UHC
    import qualified Distribution.Simple.HaskellSuite as HaskellSuite
    import qualified Distribution.Simple.PackageIndex as Index

    import Distribution.Simple.Build.Macros      (generateCabalMacrosHeader)
    import Distribution.Simple.Build.PackageInfoModule (generatePackageInfoModule)
    import Distribution.Simple.Build.PathsModule (generatePathsModule)
    import qualified Distribution.Simple.Program.HcPkg as HcPkg

    import Distribution.Simple.Compiler
    import Distribution.PackageDescription
    import qualified Distribution.InstalledPackageInfo as IPI
    import Distribution.InstalledPackageInfo (InstalledPackageInfo)
    import qualified Distribution.ModuleName as ModuleName

    import Distribution.Simple.Setup
    import Distribution.Simple.BuildTarget
    import Distribution.Simple.BuildToolDepends
    import Distribution.Simple.PreProcess
    import Distribution.Simple.LocalBuildInfo
    import Distribution.Simple.Program
    import Distribution.Simple.Program.Builtin (haskellSuiteProgram)
    import qualified Distribution.Simple.Program.GHC   as GHC
    import Distribution.Simple.Program.Types
    import Distribution.Simple.ShowBuildInfo
    import Distribution.Simple.BuildPaths
    import Distribution.Simple.Configure
    import Distribution.Simple.Register
    import Distribution.Simple.Test.LibV09
    import Distribution.Simple.Utils
    import Distribution.Utils.Json

    import Distribution.System
    import Distribution.Pretty
    import Distribution.Verbosity
    import Distribution.Version (thisVersion)

    import Distribution.Compat.Graph (IsNode(..))

    import Control.Monad
    import qualified Data.ByteString.Lazy as LBS
    import System.FilePath ( (</>), (<.>), takeDirectory )
    import System.Directory ( getCurrentDirectory, removeFile, doesFileExist )

    -- -----------------------------------------------------------------------------
    -- |Build the libraries and executables in this package.

    build    :: PackageDescription  -- ^ Mostly information from the .cabal file
             -> LocalBuildInfo      -- ^ Configuration information
             -> BuildFlags          -- ^ Flags that the user passed to build
             -> [ PPSuffixHandler ] -- ^ preprocessors to run before compiling
             -> IO ()
    build :: PackageDescription
    -> LocalBuildInfo -> BuildFlags -> [PPSuffixHandler] -> IO ()
    build PackageDescription
    pkg_descr LocalBuildInfo
    lbi BuildFlags
    flags [PPSuffixHandler]
    suffixes = do
      [TargetInfo]
    targets <- Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> [String]
    -> IO [TargetInfo]
    readTargetInfos Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi (BuildFlags -> [String]
    buildArgs BuildFlags
    flags)
      let componentsToBuild :: [TargetInfo]
    componentsToBuild = PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
    neededTargetsInBuildOrder' PackageDescription
    pkg_descr LocalBuildInfo
    lbi ((TargetInfo -> UnitId) -> [TargetInfo] -> [UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map TargetInfo -> Key TargetInfo
    TargetInfo -> UnitId
    forall a. IsNode a => a -> Key a
    nodeKey [TargetInfo]
    targets)
      Verbosity -> String -> IO ()
    info Verbosity
    verbosity (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String
    "Component build order: "
                    String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate String
    ", "
                        ((TargetInfo -> String) -> [TargetInfo] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (ComponentName -> String
    showComponentName (ComponentName -> String)
    -> (TargetInfo -> ComponentName) -> TargetInfo -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ComponentLocalBuildInfo -> ComponentName
    componentLocalName (ComponentLocalBuildInfo -> ComponentName)
    -> (TargetInfo -> ComponentLocalBuildInfo)
    -> TargetInfo
    -> ComponentName
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TargetInfo -> ComponentLocalBuildInfo
    targetCLBI)
                            [TargetInfo]
    componentsToBuild)

      Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when ([TargetInfo] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TargetInfo]
    targets) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
        -- Only bother with this message if we're building the whole package
        Verbosity -> String -> PackageIdentifier -> IO ()
    setupMessage Verbosity
    verbosity String
    "Building" (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr)

      PackageDB
    internalPackageDB <- Verbosity -> LocalBuildInfo -> String -> IO PackageDB
    createInternalPackageDB Verbosity
    verbosity LocalBuildInfo
    lbi String
    distPref

      -- Before the actual building, dump out build-information.
      -- This way, if the actual compilation failed, the options have still been
      -- dumped.
      Verbosity
    -> String
    -> Flag DumpBuildInfo
    -> PackageDescription
    -> LocalBuildInfo
    -> BuildFlags
    -> IO ()
    dumpBuildInfo Verbosity
    verbosity String
    distPref (ConfigFlags -> Flag DumpBuildInfo
    configDumpBuildInfo (LocalBuildInfo -> ConfigFlags
    configFlags LocalBuildInfo
    lbi)) PackageDescription
    pkg_descr LocalBuildInfo
    lbi BuildFlags
    flags

      -- Now do the actual building
      (\InstalledPackageIndex -> TargetInfo -> IO InstalledPackageIndex
    f -> (InstalledPackageIndex -> TargetInfo -> IO InstalledPackageIndex)
    -> InstalledPackageIndex -> [TargetInfo] -> IO ()
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m ()
    foldM_ InstalledPackageIndex -> TargetInfo -> IO InstalledPackageIndex
    f (LocalBuildInfo -> InstalledPackageIndex
    installedPkgs LocalBuildInfo
    lbi) [TargetInfo]
    componentsToBuild) ((InstalledPackageIndex -> TargetInfo -> IO InstalledPackageIndex)
     -> IO ())
    -> (InstalledPackageIndex
        -> TargetInfo -> IO InstalledPackageIndex)
    -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \InstalledPackageIndex
    index TargetInfo
    target -> do
        let comp :: Component
    comp = TargetInfo -> Component
    targetComponent TargetInfo
    target
            clbi :: ComponentLocalBuildInfo
    clbi = TargetInfo -> ComponentLocalBuildInfo
    targetCLBI TargetInfo
    target
        String
    -> PackageDescription
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO ()
    componentInitialBuildSteps String
    distPref PackageDescription
    pkg_descr LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity
        let bi :: BuildInfo
    bi     = Component -> BuildInfo
    componentBuildInfo Component
    comp
            progs' :: ProgramDb
    progs' = PackageDescription
    -> LocalBuildInfo -> BuildInfo -> ProgramDb -> ProgramDb
    addInternalBuildTools PackageDescription
    pkg_descr LocalBuildInfo
    lbi BuildInfo
    bi (LocalBuildInfo -> ProgramDb
    withPrograms LocalBuildInfo
    lbi)
            lbi' :: LocalBuildInfo
    lbi'   = LocalBuildInfo
    lbi {
                       withPrograms  = progs',
                       withPackageDB = withPackageDB lbi ++ [internalPackageDB],
                       installedPkgs = index
                     }
        Maybe InstalledPackageInfo
    mb_ipi <- Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> [PPSuffixHandler]
    -> Component
    -> ComponentLocalBuildInfo
    -> String
    -> IO (Maybe InstalledPackageInfo)
    buildComponent Verbosity
    verbosity (BuildFlags -> Flag (Maybe Int)
    buildNumJobs BuildFlags
    flags) PackageDescription
    pkg_descr
                       LocalBuildInfo
    lbi' [PPSuffixHandler]
    suffixes Component
    comp ComponentLocalBuildInfo
    clbi String
    distPref
        InstalledPackageIndex -> IO InstalledPackageIndex
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (InstalledPackageIndex
    -> (InstalledPackageInfo -> InstalledPackageIndex)
    -> Maybe InstalledPackageInfo
    -> InstalledPackageIndex
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe InstalledPackageIndex
    index (InstalledPackageInfo
    -> InstalledPackageIndex -> InstalledPackageIndex
    Index.insert (InstalledPackageInfo
     -> InstalledPackageIndex -> InstalledPackageIndex)
    -> InstalledPackageIndex
    -> InstalledPackageInfo
    -> InstalledPackageIndex
    forall a b c. (a -> b -> c) -> b -> a -> c
    `flip` InstalledPackageIndex
    index) Maybe InstalledPackageInfo
    mb_ipi)

      () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
     where
      distPref :: String
    distPref  = Flag String -> String
    forall a. WithCallStack (Flag a -> a)
    fromFlag (BuildFlags -> Flag String
    buildDistPref BuildFlags
    flags)
      verbosity :: Verbosity
    verbosity = Flag Verbosity -> Verbosity
    forall a. WithCallStack (Flag a -> a)
    fromFlag (BuildFlags -> Flag Verbosity
    buildVerbosity BuildFlags
    flags)

    -- | Write available build information for 'LocalBuildInfo' to disk.
    --
    -- Dumps detailed build information 'build-info.json' to the given directory.
    -- Build information contains basics such as compiler details, but also
    -- lists what modules a component contains and how to compile the component, assuming
    -- lib:Cabal made sure that dependencies are up-to-date.
    dumpBuildInfo :: Verbosity
                  -> FilePath           -- ^ To which directory should the build-info be dumped?
                  -> Flag DumpBuildInfo -- ^ Should we dump detailed build information for this component?
                  -> PackageDescription -- ^ Mostly information from the .cabal file
                  -> LocalBuildInfo     -- ^ Configuration information
                  -> BuildFlags         -- ^ Flags that the user passed to build
                  -> IO ()
    dumpBuildInfo :: Verbosity
    -> String
    -> Flag DumpBuildInfo
    -> PackageDescription
    -> LocalBuildInfo
    -> BuildFlags
    -> IO ()
    dumpBuildInfo Verbosity
    verbosity String
    distPref Flag DumpBuildInfo
    dumpBuildInfoFlag PackageDescription
    pkg_descr LocalBuildInfo
    lbi BuildFlags
    flags = do
      Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    shouldDumpBuildInfo (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
        -- Changing this line might break consumers of the dumped build info.
        -- Announce changes on mailing lists!
        let activeTargets :: [TargetInfo]
    activeTargets = PackageDescription -> LocalBuildInfo -> [TargetInfo]
    allTargetsInBuildOrder' PackageDescription
    pkg_descr LocalBuildInfo
    lbi
        Verbosity -> String -> IO ()
    info Verbosity
    verbosity (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String
    "Dump build information for: "
                      String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate String
    ", "
                          ((TargetInfo -> String) -> [TargetInfo] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (ComponentName -> String
    showComponentName (ComponentName -> String)
    -> (TargetInfo -> ComponentName) -> TargetInfo -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ComponentLocalBuildInfo -> ComponentName
    componentLocalName (ComponentLocalBuildInfo -> ComponentName)
    -> (TargetInfo -> ComponentLocalBuildInfo)
    -> TargetInfo
    -> ComponentName
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TargetInfo -> ComponentLocalBuildInfo
    targetCLBI)
                              [TargetInfo]
    activeTargets)
        String
    pwd <- IO String
    getCurrentDirectory

        (ConfiguredProgram
    compilerProg, ProgramDb
    _) <- case CompilerFlavor -> Maybe Program
    flavorToProgram (Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi)) of
          Maybe Program
    Nothing -> Verbosity -> String -> IO (ConfiguredProgram, ProgramDb)
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity (String -> IO (ConfiguredProgram, ProgramDb))
    -> String -> IO (ConfiguredProgram, ProgramDb)
    forall a b. (a -> b) -> a -> b
    $ String
    "dumpBuildInfo: Unknown compiler flavor: "
                                   String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CompilerFlavor -> String
    forall a. Show a => a -> String
    show (Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi))
          Just Program
    program -> Verbosity
    -> Program -> ProgramDb -> IO (ConfiguredProgram, ProgramDb)
    requireProgram Verbosity
    verbosity Program
    program (LocalBuildInfo -> ProgramDb
    withPrograms LocalBuildInfo
    lbi)

        let ([String]
    warns, Json
    json) = String
    -> PackageDescription
    -> LocalBuildInfo
    -> BuildFlags
    -> (ConfiguredProgram, Compiler)
    -> [TargetInfo]
    -> ([String], Json)
    mkBuildInfo String
    pwd PackageDescription
    pkg_descr LocalBuildInfo
    lbi BuildFlags
    flags (ConfiguredProgram
    compilerProg, LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) [TargetInfo]
    activeTargets
            buildInfoText :: ByteString
    buildInfoText = Json -> ByteString
    renderJson Json
    json
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ([String] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [String]
    warns) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          Verbosity -> String -> IO ()
    warn Verbosity
    verbosity (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String
    "Encountered warnings while dumping build-info:\n"
                        String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ [String] -> String
    unlines [String]
    warns
        String -> ByteString -> IO ()
    LBS.writeFile (String -> String
    buildInfoPref String
    distPref) ByteString
    buildInfoText

      Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not Bool
    shouldDumpBuildInfo) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
        -- Remove existing build-info.json as it might be outdated now.
        Bool
    exists <- String -> IO Bool
    doesFileExist (String -> String
    buildInfoPref String
    distPref)
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    exists (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String -> IO ()
    removeFile (String -> String
    buildInfoPref String
    distPref)
      where
        shouldDumpBuildInfo :: Bool
    shouldDumpBuildInfo = DumpBuildInfo -> Flag DumpBuildInfo -> DumpBuildInfo
    forall a. a -> Flag a -> a
    fromFlagOrDefault DumpBuildInfo
    NoDumpBuildInfo Flag DumpBuildInfo
    dumpBuildInfoFlag DumpBuildInfo -> DumpBuildInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DumpBuildInfo
    DumpBuildInfo

        -- | Given the flavor of the compiler, try to find out
        -- which program we need.
        flavorToProgram :: CompilerFlavor -> Maybe Program
        flavorToProgram :: CompilerFlavor -> Maybe Program
    flavorToProgram CompilerFlavor
    GHC             = Program -> Maybe Program
    forall a. a -> Maybe a
    Just Program
    ghcProgram
        flavorToProgram CompilerFlavor
    GHCJS           = Program -> Maybe Program
    forall a. a -> Maybe a
    Just Program
    ghcjsProgram
        flavorToProgram CompilerFlavor
    UHC             = Program -> Maybe Program
    forall a. a -> Maybe a
    Just Program
    uhcProgram
        flavorToProgram CompilerFlavor
    JHC             = Program -> Maybe Program
    forall a. a -> Maybe a
    Just Program
    jhcProgram
        flavorToProgram HaskellSuite {} = Program -> Maybe Program
    forall a. a -> Maybe a
    Just Program
    haskellSuiteProgram
        flavorToProgram CompilerFlavor
    _     = Maybe Program
    forall a. Maybe a
    Nothing

    repl     :: PackageDescription  -- ^ Mostly information from the .cabal file
             -> LocalBuildInfo      -- ^ Configuration information
             -> ReplFlags           -- ^ Flags that the user passed to build
             -> [ PPSuffixHandler ] -- ^ preprocessors to run before compiling
             -> [String]
             -> IO ()
    repl :: PackageDescription
    -> LocalBuildInfo
    -> ReplFlags
    -> [PPSuffixHandler]
    -> [String]
    -> IO ()
    repl PackageDescription
    pkg_descr LocalBuildInfo
    lbi ReplFlags
    flags [PPSuffixHandler]
    suffixes [String]
    args = do
      let distPref :: String
    distPref  = Flag String -> String
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ReplFlags -> Flag String
    replDistPref ReplFlags
    flags)
          verbosity :: Verbosity
    verbosity = Flag Verbosity -> Verbosity
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ReplFlags -> Flag Verbosity
    replVerbosity ReplFlags
    flags)

      TargetInfo
    target <- Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> [String]
    -> IO [TargetInfo]
    readTargetInfos Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi [String]
    args IO [TargetInfo] -> ([TargetInfo] -> IO TargetInfo) -> IO TargetInfo
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \[TargetInfo]
    r -> case [TargetInfo]
    r of
        -- This seems DEEPLY questionable.
        []       -> case PackageDescription -> LocalBuildInfo -> [TargetInfo]
    allTargetsInBuildOrder' PackageDescription
    pkg_descr LocalBuildInfo
    lbi of
          (TargetInfo
    target:[TargetInfo]
    _) -> TargetInfo -> IO TargetInfo
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TargetInfo
    target
          []         -> Verbosity -> String -> IO TargetInfo
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity (String -> IO TargetInfo) -> String -> IO TargetInfo
    forall a b. (a -> b) -> a -> b
    $ String
    "Failed to determine target."
        [TargetInfo
    target] -> TargetInfo -> IO TargetInfo
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TargetInfo
    target
        [TargetInfo]
    _        -> Verbosity -> String -> IO TargetInfo
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity (String -> IO TargetInfo) -> String -> IO TargetInfo
    forall a b. (a -> b) -> a -> b
    $ String
    "The 'repl' command does not support multiple targets at once."
      let componentsToBuild :: [TargetInfo]
    componentsToBuild = PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
    neededTargetsInBuildOrder' PackageDescription
    pkg_descr LocalBuildInfo
    lbi [TargetInfo -> Key TargetInfo
    forall a. IsNode a => a -> Key a
    nodeKey TargetInfo
    target]
      Verbosity -> String -> IO ()
    debug Verbosity
    verbosity (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String
    "Component build order: "
                     String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate String
    ", "
                          ((TargetInfo -> String) -> [TargetInfo] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (ComponentName -> String
    showComponentName (ComponentName -> String)
    -> (TargetInfo -> ComponentName) -> TargetInfo -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ComponentLocalBuildInfo -> ComponentName
    componentLocalName (ComponentLocalBuildInfo -> ComponentName)
    -> (TargetInfo -> ComponentLocalBuildInfo)
    -> TargetInfo
    -> ComponentName
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TargetInfo -> ComponentLocalBuildInfo
    targetCLBI)
                               [TargetInfo]
    componentsToBuild)

      PackageDB
    internalPackageDB <- Verbosity -> LocalBuildInfo -> String -> IO PackageDB
    createInternalPackageDB Verbosity
    verbosity LocalBuildInfo
    lbi String
    distPref

      let lbiForComponent :: Component -> LocalBuildInfo -> LocalBuildInfo
    lbiForComponent Component
    comp LocalBuildInfo
    lbi' =
            LocalBuildInfo
    lbi' {
              withPackageDB = withPackageDB lbi ++ [internalPackageDB],
              withPrograms  = addInternalBuildTools pkg_descr lbi'
                                (componentBuildInfo comp) (withPrograms lbi')
            }

      -- build any dependent components
      [IO (Maybe InstalledPackageInfo)] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a.
    (Foldable t, Monad m) =>
    t (m a) -> m ()
    sequence_
        [ do let clbi :: ComponentLocalBuildInfo
    clbi = TargetInfo -> ComponentLocalBuildInfo
    targetCLBI TargetInfo
    subtarget
                 comp :: Component
    comp = TargetInfo -> Component
    targetComponent TargetInfo
    subtarget
                 lbi' :: LocalBuildInfo
    lbi' = Component -> LocalBuildInfo -> LocalBuildInfo
    lbiForComponent Component
    comp LocalBuildInfo
    lbi
             String
    -> PackageDescription
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO ()
    componentInitialBuildSteps String
    distPref PackageDescription
    pkg_descr LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity
             Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> [PPSuffixHandler]
    -> Component
    -> ComponentLocalBuildInfo
    -> String
    -> IO (Maybe InstalledPackageInfo)
    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    forall a. Flag a
    NoFlag
                            PackageDescription
    pkg_descr LocalBuildInfo
    lbi' [PPSuffixHandler]
    suffixes Component
    comp ComponentLocalBuildInfo
    clbi String
    distPref
        | TargetInfo
    subtarget <- [TargetInfo] -> [TargetInfo]
    forall a. [a] -> [a]
    safeInit [TargetInfo]
    componentsToBuild ]

      -- REPL for target components
      let clbi :: ComponentLocalBuildInfo
    clbi = TargetInfo -> ComponentLocalBuildInfo
    targetCLBI TargetInfo
    target
          comp :: Component
    comp = TargetInfo -> Component
    targetComponent TargetInfo
    target
          lbi' :: LocalBuildInfo
    lbi' = Component -> LocalBuildInfo -> LocalBuildInfo
    lbiForComponent Component
    comp LocalBuildInfo
    lbi
          replFlags :: ReplOptions
    replFlags = ReplFlags -> ReplOptions
    replReplOptions ReplFlags
    flags
      String
    -> PackageDescription
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO ()
    componentInitialBuildSteps String
    distPref PackageDescription
    pkg_descr LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity
      ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> [PPSuffixHandler]
    -> Component
    -> ComponentLocalBuildInfo
    -> String
    -> IO ()
    replComponent ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi' [PPSuffixHandler]
    suffixes Component
    comp ComponentLocalBuildInfo
    clbi String
    distPref

    -- | Start an interpreter without loading any package files.
    startInterpreter :: Verbosity -> ProgramDb -> Compiler -> Platform
                     -> PackageDBStack -> IO ()
    startInterpreter :: Verbosity
    -> ProgramDb -> Compiler -> Platform -> PackageDBStack -> IO ()
    startInterpreter Verbosity
    verbosity ProgramDb
    programDb Compiler
    comp Platform
    platform PackageDBStack
    packageDBs =
      case Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp of
        CompilerFlavor
    GHC   -> Verbosity
    -> ProgramDb -> Compiler -> Platform -> PackageDBStack -> IO ()
    GHC.startInterpreter   Verbosity
    verbosity ProgramDb
    programDb Compiler
    comp Platform
    platform PackageDBStack
    packageDBs
        CompilerFlavor
    GHCJS -> Verbosity
    -> ProgramDb -> Compiler -> Platform -> PackageDBStack -> IO ()
    GHCJS.startInterpreter Verbosity
    verbosity ProgramDb
    programDb Compiler
    comp Platform
    platform PackageDBStack
    packageDBs
        CompilerFlavor
    _     -> Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity String
    "A REPL is not supported with this compiler."

    buildComponent :: Verbosity
                   -> Flag (Maybe Int)
                   -> PackageDescription
                   -> LocalBuildInfo
                   -> [PPSuffixHandler]
                   -> Component
                   -> ComponentLocalBuildInfo
                   -> FilePath
                   -> IO (Maybe InstalledPackageInfo)
    buildComponent :: Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> [PPSuffixHandler]
    -> Component
    -> ComponentLocalBuildInfo
    -> String
    -> IO (Maybe InstalledPackageInfo)
    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CLib Library
    lib) ComponentLocalBuildInfo
    clbi String
    distPref = do
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, OpenModule)]
    -> IO ()
    forall a.
    Pretty a =>
    Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, a)]
    -> IO ()
    setupMessage' Verbosity
    verbosity String
    "Building" (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr)
          (ComponentLocalBuildInfo -> ComponentName
    componentLocalName ComponentLocalBuildInfo
    clbi) (ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith ComponentLocalBuildInfo
    clbi)
        let libbi :: BuildInfo
    libbi = Library -> BuildInfo
    libBuildInfo Library
    lib
            lib' :: Library
    lib' = Library
    lib { libBuildInfo = flip addExtraAsmSources extras
                                      $ flip addExtraCmmSources extras
                                      $ flip addExtraCxxSources extras
                                      $ flip addExtraCSources   extras
                                      $ flip addExtraJsSources  extras
                                      $ libbi
                       }

        Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    buildLib Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib' ComponentLocalBuildInfo
    clbi

        let oneComponentRequested :: ComponentRequestedSpec -> Bool
    oneComponentRequested (OneComponentRequestedSpec ComponentName
    _) = Bool
    True
            oneComponentRequested ComponentRequestedSpec
    _ = Bool
    False
        -- Don't register inplace if we're only building a single component;
        -- it's not necessary because there won't be any subsequent builds
        -- that need to tag us
        if (Bool -> Bool
    not (ComponentRequestedSpec -> Bool
    oneComponentRequested (LocalBuildInfo -> ComponentRequestedSpec
    componentEnabledSpec LocalBuildInfo
    lbi)))
          then do
            -- Register the library in-place, so exes can depend
            -- on internally defined libraries.
            String
    pwd <- IO String
    getCurrentDirectory
            let -- The in place registration uses the "-inplace" suffix, not an ABI hash
                installedPkgInfo :: InstalledPackageInfo
    installedPkgInfo = String
    -> String
    -> PackageDescription
    -> AbiHash
    -> Library
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> InstalledPackageInfo
    inplaceInstalledPackageInfo String
    pwd String
    distPref PackageDescription
    pkg_descr
                                        -- NB: Use a fake ABI hash to avoid
                                        -- needing to recompute it every build.
                                        (String -> AbiHash
    mkAbiHash String
    "inplace") Library
    lib' LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi

            Verbosity -> String -> IO ()
    debug Verbosity
    verbosity (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String
    "Registering inplace:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (InstalledPackageInfo -> String
    IPI.showInstalledPackageInfo InstalledPackageInfo
    installedPkgInfo)
            Verbosity
    -> Compiler
    -> ProgramDb
    -> PackageDBStack
    -> InstalledPackageInfo
    -> RegisterOptions
    -> IO ()
    registerPackage Verbosity
    verbosity (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) (LocalBuildInfo -> ProgramDb
    withPrograms LocalBuildInfo
    lbi)
                            (LocalBuildInfo -> PackageDBStack
    withPackageDB LocalBuildInfo
    lbi) InstalledPackageInfo
    installedPkgInfo
                            RegisterOptions
    HcPkg.defaultRegisterOptions {
                              HcPkg.registerMultiInstance = True
                            }
            Maybe InstalledPackageInfo -> IO (Maybe InstalledPackageInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (InstalledPackageInfo -> Maybe InstalledPackageInfo
    forall a. a -> Maybe a
    Just InstalledPackageInfo
    installedPkgInfo)
          else Maybe InstalledPackageInfo -> IO (Maybe InstalledPackageInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe InstalledPackageInfo
    forall a. Maybe a
    Nothing

    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CFLib ForeignLib
    flib) ComponentLocalBuildInfo
    clbi String
    _distPref = do
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, OpenModule)]
    -> IO ()
    forall a.
    Pretty a =>
    Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, a)]
    -> IO ()
    setupMessage' Verbosity
    verbosity String
    "Building" (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr)
          (ComponentLocalBuildInfo -> ComponentName
    componentLocalName ComponentLocalBuildInfo
    clbi) (ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith ComponentLocalBuildInfo
    clbi)
        Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> ForeignLib
    -> ComponentLocalBuildInfo
    -> IO ()
    buildFLib Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi ForeignLib
    flib ComponentLocalBuildInfo
    clbi
        Maybe InstalledPackageInfo -> IO (Maybe InstalledPackageInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe InstalledPackageInfo
    forall a. Maybe a
    Nothing

    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CExe Executable
    exe) ComponentLocalBuildInfo
    clbi String
    _ = do
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, OpenModule)]
    -> IO ()
    forall a.
    Pretty a =>
    Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, a)]
    -> IO ()
    setupMessage' Verbosity
    verbosity String
    "Building" (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr)
          (ComponentLocalBuildInfo -> ComponentName
    componentLocalName ComponentLocalBuildInfo
    clbi) (ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith ComponentLocalBuildInfo
    clbi)
        let ebi :: BuildInfo
    ebi = Executable -> BuildInfo
    buildInfo Executable
    exe
            exe' :: Executable
    exe' = Executable
    exe { buildInfo = addExtraCSources ebi extras }
        Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    buildExe Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe' ComponentLocalBuildInfo
    clbi
        Maybe InstalledPackageInfo -> IO (Maybe InstalledPackageInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe InstalledPackageInfo
    forall a. Maybe a
    Nothing

    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CTest test :: TestSuite
    test@TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteExeV10{} })
                   ComponentLocalBuildInfo
    clbi String
    _distPref = do
        let exe :: Executable
    exe = TestSuite -> Executable
    testSuiteExeV10AsExe TestSuite
    test
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        (String
    genDir, [ModuleName]
    generatedExtras) <- [String]
    -> UnqualComponentName
    -> PackageDescription
    -> BuildInfo
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO (String, [ModuleName])
    generateCode (TestSuite -> [String]
    testCodeGenerators TestSuite
    test) (TestSuite -> UnqualComponentName
    testName TestSuite
    test) PackageDescription
    pkg_descr (TestSuite -> BuildInfo
    testBuildInfo TestSuite
    test) LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity
        Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, OpenModule)]
    -> IO ()
    forall a.
    Pretty a =>
    Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, a)]
    -> IO ()
    setupMessage' Verbosity
    verbosity String
    "Building" (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr)
          (ComponentLocalBuildInfo -> ComponentName
    componentLocalName ComponentLocalBuildInfo
    clbi) (ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith ComponentLocalBuildInfo
    clbi)
        let ebi :: BuildInfo
    ebi = Executable -> BuildInfo
    buildInfo Executable
    exe
            exe' :: Executable
    exe' = Executable
    exe { buildInfo = addSrcDir (addExtraOtherModules (addExtraCSources ebi extras) generatedExtras) genDir } -- todo extend hssrcdirs
        Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    buildExe Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe' ComponentLocalBuildInfo
    clbi
        Maybe InstalledPackageInfo -> IO (Maybe InstalledPackageInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe InstalledPackageInfo
    forall a. Maybe a
    Nothing

    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi0 [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CTest
                     test :: TestSuite
    test@TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteLibV09{} })
                   ComponentLocalBuildInfo
    clbi -- This ComponentLocalBuildInfo corresponds to a detailed
                        -- test suite and not a real component. It should not
                        -- be used, except to construct the CLBIs for the
                        -- library and stub executable that will actually be
                        -- built.
                   String
    distPref = do
        String
    pwd <- IO String
    getCurrentDirectory
        let (PackageDescription
    pkg, Library
    lib, ComponentLocalBuildInfo
    libClbi, LocalBuildInfo
    lbi, InstalledPackageInfo
    ipi, Executable
    exe, ComponentLocalBuildInfo
    exeClbi) =
              PackageDescription
    -> TestSuite
    -> ComponentLocalBuildInfo
    -> LocalBuildInfo
    -> String
    -> String
    -> (PackageDescription, Library, ComponentLocalBuildInfo,
        LocalBuildInfo, InstalledPackageInfo, Executable,
        ComponentLocalBuildInfo)
    testSuiteLibV09AsLibAndExe PackageDescription
    pkg_descr TestSuite
    test ComponentLocalBuildInfo
    clbi LocalBuildInfo
    lbi0 String
    distPref String
    pwd
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi -- TODO find cpphs processed files
        (String
    genDir, [ModuleName]
    generatedExtras) <- [String]
    -> UnqualComponentName
    -> PackageDescription
    -> BuildInfo
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO (String, [ModuleName])
    generateCode (TestSuite -> [String]
    testCodeGenerators TestSuite
    test) (TestSuite -> UnqualComponentName
    testName TestSuite
    test) PackageDescription
    pkg_descr (TestSuite -> BuildInfo
    testBuildInfo TestSuite
    test) LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity
        Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, OpenModule)]
    -> IO ()
    forall a.
    Pretty a =>
    Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, a)]
    -> IO ()
    setupMessage' Verbosity
    verbosity String
    "Building" (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr)
          (ComponentLocalBuildInfo -> ComponentName
    componentLocalName ComponentLocalBuildInfo
    clbi) (ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith ComponentLocalBuildInfo
    clbi)
        let libbi :: BuildInfo
    libbi = Library -> BuildInfo
    libBuildInfo Library
    lib
            lib' :: Library
    lib' = Library
    lib { libBuildInfo = addSrcDir (addExtraOtherModules libbi generatedExtras) genDir }
        Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    buildLib Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg LocalBuildInfo
    lbi Library
    lib' ComponentLocalBuildInfo
    libClbi
        -- NB: need to enable multiple instances here, because on 7.10+
        -- the package name is the same as the library, and we still
        -- want the registration to go through.
        Verbosity
    -> Compiler
    -> ProgramDb
    -> PackageDBStack
    -> InstalledPackageInfo
    -> RegisterOptions
    -> IO ()
    registerPackage Verbosity
    verbosity (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) (LocalBuildInfo -> ProgramDb
    withPrograms LocalBuildInfo
    lbi)
                        (LocalBuildInfo -> PackageDBStack
    withPackageDB LocalBuildInfo
    lbi) InstalledPackageInfo
    ipi
                        RegisterOptions
    HcPkg.defaultRegisterOptions {
                          HcPkg.registerMultiInstance = True
                        }
        let ebi :: BuildInfo
    ebi = Executable -> BuildInfo
    buildInfo Executable
    exe
            -- NB: The stub executable is linked against the test-library
            --     which already contains all `other-modules`, so we need
            --     to remove those from the stub-exe's build-info
            exe' :: Executable
    exe' = Executable
    exe { buildInfo = (addExtraCSources ebi extras) { otherModules = [] } }
        Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    buildExe Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe' ComponentLocalBuildInfo
    exeClbi
        Maybe InstalledPackageInfo -> IO (Maybe InstalledPackageInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe InstalledPackageInfo
    forall a. Maybe a
    Nothing -- Can't depend on test suite

    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    _ PackageDescription
    _ LocalBuildInfo
    _ [PPSuffixHandler]
    _
                   (CTest TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteUnsupported TestType
    tt })
                   ComponentLocalBuildInfo
    _ String
    _ =
        Verbosity -> String -> IO (Maybe InstalledPackageInfo)
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity (String -> IO (Maybe InstalledPackageInfo))
    -> String -> IO (Maybe InstalledPackageInfo)
    forall a b. (a -> b) -> a -> b
    $ String
    "No support for building test suite type " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ TestType -> String
    forall a. Pretty a => a -> String
    prettyShow TestType
    tt

    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CBench bm :: Benchmark
    bm@Benchmark { benchmarkInterface :: Benchmark -> BenchmarkInterface
    benchmarkInterface = BenchmarkExeV10 {} })
                   ComponentLocalBuildInfo
    clbi String
    _distPref = do
        let exe :: Executable
    exe = Benchmark -> Executable
    benchmarkExeV10asExe Benchmark
    bm
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, OpenModule)]
    -> IO ()
    forall a.
    Pretty a =>
    Verbosity
    -> String
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, a)]
    -> IO ()
    setupMessage' Verbosity
    verbosity String
    "Building" (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr)
          (ComponentLocalBuildInfo -> ComponentName
    componentLocalName ComponentLocalBuildInfo
    clbi) (ComponentLocalBuildInfo -> Maybe [(ModuleName, OpenModule)]
    maybeComponentInstantiatedWith ComponentLocalBuildInfo
    clbi)
        let ebi :: BuildInfo
    ebi = Executable -> BuildInfo
    buildInfo Executable
    exe
            exe' :: Executable
    exe' = Executable
    exe { buildInfo = addExtraCSources ebi extras }
        Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    buildExe Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe' ComponentLocalBuildInfo
    clbi
        Maybe InstalledPackageInfo -> IO (Maybe InstalledPackageInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe InstalledPackageInfo
    forall a. Maybe a
    Nothing

    buildComponent Verbosity
    verbosity Flag (Maybe Int)
    _ PackageDescription
    _ LocalBuildInfo
    _ [PPSuffixHandler]
    _
                   (CBench Benchmark { benchmarkInterface :: Benchmark -> BenchmarkInterface
    benchmarkInterface = BenchmarkUnsupported BenchmarkType
    tt })
                   ComponentLocalBuildInfo
    _ String
    _ =
        Verbosity -> String -> IO (Maybe InstalledPackageInfo)
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity (String -> IO (Maybe InstalledPackageInfo))
    -> String -> IO (Maybe InstalledPackageInfo)
    forall a b. (a -> b) -> a -> b
    $ String
    "No support for building benchmark type " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ BenchmarkType -> String
    forall a. Pretty a => a -> String
    prettyShow BenchmarkType
    tt

    generateCode
            :: [String]
               -> UnqualComponentName
               -> PackageDescription
               -> BuildInfo
               -> LocalBuildInfo
               -> ComponentLocalBuildInfo
               -> Verbosity
               -> IO (FilePath, [ModuleName.ModuleName])
    generateCode :: [String]
    -> UnqualComponentName
    -> PackageDescription
    -> BuildInfo
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO (String, [ModuleName])
    generateCode [String]
    codeGens UnqualComponentName
    nm PackageDescription
    pdesc BuildInfo
    bi LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity = do
         Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not (Bool -> Bool) -> ([String] -> Bool) -> [String] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([String] -> Bool) -> [String] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [String]
    codeGens) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> Bool -> String -> IO ()
    createDirectoryIfMissingVerbose Verbosity
    verbosity Bool
    True String
    tgtDir
         (\[ModuleName]
    x -> (String
    tgtDir,[ModuleName]
    x)) ([ModuleName] -> (String, [ModuleName]))
    -> ([[ModuleName]] -> [ModuleName])
    -> [[ModuleName]]
    -> (String, [ModuleName])
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[ModuleName]] -> [ModuleName]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[ModuleName]] -> (String, [ModuleName]))
    -> IO [[ModuleName]] -> IO (String, [ModuleName])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (String -> IO [ModuleName]) -> [String] -> IO [[ModuleName]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM String -> IO [ModuleName]
    go [String]
    codeGens
       where
         allLibs :: [Library]
    allLibs = (([Library] -> [Library])
    -> (Library -> [Library] -> [Library])
    -> Maybe Library
    -> [Library]
    -> [Library]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [Library] -> [Library]
    forall a. a -> a
    id (:) (Maybe Library -> [Library] -> [Library])
    -> Maybe Library -> [Library] -> [Library]
    forall a b. (a -> b) -> a -> b
    $ PackageDescription -> Maybe Library
    library PackageDescription
    pdesc) (PackageDescription -> [Library]
    subLibraries PackageDescription
    pdesc)
         dependencyLibs :: [Library]
    dependencyLibs = (Library -> Bool) -> [Library] -> [Library]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Library -> Bool
    forall a b. a -> b -> a
    const Bool
    True) [Library]
    allLibs -- intersect with componentPackageDeps of clbi
         srcDirs :: [SymbolicPath PackageDir SourceDir]
    srcDirs = (Library -> [SymbolicPath PackageDir SourceDir])
    -> [Library] -> [SymbolicPath PackageDir SourceDir]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (BuildInfo -> [SymbolicPath PackageDir SourceDir]
    hsSourceDirs (BuildInfo -> [SymbolicPath PackageDir SourceDir])
    -> (Library -> BuildInfo)
    -> Library
    -> [SymbolicPath PackageDir SourceDir]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Library -> BuildInfo
    libBuildInfo) [Library]
    dependencyLibs
         nm' :: String
    nm' = UnqualComponentName -> String
    unUnqualComponentName UnqualComponentName
    nm
         tgtDir :: String
    tgtDir = LocalBuildInfo -> String
    buildDir LocalBuildInfo
    lbi String -> String -> String
    </> String
    nm' String -> String -> String
    </> String
    nm' String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "-gen"
         go :: String -> IO [ModuleName.ModuleName]
         go :: String -> IO [ModuleName]
    go String
    codeGenProg = (String -> ModuleName) -> [String] -> [ModuleName]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap String -> ModuleName
    forall a. IsString a => String -> a
    fromString ([String] -> [ModuleName])
    -> (String -> [String]) -> String -> [ModuleName]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String]
    lines (String -> [ModuleName]) -> IO String -> IO [ModuleName]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Verbosity -> Program -> ProgramDb -> [String] -> IO String
    getDbProgramOutput Verbosity
    verbosity (String -> Program
    simpleProgram String
    codeGenProg) (LocalBuildInfo -> ProgramDb
    withPrograms LocalBuildInfo
    lbi)
                             ((String
    tgtDir String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : (SymbolicPath PackageDir SourceDir -> String)
    -> [SymbolicPath PackageDir SourceDir] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map SymbolicPath PackageDir SourceDir -> String
    forall from to. SymbolicPath from to -> String
    getSymbolicPath [SymbolicPath PackageDir SourceDir]
    srcDirs) [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
                             (String
    "--" String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    :
                              Compiler -> Platform -> GhcOptions -> [String]
    GHC.renderGhcOptions (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) (LocalBuildInfo -> Platform
    hostPlatform LocalBuildInfo
    lbi) (Verbosity
    -> LocalBuildInfo
    -> BuildInfo
    -> ComponentLocalBuildInfo
    -> String
    -> GhcOptions
    GHC.componentGhcOptions Verbosity
    verbosity LocalBuildInfo
    lbi BuildInfo
    bi ComponentLocalBuildInfo
    clbi String
    tgtDir)))

    -- | Add extra C sources generated by preprocessing to build
    -- information.
    addExtraCSources :: BuildInfo -> [FilePath] -> BuildInfo
    addExtraCSources :: BuildInfo -> [String] -> BuildInfo
    addExtraCSources BuildInfo
    bi [String]
    extras = BuildInfo
    bi { cSources = new }
      where new :: [String]
    new = [String] -> [String]
    forall a. Ord a => [a] -> [a]
    ordNub ([String]
    extras [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ BuildInfo -> [String]
    cSources BuildInfo
    bi)

    -- | Add extra C++ sources generated by preprocessing to build
    -- information.
    addExtraCxxSources :: BuildInfo -> [FilePath] -> BuildInfo
    addExtraCxxSources :: BuildInfo -> [String] -> BuildInfo
    addExtraCxxSources BuildInfo
    bi [String]
    extras = BuildInfo
    bi { cxxSources = new }
      where new :: [String]
    new = [String] -> [String]
    forall a. Ord a => [a] -> [a]
    ordNub ([String]
    extras [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ BuildInfo -> [String]
    cxxSources BuildInfo
    bi)

    -- | Add extra C-- sources generated by preprocessing to build
    -- information.
    addExtraCmmSources :: BuildInfo -> [FilePath] -> BuildInfo
    addExtraCmmSources :: BuildInfo -> [String] -> BuildInfo
    addExtraCmmSources BuildInfo
    bi [String]
    extras = BuildInfo
    bi { cmmSources = new }
      where new :: [String]
    new = [String] -> [String]
    forall a. Ord a => [a] -> [a]
    ordNub ([String]
    extras [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ BuildInfo -> [String]
    cmmSources BuildInfo
    bi)

    -- | Add extra ASM sources generated by preprocessing to build
    -- information.
    addExtraAsmSources :: BuildInfo -> [FilePath] -> BuildInfo
    addExtraAsmSources :: BuildInfo -> [String] -> BuildInfo
    addExtraAsmSources BuildInfo
    bi [String]
    extras = BuildInfo
    bi { asmSources = new }
      where new :: [String]
    new = [String] -> [String]
    forall a. Ord a => [a] -> [a]
    ordNub ([String]
    extras [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ BuildInfo -> [String]
    asmSources BuildInfo
    bi)

    -- | Add extra JS sources generated by preprocessing to build
    -- information.
    addExtraJsSources :: BuildInfo -> [FilePath] -> BuildInfo
    addExtraJsSources :: BuildInfo -> [String] -> BuildInfo
    addExtraJsSources BuildInfo
    bi [String]
    extras = BuildInfo
    bi { jsSources = new }
      where new :: [String]
    new = [String] -> [String]
    forall a. Ord a => [a] -> [a]
    ordNub ([String]
    extras [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ BuildInfo -> [String]
    jsSources BuildInfo
    bi)

    -- | Add extra HS modules generated by preprocessing to build
    -- information.
    addExtraOtherModules :: BuildInfo -> [ModuleName.ModuleName] -> BuildInfo
    addExtraOtherModules :: BuildInfo -> [ModuleName] -> BuildInfo
    addExtraOtherModules BuildInfo
    bi [ModuleName]
    extras = BuildInfo
    bi { otherModules = new }
      where new :: [ModuleName]
    new = [ModuleName] -> [ModuleName]
    forall a. Ord a => [a] -> [a]
    ordNub ([ModuleName]
    extras [ModuleName] -> [ModuleName] -> [ModuleName]
    forall a. [a] -> [a] -> [a]
    ++ BuildInfo -> [ModuleName]
    otherModules BuildInfo
    bi)

    -- | Add extra source dir for generated modules.
    addSrcDir :: BuildInfo -> FilePath -> BuildInfo
    addSrcDir :: BuildInfo -> String -> BuildInfo
    addSrcDir BuildInfo
    bi String
    extra = BuildInfo
    bi { hsSourceDirs = new }
      where new :: [SymbolicPath PackageDir SourceDir]
    new = [SymbolicPath PackageDir SourceDir]
    -> [SymbolicPath PackageDir SourceDir]
    forall a. Ord a => [a] -> [a]
    ordNub (String -> SymbolicPath PackageDir SourceDir
    forall from to. String -> SymbolicPath from to
    unsafeMakeSymbolicPath String
    extra SymbolicPath PackageDir SourceDir
    -> [SymbolicPath PackageDir SourceDir]
    -> [SymbolicPath PackageDir SourceDir]
    forall a. a -> [a] -> [a]
    : BuildInfo -> [SymbolicPath PackageDir SourceDir]
    hsSourceDirs BuildInfo
    bi)

    replComponent :: ReplOptions
                  -> Verbosity
                  -> PackageDescription
                  -> LocalBuildInfo
                  -> [PPSuffixHandler]
                  -> Component
                  -> ComponentLocalBuildInfo
                  -> FilePath
                  -> IO ()
    replComponent :: ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> [PPSuffixHandler]
    -> Component
    -> ComponentLocalBuildInfo
    -> String
    -> IO ()
    replComponent ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CLib Library
    lib) ComponentLocalBuildInfo
    clbi String
    _ = do
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        let libbi :: BuildInfo
    libbi = Library -> BuildInfo
    libBuildInfo Library
    lib
            lib' :: Library
    lib' = Library
    lib { libBuildInfo = libbi { cSources = cSources libbi ++ extras } }
        ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    replLib ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib' ComponentLocalBuildInfo
    clbi

    replComponent ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CFLib ForeignLib
    flib) ComponentLocalBuildInfo
    clbi String
    _ = do
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> ForeignLib
    -> ComponentLocalBuildInfo
    -> IO ()
    replFLib ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi ForeignLib
    flib ComponentLocalBuildInfo
    clbi

    replComponent ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CExe Executable
    exe) ComponentLocalBuildInfo
    clbi String
    _ = do
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        let ebi :: BuildInfo
    ebi = Executable -> BuildInfo
    buildInfo Executable
    exe
            exe' :: Executable
    exe' = Executable
    exe { buildInfo = ebi { cSources = cSources ebi ++ extras } }
        ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    replExe ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe' ComponentLocalBuildInfo
    clbi

    replComponent ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CTest test :: TestSuite
    test@TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteExeV10{} })
                   ComponentLocalBuildInfo
    clbi String
    _distPref = do
        let exe :: Executable
    exe = TestSuite -> Executable
    testSuiteExeV10AsExe TestSuite
    test
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        let ebi :: BuildInfo
    ebi = Executable -> BuildInfo
    buildInfo Executable
    exe
            exe' :: Executable
    exe' = Executable
    exe { buildInfo = ebi { cSources = cSources ebi ++ extras } }
        ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    replExe ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe' ComponentLocalBuildInfo
    clbi

    replComponent ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi0 [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CTest
                     test :: TestSuite
    test@TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteLibV09{} })
                   ComponentLocalBuildInfo
    clbi String
    distPref = do
        String
    pwd <- IO String
    getCurrentDirectory
        let (PackageDescription
    pkg, Library
    lib, ComponentLocalBuildInfo
    libClbi, LocalBuildInfo
    lbi, InstalledPackageInfo
    _, Executable
    _, ComponentLocalBuildInfo
    _) =
              PackageDescription
    -> TestSuite
    -> ComponentLocalBuildInfo
    -> LocalBuildInfo
    -> String
    -> String
    -> (PackageDescription, Library, ComponentLocalBuildInfo,
        LocalBuildInfo, InstalledPackageInfo, Executable,
        ComponentLocalBuildInfo)
    testSuiteLibV09AsLibAndExe PackageDescription
    pkg_descr TestSuite
    test ComponentLocalBuildInfo
    clbi LocalBuildInfo
    lbi0 String
    distPref String
    pwd
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        let libbi :: BuildInfo
    libbi = Library -> BuildInfo
    libBuildInfo Library
    lib
            lib' :: Library
    lib' = Library
    lib { libBuildInfo = libbi { cSources = cSources libbi ++ extras } }
        ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    replLib ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg LocalBuildInfo
    lbi Library
    lib' ComponentLocalBuildInfo
    libClbi

    replComponent ReplOptions
    _ Verbosity
    verbosity PackageDescription
    _ LocalBuildInfo
    _ [PPSuffixHandler]
    _
                  (CTest TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteUnsupported TestType
    tt })
                  ComponentLocalBuildInfo
    _ String
    _ =
        Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String
    "No support for building test suite type " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ TestType -> String
    forall a. Pretty a => a -> String
    prettyShow TestType
    tt

    replComponent ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi [PPSuffixHandler]
    suffixes
                   comp :: Component
    comp@(CBench bm :: Benchmark
    bm@Benchmark { benchmarkInterface :: Benchmark -> BenchmarkInterface
    benchmarkInterface = BenchmarkExeV10 {} })
                   ComponentLocalBuildInfo
    clbi String
    _distPref = do
        let exe :: Executable
    exe = Benchmark -> Executable
    benchmarkExeV10asExe Benchmark
    bm
        PackageDescription
    -> Component
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Bool
    -> Verbosity
    -> [PPSuffixHandler]
    -> IO ()
    preprocessComponent PackageDescription
    pkg_descr Component
    comp LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Bool
    False Verbosity
    verbosity [PPSuffixHandler]
    suffixes
        [String]
    extras <- Verbosity -> Component -> LocalBuildInfo -> IO [String]
    preprocessExtras Verbosity
    verbosity Component
    comp LocalBuildInfo
    lbi
        let ebi :: BuildInfo
    ebi = Executable -> BuildInfo
    buildInfo Executable
    exe
            exe' :: Executable
    exe' = Executable
    exe { buildInfo = ebi { cSources = cSources ebi ++ extras } }
        ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    replExe ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe' ComponentLocalBuildInfo
    clbi

    replComponent ReplOptions
    _ Verbosity
    verbosity PackageDescription
    _ LocalBuildInfo
    _ [PPSuffixHandler]
    _
                  (CBench Benchmark { benchmarkInterface :: Benchmark -> BenchmarkInterface
    benchmarkInterface = BenchmarkUnsupported BenchmarkType
    tt })
                  ComponentLocalBuildInfo
    _ String
    _ =
        Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String
    "No support for building benchmark type " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ BenchmarkType -> String
    forall a. Pretty a => a -> String
    prettyShow BenchmarkType
    tt

    ----------------------------------------------------
    -- Shared code for buildComponent and replComponent
    --

    -- | Translate a exe-style 'TestSuite' component into an exe for building
    testSuiteExeV10AsExe :: TestSuite -> Executable
    testSuiteExeV10AsExe :: TestSuite -> Executable
    testSuiteExeV10AsExe test :: TestSuite
    test@TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteExeV10 Version
    _ String
    mainFile } =
        Executable {
          exeName :: UnqualComponentName
    exeName    = TestSuite -> UnqualComponentName
    testName TestSuite
    test,
          modulePath :: String
    modulePath = String
    mainFile,
          exeScope :: ExecutableScope
    exeScope   = ExecutableScope
    ExecutablePublic,
          buildInfo :: BuildInfo
    buildInfo  = TestSuite -> BuildInfo
    testBuildInfo TestSuite
    test
        }
    testSuiteExeV10AsExe TestSuite{} = String -> Executable
    forall a. HasCallStack => String -> a
    error String
    "testSuiteExeV10AsExe: wrong kind"

    -- | Translate a exe-style 'Benchmark' component into an exe for building
    benchmarkExeV10asExe :: Benchmark -> Executable
    benchmarkExeV10asExe :: Benchmark -> Executable
    benchmarkExeV10asExe bm :: Benchmark
    bm@Benchmark { benchmarkInterface :: Benchmark -> BenchmarkInterface
    benchmarkInterface = BenchmarkExeV10 Version
    _ String
    mainFile } =
        Executable {
          exeName :: UnqualComponentName
    exeName    = Benchmark -> UnqualComponentName
    benchmarkName Benchmark
    bm,
          modulePath :: String
    modulePath = String
    mainFile,
          exeScope :: ExecutableScope
    exeScope   = ExecutableScope
    ExecutablePublic,
          buildInfo :: BuildInfo
    buildInfo  = Benchmark -> BuildInfo
    benchmarkBuildInfo Benchmark
    bm
        }
    benchmarkExeV10asExe Benchmark{} = String -> Executable
    forall a. HasCallStack => String -> a
    error String
    "benchmarkExeV10asExe: wrong kind"

    -- | Translate a lib-style 'TestSuite' component into a lib + exe for building
    testSuiteLibV09AsLibAndExe :: PackageDescription
                               -> TestSuite
                               -> ComponentLocalBuildInfo
                               -> LocalBuildInfo
                               -> FilePath
                               -> FilePath
                               -> (PackageDescription,
                                   Library, ComponentLocalBuildInfo,
                                   LocalBuildInfo,
                                   IPI.InstalledPackageInfo,
                                   Executable, ComponentLocalBuildInfo)
    testSuiteLibV09AsLibAndExe :: PackageDescription
    -> TestSuite
    -> ComponentLocalBuildInfo
    -> LocalBuildInfo
    -> String
    -> String
    -> (PackageDescription, Library, ComponentLocalBuildInfo,
        LocalBuildInfo, InstalledPackageInfo, Executable,
        ComponentLocalBuildInfo)
    testSuiteLibV09AsLibAndExe PackageDescription
    pkg_descr
                         test :: TestSuite
    test@TestSuite { testInterface :: TestSuite -> TestSuiteInterface
    testInterface = TestSuiteLibV09 Version
    _ ModuleName
    m }
                         ComponentLocalBuildInfo
    clbi LocalBuildInfo
    lbi String
    distPref String
    pwd =
        (PackageDescription
    pkg, Library
    lib, ComponentLocalBuildInfo
    libClbi, LocalBuildInfo
    lbi, InstalledPackageInfo
    ipi, Executable
    exe, ComponentLocalBuildInfo
    exeClbi)
      where
        bi :: BuildInfo
    bi  = TestSuite -> BuildInfo
    testBuildInfo TestSuite
    test
        lib :: Library
    lib = Library {
                libName :: LibraryName
    libName = LibraryName
    LMainLibName,
                exposedModules :: [ModuleName]
    exposedModules = [ ModuleName
    m ],
                reexportedModules :: [ModuleReexport]
    reexportedModules = [],
                signatures :: [ModuleName]
    signatures = [],
                libExposed :: Bool
    libExposed     = Bool
    True,
                libVisibility :: LibraryVisibility
    libVisibility  = LibraryVisibility
    LibraryVisibilityPrivate,
                libBuildInfo :: BuildInfo
    libBuildInfo   = BuildInfo
    bi
              }
        -- This is, like, the one place where we use a CTestName for a library.
        -- Should NOT use library name, since that could conflict!
        PackageIdentifier PackageName
    pkg_name Version
    pkg_ver = PackageDescription -> PackageIdentifier
    package PackageDescription
    pkg_descr
        -- Note: we do make internal library from the test!
        compat_name :: MungedPackageName
    compat_name = PackageName -> LibraryName -> MungedPackageName
    MungedPackageName PackageName
    pkg_name (UnqualComponentName -> LibraryName
    LSubLibName (TestSuite -> UnqualComponentName
    testName TestSuite
    test))
        compat_key :: String
    compat_key = Compiler -> MungedPackageName -> Version -> UnitId -> String
    computeCompatPackageKey (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) MungedPackageName
    compat_name Version
    pkg_ver (ComponentLocalBuildInfo -> UnitId
    componentUnitId ComponentLocalBuildInfo
    clbi)
        libClbi :: ComponentLocalBuildInfo
    libClbi = LibComponentLocalBuildInfo
                    { componentPackageDeps :: [(UnitId, MungedPackageId)]
    componentPackageDeps = ComponentLocalBuildInfo -> [(UnitId, MungedPackageId)]
    componentPackageDeps ComponentLocalBuildInfo
    clbi
                    , componentInternalDeps :: [UnitId]
    componentInternalDeps = ComponentLocalBuildInfo -> [UnitId]
    componentInternalDeps ComponentLocalBuildInfo
    clbi
                    , componentIsIndefinite_ :: Bool
    componentIsIndefinite_ = Bool
    False
                    , componentExeDeps :: [UnitId]
    componentExeDeps = ComponentLocalBuildInfo -> [UnitId]
    componentExeDeps ComponentLocalBuildInfo
    clbi
                    , componentLocalName :: ComponentName
    componentLocalName = LibraryName -> ComponentName
    CLibName (LibraryName -> ComponentName) -> LibraryName -> ComponentName
    forall a b. (a -> b) -> a -> b
    $ UnqualComponentName -> LibraryName
    LSubLibName (UnqualComponentName -> LibraryName)
    -> UnqualComponentName -> LibraryName
    forall a b. (a -> b) -> a -> b
    $ TestSuite -> UnqualComponentName
    testName TestSuite
    test
                    , componentIsPublic :: Bool
    componentIsPublic = Bool
    False
                    , componentIncludes :: [(OpenUnitId, ModuleRenaming)]
    componentIncludes = ComponentLocalBuildInfo -> [(OpenUnitId, ModuleRenaming)]
    componentIncludes ComponentLocalBuildInfo
    clbi
                    , componentUnitId :: UnitId
    componentUnitId = ComponentLocalBuildInfo -> UnitId
    componentUnitId ComponentLocalBuildInfo
    clbi
                    , componentComponentId :: ComponentId
    componentComponentId = ComponentLocalBuildInfo -> ComponentId
    componentComponentId ComponentLocalBuildInfo
    clbi
                    , componentInstantiatedWith :: [(ModuleName, OpenModule)]
    componentInstantiatedWith = []
                    , componentCompatPackageName :: MungedPackageName
    componentCompatPackageName = MungedPackageName
    compat_name
                    , componentCompatPackageKey :: String
    componentCompatPackageKey = String
    compat_key
                    , componentExposedModules :: [ExposedModule]
    componentExposedModules = [ModuleName -> Maybe OpenModule -> ExposedModule
    IPI.ExposedModule ModuleName
    m Maybe OpenModule
    forall a. Maybe a
    Nothing]
                    }
        pkgName' :: PackageName
    pkgName' = String -> PackageName
    mkPackageName (String -> PackageName) -> String -> PackageName
    forall a b. (a -> b) -> a -> b
    $ MungedPackageName -> String
    forall a. Pretty a => a -> String
    prettyShow MungedPackageName
    compat_name
        pkg :: PackageDescription
    pkg = PackageDescription
    pkg_descr {
                package      = (package pkg_descr) { pkgName = pkgName' }
              , executables  = []
              , testSuites   = []
              , subLibraries = [lib]
              }
        ipi :: InstalledPackageInfo
    ipi    = String
    -> String
    -> PackageDescription
    -> AbiHash
    -> Library
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> InstalledPackageInfo
    inplaceInstalledPackageInfo String
    pwd String
    distPref PackageDescription
    pkg (String -> AbiHash
    mkAbiHash String
    "") Library
    lib LocalBuildInfo
    lbi ComponentLocalBuildInfo
    libClbi
        testDir :: String
    testDir = LocalBuildInfo -> String
    buildDir LocalBuildInfo
    lbi String -> String -> String
    </> TestSuite -> String
    stubName TestSuite
    test
              String -> String -> String
    </> TestSuite -> String
    stubName TestSuite
    test String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "-tmp"
        testLibDep :: Dependency
    testLibDep = PackageName
    -> VersionRange -> NonEmptySet LibraryName -> Dependency
    Dependency
            PackageName
    pkgName'
            (Version -> VersionRange
    thisVersion (Version -> VersionRange) -> Version -> VersionRange
    forall a b. (a -> b) -> a -> b
    $ PackageIdentifier -> Version
    pkgVersion (PackageIdentifier -> Version) -> PackageIdentifier -> Version
    forall a b. (a -> b) -> a -> b
    $ PackageDescription -> PackageIdentifier
    package PackageDescription
    pkg_descr)
            NonEmptySet LibraryName
    mainLibSet
        exe :: Executable
    exe = Executable {
                exeName :: UnqualComponentName
    exeName    = String -> UnqualComponentName
    mkUnqualComponentName (String -> UnqualComponentName) -> String -> UnqualComponentName
    forall a b. (a -> b) -> a -> b
    $ TestSuite -> String
    stubName TestSuite
    test,
                modulePath :: String
    modulePath = TestSuite -> String
    stubFilePath TestSuite
    test,
                exeScope :: ExecutableScope
    exeScope   = ExecutableScope
    ExecutablePublic,
                buildInfo :: BuildInfo
    buildInfo  = (TestSuite -> BuildInfo
    testBuildInfo TestSuite
    test) {
                               hsSourceDirs       = [ unsafeMakeSymbolicPath testDir ],
                               targetBuildDepends = testLibDep
                                 : (targetBuildDepends $ testBuildInfo test)
                             }
              }
        -- | The stub executable needs a new 'ComponentLocalBuildInfo'
        -- that exposes the relevant test suite library.
        deps :: [(UnitId, MungedPackageId)]
    deps = (InstalledPackageInfo -> UnitId
    IPI.installedUnitId InstalledPackageInfo
    ipi, InstalledPackageInfo -> MungedPackageId
    forall pkg. HasMungedPackageId pkg => pkg -> MungedPackageId
    mungedId InstalledPackageInfo
    ipi)
             (UnitId, MungedPackageId)
    -> [(UnitId, MungedPackageId)] -> [(UnitId, MungedPackageId)]
    forall a. a -> [a] -> [a]
    : (((UnitId, MungedPackageId) -> Bool)
    -> [(UnitId, MungedPackageId)] -> [(UnitId, MungedPackageId)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\(UnitId
    _, MungedPackageId
    x) -> let name :: String
    name = MungedPackageName -> String
    forall a. Pretty a => a -> String
    prettyShow (MungedPackageName -> String) -> MungedPackageName -> String
    forall a b. (a -> b) -> a -> b
    $ MungedPackageId -> MungedPackageName
    mungedName MungedPackageId
    x
                                   in String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == String
    "Cabal" Bool -> Bool -> Bool
    || String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == String
    "base")
                       (ComponentLocalBuildInfo -> [(UnitId, MungedPackageId)]
    componentPackageDeps ComponentLocalBuildInfo
    clbi))
        exeClbi :: ComponentLocalBuildInfo
    exeClbi = ExeComponentLocalBuildInfo {
                    -- TODO: this is a hack, but as long as this is unique
                    -- (doesn't clobber something) we won't run into trouble
                    componentUnitId :: UnitId
    componentUnitId = String -> UnitId
    mkUnitId (TestSuite -> String
    stubName TestSuite
    test),
                    componentComponentId :: ComponentId
    componentComponentId = String -> ComponentId
    mkComponentId (TestSuite -> String
    stubName TestSuite
    test),
                    componentInternalDeps :: [UnitId]
    componentInternalDeps = [ComponentLocalBuildInfo -> UnitId
    componentUnitId ComponentLocalBuildInfo
    clbi],
                    componentExeDeps :: [UnitId]
    componentExeDeps = [],
                    componentLocalName :: ComponentName
    componentLocalName = UnqualComponentName -> ComponentName
    CExeName (UnqualComponentName -> ComponentName)
    -> UnqualComponentName -> ComponentName
    forall a b. (a -> b) -> a -> b
    $ String -> UnqualComponentName
    mkUnqualComponentName (String -> UnqualComponentName) -> String -> UnqualComponentName
    forall a b. (a -> b) -> a -> b
    $ TestSuite -> String
    stubName TestSuite
    test,
                    componentPackageDeps :: [(UnitId, MungedPackageId)]
    componentPackageDeps = [(UnitId, MungedPackageId)]
    deps,
                    -- Assert DefUnitId invariant!
                    -- Executable can't be indefinite, so dependencies must
                    -- be definite packages.
                    componentIncludes :: [(OpenUnitId, ModuleRenaming)]
    componentIncludes = [OpenUnitId] -> [ModuleRenaming] -> [(OpenUnitId, ModuleRenaming)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip (((UnitId, MungedPackageId) -> OpenUnitId)
    -> [(UnitId, MungedPackageId)] -> [OpenUnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map (DefUnitId -> OpenUnitId
    DefiniteUnitId (DefUnitId -> OpenUnitId)
    -> ((UnitId, MungedPackageId) -> DefUnitId)
    -> (UnitId, MungedPackageId)
    -> OpenUnitId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitId -> DefUnitId
    unsafeMkDefUnitId (UnitId -> DefUnitId)
    -> ((UnitId, MungedPackageId) -> UnitId)
    -> (UnitId, MungedPackageId)
    -> DefUnitId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (UnitId, MungedPackageId) -> UnitId
    forall a b. (a, b) -> a
    fst) [(UnitId, MungedPackageId)]
    deps)
                                            (ModuleRenaming -> [ModuleRenaming]
    forall a. a -> [a]
    repeat ModuleRenaming
    defaultRenaming)
                  }
    testSuiteLibV09AsLibAndExe PackageDescription
    _ TestSuite{} ComponentLocalBuildInfo
    _ LocalBuildInfo
    _ String
    _ String
    _ = String
    -> (PackageDescription, Library, ComponentLocalBuildInfo,
        LocalBuildInfo, InstalledPackageInfo, Executable,
        ComponentLocalBuildInfo)
    forall a. HasCallStack => String -> a
    error String
    "testSuiteLibV09AsLibAndExe: wrong kind"

    -- | Initialize a new package db file for libraries defined
    -- internally to the package.
    createInternalPackageDB :: Verbosity -> LocalBuildInfo -> FilePath
                            -> IO PackageDB
    createInternalPackageDB :: Verbosity -> LocalBuildInfo -> String -> IO PackageDB
    createInternalPackageDB Verbosity
    verbosity LocalBuildInfo
    lbi String
    distPref = do
        Bool
    existsAlready <- String -> IO Bool
    doesPackageDBExist String
    dbPath
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    existsAlready (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String -> IO ()
    deletePackageDB String
    dbPath
        Verbosity -> Compiler -> ProgramDb -> Bool -> String -> IO ()
    createPackageDB Verbosity
    verbosity (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) (LocalBuildInfo -> ProgramDb
    withPrograms LocalBuildInfo
    lbi) Bool
    False String
    dbPath
        PackageDB -> IO PackageDB
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String -> PackageDB
    SpecificPackageDB String
    dbPath)
      where
        dbPath :: String
    dbPath = LocalBuildInfo -> String -> String
    internalPackageDBPath LocalBuildInfo
    lbi String
    distPref

    addInternalBuildTools :: PackageDescription -> LocalBuildInfo -> BuildInfo
                          -> ProgramDb -> ProgramDb
    addInternalBuildTools :: PackageDescription
    -> LocalBuildInfo -> BuildInfo -> ProgramDb -> ProgramDb
    addInternalBuildTools PackageDescription
    pkg LocalBuildInfo
    lbi BuildInfo
    bi ProgramDb
    progs =
        (ConfiguredProgram -> ProgramDb -> ProgramDb)
    -> ProgramDb -> [ConfiguredProgram] -> ProgramDb
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr ConfiguredProgram -> ProgramDb -> ProgramDb
    updateProgram ProgramDb
    progs [ConfiguredProgram]
    internalBuildTools
      where
        internalBuildTools :: [ConfiguredProgram]
    internalBuildTools =
          [ String -> ProgramLocation -> ConfiguredProgram
    simpleConfiguredProgram String
    toolName' (String -> ProgramLocation
    FoundOnSystem String
    toolLocation)
          | UnqualComponentName
    toolName <- PackageDescription -> BuildInfo -> [UnqualComponentName]
    getAllInternalToolDependencies PackageDescription
    pkg BuildInfo
    bi
          , let toolName' :: String
    toolName' = UnqualComponentName -> String
    unUnqualComponentName UnqualComponentName
    toolName
          , let toolLocation :: String
    toolLocation = LocalBuildInfo -> String
    buildDir LocalBuildInfo
    lbi String -> String -> String
    </> String
    toolName' String -> String -> String
    </> String
    toolName' String -> String -> String
    <.> Platform -> String
    exeExtension (LocalBuildInfo -> Platform
    hostPlatform LocalBuildInfo
    lbi) ]

    -- TODO: build separate libs in separate dirs so that we can build
    -- multiple libs, e.g. for 'LibTest' library-style test suites
    buildLib :: Verbosity -> Flag (Maybe Int)
                          -> PackageDescription -> LocalBuildInfo
                          -> Library            -> ComponentLocalBuildInfo -> IO ()
    buildLib :: Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    buildLib Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi =
      case Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) of
        CompilerFlavor
    GHC   -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    GHC.buildLib   Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    GHCJS -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    GHCJS.buildLib Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    UHC   -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    UHC.buildLib   Verbosity
    verbosity         PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi
        HaskellSuite {} -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    HaskellSuite.buildLib Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    _    -> Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity String
    "Building is not supported with this compiler."

    -- | Build a foreign library
    --
    -- NOTE: We assume that we already checked that we can actually build the
    -- foreign library in configure.
    buildFLib :: Verbosity -> Flag (Maybe Int)
                           -> PackageDescription -> LocalBuildInfo
                           -> ForeignLib         -> ComponentLocalBuildInfo -> IO ()
    buildFLib :: Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> ForeignLib
    -> ComponentLocalBuildInfo
    -> IO ()
    buildFLib Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi ForeignLib
    flib ComponentLocalBuildInfo
    clbi =
        case Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) of
          CompilerFlavor
    GHC -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> ForeignLib
    -> ComponentLocalBuildInfo
    -> IO ()
    GHC.buildFLib Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi ForeignLib
    flib ComponentLocalBuildInfo
    clbi
          CompilerFlavor
    _   -> Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity String
    "Building is not supported with this compiler."

    buildExe :: Verbosity -> Flag (Maybe Int)
                          -> PackageDescription -> LocalBuildInfo
                          -> Executable         -> ComponentLocalBuildInfo -> IO ()
    buildExe :: Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    buildExe Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe ComponentLocalBuildInfo
    clbi =
      case Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) of
        CompilerFlavor
    GHC   -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    GHC.buildExe   Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    GHCJS -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    GHCJS.buildExe Verbosity
    verbosity Flag (Maybe Int)
    numJobs PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    UHC   -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    UHC.buildExe   Verbosity
    verbosity         PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    _     -> Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity String
    "Building is not supported with this compiler."

    replLib :: ReplOptions     -> Verbosity -> PackageDescription
            -> LocalBuildInfo  -> Library   -> ComponentLocalBuildInfo
            -> IO ()
    replLib :: ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    replLib ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi =
      case Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) of
        -- 'cabal repl' doesn't need to support 'ghc --make -j', so we just pass
        -- NoFlag as the numJobs parameter.
        CompilerFlavor
    GHC   -> ReplOptions
    -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    GHC.replLib   ReplOptions
    replFlags Verbosity
    verbosity Flag (Maybe Int)
    forall a. Flag a
    NoFlag PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    GHCJS -> [String]
    -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Library
    -> ComponentLocalBuildInfo
    -> IO ()
    GHCJS.replLib (ReplOptions -> [String]
    replOptionsFlags ReplOptions
    replFlags) Verbosity
    verbosity Flag (Maybe Int)
    forall a. Flag a
    NoFlag PackageDescription
    pkg_descr LocalBuildInfo
    lbi Library
    lib ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    _     -> Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity String
    "A REPL is not supported for this compiler."

    replExe :: ReplOptions     -> Verbosity  -> PackageDescription
            -> LocalBuildInfo  -> Executable -> ComponentLocalBuildInfo
            -> IO ()
    replExe :: ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    replExe ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe ComponentLocalBuildInfo
    clbi =
      case Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) of
        CompilerFlavor
    GHC   -> ReplOptions
    -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    GHC.replExe   ReplOptions
    replFlags Verbosity
    verbosity Flag (Maybe Int)
    forall a. Flag a
    NoFlag PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    GHCJS -> [String]
    -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> Executable
    -> ComponentLocalBuildInfo
    -> IO ()
    GHCJS.replExe (ReplOptions -> [String]
    replOptionsFlags ReplOptions
    replFlags) Verbosity
    verbosity Flag (Maybe Int)
    forall a. Flag a
    NoFlag PackageDescription
    pkg_descr LocalBuildInfo
    lbi Executable
    exe ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    _     -> Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity String
    "A REPL is not supported for this compiler."

    replFLib :: ReplOptions     -> Verbosity  -> PackageDescription
             -> LocalBuildInfo  -> ForeignLib -> ComponentLocalBuildInfo
             -> IO ()
    replFLib :: ReplOptions
    -> Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> ForeignLib
    -> ComponentLocalBuildInfo
    -> IO ()
    replFLib ReplOptions
    replFlags Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi ForeignLib
    exe ComponentLocalBuildInfo
    clbi =
      case Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) of
        CompilerFlavor
    GHC -> ReplOptions
    -> Verbosity
    -> Flag (Maybe Int)
    -> PackageDescription
    -> LocalBuildInfo
    -> ForeignLib
    -> ComponentLocalBuildInfo
    -> IO ()
    GHC.replFLib ReplOptions
    replFlags Verbosity
    verbosity Flag (Maybe Int)
    forall a. Flag a
    NoFlag PackageDescription
    pkg_descr LocalBuildInfo
    lbi ForeignLib
    exe ComponentLocalBuildInfo
    clbi
        CompilerFlavor
    _   -> Verbosity -> String -> IO ()
    forall a. Verbosity -> String -> IO a
    die' Verbosity
    verbosity String
    "A REPL is not supported for this compiler."

    -- | Runs 'componentInitialBuildSteps' on every configured component.
    initialBuildSteps :: FilePath -- ^"dist" prefix
                      -> PackageDescription  -- ^mostly information from the .cabal file
                      -> LocalBuildInfo -- ^Configuration information
                      -> Verbosity -- ^The verbosity to use
                      -> IO ()
    initialBuildSteps :: String
    -> PackageDescription -> LocalBuildInfo -> Verbosity -> IO ()
    initialBuildSteps String
    distPref PackageDescription
    pkg_descr LocalBuildInfo
    lbi Verbosity
    verbosity =
        PackageDescription
    -> LocalBuildInfo
    -> (Component -> ComponentLocalBuildInfo -> IO ())
    -> IO ()
    withAllComponentsInBuildOrder PackageDescription
    pkg_descr LocalBuildInfo
    lbi ((Component -> ComponentLocalBuildInfo -> IO ()) -> IO ())
    -> (Component -> ComponentLocalBuildInfo -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Component
    _comp ComponentLocalBuildInfo
    clbi ->
            String
    -> PackageDescription
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO ()
    componentInitialBuildSteps String
    distPref PackageDescription
    pkg_descr LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity

    -- | Creates the autogenerated files for a particular configured component.
    componentInitialBuildSteps :: FilePath -- ^"dist" prefix
                      -> PackageDescription  -- ^mostly information from the .cabal file
                      -> LocalBuildInfo -- ^Configuration information
                      -> ComponentLocalBuildInfo
                      -> Verbosity -- ^The verbosity to use
                      -> IO ()
    componentInitialBuildSteps :: String
    -> PackageDescription
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> Verbosity
    -> IO ()
    componentInitialBuildSteps String
    _distPref PackageDescription
    pkg_descr LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi Verbosity
    verbosity = do
      Verbosity -> Bool -> String -> IO ()
    createDirectoryIfMissingVerbose Verbosity
    verbosity Bool
    True (LocalBuildInfo -> ComponentLocalBuildInfo -> String
    componentBuildDir LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi)

      Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> IO ()
    writeAutogenFiles Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi

    -- | Generate and write out the Paths_<pkg>.hs, PackageInfo_<pkg>.hs, and cabal_macros.h files
    --
    writeAutogenFiles :: Verbosity
                      -> PackageDescription
                      -> LocalBuildInfo
                      -> ComponentLocalBuildInfo
                      -> IO ()
    writeAutogenFiles :: Verbosity
    -> PackageDescription
    -> LocalBuildInfo
    -> ComponentLocalBuildInfo
    -> IO ()
    writeAutogenFiles Verbosity
    verbosity PackageDescription
    pkg LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi = do
      Verbosity -> Bool -> String -> IO ()
    createDirectoryIfMissingVerbose Verbosity
    verbosity Bool
    True (LocalBuildInfo -> ComponentLocalBuildInfo -> String
    autogenComponentModulesDir LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi)

      let pathsModulePath :: String
    pathsModulePath = LocalBuildInfo -> ComponentLocalBuildInfo -> String
    autogenComponentModulesDir LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi
                     String -> String -> String
    </> ModuleName -> String
    ModuleName.toFilePath (PackageDescription -> ModuleName
    autogenPathsModuleName PackageDescription
    pkg) String -> String -> String
    <.> String
    "hs"
          pathsModuleDir :: String
    pathsModuleDir = String -> String
    takeDirectory String
    pathsModulePath
      -- Ensure that the directory exists!
      Verbosity -> Bool -> String -> IO ()
    createDirectoryIfMissingVerbose Verbosity
    verbosity Bool
    True String
    pathsModuleDir
      Verbosity -> String -> String -> IO ()
    rewriteFileEx Verbosity
    verbosity String
    pathsModulePath (PackageDescription
    -> LocalBuildInfo -> ComponentLocalBuildInfo -> String
    generatePathsModule PackageDescription
    pkg LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi)

      let packageInfoModulePath :: String
    packageInfoModulePath = LocalBuildInfo -> ComponentLocalBuildInfo -> String
    autogenComponentModulesDir LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi
                     String -> String -> String
    </> ModuleName -> String
    ModuleName.toFilePath (PackageDescription -> ModuleName
    autogenPackageInfoModuleName PackageDescription
    pkg) String -> String -> String
    <.> String
    "hs"
          packageInfoModuleDir :: String
    packageInfoModuleDir = String -> String
    takeDirectory String
    packageInfoModulePath
      -- Ensure that the directory exists!
      Verbosity -> Bool -> String -> IO ()
    createDirectoryIfMissingVerbose Verbosity
    verbosity Bool
    True String
    packageInfoModuleDir
      Verbosity -> String -> String -> IO ()
    rewriteFileEx Verbosity
    verbosity String
    packageInfoModulePath (PackageDescription -> LocalBuildInfo -> String
    generatePackageInfoModule PackageDescription
    pkg LocalBuildInfo
    lbi)

      --TODO: document what we're doing here, and move it to its own function
      case ComponentLocalBuildInfo
    clbi of
        LibComponentLocalBuildInfo { componentInstantiatedWith :: ComponentLocalBuildInfo -> [(ModuleName, OpenModule)]
    componentInstantiatedWith = [(ModuleName, OpenModule)]
    insts } ->
            -- Write out empty hsig files for all requirements, so that GHC
            -- has a source file to look at it when it needs to typecheck
            -- a signature.  It's harmless to write these out even when
            -- there is a real hsig file written by the user, since
            -- include path ordering ensures that the real hsig file
            -- will always be picked up before the autogenerated one.
            [ModuleName] -> (ModuleName -> IO ()) -> IO ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    t a -> (a -> f b) -> f ()
    for_ (((ModuleName, OpenModule) -> ModuleName)
    -> [(ModuleName, OpenModule)] -> [ModuleName]
    forall a b. (a -> b) -> [a] -> [b]
    map (ModuleName, OpenModule) -> ModuleName
    forall a b. (a, b) -> a
    fst [(ModuleName, OpenModule)]
    insts) ((ModuleName -> IO ()) -> IO ()) -> (ModuleName -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ModuleName
    mod_name -> do
                let sigPath :: String
    sigPath = LocalBuildInfo -> ComponentLocalBuildInfo -> String
    autogenComponentModulesDir LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi
                          String -> String -> String
    </> ModuleName -> String
    ModuleName.toFilePath ModuleName
    mod_name String -> String -> String
    <.> String
    "hsig"
                Verbosity -> Bool -> String -> IO ()
    createDirectoryIfMissingVerbose Verbosity
    verbosity Bool
    True (String -> String
    takeDirectory String
    sigPath)
                Verbosity -> String -> String -> IO ()
    rewriteFileEx Verbosity
    verbosity String
    sigPath (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                    String
    "{-# OPTIONS_GHC -w #-}\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                    String
    "{-# LANGUAGE NoImplicitPrelude #-}\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                    String
    "signature " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ModuleName -> String
    forall a. Pretty a => a -> String
    prettyShow ModuleName
    mod_name String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " where"
        ComponentLocalBuildInfo
    _ -> () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

      let cppHeaderPath :: String
    cppHeaderPath = LocalBuildInfo -> ComponentLocalBuildInfo -> String
    autogenComponentModulesDir LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi String -> String -> String
    </> String
    cppHeaderName
      Verbosity -> String -> String -> IO ()
    rewriteFileEx Verbosity
    verbosity String
    cppHeaderPath (PackageDescription
    -> LocalBuildInfo -> ComponentLocalBuildInfo -> String
    generateCabalMacrosHeader PackageDescription
    pkg LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi)