    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Distribution.Simple.Configure
    -- Copyright   :  Isaac Jones 2003-2005
    -- License     :  BSD3
    --
    -- Maintainer  :  cabal-devel@haskell.org
    -- Portability :  portable
    --
    -- This deals with the /configure/ phase. It provides the 'configure' action
    -- which is given the package description and configure flags. It then tries
    -- to: configure the compiler; resolves any conditionals in the package
    -- description; resolve the package dependencies; check if all the extensions
    -- used by this package are supported by the compiler; check that all the build
    -- tools are available (including version checks if appropriate); checks for
    -- any required @pkg-config@ packages (updating the 'BuildInfo' with the
    -- results)
    --
    -- Then based on all this it saves the info in the 'LocalBuildInfo' and writes
    -- it out to the @dist\/setup-config@ file. It also displays various details to
    -- the user, the amount of information displayed depending on the verbosity
    -- level.

    module Distribution.Simple.Configure
      ( configure
      , writePersistBuildConfig
      , getConfigStateFile
      , getPersistBuildConfig
      , checkPersistBuildConfigOutdated
      , tryGetPersistBuildConfig
      , maybeGetPersistBuildConfig
      , findDistPref, findDistPrefOrDefault
      , getInternalLibraries
      , computeComponentId
      , computeCompatPackageKey
      , localBuildInfoFile
      , getInstalledPackages
      , getInstalledPackagesMonitorFiles
      , getPackageDBContents
      , configCompilerEx, configCompilerAuxEx
      , computeEffectiveProfiling
      , ccLdOptionsBuildInfo
      , checkForeignDeps
      , interpretPackageDbFlags
      , ConfigStateFileError(..)
      , tryGetConfigStateFile
      , platformDefines,
      ) where

    import qualified Prelude as Unsafe (tail)
    import Distribution.Compat.Prelude

    import Distribution.Compiler
    import Distribution.Types.IncludeRenaming
    import Distribution.Utils.NubList
    import Distribution.Simple.Compiler
    import Distribution.Simple.PreProcess
    import Distribution.Package
    import qualified Distribution.InstalledPackageInfo as IPI
    import Distribution.InstalledPackageInfo (InstalledPackageInfo)
    import qualified Distribution.Simple.PackageIndex as PackageIndex
    import Distribution.Simple.PackageIndex (InstalledPackageIndex)
    import Distribution.PackageDescription
    import Distribution.PackageDescription.PrettyPrint
    import Distribution.PackageDescription.Configuration
    import Distribution.PackageDescription.Check hiding (doesFileExist)
    import Distribution.Simple.BuildToolDepends
    import Distribution.Simple.Program
    import Distribution.Simple.Setup as Setup
    import Distribution.Simple.BuildTarget
    import Distribution.Simple.LocalBuildInfo
    import Distribution.Types.PackageVersionConstraint
    import Distribution.Types.LocalBuildInfo
    import Distribution.Types.ComponentRequestedSpec
    import Distribution.Types.GivenComponent
    import Distribution.Simple.Utils
    import Distribution.System
    import Distribution.Version
    import Distribution.Verbosity
    import qualified Distribution.Compat.Graph as Graph
    import Distribution.Compat.Stack
    import Distribution.Backpack.Configure
    import Distribution.Backpack.DescribeUnitId
    import Distribution.Backpack.PreExistingComponent
    import Distribution.Backpack.ConfiguredComponent (newPackageDepsBehaviour)
    import Distribution.Backpack.Id
    import Distribution.Utils.LogProgress

    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 Control.Exception
        ( try )
    import Distribution.Utils.Structured ( structuredDecodeOrFailIO, structuredEncode )
    import Distribution.Compat.Directory ( listDirectory )
    import Data.ByteString.Lazy          ( ByteString )
    import qualified Data.ByteString            as BS
    import qualified Data.ByteString.Lazy.Char8 as BLC8
    import Data.List
        ( (\\), inits, stripPrefix, intersect, dropWhileEnd )
    import qualified Data.Map as Map
    import System.Directory
        ( canonicalizePath, createDirectoryIfMissing, doesFileExist
        , getTemporaryDirectory, removeFile)
    import System.FilePath
        ( (</>), isAbsolute, takeDirectory )
    import Distribution.Compat.Directory
        ( doesPathExist )
    import qualified System.Info
        ( compilerName, compilerVersion )
    import System.IO
        ( hPutStrLn, hClose )
    import Distribution.Pretty
        ( pretty, defaultStyle, prettyShow )
    import Distribution.Parsec
        ( simpleParsec )
    import Text.PrettyPrint
        ( Doc, ($+$), char, comma, hsep, nest
        , punctuate, quotes, render, renderStyle, sep, text )
    import Distribution.Compat.Environment ( lookupEnv )

    import qualified Data.Set as Set
    import qualified Distribution.Compat.NonEmptySet as NES

    type UseExternalInternalDeps = Bool

    -- | The errors that can be thrown when reading the @setup-config@ file.
    data ConfigStateFileError
        = ConfigStateFileNoHeader -- ^ No header found.
        | ConfigStateFileBadHeader -- ^ Incorrect header.
        | ConfigStateFileNoParse -- ^ Cannot parse file contents.
        | ConfigStateFileMissing -- ^ No file!
        | ConfigStateFileBadVersion PackageIdentifier PackageIdentifier
          (Either ConfigStateFileError LocalBuildInfo) -- ^ Mismatched version.
      deriving (Typeable)

    -- | Format a 'ConfigStateFileError' as a user-facing error message.
    dispConfigStateFileError :: ConfigStateFileError -> Doc
    dispConfigStateFileError :: ConfigStateFileError -> Doc
    dispConfigStateFileError ConfigStateFileError
    ConfigStateFileNoHeader =
        [Char] -> Doc
    text [Char]
    "Saved package config file header is missing."
        Doc -> Doc -> Doc
    <+> [Char] -> Doc
    text [Char]
    "Re-run the 'configure' command."
    dispConfigStateFileError ConfigStateFileError
    ConfigStateFileBadHeader =
        [Char] -> Doc
    text [Char]
    "Saved package config file header is corrupt."
        Doc -> Doc -> Doc
    <+> [Char] -> Doc
    text [Char]
    "Re-run the 'configure' command."
    dispConfigStateFileError ConfigStateFileError
    ConfigStateFileNoParse =
        [Char] -> Doc
    text [Char]
    "Saved package config file is corrupt."
        Doc -> Doc -> Doc
    <+> [Char] -> Doc
    text [Char]
    "Re-run the 'configure' command."
    dispConfigStateFileError ConfigStateFileError
    ConfigStateFileMissing =
        [Char] -> Doc
    text [Char]
    "Run the 'configure' command first."
    dispConfigStateFileError (ConfigStateFileBadVersion PackageIdentifier
    oldCabal PackageIdentifier
    oldCompiler Either ConfigStateFileError LocalBuildInfo
    _) =
        [Char] -> Doc
    text [Char]
    "Saved package config file is outdated:"
        Doc -> Doc -> Doc
    $+$ Doc
    badCabal Doc -> Doc -> Doc
    $+$ Doc
    badCompiler
        Doc -> Doc -> Doc
    $+$ [Char] -> Doc
    text [Char]
    "Re-run the 'configure' command."
        where
          badCabal :: Doc
    badCabal =
              [Char] -> Doc
    text [Char]
    "• the Cabal version changed from"
              Doc -> Doc -> Doc
    <+> PackageIdentifier -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageIdentifier
    oldCabal Doc -> Doc -> Doc
    <+> Doc
    "to" Doc -> Doc -> Doc
    <+> PackageIdentifier -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageIdentifier
    currentCabalId
          badCompiler :: Doc
    badCompiler
            | PackageIdentifier
    oldCompiler PackageIdentifier -> PackageIdentifier -> Bool
    forall a. Eq a => a -> a -> Bool
    == PackageIdentifier
    currentCompilerId = Doc
    forall a. Monoid a => a
    mempty
            | Bool
    otherwise =
                [Char] -> Doc
    text [Char]
    "• the compiler changed from"
                Doc -> Doc -> Doc
    <+> PackageIdentifier -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageIdentifier
    oldCompiler Doc -> Doc -> Doc
    <+> Doc
    "to" Doc -> Doc -> Doc
    <+> PackageIdentifier -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageIdentifier
    currentCompilerId

    instance Show ConfigStateFileError where
        show :: ConfigStateFileError -> [Char]
    show = Style -> Doc -> [Char]
    renderStyle Style
    defaultStyle (Doc -> [Char])
    -> (ConfigStateFileError -> Doc) -> ConfigStateFileError -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ConfigStateFileError -> Doc
    dispConfigStateFileError

    instance Exception ConfigStateFileError

    -- | Read the 'localBuildInfoFile'.  Throw an exception if the file is
    -- missing, if the file cannot be read, or if the file was created by an older
    -- version of Cabal.
    getConfigStateFile :: FilePath -- ^ The file path of the @setup-config@ file.
                       -> IO LocalBuildInfo
    getConfigStateFile :: [Char] -> IO LocalBuildInfo
    getConfigStateFile [Char]
    filename = do
        Bool
    exists <- [Char] -> IO Bool
    doesFileExist [Char]
    filename
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless Bool
    exists (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ ConfigStateFileError -> IO ()
    forall e a. Exception e => e -> IO a
    throwIO ConfigStateFileError
    ConfigStateFileMissing
        -- Read the config file into a strict ByteString to avoid problems with
        -- lazy I/O, then convert to lazy because the binary package needs that.
        ByteString
    contents <- [Char] -> IO ByteString
    BS.readFile [Char]
    filename
        let (ByteString
    header, ByteString
    body) = (Char -> Bool) -> ByteString -> (ByteString, ByteString)
    BLC8.span (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Char
    '\n') ([ByteString] -> ByteString
    BLC8.fromChunks [ByteString
    contents])

        (PackageIdentifier
    cabalId, PackageIdentifier
    compId) <- ByteString -> IO (PackageIdentifier, PackageIdentifier)
    parseHeader ByteString
    header

        let getStoredValue :: IO LocalBuildInfo
    getStoredValue = do
              Either [Char] LocalBuildInfo
    result <- ByteString -> IO (Either [Char] LocalBuildInfo)
    forall a.
    (Binary a, Structured a) =>
    ByteString -> IO (Either [Char] a)
    structuredDecodeOrFailIO (HasCallStack => ByteString -> ByteString
    ByteString -> ByteString
    BLC8.tail ByteString
    body)
              case Either [Char] LocalBuildInfo
    result of
                Left [Char]
    _ -> ConfigStateFileError -> IO LocalBuildInfo
    forall e a. Exception e => e -> IO a
    throwIO ConfigStateFileError
    ConfigStateFileNoParse
                Right LocalBuildInfo
    x -> LocalBuildInfo -> IO LocalBuildInfo
    forall (m :: * -> *) a. Monad m => a -> m a
    return LocalBuildInfo
    x
            deferErrorIfBadVersion :: IO LocalBuildInfo -> IO LocalBuildInfo
    deferErrorIfBadVersion IO LocalBuildInfo
    act
              | PackageIdentifier
    cabalId PackageIdentifier -> PackageIdentifier -> Bool
    forall a. Eq a => a -> a -> Bool
    /= PackageIdentifier
    currentCabalId = do
                  Either ConfigStateFileError LocalBuildInfo
    eResult <- IO LocalBuildInfo
    -> IO (Either ConfigStateFileError LocalBuildInfo)
    forall e a. Exception e => IO a -> IO (Either e a)
    try IO LocalBuildInfo
    act
                  ConfigStateFileError -> IO LocalBuildInfo
    forall e a. Exception e => e -> IO a
    throwIO (ConfigStateFileError -> IO LocalBuildInfo)
    -> ConfigStateFileError -> IO LocalBuildInfo
    forall a b. (a -> b) -> a -> b
    $ PackageIdentifier
    -> PackageIdentifier
    -> Either ConfigStateFileError LocalBuildInfo
    -> ConfigStateFileError
    ConfigStateFileBadVersion PackageIdentifier
    cabalId PackageIdentifier
    compId Either ConfigStateFileError LocalBuildInfo
    eResult
              | Bool
    otherwise = IO LocalBuildInfo
    act
        IO LocalBuildInfo -> IO LocalBuildInfo
    deferErrorIfBadVersion IO LocalBuildInfo
    getStoredValue
      where
        CallStack
    _ = CallStack
    HasCallStack => CallStack
    callStack -- TODO: attach call stack to exception

    -- | Read the 'localBuildInfoFile', returning either an error or the local build
    -- info.
    tryGetConfigStateFile :: FilePath -- ^ The file path of the @setup-config@ file.
                          -> IO (Either ConfigStateFileError LocalBuildInfo)
    tryGetConfigStateFile :: [Char] -> IO (Either ConfigStateFileError LocalBuildInfo)
    tryGetConfigStateFile = IO LocalBuildInfo
    -> IO (Either ConfigStateFileError LocalBuildInfo)
    forall e a. Exception e => IO a -> IO (Either e a)
    try (IO LocalBuildInfo
     -> IO (Either ConfigStateFileError LocalBuildInfo))
    -> ([Char] -> IO LocalBuildInfo)
    -> [Char]
    -> IO (Either ConfigStateFileError LocalBuildInfo)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> IO LocalBuildInfo
    getConfigStateFile

    -- | Try to read the 'localBuildInfoFile'.
    tryGetPersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
                             -> IO (Either ConfigStateFileError LocalBuildInfo)
    tryGetPersistBuildConfig :: [Char] -> IO (Either ConfigStateFileError LocalBuildInfo)
    tryGetPersistBuildConfig = IO LocalBuildInfo
    -> IO (Either ConfigStateFileError LocalBuildInfo)
    forall e a. Exception e => IO a -> IO (Either e a)
    try (IO LocalBuildInfo
     -> IO (Either ConfigStateFileError LocalBuildInfo))
    -> ([Char] -> IO LocalBuildInfo)
    -> [Char]
    -> IO (Either ConfigStateFileError LocalBuildInfo)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> IO LocalBuildInfo
    getPersistBuildConfig

    -- | Read the 'localBuildInfoFile'. Throw an exception if the file is
    -- missing, if the file cannot be read, or if the file was created by an older
    -- version of Cabal.
    getPersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
                          -> IO LocalBuildInfo
    getPersistBuildConfig :: [Char] -> IO LocalBuildInfo
    getPersistBuildConfig = [Char] -> IO LocalBuildInfo
    getConfigStateFile ([Char] -> IO LocalBuildInfo)
    -> ShowS -> [Char] -> IO LocalBuildInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShowS
    localBuildInfoFile

    -- | Try to read the 'localBuildInfoFile'.
    maybeGetPersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
                               -> IO (Maybe LocalBuildInfo)
    maybeGetPersistBuildConfig :: [Char] -> IO (Maybe LocalBuildInfo)
    maybeGetPersistBuildConfig =
        (Either ConfigStateFileError LocalBuildInfo
     -> Maybe LocalBuildInfo)
    -> IO (Either ConfigStateFileError LocalBuildInfo)
    -> IO (Maybe LocalBuildInfo)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM ((ConfigStateFileError -> Maybe LocalBuildInfo)
    -> (LocalBuildInfo -> Maybe LocalBuildInfo)
    -> Either ConfigStateFileError LocalBuildInfo
    -> Maybe LocalBuildInfo
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe LocalBuildInfo
    -> ConfigStateFileError -> Maybe LocalBuildInfo
    forall a b. a -> b -> a
    const Maybe LocalBuildInfo
    forall a. Maybe a
    Nothing) LocalBuildInfo -> Maybe LocalBuildInfo
    forall a. a -> Maybe a
    Just) (IO (Either ConfigStateFileError LocalBuildInfo)
     -> IO (Maybe LocalBuildInfo))
    -> ([Char] -> IO (Either ConfigStateFileError LocalBuildInfo))
    -> [Char]
    -> IO (Maybe LocalBuildInfo)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> IO (Either ConfigStateFileError LocalBuildInfo)
    tryGetPersistBuildConfig

    -- | After running configure, output the 'LocalBuildInfo' to the
    -- 'localBuildInfoFile'.
    writePersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
                            -> LocalBuildInfo -- ^ The 'LocalBuildInfo' to write.
                            -> IO ()
    writePersistBuildConfig :: [Char] -> LocalBuildInfo -> IO ()
    writePersistBuildConfig [Char]
    distPref LocalBuildInfo
    lbi = do
        Bool -> [Char] -> IO ()
    createDirectoryIfMissing Bool
    False [Char]
    distPref
        [Char] -> ByteString -> IO ()
    writeFileAtomic (ShowS
    localBuildInfoFile [Char]
    distPref) (ByteString -> IO ()) -> ByteString -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          [ByteString] -> ByteString
    BLC8.unlines [PackageIdentifier -> ByteString
    showHeader PackageIdentifier
    pkgId, LocalBuildInfo -> ByteString
    forall a. (Binary a, Structured a) => a -> ByteString
    structuredEncode LocalBuildInfo
    lbi]
      where
        pkgId :: PackageIdentifier
    pkgId = LocalBuildInfo -> PackageIdentifier
    localPackage LocalBuildInfo
    lbi

    -- | Identifier of the current Cabal package.
    currentCabalId :: PackageIdentifier
    currentCabalId :: PackageIdentifier
    currentCabalId = PackageName -> Version -> PackageIdentifier
    PackageIdentifier ([Char] -> PackageName
    mkPackageName [Char]
    "Cabal") Version
    cabalVersion

    -- | Identifier of the current compiler package.
    currentCompilerId :: PackageIdentifier
    currentCompilerId :: PackageIdentifier
    currentCompilerId = PackageName -> Version -> PackageIdentifier
    PackageIdentifier ([Char] -> PackageName
    mkPackageName [Char]
    System.Info.compilerName)
                                          (Version -> Version
    mkVersion' Version
    System.Info.compilerVersion)

    -- | Parse the @setup-config@ file header, returning the package identifiers
    -- for Cabal and the compiler.
    parseHeader :: ByteString -- ^ The file contents.
                -> IO (PackageIdentifier, PackageIdentifier)
    parseHeader :: ByteString -> IO (PackageIdentifier, PackageIdentifier)
    parseHeader ByteString
    header = case ByteString -> [ByteString]
    BLC8.words ByteString
    header of
      [ByteString
    "Saved", ByteString
    "package", ByteString
    "config", ByteString
    "for", ByteString
    pkgId, ByteString
    "written", ByteString
    "by", ByteString
    cabalId,
       ByteString
    "using", ByteString
    compId] ->
          IO (PackageIdentifier, PackageIdentifier)
    -> ((PackageIdentifier, PackageIdentifier)
        -> IO (PackageIdentifier, PackageIdentifier))
    -> Maybe (PackageIdentifier, PackageIdentifier)
    -> IO (PackageIdentifier, PackageIdentifier)
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (ConfigStateFileError -> IO (PackageIdentifier, PackageIdentifier)
    forall e a. Exception e => e -> IO a
    throwIO ConfigStateFileError
    ConfigStateFileBadHeader) (PackageIdentifier, PackageIdentifier)
    -> IO (PackageIdentifier, PackageIdentifier)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (PackageIdentifier, PackageIdentifier)
     -> IO (PackageIdentifier, PackageIdentifier))
    -> Maybe (PackageIdentifier, PackageIdentifier)
    -> IO (PackageIdentifier, PackageIdentifier)
    forall a b. (a -> b) -> a -> b
    $ do
              PackageIdentifier
    _ <- [Char] -> Maybe PackageIdentifier
    forall a. Parsec a => [Char] -> Maybe a
    simpleParsec (ByteString -> [Char]
    fromUTF8LBS ByteString
    pkgId) :: Maybe PackageIdentifier
              PackageIdentifier
    cabalId' <- [Char] -> Maybe PackageIdentifier
    forall a. Parsec a => [Char] -> Maybe a
    simpleParsec (ByteString -> [Char]
    BLC8.unpack ByteString
    cabalId)
              PackageIdentifier
    compId' <- [Char] -> Maybe PackageIdentifier
    forall a. Parsec a => [Char] -> Maybe a
    simpleParsec (ByteString -> [Char]
    BLC8.unpack ByteString
    compId)
              (PackageIdentifier, PackageIdentifier)
    -> Maybe (PackageIdentifier, PackageIdentifier)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (PackageIdentifier
    cabalId', PackageIdentifier
    compId')
      [ByteString]
    _ -> ConfigStateFileError -> IO (PackageIdentifier, PackageIdentifier)
    forall e a. Exception e => e -> IO a
    throwIO ConfigStateFileError
    ConfigStateFileNoHeader

    -- | Generate the @setup-config@ file header.
    showHeader :: PackageIdentifier -- ^ The processed package.
                -> ByteString
    showHeader :: PackageIdentifier -> ByteString
    showHeader PackageIdentifier
    pkgId = [ByteString] -> ByteString
    BLC8.unwords
        [ ByteString
    "Saved", ByteString
    "package", ByteString
    "config", ByteString
    "for"
        , [Char] -> ByteString
    toUTF8LBS ([Char] -> ByteString) -> [Char] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageIdentifier
    pkgId
        , ByteString
    "written", ByteString
    "by"
        , [Char] -> ByteString
    BLC8.pack ([Char] -> ByteString) -> [Char] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageIdentifier
    currentCabalId
        , ByteString
    "using"
        , [Char] -> ByteString
    BLC8.pack ([Char] -> ByteString) -> [Char] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageIdentifier
    currentCompilerId
        ]

    -- | Check that localBuildInfoFile is up-to-date with respect to the
    -- .cabal file.
    checkPersistBuildConfigOutdated :: FilePath -> FilePath -> IO Bool
    checkPersistBuildConfigOutdated :: [Char] -> [Char] -> IO Bool
    checkPersistBuildConfigOutdated [Char]
    distPref [Char]
    pkg_descr_file =
      [Char]
    pkg_descr_file [Char] -> [Char] -> IO Bool
    `moreRecentFile` ShowS
    localBuildInfoFile [Char]
    distPref

    -- | Get the path of @dist\/setup-config@.
    localBuildInfoFile :: FilePath -- ^ The @dist@ directory path.
                        -> FilePath
    localBuildInfoFile :: ShowS
    localBuildInfoFile [Char]
    distPref = [Char]
    distPref [Char] -> ShowS
    </> [Char]
    "setup-config"

    -- -----------------------------------------------------------------------------
    -- * Configuration
    -- -----------------------------------------------------------------------------

    -- | Return the \"dist/\" prefix, or the default prefix. The prefix is taken
    -- from (in order of highest to lowest preference) the override prefix, the
    -- \"CABAL_BUILDDIR\" environment variable, or the default prefix.
    findDistPref :: FilePath  -- ^ default \"dist\" prefix
                 -> Setup.Flag FilePath  -- ^ override \"dist\" prefix
                 -> IO FilePath
    findDistPref :: [Char] -> Flag [Char] -> IO [Char]
    findDistPref [Char]
    defDistPref Flag [Char]
    overrideDistPref = do
        Flag [Char]
    envDistPref <- (Maybe [Char] -> Flag [Char])
    -> IO (Maybe [Char]) -> IO (Flag [Char])
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM Maybe [Char] -> Flag [Char]
    forall {t :: * -> *} {a}. Foldable t => Maybe (t a) -> Flag (t a)
    parseEnvDistPref ([Char] -> IO (Maybe [Char])
    lookupEnv [Char]
    "CABAL_BUILDDIR")
        [Char] -> IO [Char]
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Char] -> IO [Char]) -> [Char] -> IO [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Flag [Char] -> [Char]
    forall a. a -> Flag a -> a
    fromFlagOrDefault [Char]
    defDistPref (Flag [Char] -> Flag [Char] -> Flag [Char]
    forall a. Monoid a => a -> a -> a
    mappend Flag [Char]
    envDistPref Flag [Char]
    overrideDistPref)
      where
        parseEnvDistPref :: Maybe (t a) -> Flag (t a)
    parseEnvDistPref Maybe (t a)
    env =
          case Maybe (t a)
    env of
            Just t a
    distPref | Bool -> Bool
    not (t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null t a
    distPref) -> t a -> Flag (t a)
    forall a. a -> Flag a
    toFlag t a
    distPref
            Maybe (t a)
    _ -> Flag (t a)
    forall a. Flag a
    NoFlag

    -- | Return the \"dist/\" prefix, or the default prefix. The prefix is taken
    -- from (in order of highest to lowest preference) the override prefix, the
    -- \"CABAL_BUILDDIR\" environment variable, or 'defaultDistPref' is used. Call
    -- this function to resolve a @*DistPref@ flag whenever it is not known to be
    -- set. (The @*DistPref@ flags are always set to a definite value before
    -- invoking 'UserHooks'.)
    findDistPrefOrDefault :: Setup.Flag FilePath  -- ^ override \"dist\" prefix
                          -> IO FilePath
    findDistPrefOrDefault :: Flag [Char] -> IO [Char]
    findDistPrefOrDefault = [Char] -> Flag [Char] -> IO [Char]
    findDistPref [Char]
    defaultDistPref

    -- |Perform the \"@.\/setup configure@\" action.
    -- Returns the @.setup-config@ file.
    configure :: (GenericPackageDescription, HookedBuildInfo)
              -> ConfigFlags -> IO LocalBuildInfo
    configure :: (GenericPackageDescription, HookedBuildInfo)
    -> ConfigFlags -> IO LocalBuildInfo
    configure (GenericPackageDescription
    pkg_descr0, HookedBuildInfo
    pbi) ConfigFlags
    cfg = do
        -- Determine the component we are configuring, if a user specified
        -- one on the command line.  We use a fake, flattened version of
        -- the package since at this point, we're not really sure what
        -- components we *can* configure.  @Nothing@ means that we should
        -- configure everything (the old behavior).
        (Maybe ComponentName
    mb_cname :: Maybe ComponentName) <- do
            let flat_pkg_descr :: PackageDescription
    flat_pkg_descr = GenericPackageDescription -> PackageDescription
    flattenPackageDescription GenericPackageDescription
    pkg_descr0
            [BuildTarget]
    targets <- Verbosity -> PackageDescription -> [[Char]] -> IO [BuildTarget]
    readBuildTargets Verbosity
    verbosity PackageDescription
    flat_pkg_descr (ConfigFlags -> [[Char]]
    configArgs ConfigFlags
    cfg)
            -- TODO: bleat if you use the module/file syntax
            let targets' :: [ComponentName]
    targets' = [ ComponentName
    cname | BuildTargetComponent ComponentName
    cname <- [BuildTarget]
    targets ]
            case [ComponentName]
    targets' of
                [ComponentName]
    _ | [[Char]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ConfigFlags -> [[Char]]
    configArgs ConfigFlags
    cfg) -> Maybe ComponentName -> IO (Maybe ComponentName)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe ComponentName
    forall a. Maybe a
    Nothing
                [ComponentName
    cname] -> Maybe ComponentName -> IO (Maybe ComponentName)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ComponentName -> Maybe ComponentName
    forall a. a -> Maybe a
    Just ComponentName
    cname)
                [] -> Verbosity -> [Char] -> IO (Maybe ComponentName)
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity [Char]
    "No valid component targets found"
                [ComponentName]
    _  -> Verbosity -> [Char] -> IO (Maybe ComponentName)
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity
                      [Char]
    "Can only configure either single component or all of them"

        let use_external_internal_deps :: Bool
    use_external_internal_deps = Maybe ComponentName -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe ComponentName
    mb_cname
        case Maybe ComponentName
    mb_cname of
            Maybe ComponentName
    Nothing -> Verbosity -> [Char] -> PackageIdentifier -> IO ()
    setupMessage Verbosity
    verbosity [Char]
    "Configuring" (GenericPackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId GenericPackageDescription
    pkg_descr0)
            Just ComponentName
    cname -> Verbosity
    -> [Char]
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, Module)]
    -> IO ()
    forall a.
    Pretty a =>
    Verbosity
    -> [Char]
    -> PackageIdentifier
    -> ComponentName
    -> Maybe [(ModuleName, a)]
    -> IO ()
    setupMessage' Verbosity
    verbosity [Char]
    "Configuring" (GenericPackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId GenericPackageDescription
    pkg_descr0)
                            ComponentName
    cname ([(ModuleName, Module)] -> Maybe [(ModuleName, Module)]
    forall a. a -> Maybe a
    Just (ConfigFlags -> [(ModuleName, Module)]
    configInstantiateWith ConfigFlags
    cfg))

        -- configCID is only valid for per-component configure
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Maybe ComponentId -> Bool
    forall a. Maybe a -> Bool
    isJust (Flag ComponentId -> Maybe ComponentId
    forall a. Flag a -> Maybe a
    flagToMaybe (ConfigFlags -> Flag ComponentId
    configCID ConfigFlags
    cfg)) Bool -> Bool -> Bool
    && Maybe ComponentName -> Bool
    forall a. Maybe a -> Bool
    isNothing Maybe ComponentName
    mb_cname) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity [Char]
    "--cid is only supported for per-component configure"

        Verbosity -> ConfigFlags -> IO ()
    checkDeprecatedFlags Verbosity
    verbosity ConfigFlags
    cfg
        Verbosity -> GenericPackageDescription -> ConfigFlags -> IO ()
    checkExactConfiguration Verbosity
    verbosity GenericPackageDescription
    pkg_descr0 ConfigFlags
    cfg

        -- Where to build the package
        let buildDir :: FilePath -- e.g. dist/build
            -- fromFlag OK due to Distribution.Simple calling
            -- findDistPrefOrDefault to fill it in
            buildDir :: [Char]
    buildDir = Flag [Char] -> [Char]
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag [Char]
    configDistPref ConfigFlags
    cfg) [Char] -> ShowS
    </> [Char]
    "build"
        Verbosity -> Bool -> [Char] -> IO ()
    createDirectoryIfMissingVerbose (Verbosity -> Verbosity
    lessVerbose Verbosity
    verbosity) Bool
    True [Char]
    buildDir

        -- What package database(s) to use
        let packageDbs :: PackageDBStack
            packageDbs :: PackageDBStack
    packageDbs
             = Bool -> [Maybe PackageDB] -> PackageDBStack
    interpretPackageDbFlags
                (Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configUserInstall ConfigFlags
    cfg))
                (ConfigFlags -> [Maybe PackageDB]
    configPackageDBs ConfigFlags
    cfg)

        -- comp:            the compiler we're building with
        -- compPlatform:    the platform we're building for
        -- programDb:  location and args of all programs we're
        --                  building with
        (Compiler
    comp         :: Compiler,
         Platform
    compPlatform :: Platform,
         ProgramDb
    programDb    :: ProgramDb)
            <- Maybe CompilerFlavor
    -> Maybe [Char]
    -> Maybe [Char]
    -> ProgramDb
    -> Verbosity
    -> IO (Compiler, Platform, ProgramDb)
    configCompilerEx
                (Flag CompilerFlavor -> Maybe CompilerFlavor
    forall a. Flag a -> Maybe a
    flagToMaybe (ConfigFlags -> Flag CompilerFlavor
    configHcFlavor ConfigFlags
    cfg))
                (Flag [Char] -> Maybe [Char]
    forall a. Flag a -> Maybe a
    flagToMaybe (ConfigFlags -> Flag [Char]
    configHcPath ConfigFlags
    cfg))
                (Flag [Char] -> Maybe [Char]
    forall a. Flag a -> Maybe a
    flagToMaybe (ConfigFlags -> Flag [Char]
    configHcPkg ConfigFlags
    cfg))
                (ConfigFlags -> ProgramDb -> ProgramDb
    mkProgramDb ConfigFlags
    cfg (WithCallStack (ConfigFlags -> ProgramDb)
    ConfigFlags -> ProgramDb
    configPrograms ConfigFlags
    cfg))
                (Verbosity -> Verbosity
    lessVerbose Verbosity
    verbosity)

        -- The InstalledPackageIndex of all installed packages
        InstalledPackageIndex
    installedPackageSet :: InstalledPackageIndex
            <- Verbosity
    -> Compiler
    -> PackageDBStack
    -> ProgramDb
    -> IO InstalledPackageIndex
    getInstalledPackages (Verbosity -> Verbosity
    lessVerbose Verbosity
    verbosity) Compiler
    comp
                                      PackageDBStack
    packageDbs ProgramDb
    programDb

        -- The set of package names which are "shadowed" by internal
        -- packages, and which component they map to
        let internalPackageSet :: Set LibraryName
            internalPackageSet :: Set LibraryName
    internalPackageSet = GenericPackageDescription -> Set LibraryName
    getInternalLibraries GenericPackageDescription
    pkg_descr0

        -- Make a data structure describing what components are enabled.
        let enabled :: ComponentRequestedSpec
            enabled :: ComponentRequestedSpec
    enabled = case Maybe ComponentName
    mb_cname of
                        Just ComponentName
    cname -> ComponentName -> ComponentRequestedSpec
    OneComponentRequestedSpec ComponentName
    cname
                        Maybe ComponentName
    Nothing -> ComponentRequestedSpec
                                    -- The flag name (@--enable-tests@) is a
                                    -- little bit of a misnomer, because
                                    -- just passing this flag won't
                                    -- "enable", in our internal
                                    -- nomenclature; it's just a request; a
                                    -- @buildable: False@ might make it
                                    -- not possible to enable.
                                    { testsRequested :: Bool
    testsRequested = Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configTests ConfigFlags
    cfg)
                                    , benchmarksRequested :: Bool
    benchmarksRequested =
                                      Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configBenchmarks ConfigFlags
    cfg) }
        -- Some sanity checks related to enabling components.
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Maybe ComponentName -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe ComponentName
    mb_cname
              Bool -> Bool -> Bool
    && (Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configTests ConfigFlags
    cfg) Bool -> Bool -> Bool
    || Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configBenchmarks ConfigFlags
    cfg))) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                  [Char]
    "--enable-tests/--enable-benchmarks are incompatible with" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                  [Char]
    " explicitly specifying a component to configure."

        -- Some sanity checks related to dynamic/static linking.
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configDynExe ConfigFlags
    cfg) Bool -> Bool -> Bool
    && Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configFullyStaticExe ConfigFlags
    cfg)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                  [Char]
    "--enable-executable-dynamic and --enable-executable-static" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                  [Char]
    " are incompatible with each other."

        -- allConstraints:  The set of all 'Dependency's we have.  Used ONLY
        --                  to 'configureFinalizedPackage'.
        -- requiredDepsMap: A map from 'PackageName' to the specifically
        --                  required 'InstalledPackageInfo', due to --dependency
        --
        -- NB: These constraints are to be applied to ALL components of
        -- a package.  Thus, it's not an error if allConstraints contains
        -- more constraints than is necessary for a component (another
        -- component might need it.)
        --
        -- NB: The fact that we bundle all the constraints together means
        -- that is not possible to configure a test-suite to use one
        -- version of a dependency, and the executable to use another.
        ([PackageVersionConstraint]
    allConstraints  :: [PackageVersionConstraint],
         Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap :: Map (PackageName, ComponentName) InstalledPackageInfo)
            <- ([Char]
     -> IO
          ([PackageVersionConstraint],
           Map (PackageName, ComponentName) InstalledPackageInfo))
    -> (([PackageVersionConstraint],
         Map (PackageName, ComponentName) InstalledPackageInfo)
        -> IO
             ([PackageVersionConstraint],
              Map (PackageName, ComponentName) InstalledPackageInfo))
    -> Either
         [Char]
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    -> IO
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Verbosity
    -> [Char]
    -> IO
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity) ([PackageVersionConstraint],
     Map (PackageName, ComponentName) InstalledPackageInfo)
    -> IO
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either
       [Char]
       ([PackageVersionConstraint],
        Map (PackageName, ComponentName) InstalledPackageInfo)
     -> IO
          ([PackageVersionConstraint],
           Map (PackageName, ComponentName) InstalledPackageInfo))
    -> Either
         [Char]
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    -> IO
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    forall a b. (a -> b) -> a -> b
    $
                  [PackageVersionConstraint]
    -> [GivenComponent]
    -> InstalledPackageIndex
    -> Either
         [Char]
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    combinedConstraints (ConfigFlags -> [PackageVersionConstraint]
    configConstraints ConfigFlags
    cfg)
                                      (ConfigFlags -> [GivenComponent]
    configDependencies ConfigFlags
    cfg)
                                      InstalledPackageIndex
    installedPackageSet

        -- pkg_descr:   The resolved package description, that does not contain any
        --              conditionals, because we have an assignment for
        --              every flag, either picking them ourselves using a
        --              simple naive algorithm, or having them be passed to
        --              us by 'configConfigurationsFlags')
        -- flags:       The 'FlagAssignment' that the conditionals were
        --              resolved with.
        --
        -- NB: Why doesn't finalizing a package also tell us what the
        -- dependencies are (e.g. when we run the naive algorithm,
        -- we are checking if dependencies are satisfiable)?  The
        -- primary reason is that we may NOT have done any solving:
        -- if the flags are all chosen for us, this step is a simple
        -- matter of flattening according to that assignment.  It's
        -- cleaner to then configure the dependencies afterwards.
        (PackageDescription
    pkg_descr :: PackageDescription,
         FlagAssignment
    flags     :: FlagAssignment)
            <- Verbosity
    -> ConfigFlags
    -> ComponentRequestedSpec
    -> [PackageVersionConstraint]
    -> (Dependency -> Bool)
    -> Compiler
    -> Platform
    -> GenericPackageDescription
    -> IO (PackageDescription, FlagAssignment)
    configureFinalizedPackage Verbosity
    verbosity ConfigFlags
    cfg ComponentRequestedSpec
    enabled
                    [PackageVersionConstraint]
    allConstraints
                    (Bool
    -> Bool
    -> Bool
    -> PackageName
    -> InstalledPackageIndex
    -> Set LibraryName
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> Dependency
    -> Bool
    dependencySatisfiable
                        Bool
    use_external_internal_deps
                        (Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False (ConfigFlags -> Flag Bool
    configExactConfiguration ConfigFlags
    cfg))
                        (Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False (ConfigFlags -> Flag Bool
    configAllowDependingOnPrivateLibs ConfigFlags
    cfg))
                        (GenericPackageDescription -> PackageName
    forall pkg. Package pkg => pkg -> PackageName
    packageName GenericPackageDescription
    pkg_descr0)
                        InstalledPackageIndex
    installedPackageSet
                        Set LibraryName
    internalPackageSet
                        Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap)
                    Compiler
    comp
                    Platform
    compPlatform
                    GenericPackageDescription
    pkg_descr0

        Verbosity -> [Char] -> IO ()
    debug Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Finalized package description:\n"
                      [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageDescription -> [Char]
    showPackageDescription PackageDescription
    pkg_descr

        let cabalFileDir :: [Char]
    cabalFileDir = [Char] -> ShowS -> Maybe [Char] -> [Char]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [Char]
    "." ShowS
    takeDirectory (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $
              Flag [Char] -> Maybe [Char]
    forall a. Flag a -> Maybe a
    flagToMaybe (ConfigFlags -> Flag [Char]
    configCabalFilePath ConfigFlags
    cfg)
        Verbosity
    -> Compiler
    -> PackageDescription
    -> ComponentRequestedSpec
    -> IO ()
    checkCompilerProblems Verbosity
    verbosity Compiler
    comp PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled
        Verbosity
    -> [Char]
    -> GenericPackageDescription
    -> PackageDescription
    -> IO ()
    checkPackageProblems Verbosity
    verbosity [Char]
    cabalFileDir GenericPackageDescription
    pkg_descr0
            (HookedBuildInfo -> PackageDescription -> PackageDescription
    updatePackageDescription HookedBuildInfo
    pbi PackageDescription
    pkg_descr)

        -- The list of 'InstalledPackageInfo' recording the selected
        -- dependencies on external packages.
        --
        -- Invariant: For any package name, there is at most one package
        -- in externalPackageDeps which has that name.
        --
        -- NB: The dependency selection is global over ALL components
        -- in the package (similar to how allConstraints and
        -- requiredDepsMap are global over all components).  In particular,
        -- if *any* component (post-flag resolution) has an unsatisfiable
        -- dependency, we will fail.  This can sometimes be undesirable
        -- for users, see #1786 (benchmark conflicts with executable),
        --
        -- In the presence of Backpack, these package dependencies are
        -- NOT complete: they only ever include the INDEFINITE
        -- dependencies.  After we apply an instantiation, we'll get
        -- definite references which constitute extra dependencies.
        -- (Why not have cabal-install pass these in explicitly?
        -- For one it's deterministic; for two, we need to associate
        -- them with renamings which would require a far more complicated
        -- input scheme than what we have today.)
        [PreExistingComponent]
    externalPkgDeps :: [PreExistingComponent]
            <- Verbosity
    -> Bool
    -> Set LibraryName
    -> InstalledPackageIndex
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> PackageDescription
    -> ComponentRequestedSpec
    -> IO [PreExistingComponent]
    configureDependencies
                    Verbosity
    verbosity
                    Bool
    use_external_internal_deps
                    Set LibraryName
    internalPackageSet
                    InstalledPackageIndex
    installedPackageSet
                    Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap
                    PackageDescription
    pkg_descr
                    ComponentRequestedSpec
    enabled

        -- Compute installation directory templates, based on user
        -- configuration.
        --
        -- TODO: Move this into a helper function.
        InstallDirTemplates
    defaultDirs :: InstallDirTemplates
            <- Bool -> CompilerFlavor -> Bool -> Bool -> IO InstallDirTemplates
    defaultInstallDirs' Bool
    use_external_internal_deps
                                  (Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp)
                                  (Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configUserInstall ConfigFlags
    cfg))
                                  (PackageDescription -> Bool
    hasLibs PackageDescription
    pkg_descr)
        let installDirs :: InstallDirTemplates
            installDirs :: InstallDirTemplates
    installDirs = (PathTemplate -> Flag PathTemplate -> PathTemplate)
    -> InstallDirTemplates
    -> InstallDirs (Flag PathTemplate)
    -> InstallDirTemplates
    forall a b c.
    (a -> b -> c) -> InstallDirs a -> InstallDirs b -> InstallDirs c
    combineInstallDirs PathTemplate -> Flag PathTemplate -> PathTemplate
    forall a. a -> Flag a -> a
    fromFlagOrDefault
                            InstallDirTemplates
    defaultDirs (ConfigFlags -> InstallDirs (Flag PathTemplate)
    configInstallDirs ConfigFlags
    cfg)

        -- Check languages and extensions
        -- TODO: Move this into a helper function.
        let langlist :: [Language]
    langlist = [Language] -> [Language]
    forall a. Eq a => [a] -> [a]
    nub ([Language] -> [Language]) -> [Language] -> [Language]
    forall a b. (a -> b) -> a -> b
    $ [Maybe Language] -> [Language]
    forall a. [Maybe a] -> [a]
    catMaybes ([Maybe Language] -> [Language]) -> [Maybe Language] -> [Language]
    forall a b. (a -> b) -> a -> b
    $ (BuildInfo -> Maybe Language) -> [BuildInfo] -> [Maybe Language]
    forall a b. (a -> b) -> [a] -> [b]
    map BuildInfo -> Maybe Language
    defaultLanguage
                       (PackageDescription -> ComponentRequestedSpec -> [BuildInfo]
    enabledBuildInfos PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled)
        let langs :: [Language]
    langs = Compiler -> [Language] -> [Language]
    unsupportedLanguages Compiler
    comp [Language]
    langlist
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not ([Language] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Language]
    langs)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "The package " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (GenericPackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId GenericPackageDescription
    pkg_descr0)
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " requires the following languages which are not "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "supported by " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ CompilerId -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (Compiler -> CompilerId
    compilerId Compiler
    comp) [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ": "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ", " ((Language -> [Char]) -> [Language] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map Language -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow [Language]
    langs)
        let extlist :: [Extension]
    extlist = [Extension] -> [Extension]
    forall a. Eq a => [a] -> [a]
    nub ([Extension] -> [Extension]) -> [Extension] -> [Extension]
    forall a b. (a -> b) -> a -> b
    $ (BuildInfo -> [Extension]) -> [BuildInfo] -> [Extension]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap BuildInfo -> [Extension]
    allExtensions
                      (PackageDescription -> ComponentRequestedSpec -> [BuildInfo]
    enabledBuildInfos PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled)
        let exts :: [Extension]
    exts = Compiler -> [Extension] -> [Extension]
    unsupportedExtensions Compiler
    comp [Extension]
    extlist
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not ([Extension] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Extension]
    exts)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "The package " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (GenericPackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId GenericPackageDescription
    pkg_descr0)
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " requires the following language extensions which are not "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "supported by " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ CompilerId -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (Compiler -> CompilerId
    compilerId Compiler
    comp) [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ": "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ", " ((Extension -> [Char]) -> [Extension] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map Extension -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow [Extension]
    exts)

        -- Check foreign library build requirements
        let flibs :: [ForeignLib]
    flibs = [ForeignLib
    flib | CFLib ForeignLib
    flib <- PackageDescription -> ComponentRequestedSpec -> [Component]
    enabledComponents PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled]
        let unsupportedFLibs :: [[Char]]
    unsupportedFLibs = Compiler -> Platform -> [ForeignLib] -> [[Char]]
    unsupportedForeignLibs Compiler
    comp Platform
    compPlatform [ForeignLib]
    flibs
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not ([[Char]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [[Char]]
    unsupportedFLibs)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Cannot build some foreign libraries: "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    "," [[Char]]
    unsupportedFLibs

        -- Configure certain external build tools, see below for which ones.
        let requiredBuildTools :: [LegacyExeDependency]
    requiredBuildTools = do
              BuildInfo
    bi <- PackageDescription -> ComponentRequestedSpec -> [BuildInfo]
    enabledBuildInfos PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled
              -- First, we collect any tool dep that we know is external. This is,
              -- in practice:
              --
              -- 1. `build-tools` entries on the whitelist
              --
              -- 2. `build-tool-depends` that aren't from the current package.
              let externBuildToolDeps :: [LegacyExeDependency]
    externBuildToolDeps =
                    [ [Char] -> VersionRange -> LegacyExeDependency
    LegacyExeDependency (UnqualComponentName -> [Char]
    unUnqualComponentName UnqualComponentName
    eName) VersionRange
    versionRange
                    | buildTool :: ExeDependency
    buildTool@(ExeDependency PackageName
    _ UnqualComponentName
    eName VersionRange
    versionRange)
                      <- PackageDescription -> BuildInfo -> [ExeDependency]
    getAllToolDependencies PackageDescription
    pkg_descr BuildInfo
    bi
                    , Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ PackageDescription -> ExeDependency -> Bool
    isInternal PackageDescription
    pkg_descr ExeDependency
    buildTool ]
              -- Second, we collect any build-tools entry we don't know how to
              -- desugar. We'll never have any idea how to build them, so we just
              -- hope they are already on the PATH.
              let unknownBuildTools :: [LegacyExeDependency]
    unknownBuildTools =
                    [ LegacyExeDependency
    buildTool
                    | LegacyExeDependency
    buildTool <- BuildInfo -> [LegacyExeDependency]
    buildTools BuildInfo
    bi
                    , Maybe ExeDependency
    forall a. Maybe a
    Nothing Maybe ExeDependency -> Maybe ExeDependency -> Bool
    forall a. Eq a => a -> a -> Bool
    == PackageDescription -> LegacyExeDependency -> Maybe ExeDependency
    desugarBuildTool PackageDescription
    pkg_descr LegacyExeDependency
    buildTool ]
              [LegacyExeDependency]
    externBuildToolDeps [LegacyExeDependency]
    -> [LegacyExeDependency] -> [LegacyExeDependency]
    forall a. [a] -> [a] -> [a]
    ++ [LegacyExeDependency]
    unknownBuildTools

        ProgramDb
    programDb' <-
              Verbosity -> ProgramDb -> IO ProgramDb
    configureAllKnownPrograms (Verbosity -> Verbosity
    lessVerbose Verbosity
    verbosity) ProgramDb
    programDb
          IO ProgramDb -> (ProgramDb -> IO ProgramDb) -> IO ProgramDb
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Verbosity -> [LegacyExeDependency] -> ProgramDb -> IO ProgramDb
    configureRequiredPrograms Verbosity
    verbosity [LegacyExeDependency]
    requiredBuildTools

        (PackageDescription
    pkg_descr', ProgramDb
    programDb'') <-
          Verbosity
    -> PackageDescription
    -> ProgramDb
    -> ComponentRequestedSpec
    -> IO (PackageDescription, ProgramDb)
    configurePkgconfigPackages Verbosity
    verbosity PackageDescription
    pkg_descr ProgramDb
    programDb' ComponentRequestedSpec
    enabled

        -- Compute internal component graph
        --
        -- The general idea is that we take a look at all the source level
        -- components (which may build-depends on each other) and form a graph.
        -- From there, we build a ComponentLocalBuildInfo for each of the
        -- components, which lets us actually build each component.
        -- internalPackageSet
        -- use_external_internal_deps
        ([ComponentLocalBuildInfo]
    buildComponents :: [ComponentLocalBuildInfo],
         InstalledPackageIndex
    packageDependsIndex :: InstalledPackageIndex) <-
          Verbosity
    -> LogProgress ([ComponentLocalBuildInfo], InstalledPackageIndex)
    -> IO ([ComponentLocalBuildInfo], InstalledPackageIndex)
    forall a. Verbosity -> LogProgress a -> IO a
    runLogProgress Verbosity
    verbosity (LogProgress ([ComponentLocalBuildInfo], InstalledPackageIndex)
     -> IO ([ComponentLocalBuildInfo], InstalledPackageIndex))
    -> LogProgress ([ComponentLocalBuildInfo], InstalledPackageIndex)
    -> IO ([ComponentLocalBuildInfo], InstalledPackageIndex)
    forall a b. (a -> b) -> a -> b
    $ Verbosity
    -> Bool
    -> ComponentRequestedSpec
    -> Bool
    -> Flag [Char]
    -> Flag ComponentId
    -> PackageDescription
    -> [PreExistingComponent]
    -> FlagAssignment
    -> [(ModuleName, Module)]
    -> InstalledPackageIndex
    -> Compiler
    -> LogProgress ([ComponentLocalBuildInfo], InstalledPackageIndex)
    configureComponentLocalBuildInfos
                Verbosity
    verbosity
                Bool
    use_external_internal_deps
                ComponentRequestedSpec
    enabled
                (Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False (ConfigFlags -> Flag Bool
    configDeterministic ConfigFlags
    cfg))
                (ConfigFlags -> Flag [Char]
    configIPID ConfigFlags
    cfg)
                (ConfigFlags -> Flag ComponentId
    configCID ConfigFlags
    cfg)
                PackageDescription
    pkg_descr
                [PreExistingComponent]
    externalPkgDeps
                (ConfigFlags -> FlagAssignment
    configConfigurationsFlags ConfigFlags
    cfg)
                (ConfigFlags -> [(ModuleName, Module)]
    configInstantiateWith ConfigFlags
    cfg)
                InstalledPackageIndex
    installedPackageSet
                Compiler
    comp

        -- Decide if we're going to compile with split sections.
        Bool
    split_sections :: Bool <-
           if Bool -> Bool
    not (Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configSplitSections ConfigFlags
    cfg)
                then Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
                else case Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp of
                            CompilerFlavor
    GHC | Compiler -> Version
    compilerVersion Compiler
    comp Version -> Version -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [Int] -> Version
    mkVersion [Int
    8,Int
    0]
                              -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
                            CompilerFlavor
    GHCJS
                              -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
                            CompilerFlavor
    _ -> do Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
                                         ([Char]
    "this compiler does not support " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                          [Char]
    "--enable-split-sections; ignoring")
                                    Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

        -- Decide if we're going to compile with split objects.
        Bool
    split_objs :: Bool <-
           if Bool -> Bool
    not (Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configSplitObjs ConfigFlags
    cfg)
                then Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
                else case Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp of
                            CompilerFlavor
    _ | Bool
    split_sections
                              -> do Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
                                         ([Char]
    "--enable-split-sections and " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                          [Char]
    "--enable-split-objs are mutually" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                          [Char]
    "exclusive; ignoring the latter")
                                    Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
                            CompilerFlavor
    GHC
                              -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
                            CompilerFlavor
    GHCJS
                              -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
                            CompilerFlavor
    _ -> do Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
                                         ([Char]
    "this compiler does not support " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                          [Char]
    "--enable-split-objs; ignoring")
                                    Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

        let ghciLibByDefault :: Bool
    ghciLibByDefault =
              case Compiler -> CompilerId
    compilerId Compiler
    comp of
                CompilerId CompilerFlavor
    GHC Version
    _ ->
                  -- If ghc is non-dynamic, then ghci needs object files,
                  -- so we build one by default.
                  --
                  -- Technically, archive files should be sufficient for ghci,
                  -- but because of GHC bug #8942, it has never been safe to
                  -- rely on them. By the time that bug was fixed, ghci had
                  -- been changed to read shared libraries instead of archive
                  -- files (see next code block).
                  Bool -> Bool
    not (Compiler -> Bool
    GHC.isDynamic Compiler
    comp)
                CompilerId CompilerFlavor
    GHCJS Version
    _ ->
                  Bool -> Bool
    not (Compiler -> Bool
    GHCJS.isDynamic Compiler
    comp)
                CompilerId
    _ -> Bool
    False

        let sharedLibsByDefault :: Bool
    sharedLibsByDefault
              | Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configDynExe ConfigFlags
    cfg) =
                  -- build a shared library if dynamically-linked
                  -- executables are requested
                  Bool
    True
              | Bool
    otherwise = case Compiler -> CompilerId
    compilerId Compiler
    comp of
                CompilerId CompilerFlavor
    GHC Version
    _ ->
                  -- if ghc is dynamic, then ghci needs a shared
                  -- library, so we build one by default.
                  Compiler -> Bool
    GHC.isDynamic Compiler
    comp
                CompilerId CompilerFlavor
    GHCJS Version
    _ ->
                  Compiler -> Bool
    GHCJS.isDynamic Compiler
    comp
                CompilerId
    _ -> Bool
    False
            withSharedLib_ :: Bool
    withSharedLib_ =
                -- build shared libraries if required by GHC or by the
                -- executable linking mode, but allow the user to force
                -- building only static library archives with
                -- --disable-shared.
                Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    sharedLibsByDefault (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configSharedLib ConfigFlags
    cfg

            withStaticLib_ :: Bool
    withStaticLib_ =
                -- build a static library (all dependent libraries rolled
                -- into a huge .a archive) via GHCs -staticlib flag.
                Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configStaticLib ConfigFlags
    cfg

            withDynExe_ :: Bool
    withDynExe_ = Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configDynExe ConfigFlags
    cfg

            withFullyStaticExe_ :: Bool
    withFullyStaticExe_ = Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configFullyStaticExe ConfigFlags
    cfg
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool
    withDynExe_ Bool -> Bool -> Bool
    && Bool -> Bool
    not Bool
    withSharedLib_) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $
               [Char]
    "Executables will use dynamic linking, but a shared library "
            [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "is not being built. Linking will fail if any executables "
            [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "depend on the library."

        LocalBuildInfo -> LocalBuildInfo
    setProfLBI <- Verbosity
    -> ConfigFlags -> Compiler -> IO (LocalBuildInfo -> LocalBuildInfo)
    configureProfiling Verbosity
    verbosity ConfigFlags
    cfg Compiler
    comp

        LocalBuildInfo -> LocalBuildInfo
    setCoverageLBI <- Verbosity
    -> ConfigFlags -> Compiler -> IO (LocalBuildInfo -> LocalBuildInfo)
    configureCoverage Verbosity
    verbosity ConfigFlags
    cfg Compiler
    comp

        -- Turn off library and executable stripping when `debug-info` is set
        -- to anything other than zero.
        let
            strip_libexe :: [Char] -> (ConfigFlags -> Flag Bool) -> IO Bool
    strip_libexe [Char]
    s ConfigFlags -> Flag Bool
    f =
              let defaultStrip :: Bool
    defaultStrip = Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    True (ConfigFlags -> Flag Bool
    f ConfigFlags
    cfg)
              in case Flag DebugInfoLevel -> DebugInfoLevel
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag DebugInfoLevel
    configDebugInfo ConfigFlags
    cfg) of
                          DebugInfoLevel
    NoDebugInfo -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    defaultStrip
                          DebugInfoLevel
    _ -> case ConfigFlags -> Flag Bool
    f ConfigFlags
    cfg of
                                 Flag Bool
    True -> do
                                  Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Setting debug-info implies "
                                                    [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    s [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "-stripping: False"
                                  Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

                                 Flag Bool
    _ -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

        Bool
    strip_lib <- [Char] -> (ConfigFlags -> Flag Bool) -> IO Bool
    strip_libexe [Char]
    "library" ConfigFlags -> Flag Bool
    configStripLibs
        Bool
    strip_exe <- [Char] -> (ConfigFlags -> Flag Bool) -> IO Bool
    strip_libexe [Char]
    "executable" ConfigFlags -> Flag Bool
    configStripExes

        let reloc :: Bool
    reloc = Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configRelocatable ConfigFlags
    cfg

        let buildComponentsMap :: Map ComponentName [ComponentLocalBuildInfo]
    buildComponentsMap =
                (Map ComponentName [ComponentLocalBuildInfo]
     -> ComponentLocalBuildInfo
     -> Map ComponentName [ComponentLocalBuildInfo])
    -> Map ComponentName [ComponentLocalBuildInfo]
    -> [ComponentLocalBuildInfo]
    -> Map ComponentName [ComponentLocalBuildInfo]
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' (\Map ComponentName [ComponentLocalBuildInfo]
    m ComponentLocalBuildInfo
    clbi -> ([ComponentLocalBuildInfo]
     -> [ComponentLocalBuildInfo] -> [ComponentLocalBuildInfo])
    -> ComponentName
    -> [ComponentLocalBuildInfo]
    -> Map ComponentName [ComponentLocalBuildInfo]
    -> Map ComponentName [ComponentLocalBuildInfo]
    forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
    Map.insertWith [ComponentLocalBuildInfo]
    -> [ComponentLocalBuildInfo] -> [ComponentLocalBuildInfo]
    forall a. [a] -> [a] -> [a]
    (++)
                                   (ComponentLocalBuildInfo -> ComponentName
    componentLocalName ComponentLocalBuildInfo
    clbi) [ComponentLocalBuildInfo
    clbi] Map ComponentName [ComponentLocalBuildInfo]
    m)
                       Map ComponentName [ComponentLocalBuildInfo]
    forall k a. Map k a
    Map.empty [ComponentLocalBuildInfo]
    buildComponents

        let lbi :: LocalBuildInfo
    lbi = (LocalBuildInfo -> LocalBuildInfo
    setCoverageLBI (LocalBuildInfo -> LocalBuildInfo)
    -> (LocalBuildInfo -> LocalBuildInfo)
    -> LocalBuildInfo
    -> LocalBuildInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LocalBuildInfo -> LocalBuildInfo
    setProfLBI)
                  LocalBuildInfo {
                    configFlags :: ConfigFlags
    configFlags         = ConfigFlags
    cfg,
                    flagAssignment :: FlagAssignment
    flagAssignment      = FlagAssignment
    flags,
                    componentEnabledSpec :: ComponentRequestedSpec
    componentEnabledSpec = ComponentRequestedSpec
    enabled,
                    extraConfigArgs :: [[Char]]
    extraConfigArgs     = [],  -- Currently configure does not
                                               -- take extra args, but if it
                                               -- did they would go here.
                    installDirTemplates :: InstallDirTemplates
    installDirTemplates = InstallDirTemplates
    installDirs,
                    compiler :: Compiler
    compiler            = Compiler
    comp,
                    hostPlatform :: Platform
    hostPlatform        = Platform
    compPlatform,
                    buildDir :: [Char]
    buildDir            = [Char]
    buildDir,
                    cabalFilePath :: Maybe [Char]
    cabalFilePath       = Flag [Char] -> Maybe [Char]
    forall a. Flag a -> Maybe a
    flagToMaybe (ConfigFlags -> Flag [Char]
    configCabalFilePath ConfigFlags
    cfg),
                    componentGraph :: Graph ComponentLocalBuildInfo
    componentGraph      = [ComponentLocalBuildInfo] -> Graph ComponentLocalBuildInfo
    forall a. (IsNode a, Show (Key a)) => [a] -> Graph a
    Graph.fromDistinctList [ComponentLocalBuildInfo]
    buildComponents,
                    componentNameMap :: Map ComponentName [ComponentLocalBuildInfo]
    componentNameMap    = Map ComponentName [ComponentLocalBuildInfo]
    buildComponentsMap,
                    installedPkgs :: InstalledPackageIndex
    installedPkgs       = InstalledPackageIndex
    packageDependsIndex,
                    pkgDescrFile :: Maybe [Char]
    pkgDescrFile        = Maybe [Char]
    forall a. Maybe a
    Nothing,
                    localPkgDescr :: PackageDescription
    localPkgDescr       = PackageDescription
    pkg_descr',
                    withPrograms :: ProgramDb
    withPrograms        = ProgramDb
    programDb'',
                    withVanillaLib :: Bool
    withVanillaLib      = Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag Bool
    configVanillaLib ConfigFlags
    cfg,
                    withSharedLib :: Bool
    withSharedLib       = Bool
    withSharedLib_,
                    withStaticLib :: Bool
    withStaticLib       = Bool
    withStaticLib_,
                    withDynExe :: Bool
    withDynExe          = Bool
    withDynExe_,
                    withFullyStaticExe :: Bool
    withFullyStaticExe  = Bool
    withFullyStaticExe_,
                    withProfLib :: Bool
    withProfLib         = Bool
    False,
                    withProfLibDetail :: ProfDetailLevel
    withProfLibDetail   = ProfDetailLevel
    ProfDetailNone,
                    withProfExe :: Bool
    withProfExe         = Bool
    False,
                    withProfExeDetail :: ProfDetailLevel
    withProfExeDetail   = ProfDetailLevel
    ProfDetailNone,
                    withOptimization :: OptimisationLevel
    withOptimization    = Flag OptimisationLevel -> OptimisationLevel
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag OptimisationLevel -> OptimisationLevel)
    -> Flag OptimisationLevel -> OptimisationLevel
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag OptimisationLevel
    configOptimization ConfigFlags
    cfg,
                    withDebugInfo :: DebugInfoLevel
    withDebugInfo       = Flag DebugInfoLevel -> DebugInfoLevel
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag DebugInfoLevel -> DebugInfoLevel)
    -> Flag DebugInfoLevel -> DebugInfoLevel
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag DebugInfoLevel
    configDebugInfo ConfigFlags
    cfg,
                    withGHCiLib :: Bool
    withGHCiLib         = Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    ghciLibByDefault (Flag Bool -> Bool) -> Flag Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $
                                          ConfigFlags -> Flag Bool
    configGHCiLib ConfigFlags
    cfg,
                    splitSections :: Bool
    splitSections       = Bool
    split_sections,
                    splitObjs :: Bool
    splitObjs           = Bool
    split_objs,
                    stripExes :: Bool
    stripExes           = Bool
    strip_exe,
                    stripLibs :: Bool
    stripLibs           = Bool
    strip_lib,
                    exeCoverage :: Bool
    exeCoverage         = Bool
    False,
                    libCoverage :: Bool
    libCoverage         = Bool
    False,
                    withPackageDB :: PackageDBStack
    withPackageDB       = PackageDBStack
    packageDbs,
                    progPrefix :: PathTemplate
    progPrefix          = Flag PathTemplate -> PathTemplate
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag PathTemplate -> PathTemplate)
    -> Flag PathTemplate -> PathTemplate
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag PathTemplate
    configProgPrefix ConfigFlags
    cfg,
                    progSuffix :: PathTemplate
    progSuffix          = Flag PathTemplate -> PathTemplate
    forall a. WithCallStack (Flag a -> a)
    fromFlag (Flag PathTemplate -> PathTemplate)
    -> Flag PathTemplate -> PathTemplate
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag PathTemplate
    configProgSuffix ConfigFlags
    cfg,
                    relocatable :: Bool
    relocatable         = Bool
    reloc
                  }

        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    reloc (Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
    checkRelocatable Verbosity
    verbosity PackageDescription
    pkg_descr LocalBuildInfo
    lbi)

        -- TODO: This is not entirely correct, because the dirs may vary
        -- across libraries/executables
        let dirs :: InstallDirs [Char]
    dirs = PackageDescription
    -> LocalBuildInfo -> CopyDest -> InstallDirs [Char]
    absoluteInstallDirs PackageDescription
    pkg_descr LocalBuildInfo
    lbi CopyDest
    NoCopyDest
            relative :: InstallDirs (Maybe [Char])
    relative = PackageIdentifier -> LocalBuildInfo -> InstallDirs (Maybe [Char])
    prefixRelativeInstallDirs (PackageDescription -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PackageDescription
    pkg_descr) LocalBuildInfo
    lbi

        -- PKGROOT: allowing ${pkgroot} to be passed as --prefix to
        -- cabal configure, is only a hidden option. It allows packages
        -- to be relocatable with their package database.  This however
        -- breaks when the Paths_* or other includes are used that
        -- contain hard coded paths. This is still an open TODO.
        --
        -- Allowing ${pkgroot} here, however requires less custom hooks
        -- in scripts that *really* want ${pkgroot}. See haskell/cabal/#4872
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ([Char] -> Bool
    isAbsolute (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    dirs)
               Bool -> Bool -> Bool
    || [Char]
    "${pkgroot}" [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    dirs) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            [Char]
    "expected an absolute directory name for --prefix: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    dirs

        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when ([Char]
    "${pkgroot}" [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    dirs) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Using ${pkgroot} in prefix " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    dirs
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " will not work if you rely on the Path_* module "
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " or other hard coded paths.  Cabal does not yet "
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " support fully  relocatable builds! "
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " See #462 #2302 #2994 #3305 #3473 #3586 #3909"
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " #4097 #4291 #4872"

        Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Using " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageIdentifier
    currentCabalId
                      [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " compiled by " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageIdentifier
    currentCompilerId
        Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Using compiler: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Compiler -> [Char]
    showCompilerId Compiler
    comp
        Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Using install prefix: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    dirs

        let dirinfo :: [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    name [Char]
    dir Maybe a
    isPrefixRelative =
              Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    name [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " installed in: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    dir [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    relNote
              where relNote :: [Char]
    relNote = case OS
    buildOS of
                      OS
    Windows | Bool -> Bool
    not (PackageDescription -> Bool
    hasLibs PackageDescription
    pkg_descr)
                             Bool -> Bool -> Bool
    && Maybe a -> Bool
    forall a. Maybe a -> Bool
    isNothing Maybe a
    isPrefixRelative
                             -> [Char]
    "  (fixed location)"
                      OS
    _      -> [Char]
    ""

        [Char] -> [Char] -> Maybe [Char] -> IO ()
    forall {a}. [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    "Executables"      (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    bindir InstallDirs [Char]
    dirs)     (InstallDirs (Maybe [Char]) -> Maybe [Char]
    forall dir. InstallDirs dir -> dir
    bindir InstallDirs (Maybe [Char])
    relative)
        [Char] -> [Char] -> Maybe [Char] -> IO ()
    forall {a}. [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    "Libraries"        (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    libdir InstallDirs [Char]
    dirs)     (InstallDirs (Maybe [Char]) -> Maybe [Char]
    forall dir. InstallDirs dir -> dir
    libdir InstallDirs (Maybe [Char])
    relative)
        [Char] -> [Char] -> Maybe [Char] -> IO ()
    forall {a}. [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    "Dynamic Libraries" (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    dynlibdir InstallDirs [Char]
    dirs) (InstallDirs (Maybe [Char]) -> Maybe [Char]
    forall dir. InstallDirs dir -> dir
    dynlibdir InstallDirs (Maybe [Char])
    relative)
        [Char] -> [Char] -> Maybe [Char] -> IO ()
    forall {a}. [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    "Private executables" (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    libexecdir InstallDirs [Char]
    dirs) (InstallDirs (Maybe [Char]) -> Maybe [Char]
    forall dir. InstallDirs dir -> dir
    libexecdir InstallDirs (Maybe [Char])
    relative)
        [Char] -> [Char] -> Maybe [Char] -> IO ()
    forall {a}. [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    "Data files"       (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    datadir InstallDirs [Char]
    dirs)    (InstallDirs (Maybe [Char]) -> Maybe [Char]
    forall dir. InstallDirs dir -> dir
    datadir InstallDirs (Maybe [Char])
    relative)
        [Char] -> [Char] -> Maybe [Char] -> IO ()
    forall {a}. [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    "Documentation"    (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    docdir InstallDirs [Char]
    dirs)     (InstallDirs (Maybe [Char]) -> Maybe [Char]
    forall dir. InstallDirs dir -> dir
    docdir InstallDirs (Maybe [Char])
    relative)
        [Char] -> [Char] -> Maybe [Char] -> IO ()
    forall {a}. [Char] -> [Char] -> Maybe a -> IO ()
    dirinfo [Char]
    "Configuration files" (InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    sysconfdir InstallDirs [Char]
    dirs) (InstallDirs (Maybe [Char]) -> Maybe [Char]
    forall dir. InstallDirs dir -> dir
    sysconfdir InstallDirs (Maybe [Char])
    relative)

        [IO ()] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a.
    (Foldable t, Monad m) =>
    t (m a) -> m ()
    sequence_ [ Verbosity -> Program -> Maybe ConfiguredProgram -> IO ()
    reportProgram Verbosity
    verbosity Program
    prog Maybe ConfiguredProgram
    configuredProg
                  | (Program
    prog, Maybe ConfiguredProgram
    configuredProg) <- ProgramDb -> [(Program, Maybe ConfiguredProgram)]
    knownPrograms ProgramDb
    programDb'' ]

        LocalBuildInfo -> IO LocalBuildInfo
    forall (m :: * -> *) a. Monad m => a -> m a
    return LocalBuildInfo
    lbi

        where
          verbosity :: Verbosity
    verbosity = Flag Verbosity -> Verbosity
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Verbosity
    configVerbosity ConfigFlags
    cfg)

    mkProgramDb :: ConfigFlags -> ProgramDb -> ProgramDb
    mkProgramDb :: ConfigFlags -> ProgramDb -> ProgramDb
    mkProgramDb ConfigFlags
    cfg ProgramDb
    initialProgramDb = ProgramDb
    programDb
      where
        programDb :: ProgramDb
    programDb  = [([Char], [[Char]])] -> ProgramDb -> ProgramDb
    userSpecifyArgss (ConfigFlags -> [([Char], [[Char]])]
    configProgramArgs ConfigFlags
    cfg)
                     (ProgramDb -> ProgramDb)
    -> (ProgramDb -> ProgramDb) -> ProgramDb -> ProgramDb
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [([Char], [Char])] -> ProgramDb -> ProgramDb
    userSpecifyPaths (ConfigFlags -> [([Char], [Char])]
    configProgramPaths ConfigFlags
    cfg)
                     (ProgramDb -> ProgramDb)
    -> (ProgramDb -> ProgramDb) -> ProgramDb -> ProgramDb
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ProgramSearchPath -> ProgramDb -> ProgramDb
    setProgramSearchPath ProgramSearchPath
    searchpath
                     (ProgramDb -> ProgramDb) -> ProgramDb -> ProgramDb
    forall a b. (a -> b) -> a -> b
    $ ProgramDb
    initialProgramDb
        searchpath :: ProgramSearchPath
    searchpath = ProgramDb -> ProgramSearchPath
    getProgramSearchPath ProgramDb
    initialProgramDb
                     ProgramSearchPath -> ProgramSearchPath -> ProgramSearchPath
    forall a. [a] -> [a] -> [a]
    ++ ([Char] -> ProgramSearchPathEntry) -> [[Char]] -> ProgramSearchPath
    forall a b. (a -> b) -> [a] -> [b]
    map [Char] -> ProgramSearchPathEntry
    ProgramSearchPathDir
                     (NubList [Char] -> [[Char]]
    forall a. NubList a -> [a]
    fromNubList (NubList [Char] -> [[Char]]) -> NubList [Char] -> [[Char]]
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> NubList [Char]
    configProgramPathExtra ConfigFlags
    cfg)

    -- -----------------------------------------------------------------------------
    -- Helper functions for configure

    -- | Check if the user used any deprecated flags.
    checkDeprecatedFlags :: Verbosity -> ConfigFlags -> IO ()
    checkDeprecatedFlags :: Verbosity -> ConfigFlags -> IO ()
    checkDeprecatedFlags Verbosity
    verbosity ConfigFlags
    cfg = do
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (ConfigFlags -> Flag Bool
    configProfExe ConfigFlags
    cfg Flag Bool -> Flag Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == Flag Bool
    forall a. Flag a
    NoFlag) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
          let enable :: [Char]
    enable | Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configProfExe ConfigFlags
    cfg) = [Char]
    "enable"
                     | Bool
    otherwise = [Char]
    "disable"
          Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
            ([Char]
    "The flag --" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    enable [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "-executable-profiling is deprecated. "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "Please use --" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    enable [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "-profiling instead.")

        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (ConfigFlags -> Flag Bool
    configLibCoverage ConfigFlags
    cfg Flag Bool -> Flag Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == Flag Bool
    forall a. Flag a
    NoFlag) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
          let enable :: [Char]
    enable | Flag Bool -> Bool
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Bool
    configLibCoverage ConfigFlags
    cfg) = [Char]
    "enable"
                     | Bool
    otherwise = [Char]
    "disable"
          Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
            ([Char]
    "The flag --" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    enable [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "-library-coverage is deprecated. "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "Please use --" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    enable [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "-coverage instead.")

    -- | Sanity check: if '--exact-configuration' was given, ensure that the
    -- complete flag assignment was specified on the command line.
    checkExactConfiguration
      :: Verbosity -> GenericPackageDescription -> ConfigFlags -> IO ()
    checkExactConfiguration :: Verbosity -> GenericPackageDescription -> ConfigFlags -> IO ()
    checkExactConfiguration Verbosity
    verbosity GenericPackageDescription
    pkg_descr0 ConfigFlags
    cfg =
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False (ConfigFlags -> Flag Bool
    configExactConfiguration ConfigFlags
    cfg)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
          let cmdlineFlags :: [FlagName]
    cmdlineFlags = ((FlagName, Bool) -> FlagName) -> [(FlagName, Bool)] -> [FlagName]
    forall a b. (a -> b) -> [a] -> [b]
    map (FlagName, Bool) -> FlagName
    forall a b. (a, b) -> a
    fst (FlagAssignment -> [(FlagName, Bool)]
    unFlagAssignment (ConfigFlags -> FlagAssignment
    configConfigurationsFlags ConfigFlags
    cfg))
              allFlags :: [FlagName]
    allFlags     = (PackageFlag -> FlagName) -> [PackageFlag] -> [FlagName]
    forall a b. (a -> b) -> [a] -> [b]
    map PackageFlag -> FlagName
    flagName ([PackageFlag] -> [FlagName])
    -> (GenericPackageDescription -> [PackageFlag])
    -> GenericPackageDescription
    -> [FlagName]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GenericPackageDescription -> [PackageFlag]
    genPackageFlags (GenericPackageDescription -> [FlagName])
    -> GenericPackageDescription -> [FlagName]
    forall a b. (a -> b) -> a -> b
    $ GenericPackageDescription
    pkg_descr0
              diffFlags :: [FlagName]
    diffFlags    = [FlagName]
    allFlags [FlagName] -> [FlagName] -> [FlagName]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [FlagName]
    cmdlineFlags
          Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not (Bool -> Bool) -> ([FlagName] -> Bool) -> [FlagName] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [FlagName] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([FlagName] -> Bool) -> [FlagName] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [FlagName]
    diffFlags) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "'--exact-configuration' was given, "
            [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "but the following flags were not specified: "
            [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ", " ((FlagName -> [Char]) -> [FlagName] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map FlagName -> [Char]
    forall a. Show a => a -> [Char]
    show [FlagName]
    diffFlags)

    -- | Create a PackageIndex that makes *any libraries that might be*
    -- defined internally to this package look like installed packages, in
    -- case an executable should refer to any of them as dependencies.
    --
    -- It must be *any libraries that might be* defined rather than the
    -- actual definitions, because these depend on conditionals in the .cabal
    -- file, and we haven't resolved them yet.  finalizePD
    -- does the resolution of conditionals, and it takes internalPackageSet
    -- as part of its input.
    getInternalLibraries :: GenericPackageDescription
                         -> Set LibraryName
    getInternalLibraries :: GenericPackageDescription -> Set LibraryName
    getInternalLibraries GenericPackageDescription
    pkg_descr0 =
        -- TODO: some day, executables will be fair game here too!
        let pkg_descr :: PackageDescription
    pkg_descr = GenericPackageDescription -> PackageDescription
    flattenPackageDescription GenericPackageDescription
    pkg_descr0
        in [LibraryName] -> Set LibraryName
    forall a. Ord a => [a] -> Set a
    Set.fromList ((Library -> LibraryName) -> [Library] -> [LibraryName]
    forall a b. (a -> b) -> [a] -> [b]
    map Library -> LibraryName
    libName (PackageDescription -> [Library]
    allLibraries PackageDescription
    pkg_descr))

    -- | Returns true if a dependency is satisfiable.  This function may
    -- report a dependency satisfiable even when it is not, but not vice
    -- versa. This is to be passed to finalize
    dependencySatisfiable
        :: Bool -- ^ use external internal deps?
        -> Bool -- ^ exact configuration?
        -> Bool -- ^ allow depending on private libs?
        -> PackageName
        -> InstalledPackageIndex -- ^ installed set
        -> Set LibraryName -- ^ library components
        -> Map (PackageName, ComponentName) InstalledPackageInfo
           -- ^ required dependencies
        -> (Dependency -> Bool)
    dependencySatisfiable :: Bool
    -> Bool
    -> Bool
    -> PackageName
    -> InstalledPackageIndex
    -> Set LibraryName
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> Dependency
    -> Bool
    dependencySatisfiable
      Bool
    use_external_internal_deps
      Bool
    exact_config
      Bool
    allow_private_deps
      PackageName
    pn InstalledPackageIndex
    installedPackageSet Set LibraryName
    packageLibraries Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap
      (Dependency PackageName
    depName VersionRange
    vr NonEmptySet LibraryName
    sublibs)
        | Bool
    exact_config
        -- When we're given '--exact-configuration', we assume that all
        -- dependencies and flags are exactly specified on the command
        -- line. Thus we only consult the 'requiredDepsMap'. Note that
        -- we're not doing the version range check, so if there's some
        -- dependency that wasn't specified on the command line,
        -- 'finalizePD' will fail.
        -- TODO: mention '--exact-configuration' in the error message
        -- when this fails?
        = if Bool
    isInternalDep Bool -> Bool -> Bool
    && Bool -> Bool
    not Bool
    use_external_internal_deps
            -- Except for internal deps, when we're NOT per-component mode;
            -- those are just True.
            then Bool
    internalDepSatisfiable
            else
              -- Backward compatibility for the old sublibrary syntax
              (NonEmptySet LibraryName
    sublibs NonEmptySet LibraryName -> NonEmptySet LibraryName -> Bool
    forall a. Eq a => a -> a -> Bool
    == NonEmptySet LibraryName
    mainLibSet
                Bool -> Bool -> Bool
    && (PackageName, ComponentName)
    -> Map (PackageName, ComponentName) InstalledPackageInfo -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    Map.member
                     (PackageName
    pn, 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
    $
                          PackageName -> UnqualComponentName
    packageNameToUnqualComponentName PackageName
    depName)
                     Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap)

              Bool -> Bool -> Bool
    || (LibraryName -> Bool) -> NonEmptySet LibraryName -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all LibraryName -> Bool
    visible NonEmptySet LibraryName
    sublibs

        | Bool
    isInternalDep
        = if Bool
    use_external_internal_deps
            -- When we are doing per-component configure, we now need to
            -- test if the internal dependency is in the index.  This has
            -- DIFFERENT semantics from normal dependency satisfiability.
            then Bool
    internalDepSatisfiableExternally
            -- If a 'PackageName' is defined by an internal component, the dep is
            -- satisfiable (we're going to build it ourselves)
            else Bool
    internalDepSatisfiable

        | Bool
    otherwise
        = Bool
    depSatisfiable

      where
        -- Internal dependency is when dependency is the same as package.
        isInternalDep :: Bool
    isInternalDep = PackageName
    pn PackageName -> PackageName -> Bool
    forall a. Eq a => a -> a -> Bool
    == PackageName
    depName

        depSatisfiable :: Bool
    depSatisfiable =
            Bool -> Bool
    not (Bool -> Bool)
    -> ([(Version, [InstalledPackageInfo])] -> Bool)
    -> [(Version, [InstalledPackageInfo])]
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(Version, [InstalledPackageInfo])] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([(Version, [InstalledPackageInfo])] -> Bool)
    -> [(Version, [InstalledPackageInfo])] -> Bool
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageIndex
    -> PackageName
    -> VersionRange
    -> [(Version, [InstalledPackageInfo])]
    PackageIndex.lookupDependency InstalledPackageIndex
    installedPackageSet PackageName
    depName VersionRange
    vr

        internalDepSatisfiable :: Bool
    internalDepSatisfiable =
            Set LibraryName -> Set LibraryName -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    Set.isSubsetOf (NonEmptySet LibraryName -> Set LibraryName
    forall a. NonEmptySet a -> Set a
    NES.toSet NonEmptySet LibraryName
    sublibs) Set LibraryName
    packageLibraries
        internalDepSatisfiableExternally :: Bool
    internalDepSatisfiableExternally =
            (LibraryName -> Bool) -> NonEmptySet LibraryName -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (\LibraryName
    ln -> Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ [(Version, [InstalledPackageInfo])] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([(Version, [InstalledPackageInfo])] -> Bool)
    -> [(Version, [InstalledPackageInfo])] -> Bool
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageIndex
    -> PackageName
    -> VersionRange
    -> LibraryName
    -> [(Version, [InstalledPackageInfo])]
    PackageIndex.lookupInternalDependency InstalledPackageIndex
    installedPackageSet PackageName
    pn VersionRange
    vr LibraryName
    ln) NonEmptySet LibraryName
    sublibs

        -- Check whether a library exists and is visible.
        -- We don't disambiguate between dependency on non-existent or private
        -- library yet, so we just return a bool and later report a generic error.
        visible :: LibraryName -> Bool
    visible LibraryName
    lib = Bool
    -> (InstalledPackageInfo -> Bool)
    -> Maybe InstalledPackageInfo
    -> Bool
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe
                        Bool
    False -- Does not even exist (wasn't in the depsMap)
                        (\InstalledPackageInfo
    ipi -> InstalledPackageInfo -> LibraryVisibility
    IPI.libVisibility InstalledPackageInfo
    ipi LibraryVisibility -> LibraryVisibility -> Bool
    forall a. Eq a => a -> a -> Bool
    == LibraryVisibility
    LibraryVisibilityPublic
                              -- If the override is enabled, the visibility does
                              -- not matter (it's handled externally)
                              Bool -> Bool -> Bool
    || Bool
    allow_private_deps
                              -- If it's a library of the same package then it's
                              -- always visible.
                              -- This is only triggered when passing a component
                              -- of the same package as --dependency, such as in:
                              -- cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit.test.hs
                              Bool -> Bool -> Bool
    || PackageIdentifier -> PackageName
    pkgName (InstalledPackageInfo -> PackageIdentifier
    IPI.sourcePackageId InstalledPackageInfo
    ipi) PackageName -> PackageName -> Bool
    forall a. Eq a => a -> a -> Bool
    == PackageName
    pn)
                        Maybe InstalledPackageInfo
    maybeIPI
          where maybeIPI :: Maybe InstalledPackageInfo
    maybeIPI = (PackageName, ComponentName)
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> Maybe InstalledPackageInfo
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup (PackageName
    depName, LibraryName -> ComponentName
    CLibName LibraryName
    lib) Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap

    -- | Finalize a generic package description.  The workhorse is
    -- 'finalizePD' but there's a bit of other nattering
    -- about necessary.
    --
    -- TODO: what exactly is the business with @flaggedTests@ and
    -- @flaggedBenchmarks@?
    configureFinalizedPackage
        :: Verbosity
        -> ConfigFlags
        -> ComponentRequestedSpec
        -> [PackageVersionConstraint]
        -> (Dependency -> Bool) -- ^ tests if a dependency is satisfiable.
                                -- Might say it's satisfiable even when not.
        -> Compiler
        -> Platform
        -> GenericPackageDescription
        -> IO (PackageDescription, FlagAssignment)
    configureFinalizedPackage :: Verbosity
    -> ConfigFlags
    -> ComponentRequestedSpec
    -> [PackageVersionConstraint]
    -> (Dependency -> Bool)
    -> Compiler
    -> Platform
    -> GenericPackageDescription
    -> IO (PackageDescription, FlagAssignment)
    configureFinalizedPackage Verbosity
    verbosity ConfigFlags
    cfg ComponentRequestedSpec
    enabled
      [PackageVersionConstraint]
    allConstraints Dependency -> Bool
    satisfies Compiler
    comp Platform
    compPlatform GenericPackageDescription
    pkg_descr0 = do

        (PackageDescription
    pkg_descr0', FlagAssignment
    flags) <-
                case FlagAssignment
    -> ComponentRequestedSpec
    -> (Dependency -> Bool)
    -> Platform
    -> CompilerInfo
    -> [PackageVersionConstraint]
    -> GenericPackageDescription
    -> Either [Dependency] (PackageDescription, FlagAssignment)
    finalizePD
                       (ConfigFlags -> FlagAssignment
    configConfigurationsFlags ConfigFlags
    cfg)
                       ComponentRequestedSpec
    enabled
                       Dependency -> Bool
    satisfies
                       Platform
    compPlatform
                       (Compiler -> CompilerInfo
    compilerInfo Compiler
    comp)
                       [PackageVersionConstraint]
    allConstraints
                       GenericPackageDescription
    pkg_descr0
                of Right (PackageDescription, FlagAssignment)
    r -> (PackageDescription, FlagAssignment)
    -> IO (PackageDescription, FlagAssignment)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (PackageDescription, FlagAssignment)
    r
                   Left [Dependency]
    missing ->
                       Verbosity -> [Char] -> IO (PackageDescription, FlagAssignment)
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO (PackageDescription, FlagAssignment))
    -> [Char] -> IO (PackageDescription, FlagAssignment)
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Encountered missing or private dependencies:\n"
                         [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ (Doc -> [Char]
    render (Doc -> [Char]) -> ([Dependency] -> Doc) -> [Dependency] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Doc -> Doc
    nest Int
    4 (Doc -> Doc) -> ([Dependency] -> Doc) -> [Dependency] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Doc] -> Doc
    sep ([Doc] -> Doc) -> ([Dependency] -> [Doc]) -> [Dependency] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma
                                    ([Doc] -> [Doc])
    -> ([Dependency] -> [Doc]) -> [Dependency] -> [Doc]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Dependency -> Doc) -> [Dependency] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map (Dependency -> Doc
    forall a. Pretty a => a -> Doc
    pretty (Dependency -> Doc)
    -> (Dependency -> Dependency) -> Dependency -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Dependency -> Dependency
    simplifyDependency)
                                    ([Dependency] -> [Char]) -> [Dependency] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ [Dependency]
    missing)

        -- add extra include/lib dirs as specified in cfg
        -- we do it here so that those get checked too
        let pkg_descr :: PackageDescription
    pkg_descr = PackageDescription -> PackageDescription
    addExtraIncludeLibDirs PackageDescription
    pkg_descr0'

        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (FlagAssignment -> Bool
    nullFlagAssignment FlagAssignment
    flags) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Flags chosen: "
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ", " [ FlagName -> [Char]
    unFlagName FlagName
    fn [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "=" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Bool -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow Bool
    value
                                            | (FlagName
    fn, Bool
    value) <- FlagAssignment -> [(FlagName, Bool)]
    unFlagAssignment FlagAssignment
    flags ]

        (PackageDescription, FlagAssignment)
    -> IO (PackageDescription, FlagAssignment)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (PackageDescription
    pkg_descr, FlagAssignment
    flags)
      where
        addExtraIncludeLibDirs :: PackageDescription -> PackageDescription
    addExtraIncludeLibDirs PackageDescription
    pkg_descr =
            let extraBi :: BuildInfo
    extraBi = BuildInfo
    forall a. Monoid a => a
    mempty { extraLibDirs :: [[Char]]
    extraLibDirs = ConfigFlags -> [[Char]]
    configExtraLibDirs ConfigFlags
    cfg
                                 , extraFrameworkDirs :: [[Char]]
    extraFrameworkDirs = ConfigFlags -> [[Char]]
    configExtraFrameworkDirs ConfigFlags
    cfg
                                 , includeDirs :: [[Char]]
    includeDirs = ConfigFlags -> [[Char]]
    configExtraIncludeDirs ConfigFlags
    cfg}
                modifyLib :: Library -> Library
    modifyLib Library
    l        = Library
    l{ libBuildInfo :: BuildInfo
    libBuildInfo        = Library -> BuildInfo
    libBuildInfo Library
    l
                                                              BuildInfo -> BuildInfo -> BuildInfo
    forall a. Monoid a => a -> a -> a
    `mappend` BuildInfo
    extraBi }
                modifyExecutable :: Executable -> Executable
    modifyExecutable Executable
    e = Executable
    e{ buildInfo :: BuildInfo
    buildInfo           = Executable -> BuildInfo
    buildInfo Executable
    e
                                                              BuildInfo -> BuildInfo -> BuildInfo
    forall a. Monoid a => a -> a -> a
    `mappend` BuildInfo
    extraBi}
                modifyForeignLib :: ForeignLib -> ForeignLib
    modifyForeignLib ForeignLib
    f = ForeignLib
    f{ foreignLibBuildInfo :: BuildInfo
    foreignLibBuildInfo = ForeignLib -> BuildInfo
    foreignLibBuildInfo ForeignLib
    f
                                                              BuildInfo -> BuildInfo -> BuildInfo
    forall a. Monoid a => a -> a -> a
    `mappend` BuildInfo
    extraBi}
                modifyTestsuite :: TestSuite -> TestSuite
    modifyTestsuite  TestSuite
    t = TestSuite
    t{ testBuildInfo :: BuildInfo
    testBuildInfo      = TestSuite -> BuildInfo
    testBuildInfo TestSuite
    t
                                                              BuildInfo -> BuildInfo -> BuildInfo
    forall a. Monoid a => a -> a -> a
    `mappend` BuildInfo
    extraBi}
                modifyBenchmark :: Benchmark -> Benchmark
    modifyBenchmark  Benchmark
    b = Benchmark
    b{ benchmarkBuildInfo :: BuildInfo
    benchmarkBuildInfo  = Benchmark -> BuildInfo
    benchmarkBuildInfo Benchmark
    b
                                                              BuildInfo -> BuildInfo -> BuildInfo
    forall a. Monoid a => a -> a -> a
    `mappend` BuildInfo
    extraBi}
            in PackageDescription
    pkg_descr
                 { library :: Maybe Library
    library      = Library -> Library
    modifyLib        (Library -> Library) -> Maybe Library -> Maybe Library
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` PackageDescription -> Maybe Library
    library      PackageDescription
    pkg_descr
                 , subLibraries :: [Library]
    subLibraries = Library -> Library
    modifyLib        (Library -> Library) -> [Library] -> [Library]
    forall a b. (a -> b) -> [a] -> [b]
    `map`  PackageDescription -> [Library]
    subLibraries PackageDescription
    pkg_descr
                 , executables :: [Executable]
    executables  = Executable -> Executable
    modifyExecutable (Executable -> Executable) -> [Executable] -> [Executable]
    forall a b. (a -> b) -> [a] -> [b]
    `map`  PackageDescription -> [Executable]
    executables  PackageDescription
    pkg_descr
                 , foreignLibs :: [ForeignLib]
    foreignLibs  = ForeignLib -> ForeignLib
    modifyForeignLib (ForeignLib -> ForeignLib) -> [ForeignLib] -> [ForeignLib]
    forall a b. (a -> b) -> [a] -> [b]
    `map`  PackageDescription -> [ForeignLib]
    foreignLibs  PackageDescription
    pkg_descr
                 , testSuites :: [TestSuite]
    testSuites   = TestSuite -> TestSuite
    modifyTestsuite  (TestSuite -> TestSuite) -> [TestSuite] -> [TestSuite]
    forall a b. (a -> b) -> [a] -> [b]
    `map`  PackageDescription -> [TestSuite]
    testSuites   PackageDescription
    pkg_descr
                 , benchmarks :: [Benchmark]
    benchmarks   = Benchmark -> Benchmark
    modifyBenchmark  (Benchmark -> Benchmark) -> [Benchmark] -> [Benchmark]
    forall a b. (a -> b) -> [a] -> [b]
    `map`  PackageDescription -> [Benchmark]
    benchmarks   PackageDescription
    pkg_descr
                 }

    -- | Check for use of Cabal features which require compiler support
    checkCompilerProblems
      :: Verbosity -> Compiler -> PackageDescription -> ComponentRequestedSpec -> IO ()
    checkCompilerProblems :: Verbosity
    -> Compiler
    -> PackageDescription
    -> ComponentRequestedSpec
    -> IO ()
    checkCompilerProblems Verbosity
    verbosity Compiler
    comp PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled = do
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (Compiler -> Bool
    renamingPackageFlagsSupported Compiler
    comp Bool -> Bool -> Bool
    ||
                 (BuildInfo -> Bool) -> [BuildInfo] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all ((Mixin -> Bool) -> [Mixin] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (IncludeRenaming -> Bool
    isDefaultIncludeRenaming (IncludeRenaming -> Bool)
    -> (Mixin -> IncludeRenaming) -> Mixin -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Mixin -> IncludeRenaming
    mixinIncludeRenaming) ([Mixin] -> Bool) -> (BuildInfo -> [Mixin]) -> BuildInfo -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BuildInfo -> [Mixin]
    mixins)
                             (PackageDescription -> ComponentRequestedSpec -> [BuildInfo]
    enabledBuildInfos PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                  [Char]
    "Your compiler does not support thinning and renaming on "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "package flags.  To use this feature you must use "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "GHC 7.9 or later."

        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when ((Library -> Bool) -> [Library] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Bool -> Bool
    not(Bool -> Bool) -> (Library -> Bool) -> Library -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .[ModuleReexport] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null([ModuleReexport] -> Bool)
    -> (Library -> [ModuleReexport]) -> Library -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Library -> [ModuleReexport]
    reexportedModules) (PackageDescription -> [Library]
    allLibraries PackageDescription
    pkg_descr)
              Bool -> Bool -> Bool
    && Bool -> Bool
    not (Compiler -> Bool
    reexportedModulesSupported Compiler
    comp)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                 [Char]
    "Your compiler does not support module re-exports. To use "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "this feature you must use GHC 7.9 or later."

        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when ((Library -> Bool) -> [Library] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Bool -> Bool
    not(Bool -> Bool) -> (Library -> Bool) -> Library -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .[ModuleName] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null([ModuleName] -> Bool)
    -> (Library -> [ModuleName]) -> Library -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Library -> [ModuleName]
    signatures) (PackageDescription -> [Library]
    allLibraries PackageDescription
    pkg_descr)
              Bool -> Bool -> Bool
    && Bool -> Bool
    not (Compiler -> Bool
    backpackSupported Compiler
    comp)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                   [Char]
    "Your compiler does not support Backpack. To use "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "this feature you must use GHC 8.1 or later."

    -- | Select dependencies for the package.
    configureDependencies
        :: Verbosity
        -> UseExternalInternalDeps
        -> Set LibraryName
        -> InstalledPackageIndex -- ^ installed packages
        -> Map (PackageName, ComponentName) InstalledPackageInfo -- ^ required deps
        -> PackageDescription
        -> ComponentRequestedSpec
        -> IO [PreExistingComponent]
    configureDependencies :: Verbosity
    -> Bool
    -> Set LibraryName
    -> InstalledPackageIndex
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> PackageDescription
    -> ComponentRequestedSpec
    -> IO [PreExistingComponent]
    configureDependencies Verbosity
    verbosity Bool
    use_external_internal_deps
      Set LibraryName
    packageLibraries InstalledPackageIndex
    installedPackageSet Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap PackageDescription
    pkg_descr ComponentRequestedSpec
    enableSpec = do
        let failedDeps :: [FailedDependency]
            allPkgDeps :: [ResolvedDependency]
            ([FailedDependency]
    failedDeps, [ResolvedDependency]
    allPkgDeps) = [Either FailedDependency ResolvedDependency]
    -> ([FailedDependency], [ResolvedDependency])
    forall a b. [Either a b] -> ([a], [b])
    partitionEithers ([Either FailedDependency ResolvedDependency]
     -> ([FailedDependency], [ResolvedDependency]))
    -> [Either FailedDependency ResolvedDependency]
    -> ([FailedDependency], [ResolvedDependency])
    forall a b. (a -> b) -> a -> b
    $ [[Either FailedDependency ResolvedDependency]]
    -> [Either FailedDependency ResolvedDependency]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat
              [ (DependencyResolution -> ResolvedDependency)
    -> Either FailedDependency DependencyResolution
    -> Either FailedDependency ResolvedDependency
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\DependencyResolution
    s -> (Dependency
    dep, DependencyResolution
    s)) (Either FailedDependency DependencyResolution
     -> Either FailedDependency ResolvedDependency)
    -> [Either FailedDependency DependencyResolution]
    -> [Either FailedDependency ResolvedDependency]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Either FailedDependency DependencyResolution]
    status
              | Dependency
    dep <- PackageDescription -> ComponentRequestedSpec -> [Dependency]
    enabledBuildDepends PackageDescription
    pkg_descr ComponentRequestedSpec
    enableSpec
              , let status :: [Either FailedDependency DependencyResolution]
    status = PackageIdentifier
    -> Set LibraryName
    -> InstalledPackageIndex
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> Bool
    -> Dependency
    -> [Either FailedDependency DependencyResolution]
    selectDependency (PackageDescription -> PackageIdentifier
    package PackageDescription
    pkg_descr)
                      Set LibraryName
    packageLibraries InstalledPackageIndex
    installedPackageSet
                      Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap Bool
    use_external_internal_deps Dependency
    dep ]

            internalPkgDeps :: [PackageIdentifier]
    internalPkgDeps = [ PackageIdentifier
    pkgid
                              | (Dependency
    _, InternalDependency PackageIdentifier
    pkgid) <- [ResolvedDependency]
    allPkgDeps ]
            -- NB: we have to SAVE the package name, because this is the only
            -- way we can be able to resolve package names in the package
            -- description.
            externalPkgDeps :: [PreExistingComponent]
    externalPkgDeps = [ PreExistingComponent
    pec
                              | (Dependency
    _, ExternalDependency PreExistingComponent
    pec)   <- [ResolvedDependency]
    allPkgDeps ]

        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not ([PackageIdentifier] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [PackageIdentifier]
    internalPkgDeps)
              Bool -> Bool -> Bool
    && Bool -> Bool
    not (PackageDescription -> Bool
    newPackageDepsBehaviour PackageDescription
    pkg_descr)) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "The field 'build-depends: "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ", " ((PackageIdentifier -> [Char]) -> [PackageIdentifier] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map (PackageName -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (PackageName -> [Char])
    -> (PackageIdentifier -> PackageName)
    -> PackageIdentifier
    -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PackageIdentifier -> PackageName
    forall pkg. Package pkg => pkg -> PackageName
    packageName) [PackageIdentifier]
    internalPkgDeps)
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "' refers to a library which is defined within the same "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "package. To use this feature the package must specify at "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "least 'cabal-version: >= 1.8'."

        Verbosity -> [FailedDependency] -> IO ()
    reportFailedDependencies Verbosity
    verbosity [FailedDependency]
    failedDeps
        Verbosity -> [ResolvedDependency] -> IO ()
    reportSelectedDependencies Verbosity
    verbosity [ResolvedDependency]
    allPkgDeps

        [PreExistingComponent] -> IO [PreExistingComponent]
    forall (m :: * -> *) a. Monad m => a -> m a
    return [PreExistingComponent]
    externalPkgDeps

    -- | Select and apply coverage settings for the build based on the
    -- 'ConfigFlags' and 'Compiler'.
    configureCoverage :: Verbosity -> ConfigFlags -> Compiler
                      -> IO (LocalBuildInfo -> LocalBuildInfo)
    configureCoverage :: Verbosity
    -> ConfigFlags -> Compiler -> IO (LocalBuildInfo -> LocalBuildInfo)
    configureCoverage Verbosity
    verbosity ConfigFlags
    cfg Compiler
    comp = do
        let tryExeCoverage :: Bool
    tryExeCoverage = Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False (ConfigFlags -> Flag Bool
    configCoverage ConfigFlags
    cfg)
            tryLibCoverage :: Bool
    tryLibCoverage = Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    tryExeCoverage
                             (Flag Bool -> Flag Bool -> Flag Bool
    forall a. Monoid a => a -> a -> a
    mappend (ConfigFlags -> Flag Bool
    configCoverage ConfigFlags
    cfg) (ConfigFlags -> Flag Bool
    configLibCoverage ConfigFlags
    cfg))
        if Compiler -> Bool
    coverageSupported Compiler
    comp
          then do
            let apply :: LocalBuildInfo -> LocalBuildInfo
    apply LocalBuildInfo
    lbi = LocalBuildInfo
    lbi { libCoverage :: Bool
    libCoverage = Bool
    tryLibCoverage
                                , exeCoverage :: Bool
    exeCoverage = Bool
    tryExeCoverage
                                }
            (LocalBuildInfo -> LocalBuildInfo)
    -> IO (LocalBuildInfo -> LocalBuildInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return LocalBuildInfo -> LocalBuildInfo
    apply
          else do
            let apply :: LocalBuildInfo -> LocalBuildInfo
    apply LocalBuildInfo
    lbi = LocalBuildInfo
    lbi { libCoverage :: Bool
    libCoverage = Bool
    False
                                , exeCoverage :: Bool
    exeCoverage = Bool
    False
                                }
            Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool
    tryExeCoverage Bool -> Bool -> Bool
    || Bool
    tryLibCoverage) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
              ([Char]
    "The compiler " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Compiler -> [Char]
    showCompilerId Compiler
    comp [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " does not support "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "program coverage. Program coverage has been disabled.")
            (LocalBuildInfo -> LocalBuildInfo)
    -> IO (LocalBuildInfo -> LocalBuildInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return LocalBuildInfo -> LocalBuildInfo
    apply

    -- | Compute the effective value of the profiling flags
    -- @--enable-library-profiling@ and @--enable-executable-profiling@
    -- from the specified 'ConfigFlags'.  This may be useful for
    -- external Cabal tools which need to interact with Setup in
    -- a backwards-compatible way: the most predictable mechanism
    -- for enabling profiling across many legacy versions is to
    -- NOT use @--enable-profiling@ and use those two flags instead.
    --
    -- Note that @--enable-executable-profiling@ also affects profiling
    -- of benchmarks and (non-detailed) test suites.
    computeEffectiveProfiling :: ConfigFlags -> (Bool {- lib -}, Bool {- exe -})
    computeEffectiveProfiling :: ConfigFlags -> (Bool, Bool)
    computeEffectiveProfiling ConfigFlags
    cfg =
      -- The --profiling flag sets the default for both libs and exes,
      -- but can be overidden by --library-profiling, or the old deprecated
      -- --executable-profiling flag.
      --
      -- The --profiling-detail and --library-profiling-detail flags behave
      -- similarly
      let tryExeProfiling :: Bool
    tryExeProfiling = Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    False
                            (Flag Bool -> Flag Bool -> Flag Bool
    forall a. Monoid a => a -> a -> a
    mappend (ConfigFlags -> Flag Bool
    configProf ConfigFlags
    cfg) (ConfigFlags -> Flag Bool
    configProfExe ConfigFlags
    cfg))
          tryLibProfiling :: Bool
    tryLibProfiling = Bool -> Flag Bool -> Bool
    forall a. a -> Flag a -> a
    fromFlagOrDefault Bool
    tryExeProfiling
                            (Flag Bool -> Flag Bool -> Flag Bool
    forall a. Monoid a => a -> a -> a
    mappend (ConfigFlags -> Flag Bool
    configProf ConfigFlags
    cfg) (ConfigFlags -> Flag Bool
    configProfLib ConfigFlags
    cfg))
      in (Bool
    tryLibProfiling, Bool
    tryExeProfiling)

    -- | Select and apply profiling settings for the build based on the
    -- 'ConfigFlags' and 'Compiler'.
    configureProfiling :: Verbosity -> ConfigFlags -> Compiler
                       -> IO (LocalBuildInfo -> LocalBuildInfo)
    configureProfiling :: Verbosity
    -> ConfigFlags -> Compiler -> IO (LocalBuildInfo -> LocalBuildInfo)
    configureProfiling Verbosity
    verbosity ConfigFlags
    cfg Compiler
    comp = do
      let (Bool
    tryLibProfiling, Bool
    tryExeProfiling) = ConfigFlags -> (Bool, Bool)
    computeEffectiveProfiling ConfigFlags
    cfg

          tryExeProfileLevel :: ProfDetailLevel
    tryExeProfileLevel = ProfDetailLevel -> Flag ProfDetailLevel -> ProfDetailLevel
    forall a. a -> Flag a -> a
    fromFlagOrDefault ProfDetailLevel
    ProfDetailDefault
                               (ConfigFlags -> Flag ProfDetailLevel
    configProfDetail ConfigFlags
    cfg)
          tryLibProfileLevel :: ProfDetailLevel
    tryLibProfileLevel = ProfDetailLevel -> Flag ProfDetailLevel -> ProfDetailLevel
    forall a. a -> Flag a -> a
    fromFlagOrDefault ProfDetailLevel
    ProfDetailDefault
                               (Flag ProfDetailLevel
    -> Flag ProfDetailLevel -> Flag ProfDetailLevel
    forall a. Monoid a => a -> a -> a
    mappend
                                (ConfigFlags -> Flag ProfDetailLevel
    configProfDetail ConfigFlags
    cfg)
                                (ConfigFlags -> Flag ProfDetailLevel
    configProfLibDetail ConfigFlags
    cfg))

          checkProfileLevel :: ProfDetailLevel -> IO ProfDetailLevel
    checkProfileLevel (ProfDetailOther [Char]
    other) = do
            Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
              ([Char]
    "Unknown profiling detail level '" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    other
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "', using default.\nThe profiling detail levels are: "
               [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ", "
               [ [Char]
    name | ([Char]
    name, [[Char]]
    _, ProfDetailLevel
    _) <- [([Char], [[Char]], ProfDetailLevel)]
    knownProfDetailLevels ])
            ProfDetailLevel -> IO ProfDetailLevel
    forall (m :: * -> *) a. Monad m => a -> m a
    return ProfDetailLevel
    ProfDetailDefault
          checkProfileLevel ProfDetailLevel
    other = ProfDetailLevel -> IO ProfDetailLevel
    forall (m :: * -> *) a. Monad m => a -> m a
    return ProfDetailLevel
    other

      (Bool
    exeProfWithoutLibProf, LocalBuildInfo -> LocalBuildInfo
    applyProfiling) <-
        if Compiler -> Bool
    profilingSupported Compiler
    comp
        then do
          ProfDetailLevel
    exeLevel <- ProfDetailLevel -> IO ProfDetailLevel
    checkProfileLevel ProfDetailLevel
    tryExeProfileLevel
          ProfDetailLevel
    libLevel <- ProfDetailLevel -> IO ProfDetailLevel
    checkProfileLevel ProfDetailLevel
    tryLibProfileLevel
          let apply :: LocalBuildInfo -> LocalBuildInfo
    apply LocalBuildInfo
    lbi = LocalBuildInfo
    lbi { withProfLib :: Bool
    withProfLib       = Bool
    tryLibProfiling
                              , withProfLibDetail :: ProfDetailLevel
    withProfLibDetail = ProfDetailLevel
    libLevel
                              , withProfExe :: Bool
    withProfExe       = Bool
    tryExeProfiling
                              , withProfExeDetail :: ProfDetailLevel
    withProfExeDetail = ProfDetailLevel
    exeLevel
                              }
          (Bool, LocalBuildInfo -> LocalBuildInfo)
    -> IO (Bool, LocalBuildInfo -> LocalBuildInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool
    tryExeProfiling Bool -> Bool -> Bool
    && Bool -> Bool
    not Bool
    tryLibProfiling, LocalBuildInfo -> LocalBuildInfo
    apply)
        else do
          let apply :: LocalBuildInfo -> LocalBuildInfo
    apply LocalBuildInfo
    lbi = LocalBuildInfo
    lbi { withProfLib :: Bool
    withProfLib = Bool
    False
                              , withProfLibDetail :: ProfDetailLevel
    withProfLibDetail = ProfDetailLevel
    ProfDetailNone
                              , withProfExe :: Bool
    withProfExe = Bool
    False
                              , withProfExeDetail :: ProfDetailLevel
    withProfExeDetail = ProfDetailLevel
    ProfDetailNone
                              }
          Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool
    tryExeProfiling Bool -> Bool -> Bool
    || Bool
    tryLibProfiling) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
            ([Char]
    "The compiler " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Compiler -> [Char]
    showCompilerId Compiler
    comp [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " does not support "
             [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "profiling. Profiling has been disabled.")
          (Bool, LocalBuildInfo -> LocalBuildInfo)
    -> IO (Bool, LocalBuildInfo -> LocalBuildInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool
    False, LocalBuildInfo -> LocalBuildInfo
    apply)

      Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    exeProfWithoutLibProf (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity
        ([Char]
    "Executables will be built with profiling, but library "
         [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "profiling is disabled. Linking will fail if any executables "
         [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "depend on the library.")

      (LocalBuildInfo -> LocalBuildInfo)
    -> IO (LocalBuildInfo -> LocalBuildInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return LocalBuildInfo -> LocalBuildInfo
    applyProfiling

    -- -----------------------------------------------------------------------------
    -- Configuring package dependencies

    reportProgram :: Verbosity -> Program -> Maybe ConfiguredProgram -> IO ()
    reportProgram :: Verbosity -> Program -> Maybe ConfiguredProgram -> IO ()
    reportProgram Verbosity
    verbosity Program
    prog Maybe ConfiguredProgram
    Nothing
        = Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "No " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Program -> [Char]
    programName Program
    prog [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " found"
    reportProgram Verbosity
    verbosity Program
    prog (Just ConfiguredProgram
    configuredProg)
        = Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Using " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Program -> [Char]
    programName Program
    prog [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    version [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    location
        where location :: [Char]
    location = case ConfiguredProgram -> ProgramLocation
    programLocation ConfiguredProgram
    configuredProg of
                FoundOnSystem [Char]
    p -> [Char]
    " found on system at: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    p
                UserSpecified [Char]
    p -> [Char]
    " given by user at: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    p
              version :: [Char]
    version = case ConfiguredProgram -> Maybe Version
    programVersion ConfiguredProgram
    configuredProg of
                Maybe Version
    Nothing -> [Char]
    ""
                Just Version
    v  -> [Char]
    " version " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Version -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow Version
    v

    hackageUrl :: String
    hackageUrl :: [Char]
    hackageUrl = [Char]
    "http://hackage.haskell.org/package/"

    type ResolvedDependency = (Dependency, DependencyResolution)

    data DependencyResolution
        -- | An external dependency from the package database, OR an
        -- internal dependency which we are getting from the package
        -- database.
        = ExternalDependency PreExistingComponent
        -- | An internal dependency ('PackageId' should be a library name)
        -- which we are going to have to build.  (The
        -- 'PackageId' here is a hack to get a modest amount of
        -- polymorphism out of the 'Package' typeclass.)
        | InternalDependency PackageId

    data FailedDependency = DependencyNotExists PackageName
                          | DependencyMissingInternal PackageName LibraryName
                          | DependencyNoVersion Dependency

    -- | Test for a package dependency and record the version we have installed.
    selectDependency :: PackageId -- ^ Package id of current package
                     -> Set LibraryName -- ^ package libraries
                     -> InstalledPackageIndex  -- ^ Installed packages
                     -> Map (PackageName, ComponentName) InstalledPackageInfo
                        -- ^ Packages for which we have been given specific deps to
                        -- use
                     -> UseExternalInternalDeps -- ^ Are we configuring a
                                                -- single component?
                     -> Dependency
                     -> [Either FailedDependency DependencyResolution]
    selectDependency :: PackageIdentifier
    -> Set LibraryName
    -> InstalledPackageIndex
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> Bool
    -> Dependency
    -> [Either FailedDependency DependencyResolution]
    selectDependency PackageIdentifier
    pkgid Set LibraryName
    internalIndex InstalledPackageIndex
    installedIndex Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap
      Bool
    use_external_internal_deps
      (Dependency PackageName
    dep_pkgname VersionRange
    vr NonEmptySet LibraryName
    libs) =
      -- If the dependency specification matches anything in the internal package
      -- index, then we prefer that match to anything in the second.
      -- For example:
      --
      -- Name: MyLibrary
      -- Version: 0.1
      -- Library
      --     ..
      -- Executable my-exec
      --     build-depends: MyLibrary
      --
      -- We want "build-depends: MyLibrary" always to match the internal library
      -- even if there is a newer installed library "MyLibrary-0.2".
      if PackageName
    dep_pkgname PackageName -> PackageName -> Bool
    forall a. Eq a => a -> a -> Bool
    == PackageName
    pn
      then
          if Bool
    use_external_internal_deps
          then LibraryName -> Either FailedDependency DependencyResolution
    do_external_internal (LibraryName -> Either FailedDependency DependencyResolution)
    -> [LibraryName] -> [Either FailedDependency DependencyResolution]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> NonEmptySet LibraryName -> [LibraryName]
    forall a. NonEmptySet a -> [a]
    NES.toList NonEmptySet LibraryName
    libs
          else LibraryName -> Either FailedDependency DependencyResolution
    do_internal (LibraryName -> Either FailedDependency DependencyResolution)
    -> [LibraryName] -> [Either FailedDependency DependencyResolution]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> NonEmptySet LibraryName -> [LibraryName]
    forall a. NonEmptySet a -> [a]
    NES.toList NonEmptySet LibraryName
    libs
      else
          LibraryName -> Either FailedDependency DependencyResolution
    do_external_external (LibraryName -> Either FailedDependency DependencyResolution)
    -> [LibraryName] -> [Either FailedDependency DependencyResolution]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> NonEmptySet LibraryName -> [LibraryName]
    forall a. NonEmptySet a -> [a]
    NES.toList NonEmptySet LibraryName
    libs
      where
        pn :: PackageName
    pn = PackageIdentifier -> PackageName
    forall pkg. Package pkg => pkg -> PackageName
    packageName PackageIdentifier
    pkgid

        -- It's an internal library, and we're not per-component build
        do_internal :: LibraryName -> Either FailedDependency DependencyResolution
    do_internal LibraryName
    lib
            | LibraryName -> Set LibraryName -> Bool
    forall a. Ord a => a -> Set a -> Bool
    Set.member LibraryName
    lib Set LibraryName
    internalIndex
            = DependencyResolution
    -> Either FailedDependency DependencyResolution
    forall a b. b -> Either a b
    Right (DependencyResolution
     -> Either FailedDependency DependencyResolution)
    -> DependencyResolution
    -> Either FailedDependency DependencyResolution
    forall a b. (a -> b) -> a -> b
    $ PackageIdentifier -> DependencyResolution
    InternalDependency (PackageIdentifier -> DependencyResolution)
    -> PackageIdentifier -> DependencyResolution
    forall a b. (a -> b) -> a -> b
    $ PackageName -> Version -> PackageIdentifier
    PackageIdentifier PackageName
    dep_pkgname (Version -> PackageIdentifier) -> Version -> PackageIdentifier
    forall a b. (a -> b) -> a -> b
    $ PackageIdentifier -> Version
    forall pkg. Package pkg => pkg -> Version
    packageVersion PackageIdentifier
    pkgid

            | Bool
    otherwise
            = FailedDependency -> Either FailedDependency DependencyResolution
    forall a b. a -> Either a b
    Left (FailedDependency -> Either FailedDependency DependencyResolution)
    -> FailedDependency -> Either FailedDependency DependencyResolution
    forall a b. (a -> b) -> a -> b
    $ PackageName -> LibraryName -> FailedDependency
    DependencyMissingInternal PackageName
    dep_pkgname LibraryName
    lib

        -- We have to look it up externally
        do_external_external :: LibraryName -> Either FailedDependency DependencyResolution
        do_external_external :: LibraryName -> Either FailedDependency DependencyResolution
    do_external_external LibraryName
    lib = do
          InstalledPackageInfo
    ipi <- case (PackageName, ComponentName)
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> Maybe InstalledPackageInfo
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup (PackageName
    dep_pkgname, LibraryName -> ComponentName
    CLibName LibraryName
    lib) Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap of
            -- If we know the exact pkg to use, then use it.
            Just InstalledPackageInfo
    pkginstance -> InstalledPackageInfo
    -> Either FailedDependency InstalledPackageInfo
    forall a b. b -> Either a b
    Right InstalledPackageInfo
    pkginstance
            -- Otherwise we just pick an arbitrary instance of the latest version.
            Maybe InstalledPackageInfo
    Nothing -> case [(Version, [InstalledPackageInfo])] -> Maybe InstalledPackageInfo
    pickLastIPI ([(Version, [InstalledPackageInfo])] -> Maybe InstalledPackageInfo)
    -> [(Version, [InstalledPackageInfo])]
    -> Maybe InstalledPackageInfo
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageIndex
    -> PackageName
    -> VersionRange
    -> [(Version, [InstalledPackageInfo])]
    PackageIndex.lookupDependency InstalledPackageIndex
    installedIndex PackageName
    dep_pkgname VersionRange
    vr of
              Maybe InstalledPackageInfo
    Nothing  -> FailedDependency -> Either FailedDependency InstalledPackageInfo
    forall a b. a -> Either a b
    Left (PackageName -> FailedDependency
    DependencyNotExists PackageName
    dep_pkgname)
              Just InstalledPackageInfo
    pkg -> InstalledPackageInfo
    -> Either FailedDependency InstalledPackageInfo
    forall a b. b -> Either a b
    Right InstalledPackageInfo
    pkg
          DependencyResolution
    -> Either FailedDependency DependencyResolution
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DependencyResolution
     -> Either FailedDependency DependencyResolution)
    -> DependencyResolution
    -> Either FailedDependency DependencyResolution
    forall a b. (a -> b) -> a -> b
    $ PreExistingComponent -> DependencyResolution
    ExternalDependency (PreExistingComponent -> DependencyResolution)
    -> PreExistingComponent -> DependencyResolution
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageInfo -> PreExistingComponent
    ipiToPreExistingComponent InstalledPackageInfo
    ipi

        do_external_internal :: LibraryName -> Either FailedDependency DependencyResolution
        do_external_internal :: LibraryName -> Either FailedDependency DependencyResolution
    do_external_internal LibraryName
    lib = do
          InstalledPackageInfo
    ipi <- case (PackageName, ComponentName)
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    -> Maybe InstalledPackageInfo
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup (PackageName
    dep_pkgname, LibraryName -> ComponentName
    CLibName LibraryName
    lib) Map (PackageName, ComponentName) InstalledPackageInfo
    requiredDepsMap of
            -- If we know the exact pkg to use, then use it.
            Just InstalledPackageInfo
    pkginstance -> InstalledPackageInfo
    -> Either FailedDependency InstalledPackageInfo
    forall a b. b -> Either a b
    Right InstalledPackageInfo
    pkginstance
            Maybe InstalledPackageInfo
    Nothing -> case [(Version, [InstalledPackageInfo])] -> Maybe InstalledPackageInfo
    pickLastIPI ([(Version, [InstalledPackageInfo])] -> Maybe InstalledPackageInfo)
    -> [(Version, [InstalledPackageInfo])]
    -> Maybe InstalledPackageInfo
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageIndex
    -> PackageName
    -> VersionRange
    -> LibraryName
    -> [(Version, [InstalledPackageInfo])]
    PackageIndex.lookupInternalDependency InstalledPackageIndex
    installedIndex PackageName
    pn VersionRange
    vr LibraryName
    lib of
              -- It's an internal library, being looked up externally
              Maybe InstalledPackageInfo
    Nothing  -> FailedDependency -> Either FailedDependency InstalledPackageInfo
    forall a b. a -> Either a b
    Left (PackageName -> LibraryName -> FailedDependency
    DependencyMissingInternal PackageName
    dep_pkgname LibraryName
    lib)
              Just InstalledPackageInfo
    pkg -> InstalledPackageInfo
    -> Either FailedDependency InstalledPackageInfo
    forall a b. b -> Either a b
    Right InstalledPackageInfo
    pkg
          DependencyResolution
    -> Either FailedDependency DependencyResolution
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DependencyResolution
     -> Either FailedDependency DependencyResolution)
    -> DependencyResolution
    -> Either FailedDependency DependencyResolution
    forall a b. (a -> b) -> a -> b
    $ PreExistingComponent -> DependencyResolution
    ExternalDependency (PreExistingComponent -> DependencyResolution)
    -> PreExistingComponent -> DependencyResolution
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageInfo -> PreExistingComponent
    ipiToPreExistingComponent InstalledPackageInfo
    ipi

        pickLastIPI :: [(Version, [InstalledPackageInfo])] -> Maybe InstalledPackageInfo
        pickLastIPI :: [(Version, [InstalledPackageInfo])] -> Maybe InstalledPackageInfo
    pickLastIPI [(Version, [InstalledPackageInfo])]
    pkgs = [InstalledPackageInfo] -> Maybe InstalledPackageInfo
    forall a. [a] -> Maybe a
    safeHead ([InstalledPackageInfo] -> Maybe InstalledPackageInfo)
    -> (NonEmpty (Version, [InstalledPackageInfo])
        -> [InstalledPackageInfo])
    -> NonEmpty (Version, [InstalledPackageInfo])
    -> Maybe InstalledPackageInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Version, [InstalledPackageInfo]) -> [InstalledPackageInfo]
    forall a b. (a, b) -> b
    snd ((Version, [InstalledPackageInfo]) -> [InstalledPackageInfo])
    -> (NonEmpty (Version, [InstalledPackageInfo])
        -> (Version, [InstalledPackageInfo]))
    -> NonEmpty (Version, [InstalledPackageInfo])
    -> [InstalledPackageInfo]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NonEmpty (Version, [InstalledPackageInfo])
    -> (Version, [InstalledPackageInfo])
    forall a. NonEmpty a -> a
    last (NonEmpty (Version, [InstalledPackageInfo])
     -> Maybe InstalledPackageInfo)
    -> Maybe (NonEmpty (Version, [InstalledPackageInfo]))
    -> Maybe InstalledPackageInfo
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [(Version, [InstalledPackageInfo])]
    -> Maybe (NonEmpty (Version, [InstalledPackageInfo]))
    forall a. [a] -> Maybe (NonEmpty a)
    nonEmpty [(Version, [InstalledPackageInfo])]
    pkgs

    reportSelectedDependencies :: Verbosity
                               -> [ResolvedDependency] -> IO ()
    reportSelectedDependencies :: Verbosity -> [ResolvedDependency] -> IO ()
    reportSelectedDependencies Verbosity
    verbosity [ResolvedDependency]
    deps =
      Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [[Char]] -> [Char]
    unlines
        [ [Char]
    "Dependency " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Dependency -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (Dependency -> Dependency
    simplifyDependency Dependency
    dep)
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ": using " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageIdentifier -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageIdentifier
    pkgid
        | (Dependency
    dep, DependencyResolution
    resolution) <- [ResolvedDependency]
    deps
        , let pkgid :: PackageIdentifier
    pkgid = case DependencyResolution
    resolution of
                ExternalDependency PreExistingComponent
    pkg'   -> PreExistingComponent -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId PreExistingComponent
    pkg'
                InternalDependency PackageIdentifier
    pkgid' -> PackageIdentifier
    pkgid' ]

    reportFailedDependencies :: Verbosity -> [FailedDependency] -> IO ()
    reportFailedDependencies :: Verbosity -> [FailedDependency] -> IO ()
    reportFailedDependencies Verbosity
    _ []     = () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    reportFailedDependencies Verbosity
    verbosity [FailedDependency]
    failed =
        Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    "\n\n" ((FailedDependency -> [Char]) -> [FailedDependency] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map FailedDependency -> [Char]
    reportFailedDependency [FailedDependency]
    failed))

      where
        reportFailedDependency :: FailedDependency -> [Char]
    reportFailedDependency (DependencyNotExists PackageName
    pkgname) =
             [Char]
    "there is no version of " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageName -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageName
    pkgname [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " installed.\n"
          [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "Perhaps you need to download and install it from\n"
          [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    hackageUrl [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageName -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageName
    pkgname [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "?"

        reportFailedDependency (DependencyMissingInternal PackageName
    pkgname LibraryName
    lib) =
             [Char]
    "internal dependency " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Doc -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (LibraryName -> Doc
    prettyLibraryNameComponent LibraryName
    lib) [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " not installed.\n"
          [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "Perhaps you need to configure and install it first?\n"
          [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "(This library was defined by " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PackageName -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PackageName
    pkgname [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ")"

        reportFailedDependency (DependencyNoVersion Dependency
    dep) =
            [Char]
    "cannot satisfy dependency " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Dependency -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow (Dependency -> Dependency
    simplifyDependency Dependency
    dep) [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\n"

    -- | List all installed packages in the given package databases.
    -- Non-existent package databases do not cause errors, they just get skipped
    -- with a warning and treated as empty ones, since technically they do not
    -- contain any package.
    getInstalledPackages :: Verbosity -> Compiler
                         -> PackageDBStack -- ^ The stack of package databases.
                         -> ProgramDb
                         -> IO InstalledPackageIndex
    getInstalledPackages :: Verbosity
    -> Compiler
    -> PackageDBStack
    -> ProgramDb
    -> IO InstalledPackageIndex
    getInstalledPackages Verbosity
    verbosity Compiler
    comp PackageDBStack
    packageDBs ProgramDb
    progdb = do
      Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (PackageDBStack -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null PackageDBStack
    packageDBs) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
        Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "No package databases have been specified. If you use "
           [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "--package-db=clear, you must follow it with --package-db= "
           [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "with 'global', 'user' or a specific file."

      Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity [Char]
    "Reading installed packages..."
      -- do not check empty packagedbs (ghc-pkg would error out)
      PackageDBStack
    packageDBs' <- (PackageDB -> IO Bool) -> PackageDBStack -> IO PackageDBStack
    forall (m :: * -> *) a.
    Applicative m =>
    (a -> m Bool) -> [a] -> m [a]
    filterM PackageDB -> IO Bool
    packageDBExists PackageDBStack
    packageDBs
      case Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp of
        CompilerFlavor
    GHC   -> Verbosity
    -> Compiler
    -> PackageDBStack
    -> ProgramDb
    -> IO InstalledPackageIndex
    GHC.getInstalledPackages Verbosity
    verbosity Compiler
    comp PackageDBStack
    packageDBs' ProgramDb
    progdb
        CompilerFlavor
    GHCJS -> Verbosity
    -> PackageDBStack -> ProgramDb -> IO InstalledPackageIndex
    GHCJS.getInstalledPackages Verbosity
    verbosity PackageDBStack
    packageDBs' ProgramDb
    progdb
        CompilerFlavor
    UHC   -> Verbosity
    -> Compiler
    -> PackageDBStack
    -> ProgramDb
    -> IO InstalledPackageIndex
    UHC.getInstalledPackages Verbosity
    verbosity Compiler
    comp PackageDBStack
    packageDBs' ProgramDb
    progdb
        HaskellSuite {} ->
          Verbosity
    -> PackageDBStack -> ProgramDb -> IO InstalledPackageIndex
    HaskellSuite.getInstalledPackages Verbosity
    verbosity PackageDBStack
    packageDBs' ProgramDb
    progdb
        CompilerFlavor
    flv -> Verbosity -> [Char] -> IO InstalledPackageIndex
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO InstalledPackageIndex)
    -> [Char] -> IO InstalledPackageIndex
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "don't know how to find the installed packages for "
                  [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ CompilerFlavor -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow CompilerFlavor
    flv
      where
        packageDBExists :: PackageDB -> IO Bool
    packageDBExists (SpecificPackageDB [Char]
    path) = do
          Bool
    exists <- [Char] -> IO Bool
    doesPathExist [Char]
    path
          Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless Bool
    exists (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
            Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Package db " [Char] -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> [Char]
    path [Char] -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> [Char]
    " does not exist yet"
          Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    exists
        -- Checking the user and global package dbs is more complicated and needs
        -- way more data. Also ghc-pkg won't error out unless the user/global
        -- pkgdb is overridden with an empty one, so we just don't check for them.
        packageDBExists PackageDB
    UserPackageDB            = Bool -> IO Bool
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Bool
    True
        packageDBExists PackageDB
    GlobalPackageDB          = Bool -> IO Bool
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Bool
    True

    -- | Like 'getInstalledPackages', but for a single package DB.
    --
    -- NB: Why isn't this always a fall through to 'getInstalledPackages'?
    -- That is because 'getInstalledPackages' performs some sanity checks
    -- on the package database stack in question.  However, when sandboxes
    -- are involved these sanity checks are not desirable.
    getPackageDBContents :: Verbosity -> Compiler
                         -> PackageDB -> ProgramDb
                         -> IO InstalledPackageIndex
    getPackageDBContents :: Verbosity
    -> Compiler -> PackageDB -> ProgramDb -> IO InstalledPackageIndex
    getPackageDBContents Verbosity
    verbosity Compiler
    comp PackageDB
    packageDB ProgramDb
    progdb = do
      Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity [Char]
    "Reading installed packages..."
      case Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp of
        CompilerFlavor
    GHC -> Verbosity -> PackageDB -> ProgramDb -> IO InstalledPackageIndex
    GHC.getPackageDBContents Verbosity
    verbosity PackageDB
    packageDB ProgramDb
    progdb
        CompilerFlavor
    GHCJS -> Verbosity -> PackageDB -> ProgramDb -> IO InstalledPackageIndex
    GHCJS.getPackageDBContents Verbosity
    verbosity PackageDB
    packageDB ProgramDb
    progdb
        -- For other compilers, try to fall back on 'getInstalledPackages'.
        CompilerFlavor
    _   -> Verbosity
    -> Compiler
    -> PackageDBStack
    -> ProgramDb
    -> IO InstalledPackageIndex
    getInstalledPackages Verbosity
    verbosity Compiler
    comp [PackageDB
    packageDB] ProgramDb
    progdb

    -- | A set of files (or directories) that can be monitored to detect when
    -- there might have been a change in the installed packages.
    --
    getInstalledPackagesMonitorFiles :: Verbosity -> Compiler
                                     -> PackageDBStack
                                     -> ProgramDb -> Platform
                                     -> IO [FilePath]
    getInstalledPackagesMonitorFiles :: Verbosity
    -> Compiler
    -> PackageDBStack
    -> ProgramDb
    -> Platform
    -> IO [[Char]]
    getInstalledPackagesMonitorFiles Verbosity
    verbosity Compiler
    comp PackageDBStack
    packageDBs ProgramDb
    progdb Platform
    platform =
      case Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp of
        CompilerFlavor
    GHC   -> Verbosity -> Platform -> ProgramDb -> PackageDBStack -> IO [[Char]]
    GHC.getInstalledPackagesMonitorFiles
                   Verbosity
    verbosity Platform
    platform ProgramDb
    progdb PackageDBStack
    packageDBs
        CompilerFlavor
    other -> do
          Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "don't know how to find change monitoring files for "
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "the installed package databases for " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ CompilerFlavor -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow CompilerFlavor
    other
          [[Char]] -> IO [[Char]]
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

    -- | The user interface specifies the package dbs to use with a combination of
    -- @--global@, @--user@ and @--package-db=global|user|clear|$file@.
    -- This function combines the global/user flag and interprets the package-db
    -- flag into a single package db stack.
    --
    interpretPackageDbFlags :: Bool -> [Maybe PackageDB] -> PackageDBStack
    interpretPackageDbFlags :: Bool -> [Maybe PackageDB] -> PackageDBStack
    interpretPackageDbFlags Bool
    userInstall [Maybe PackageDB]
    specificDBs =
        PackageDBStack -> [Maybe PackageDB] -> PackageDBStack
    forall {a}. [a] -> [Maybe a] -> [a]
    extra PackageDBStack
    initialStack [Maybe PackageDB]
    specificDBs
      where
        initialStack :: PackageDBStack
    initialStack | Bool
    userInstall = [PackageDB
    GlobalPackageDB, PackageDB
    UserPackageDB]
                     | Bool
    otherwise   = [PackageDB
    GlobalPackageDB]

        extra :: [a] -> [Maybe a] -> [a]
    extra [a]
    dbs' []            = [a]
    dbs'
        extra [a]
    _    (Maybe a
    Nothing:[Maybe a]
    dbs) = [a] -> [Maybe a] -> [a]
    extra []             [Maybe a]
    dbs
        extra [a]
    dbs' (Just a
    db:[Maybe a]
    dbs) = [a] -> [Maybe a] -> [a]
    extra ([a]
    dbs' [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ [a
    db]) [Maybe a]
    dbs

    -- We are given both --constraint="foo < 2.0" style constraints and also
    -- specific packages to pick via --dependency="foo=foo-2.0-177d5cdf20962d0581".
    --
    -- When finalising the package we have to take into account the specific
    -- installed deps we've been given, and the finalise function expects
    -- constraints, so we have to translate these deps into version constraints.
    --
    -- But after finalising we then have to make sure we pick the right specific
    -- deps in the end. So we still need to remember which installed packages to
    -- pick.
    combinedConstraints
      :: [PackageVersionConstraint]
      -> [GivenComponent]
      -> InstalledPackageIndex
      -> Either String ([PackageVersionConstraint],
                         Map (PackageName, ComponentName) InstalledPackageInfo)
    combinedConstraints :: [PackageVersionConstraint]
    -> [GivenComponent]
    -> InstalledPackageIndex
    -> Either
         [Char]
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    combinedConstraints [PackageVersionConstraint]
    constraints [GivenComponent]
    dependencies InstalledPackageIndex
    installedPackages = do

        Bool -> Either [Char] () -> Either [Char] ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not ([(PackageName, ComponentName, ComponentId)] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(PackageName, ComponentName, ComponentId)]
    badComponentIds)) (Either [Char] () -> Either [Char] ())
    -> Either [Char] () -> Either [Char] ()
    forall a b. (a -> b) -> a -> b
    $
          [Char] -> Either [Char] ()
    forall a b. a -> Either a b
    Left ([Char] -> Either [Char] ()) -> [Char] -> Either [Char] ()
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Char]
    render (Doc -> [Char]) -> Doc -> [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Doc
    text [Char]
    "The following package dependencies were requested"
             Doc -> Doc -> Doc
    $+$ Int -> Doc -> Doc
    nest Int
    4 ([(PackageName, ComponentName, ComponentId)] -> Doc
    forall {a} {a}.
    (Pretty a, Pretty a) =>
    [(a, ComponentName, a)] -> Doc
    dispDependencies [(PackageName, ComponentName, ComponentId)]
    badComponentIds)
             Doc -> Doc -> Doc
    $+$ [Char] -> Doc
    text [Char]
    "however the given installed package instance does not exist."

        --TODO: we don't check that all dependencies are used!

        ([PackageVersionConstraint],
     Map (PackageName, ComponentName) InstalledPackageInfo)
    -> Either
         [Char]
         ([PackageVersionConstraint],
          Map (PackageName, ComponentName) InstalledPackageInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([PackageVersionConstraint]
    allConstraints, Map (PackageName, ComponentName) InstalledPackageInfo
    idConstraintMap)

      where
        allConstraints :: [PackageVersionConstraint]
        allConstraints :: [PackageVersionConstraint]
    allConstraints = [PackageVersionConstraint]
    constraints
                      [PackageVersionConstraint]
    -> [PackageVersionConstraint] -> [PackageVersionConstraint]
    forall a. [a] -> [a] -> [a]
    ++ [ PackageIdentifier -> PackageVersionConstraint
    thisPackageVersionConstraint (InstalledPackageInfo -> PackageIdentifier
    forall pkg. Package pkg => pkg -> PackageIdentifier
    packageId InstalledPackageInfo
    pkg)
                         | (PackageName
    _, ComponentName
    _, ComponentId
    _, Just InstalledPackageInfo
    pkg) <- [(PackageName, ComponentName, ComponentId,
      Maybe InstalledPackageInfo)]
    dependenciesPkgInfo ]

        idConstraintMap :: Map (PackageName, ComponentName) InstalledPackageInfo
        idConstraintMap :: Map (PackageName, ComponentName) InstalledPackageInfo
    idConstraintMap = [((PackageName, ComponentName), InstalledPackageInfo)]
    -> Map (PackageName, ComponentName) InstalledPackageInfo
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList
                            -- NB: do NOT use the packageName from
                            -- dependenciesPkgInfo!
                            [ ((PackageName
    pn, ComponentName
    cname), InstalledPackageInfo
    pkg)
                            | (PackageName
    pn, ComponentName
    cname, ComponentId
    _, Just InstalledPackageInfo
    pkg) <- [(PackageName, ComponentName, ComponentId,
      Maybe InstalledPackageInfo)]
    dependenciesPkgInfo ]

        -- The dependencies along with the installed package info, if it exists
        dependenciesPkgInfo :: [(PackageName, ComponentName, ComponentId,
                                 Maybe InstalledPackageInfo)]
        dependenciesPkgInfo :: [(PackageName, ComponentName, ComponentId,
      Maybe InstalledPackageInfo)]
    dependenciesPkgInfo =
          [ (PackageName
    pkgname, LibraryName -> ComponentName
    CLibName LibraryName
    lname, ComponentId
    cid, Maybe InstalledPackageInfo
    mpkg)
          | GivenComponent PackageName
    pkgname LibraryName
    lname ComponentId
    cid <- [GivenComponent]
    dependencies
          , let mpkg :: Maybe InstalledPackageInfo
    mpkg = InstalledPackageIndex -> ComponentId -> Maybe InstalledPackageInfo
    forall a. PackageIndex a -> ComponentId -> Maybe a
    PackageIndex.lookupComponentId
                         InstalledPackageIndex
    installedPackages ComponentId
    cid
          ]

        -- If we looked up a package specified by an installed package id
        -- (i.e. someone has written a hash) and didn't find it then it's
        -- an error.
        badComponentIds :: [(PackageName, ComponentName, ComponentId)]
    badComponentIds =
          [ (PackageName
    pkgname, ComponentName
    cname, ComponentId
    cid)
          | (PackageName
    pkgname, ComponentName
    cname, ComponentId
    cid, Maybe InstalledPackageInfo
    Nothing) <- [(PackageName, ComponentName, ComponentId,
      Maybe InstalledPackageInfo)]
    dependenciesPkgInfo ]

        dispDependencies :: [(a, ComponentName, a)] -> Doc
    dispDependencies [(a, ComponentName, a)]
    deps =
          [Doc] -> Doc
    hsep [      [Char] -> Doc
    text [Char]
    "--dependency="
                 Doc -> Doc -> Doc
    <<>> Doc -> Doc
    quotes
                        (a -> Doc
    forall a. Pretty a => a -> Doc
    pretty a
    pkgname
                         Doc -> Doc -> Doc
    <<>> case ComponentName
    cname of
                                CLibName LibraryName
    LMainLibName    -> Doc
    ""
                                CLibName (LSubLibName UnqualComponentName
    n) -> Doc
    ":" Doc -> Doc -> Doc
    <<>> UnqualComponentName -> Doc
    forall a. Pretty a => a -> Doc
    pretty UnqualComponentName
    n
                                ComponentName
    _                        -> Doc
    ":" Doc -> Doc -> Doc
    <<>> ComponentName -> Doc
    forall a. Pretty a => a -> Doc
    pretty ComponentName
    cname
                         Doc -> Doc -> Doc
    <<>> Char -> Doc
    char Char
    '='
                         Doc -> Doc -> Doc
    <<>> a -> Doc
    forall a. Pretty a => a -> Doc
    pretty a
    cid)
               | (a
    pkgname, ComponentName
    cname, a
    cid) <- [(a, ComponentName, a)]
    deps ]

    -- -----------------------------------------------------------------------------
    -- Configuring program dependencies

    configureRequiredPrograms :: Verbosity -> [LegacyExeDependency] -> ProgramDb
                                 -> IO ProgramDb
    configureRequiredPrograms :: Verbosity -> [LegacyExeDependency] -> ProgramDb -> IO ProgramDb
    configureRequiredPrograms Verbosity
    verbosity [LegacyExeDependency]
    deps ProgramDb
    progdb =
      (ProgramDb -> LegacyExeDependency -> IO ProgramDb)
    -> ProgramDb -> [LegacyExeDependency] -> IO ProgramDb
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM (Verbosity -> ProgramDb -> LegacyExeDependency -> IO ProgramDb
    configureRequiredProgram Verbosity
    verbosity) ProgramDb
    progdb [LegacyExeDependency]
    deps

    -- | Configure a required program, ensuring that it exists in the PATH
    -- (or where the user has specified the program must live) and making it
    -- available for use via the 'ProgramDb' interface.  If the program is
    -- known (exists in the input 'ProgramDb'), we will make sure that the
    -- program matches the required version; otherwise we will accept
    -- any version of the program and assume that it is a simpleProgram.
    configureRequiredProgram :: Verbosity -> ProgramDb -> LegacyExeDependency
                                -> IO ProgramDb
    configureRequiredProgram :: Verbosity -> ProgramDb -> LegacyExeDependency -> IO ProgramDb
    configureRequiredProgram Verbosity
    verbosity ProgramDb
    progdb
      (LegacyExeDependency [Char]
    progName VersionRange
    verRange) =
      case [Char] -> ProgramDb -> Maybe Program
    lookupKnownProgram [Char]
    progName ProgramDb
    progdb of
        Maybe Program
    Nothing ->
          -- Try to configure it as a 'simpleProgram' automatically
          --
          -- There's a bit of a story behind this line.  In old versions
          -- of Cabal, there were only internal build-tools dependencies.  So the
          -- behavior in this case was:
          --
          --    - If a build-tool dependency was internal, don't do
          --      any checking.
          --
          --    - If it was external, call 'configureRequiredProgram' to
          --      "configure" the executable.  In particular, if
          --      the program was not "known" (present in 'ProgramDb'),
          --      then we would just error.  This was fine, because
          --      the only way a program could be executed from 'ProgramDb'
          --      is if some library code from Cabal actually called it,
          --      and the pre-existing Cabal code only calls known
          --      programs from 'defaultProgramDb', and so if it
          --      is calling something else, you have a Custom setup
          --      script, and in that case you are expected to register
          --      the program you want to call in the ProgramDb.
          --
          -- OK, so that was fine, until I (ezyang, in 2016) refactored
          -- Cabal to support per-component builds.  In this case, what
          -- was previously an internal build-tool dependency now became
          -- an external one, and now previously "internal" dependencies
          -- are now external.  But these are permitted to exist even
          -- when they are not previously configured (something that
          -- can only occur by a Custom script.)
          --
          -- So, I decided, "Fine, let's just accept these in any
          -- case."  Thus this line.  The alternative would have been to
          -- somehow detect when a build-tools dependency was "internal" (by
          -- looking at the unflattened package description) but this
          -- would also be incompatible with future work to support
          -- external executable dependencies: we definitely cannot
          -- assume they will be preinitialized in the 'ProgramDb'.
          Verbosity -> Program -> ProgramDb -> IO ProgramDb
    configureProgram Verbosity
    verbosity ([Char] -> Program
    simpleProgram [Char]
    progName) ProgramDb
    progdb
        Just Program
    prog
          -- requireProgramVersion always requires the program have a version
          -- but if the user says "build-depends: foo" ie no version constraint
          -- then we should not fail if we cannot discover the program version.
          | VersionRange
    verRange VersionRange -> VersionRange -> Bool
    forall a. Eq a => a -> a -> Bool
    == VersionRange
    anyVersion -> do
              (ConfiguredProgram
    _, ProgramDb
    progdb') <- Verbosity
    -> Program -> ProgramDb -> IO (ConfiguredProgram, ProgramDb)
    requireProgram Verbosity
    verbosity Program
    prog ProgramDb
    progdb
              ProgramDb -> IO ProgramDb
    forall (m :: * -> *) a. Monad m => a -> m a
    return ProgramDb
    progdb'
          | Bool
    otherwise -> do
              (ConfiguredProgram
    _, Version
    _, ProgramDb
    progdb') <- Verbosity
    -> Program
    -> VersionRange
    -> ProgramDb
    -> IO (ConfiguredProgram, Version, ProgramDb)
    requireProgramVersion Verbosity
    verbosity Program
    prog VersionRange
    verRange ProgramDb
    progdb
              ProgramDb -> IO ProgramDb
    forall (m :: * -> *) a. Monad m => a -> m a
    return ProgramDb
    progdb'

    -- -----------------------------------------------------------------------------
    -- Configuring pkg-config package dependencies

    configurePkgconfigPackages :: Verbosity -> PackageDescription
                               -> ProgramDb -> ComponentRequestedSpec
                               -> IO (PackageDescription, ProgramDb)
    configurePkgconfigPackages :: Verbosity
    -> PackageDescription
    -> ProgramDb
    -> ComponentRequestedSpec
    -> IO (PackageDescription, ProgramDb)
    configurePkgconfigPackages Verbosity
    verbosity PackageDescription
    pkg_descr ProgramDb
    progdb ComponentRequestedSpec
    enabled
      | [PkgconfigDependency] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [PkgconfigDependency]
    allpkgs = (PackageDescription, ProgramDb)
    -> IO (PackageDescription, ProgramDb)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (PackageDescription
    pkg_descr, ProgramDb
    progdb)
      | Bool
    otherwise    = do
        (ConfiguredProgram
    _, Version
    _, ProgramDb
    progdb') <- Verbosity
    -> Program
    -> VersionRange
    -> ProgramDb
    -> IO (ConfiguredProgram, Version, ProgramDb)
    requireProgramVersion
                           (Verbosity -> Verbosity
    lessVerbose Verbosity
    verbosity) Program
    pkgConfigProgram
                           (Version -> VersionRange
    orLaterVersion (Version -> VersionRange) -> Version -> VersionRange
    forall a b. (a -> b) -> a -> b
    $ [Int] -> Version
    mkVersion [Int
    0,Int
    9,Int
    0]) ProgramDb
    progdb
        (PkgconfigDependency -> IO ()) -> [PkgconfigDependency] -> IO ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    (a -> f b) -> t a -> f ()
    traverse_ PkgconfigDependency -> IO ()
    requirePkg [PkgconfigDependency]
    allpkgs
        Maybe Library
    mlib' <- (Library -> IO Library) -> Maybe Library -> IO (Maybe Library)
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse Library -> IO Library
    addPkgConfigBILib (PackageDescription -> Maybe Library
    library PackageDescription
    pkg_descr)
        [Library]
    libs' <- (Library -> IO Library) -> [Library] -> IO [Library]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse Library -> IO Library
    addPkgConfigBILib (PackageDescription -> [Library]
    subLibraries PackageDescription
    pkg_descr)
        [Executable]
    exes' <- (Executable -> IO Executable) -> [Executable] -> IO [Executable]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse Executable -> IO Executable
    addPkgConfigBIExe (PackageDescription -> [Executable]
    executables PackageDescription
    pkg_descr)
        [TestSuite]
    tests' <- (TestSuite -> IO TestSuite) -> [TestSuite] -> IO [TestSuite]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse TestSuite -> IO TestSuite
    addPkgConfigBITest (PackageDescription -> [TestSuite]
    testSuites PackageDescription
    pkg_descr)
        [Benchmark]
    benches' <- (Benchmark -> IO Benchmark) -> [Benchmark] -> IO [Benchmark]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse Benchmark -> IO Benchmark
    addPkgConfigBIBench (PackageDescription -> [Benchmark]
    benchmarks PackageDescription
    pkg_descr)
        let pkg_descr' :: PackageDescription
    pkg_descr' = PackageDescription
    pkg_descr { library :: Maybe Library
    library = Maybe Library
    mlib',
                                     subLibraries :: [Library]
    subLibraries = [Library]
    libs', executables :: [Executable]
    executables = [Executable]
    exes',
                                     testSuites :: [TestSuite]
    testSuites = [TestSuite]
    tests', benchmarks :: [Benchmark]
    benchmarks = [Benchmark]
    benches' }
        (PackageDescription, ProgramDb)
    -> IO (PackageDescription, ProgramDb)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (PackageDescription
    pkg_descr', ProgramDb
    progdb')

      where
        allpkgs :: [PkgconfigDependency]
    allpkgs = (BuildInfo -> [PkgconfigDependency])
    -> [BuildInfo] -> [PkgconfigDependency]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap BuildInfo -> [PkgconfigDependency]
    pkgconfigDepends (PackageDescription -> ComponentRequestedSpec -> [BuildInfo]
    enabledBuildInfos PackageDescription
    pkg_descr ComponentRequestedSpec
    enabled)
        pkgconfig :: [[Char]] -> IO [Char]
    pkgconfig = Verbosity -> Program -> ProgramDb -> [[Char]] -> IO [Char]
    getDbProgramOutput (Verbosity -> Verbosity
    lessVerbose Verbosity
    verbosity)
                      Program
    pkgConfigProgram ProgramDb
    progdb

        requirePkg :: PkgconfigDependency -> IO ()
    requirePkg dep :: PkgconfigDependency
    dep@(PkgconfigDependency PkgconfigName
    pkgn PkgconfigVersionRange
    range) = do
          [Char]
    version <- [[Char]] -> IO [Char]
    pkgconfig [[Char]
    "--modversion", [Char]
    pkg]
                     IO [Char] -> (IOException -> IO [Char]) -> IO [Char]
    forall a. IO a -> (IOException -> IO a) -> IO a
    `catchIO`   (\IOException
    _ -> Verbosity -> [Char] -> IO [Char]
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity [Char]
    notFound)
                     IO [Char] -> (ExitCode -> IO [Char]) -> IO [Char]
    forall a. IO a -> (ExitCode -> IO a) -> IO a
    `catchExit` (\ExitCode
    _ -> Verbosity -> [Char] -> IO [Char]
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity [Char]
    notFound)
          let trim :: ShowS
    trim = (Char -> Bool) -> ShowS
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    isSpace ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> Bool) -> ShowS
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhileEnd Char -> Bool
    isSpace
          let v :: PkgconfigVersion
    v = ByteString -> PkgconfigVersion
    PkgconfigVersion ([Char] -> ByteString
    toUTF8BS ([Char] -> ByteString) -> [Char] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ShowS
    trim [Char]
    version)
          if Bool -> Bool
    not (PkgconfigVersion -> PkgconfigVersionRange -> Bool
    withinPkgconfigVersionRange PkgconfigVersion
    v PkgconfigVersionRange
    range)
          then Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity (PkgconfigVersion -> [Char]
    forall a. Pretty a => a -> [Char]
    badVersion PkgconfigVersion
    v)
          else Verbosity -> [Char] -> IO ()
    info Verbosity
    verbosity (PkgconfigVersion -> [Char]
    forall a. Pretty a => a -> [Char]
    depSatisfied PkgconfigVersion
    v)
          where
            notFound :: [Char]
    notFound     = [Char]
    "The pkg-config package '" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    pkg [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "'"
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    versionRequirement
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is required but it could not be found."
            badVersion :: a -> [Char]
    badVersion a
    v = [Char]
    "The pkg-config package '" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    pkg [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "'"
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    versionRequirement
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is required but the version installed on the"
                        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " system is version " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow a
    v
            depSatisfied :: a -> [Char]
    depSatisfied a
    v = [Char]
    "Dependency " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PkgconfigDependency -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PkgconfigDependency
    dep
                          [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ": using version " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow a
    v

            versionRequirement :: [Char]
    versionRequirement
              | PkgconfigVersionRange -> Bool
    isAnyPkgconfigVersion PkgconfigVersionRange
    range = [Char]
    ""
              | Bool
    otherwise                   = [Char]
    " version " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ PkgconfigVersionRange -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PkgconfigVersionRange
    range

            pkg :: [Char]
    pkg = PkgconfigName -> [Char]
    unPkgconfigName PkgconfigName
    pkgn

        -- Adds pkgconfig dependencies to the build info for a component
        addPkgConfigBI :: (t -> BuildInfo) -> (t -> BuildInfo -> b) -> t -> IO b
    addPkgConfigBI t -> BuildInfo
    compBI t -> BuildInfo -> b
    setCompBI t
    comp = do
          BuildInfo
    bi <- [PkgconfigDependency] -> IO BuildInfo
    pkgconfigBuildInfo (BuildInfo -> [PkgconfigDependency]
    pkgconfigDepends (t -> BuildInfo
    compBI t
    comp))
          b -> IO b
    forall (m :: * -> *) a. Monad m => a -> m a
    return (b -> IO b) -> b -> IO b
    forall a b. (a -> b) -> a -> b
    $ t -> BuildInfo -> b
    setCompBI t
    comp (t -> BuildInfo
    compBI t
    comp BuildInfo -> BuildInfo -> BuildInfo
    forall a. Monoid a => a -> a -> a
    `mappend` BuildInfo
    bi)

        -- Adds pkgconfig dependencies to the build info for a library
        addPkgConfigBILib :: Library -> IO Library
    addPkgConfigBILib = (Library -> BuildInfo)
    -> (Library -> BuildInfo -> Library) -> Library -> IO Library
    forall {t} {b}.
    (t -> BuildInfo) -> (t -> BuildInfo -> b) -> t -> IO b
    addPkgConfigBI Library -> BuildInfo
    libBuildInfo ((Library -> BuildInfo -> Library) -> Library -> IO Library)
    -> (Library -> BuildInfo -> Library) -> Library -> IO Library
    forall a b. (a -> b) -> a -> b
    $
                              \Library
    lib BuildInfo
    bi -> Library
    lib { libBuildInfo :: BuildInfo
    libBuildInfo = BuildInfo
    bi }

        -- Adds pkgconfig dependencies to the build info for an executable
        addPkgConfigBIExe :: Executable -> IO Executable
    addPkgConfigBIExe = (Executable -> BuildInfo)
    -> (Executable -> BuildInfo -> Executable)
    -> Executable
    -> IO Executable
    forall {t} {b}.
    (t -> BuildInfo) -> (t -> BuildInfo -> b) -> t -> IO b
    addPkgConfigBI Executable -> BuildInfo
    buildInfo ((Executable -> BuildInfo -> Executable)
     -> Executable -> IO Executable)
    -> (Executable -> BuildInfo -> Executable)
    -> Executable
    -> IO Executable
    forall a b. (a -> b) -> a -> b
    $
                              \Executable
    exe BuildInfo
    bi -> Executable
    exe { buildInfo :: BuildInfo
    buildInfo = BuildInfo
    bi }

        -- Adds pkgconfig dependencies to the build info for a test suite
        addPkgConfigBITest :: TestSuite -> IO TestSuite
    addPkgConfigBITest = (TestSuite -> BuildInfo)
    -> (TestSuite -> BuildInfo -> TestSuite)
    -> TestSuite
    -> IO TestSuite
    forall {t} {b}.
    (t -> BuildInfo) -> (t -> BuildInfo -> b) -> t -> IO b
    addPkgConfigBI TestSuite -> BuildInfo
    testBuildInfo ((TestSuite -> BuildInfo -> TestSuite)
     -> TestSuite -> IO TestSuite)
    -> (TestSuite -> BuildInfo -> TestSuite)
    -> TestSuite
    -> IO TestSuite
    forall a b. (a -> b) -> a -> b
    $
                              \TestSuite
    test BuildInfo
    bi -> TestSuite
    test { testBuildInfo :: BuildInfo
    testBuildInfo = BuildInfo
    bi }

        -- Adds pkgconfig dependencies to the build info for a benchmark
        addPkgConfigBIBench :: Benchmark -> IO Benchmark
    addPkgConfigBIBench = (Benchmark -> BuildInfo)
    -> (Benchmark -> BuildInfo -> Benchmark)
    -> Benchmark
    -> IO Benchmark
    forall {t} {b}.
    (t -> BuildInfo) -> (t -> BuildInfo -> b) -> t -> IO b
    addPkgConfigBI Benchmark -> BuildInfo
    benchmarkBuildInfo ((Benchmark -> BuildInfo -> Benchmark)
     -> Benchmark -> IO Benchmark)
    -> (Benchmark -> BuildInfo -> Benchmark)
    -> Benchmark
    -> IO Benchmark
    forall a b. (a -> b) -> a -> b
    $
                              \Benchmark
    bench BuildInfo
    bi -> Benchmark
    bench { benchmarkBuildInfo :: BuildInfo
    benchmarkBuildInfo = BuildInfo
    bi }

        pkgconfigBuildInfo :: [PkgconfigDependency] -> IO BuildInfo
        pkgconfigBuildInfo :: [PkgconfigDependency] -> IO BuildInfo
    pkgconfigBuildInfo []      = BuildInfo -> IO BuildInfo
    forall (m :: * -> *) a. Monad m => a -> m a
    return BuildInfo
    forall a. Monoid a => a
    mempty
        pkgconfigBuildInfo [PkgconfigDependency]
    pkgdeps = do
          let pkgs :: [[Char]]
    pkgs = [[Char]] -> [[Char]]
    forall a. Eq a => [a] -> [a]
    nub [ PkgconfigName -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow PkgconfigName
    pkg | PkgconfigDependency PkgconfigName
    pkg PkgconfigVersionRange
    _ <- [PkgconfigDependency]
    pkgdeps ]
          [Char]
    ccflags <- [[Char]] -> IO [Char]
    pkgconfig ([Char]
    "--cflags" [Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    : [[Char]]
    pkgs)
          [Char]
    ldflags <- [[Char]] -> IO [Char]
    pkgconfig ([Char]
    "--libs"   [Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    : [[Char]]
    pkgs)
          BuildInfo -> IO BuildInfo
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([[Char]] -> [[Char]] -> BuildInfo
    ccLdOptionsBuildInfo ([Char] -> [[Char]]
    words [Char]
    ccflags) ([Char] -> [[Char]]
    words [Char]
    ldflags))

    -- | Makes a 'BuildInfo' from C compiler and linker flags.
    --
    -- This can be used with the output from configuration programs like pkg-config
    -- and similar package-specific programs like mysql-config, freealut-config etc.
    -- For example:
    --
    -- > ccflags <- getDbProgramOutput verbosity prog progdb ["--cflags"]
    -- > ldflags <- getDbProgramOutput verbosity prog progdb ["--libs"]
    -- > return (ccldOptionsBuildInfo (words ccflags) (words ldflags))
    --
    ccLdOptionsBuildInfo :: [String] -> [String] -> BuildInfo
    ccLdOptionsBuildInfo :: [[Char]] -> [[Char]] -> BuildInfo
    ccLdOptionsBuildInfo [[Char]]
    cflags [[Char]]
    ldflags =
      let ([[Char]]
    includeDirs',  [[Char]]
    cflags')   = ([Char] -> Bool) -> [[Char]] -> ([[Char]], [[Char]])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition ([Char]
    "-I" [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf`) [[Char]]
    cflags
          ([[Char]]
    extraLibs',    [[Char]]
    ldflags')  = ([Char] -> Bool) -> [[Char]] -> ([[Char]], [[Char]])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition ([Char]
    "-l" [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf`) [[Char]]
    ldflags
          ([[Char]]
    extraLibDirs', [[Char]]
    ldflags'') = ([Char] -> Bool) -> [[Char]] -> ([[Char]], [[Char]])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition ([Char]
    "-L" [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf`) [[Char]]
    ldflags'
      in BuildInfo
    forall a. Monoid a => a
    mempty {
           includeDirs :: [[Char]]
    includeDirs  = ShowS -> [[Char]] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int -> ShowS
    forall a. Int -> [a] -> [a]
    drop Int
    2) [[Char]]
    includeDirs',
           extraLibs :: [[Char]]
    extraLibs    = ShowS -> [[Char]] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int -> ShowS
    forall a. Int -> [a] -> [a]
    drop Int
    2) [[Char]]
    extraLibs',
           extraLibDirs :: [[Char]]
    extraLibDirs = ShowS -> [[Char]] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int -> ShowS
    forall a. Int -> [a] -> [a]
    drop Int
    2) [[Char]]
    extraLibDirs',
           ccOptions :: [[Char]]
    ccOptions    = [[Char]]
    cflags',
           ldOptions :: [[Char]]
    ldOptions    = [[Char]]
    ldflags''
         }

    -- -----------------------------------------------------------------------------
    -- Determining the compiler details

    configCompilerAuxEx :: ConfigFlags
                        -> IO (Compiler, Platform, ProgramDb)
    configCompilerAuxEx :: ConfigFlags -> IO (Compiler, Platform, ProgramDb)
    configCompilerAuxEx ConfigFlags
    cfg = Maybe CompilerFlavor
    -> Maybe [Char]
    -> Maybe [Char]
    -> ProgramDb
    -> Verbosity
    -> IO (Compiler, Platform, ProgramDb)
    configCompilerEx (Flag CompilerFlavor -> Maybe CompilerFlavor
    forall a. Flag a -> Maybe a
    flagToMaybe (Flag CompilerFlavor -> Maybe CompilerFlavor)
    -> Flag CompilerFlavor -> Maybe CompilerFlavor
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag CompilerFlavor
    configHcFlavor ConfigFlags
    cfg)
                                               (Flag [Char] -> Maybe [Char]
    forall a. Flag a -> Maybe a
    flagToMaybe (Flag [Char] -> Maybe [Char]) -> Flag [Char] -> Maybe [Char]
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag [Char]
    configHcPath ConfigFlags
    cfg)
                                               (Flag [Char] -> Maybe [Char]
    forall a. Flag a -> Maybe a
    flagToMaybe (Flag [Char] -> Maybe [Char]) -> Flag [Char] -> Maybe [Char]
    forall a b. (a -> b) -> a -> b
    $ ConfigFlags -> Flag [Char]
    configHcPkg ConfigFlags
    cfg)
                                               ProgramDb
    programDb
                                               (Flag Verbosity -> Verbosity
    forall a. WithCallStack (Flag a -> a)
    fromFlag (ConfigFlags -> Flag Verbosity
    configVerbosity ConfigFlags
    cfg))
      where
        programDb :: ProgramDb
    programDb = ConfigFlags -> ProgramDb -> ProgramDb
    mkProgramDb ConfigFlags
    cfg ProgramDb
    defaultProgramDb

    configCompilerEx :: Maybe CompilerFlavor -> Maybe FilePath -> Maybe FilePath
                     -> ProgramDb -> Verbosity
                     -> IO (Compiler, Platform, ProgramDb)
    configCompilerEx :: Maybe CompilerFlavor
    -> Maybe [Char]
    -> Maybe [Char]
    -> ProgramDb
    -> Verbosity
    -> IO (Compiler, Platform, ProgramDb)
    configCompilerEx Maybe CompilerFlavor
    Nothing Maybe [Char]
    _ Maybe [Char]
    _ ProgramDb
    _ Verbosity
    verbosity = Verbosity -> [Char] -> IO (Compiler, Platform, ProgramDb)
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity [Char]
    "Unknown compiler"
    configCompilerEx (Just CompilerFlavor
    hcFlavor) Maybe [Char]
    hcPath Maybe [Char]
    hcPkg ProgramDb
    progdb Verbosity
    verbosity = do
      (Compiler
    comp, Maybe Platform
    maybePlatform, ProgramDb
    programDb) <- case CompilerFlavor
    hcFlavor of
        CompilerFlavor
    GHC   -> Verbosity
    -> Maybe [Char]
    -> Maybe [Char]
    -> ProgramDb
    -> IO (Compiler, Maybe Platform, ProgramDb)
    GHC.configure  Verbosity
    verbosity Maybe [Char]
    hcPath Maybe [Char]
    hcPkg ProgramDb
    progdb
        CompilerFlavor
    GHCJS -> Verbosity
    -> Maybe [Char]
    -> Maybe [Char]
    -> ProgramDb
    -> IO (Compiler, Maybe Platform, ProgramDb)
    GHCJS.configure Verbosity
    verbosity Maybe [Char]
    hcPath Maybe [Char]
    hcPkg ProgramDb
    progdb
        CompilerFlavor
    UHC   -> Verbosity
    -> Maybe [Char]
    -> Maybe [Char]
    -> ProgramDb
    -> IO (Compiler, Maybe Platform, ProgramDb)
    UHC.configure  Verbosity
    verbosity Maybe [Char]
    hcPath Maybe [Char]
    hcPkg ProgramDb
    progdb
        HaskellSuite {} -> Verbosity
    -> Maybe [Char]
    -> Maybe [Char]
    -> ProgramDb
    -> IO (Compiler, Maybe Platform, ProgramDb)
    HaskellSuite.configure Verbosity
    verbosity Maybe [Char]
    hcPath Maybe [Char]
    hcPkg ProgramDb
    progdb
        CompilerFlavor
    _    -> Verbosity -> [Char] -> IO (Compiler, Maybe Platform, ProgramDb)
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity [Char]
    "Unknown compiler"
      (Compiler, Platform, ProgramDb)
    -> IO (Compiler, Platform, ProgramDb)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Compiler
    comp, Platform -> Maybe Platform -> Platform
    forall a. a -> Maybe a -> a
    fromMaybe Platform
    buildPlatform Maybe Platform
    maybePlatform, ProgramDb
    programDb)

    -- -----------------------------------------------------------------------------
    -- Testing C lib and header dependencies

    -- Try to build a test C program which includes every header and links every
    -- lib. If that fails, try to narrow it down by preprocessing (only) and linking
    -- with individual headers and libs.  If none is the obvious culprit then give a
    -- generic error message.
    -- TODO: produce a log file from the compiler errors, if any.
    checkForeignDeps :: PackageDescription -> LocalBuildInfo -> Verbosity -> IO ()
    checkForeignDeps :: PackageDescription -> LocalBuildInfo -> Verbosity -> IO ()
    checkForeignDeps PackageDescription
    pkg LocalBuildInfo
    lbi Verbosity
    verbosity =
      [[Char]] -> [[Char]] -> IO () -> IO () -> IO ()
    forall {b}. [[Char]] -> [[Char]] -> IO b -> IO b -> IO b
    ifBuildsWith [[Char]]
    allHeaders ([[Char]]
    commonCcArgs [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [[Char]] -> [[Char]]
    makeLdArgs [[Char]]
    allLibs) -- I'm feeling
                                                                   -- lucky
               (() -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())
               (do [[Char]]
    missingLibs <- IO [[Char]]
    findMissingLibs
                   Maybe (Either [Char] [Char])
    missingHdr  <- IO (Maybe (Either [Char] [Char]))
    findOffendingHdr
                   Maybe (Either [Char] [Char]) -> [[Char]] -> IO ()
    explainErrors Maybe (Either [Char] [Char])
    missingHdr [[Char]]
    missingLibs)
          where
            allHeaders :: [[Char]]
    allHeaders = (BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    includes
            allLibs :: [[Char]]
    allLibs    = (BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    extraLibs

            ifBuildsWith :: [[Char]] -> [[Char]] -> IO b -> IO b -> IO b
    ifBuildsWith [[Char]]
    headers [[Char]]
    args IO b
    success IO b
    failure = do
                IO ()
    checkDuplicateHeaders
                Bool
    ok <- [Char] -> [[Char]] -> IO Bool
    builds ([[Char]] -> [Char]
    makeProgram [[Char]]
    headers) [[Char]]
    args
                if Bool
    ok then IO b
    success else IO b
    failure

            -- Ensure that there is only one header with a given name
            -- in either the generated (most likely by `configure`)
            -- build directory (e.g. `dist/build`) or in the source directory.
            --
            -- If it exists in both, we'll remove the one in the source
            -- directory, as the generated should take precedence.
            --
            -- C compilers like to prefer source local relative includes,
            -- so the search paths provided to the compiler via -I are
            -- ignored if the included file can be found relative to the
            -- including file.  As such we need to take drastic measures
            -- and delete the offending file in the source directory.
            checkDuplicateHeaders :: IO ()
    checkDuplicateHeaders = do
              let relIncDirs :: [[Char]]
    relIncDirs = ([Char] -> Bool) -> [[Char]] -> [[Char]]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> ([Char] -> Bool) -> [Char] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Bool
    isAbsolute) ((BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    includeDirs)
                  isHeader :: [Char] -> Bool
    isHeader   = [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isSuffixOf [Char]
    ".h"
              [[[Char]]]
    genHeaders <- [[Char]] -> ([Char] -> IO [[Char]]) -> IO [[[Char]]]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    t a -> (a -> f b) -> f (t b)
    for [[Char]]
    relIncDirs (([Char] -> IO [[Char]]) -> IO [[[Char]]])
    -> ([Char] -> IO [[Char]]) -> IO [[[Char]]]
    forall a b. (a -> b) -> a -> b
    $ \[Char]
    dir ->
                ShowS -> [[Char]] -> [[Char]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ([Char]
    dir [Char] -> ShowS
    </>) ([[Char]] -> [[Char]])
    -> ([[Char]] -> [[Char]]) -> [[Char]] -> [[Char]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char] -> Bool) -> [[Char]] -> [[Char]]
    forall a. (a -> Bool) -> [a] -> [a]
    filter [Char] -> Bool
    isHeader ([[Char]] -> [[Char]]) -> IO [[Char]] -> IO [[Char]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                [Char] -> IO [[Char]]
    listDirectory (LocalBuildInfo -> [Char]
    buildDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    dir) IO [[Char]] -> (IOException -> IO [[Char]]) -> IO [[Char]]
    forall a. IO a -> (IOException -> IO a) -> IO a
    `catchIO` (\IOException
    _ -> [[Char]] -> IO [[Char]]
    forall (m :: * -> *) a. Monad m => a -> m a
    return [])
              [[[Char]]]
    srcHeaders <- [[Char]] -> ([Char] -> IO [[Char]]) -> IO [[[Char]]]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    t a -> (a -> f b) -> f (t b)
    for [[Char]]
    relIncDirs (([Char] -> IO [[Char]]) -> IO [[[Char]]])
    -> ([Char] -> IO [[Char]]) -> IO [[[Char]]]
    forall a b. (a -> b) -> a -> b
    $ \[Char]
    dir ->
                ShowS -> [[Char]] -> [[Char]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ([Char]
    dir [Char] -> ShowS
    </>) ([[Char]] -> [[Char]])
    -> ([[Char]] -> [[Char]]) -> [[Char]] -> [[Char]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char] -> Bool) -> [[Char]] -> [[Char]]
    forall a. (a -> Bool) -> [a] -> [a]
    filter [Char] -> Bool
    isHeader ([[Char]] -> [[Char]]) -> IO [[Char]] -> IO [[Char]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                [Char] -> IO [[Char]]
    listDirectory (LocalBuildInfo -> [Char]
    baseDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    dir) IO [[Char]] -> (IOException -> IO [[Char]]) -> IO [[Char]]
    forall a. IO a -> (IOException -> IO a) -> IO a
    `catchIO` (\IOException
    _ -> [[Char]] -> IO [[Char]]
    forall (m :: * -> *) a. Monad m => a -> m a
    return [])
              let commonHeaders :: [[Char]]
    commonHeaders = [[[Char]]] -> [[Char]]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [[[Char]]]
    genHeaders [[Char]] -> [[Char]] -> [[Char]]
    forall a. Eq a => [a] -> [a] -> [a]
    `intersect` [[[Char]]] -> [[Char]]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [[[Char]]]
    srcHeaders
              [[Char]] -> ([Char] -> IO ()) -> IO ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    t a -> (a -> f b) -> f ()
    for_ [[Char]]
    commonHeaders (([Char] -> IO ()) -> IO ()) -> ([Char] -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \[Char]
    hdr -> do
                Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Duplicate header found in "
                              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ (LocalBuildInfo -> [Char]
    buildDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    hdr)
                              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " and "
                              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ (LocalBuildInfo -> [Char]
    baseDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    hdr)
                              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "; removing "
                              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ (LocalBuildInfo -> [Char]
    baseDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    hdr)
                [Char] -> IO ()
    removeFile (LocalBuildInfo -> [Char]
    baseDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    hdr)

            findOffendingHdr :: IO (Maybe (Either [Char] [Char]))
    findOffendingHdr =
                [[Char]]
    -> [[Char]]
    -> IO (Maybe (Either [Char] [Char]))
    -> IO (Maybe (Either [Char] [Char]))
    -> IO (Maybe (Either [Char] [Char]))
    forall {b}. [[Char]] -> [[Char]] -> IO b -> IO b -> IO b
    ifBuildsWith [[Char]]
    allHeaders [[Char]]
    ccArgs
                             (Maybe (Either [Char] [Char]) -> IO (Maybe (Either [Char] [Char]))
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either [Char] [Char])
    forall a. Maybe a
    Nothing)
                             ([[[Char]]] -> IO (Maybe (Either [Char] [Char]))
    go ([[[Char]]] -> IO (Maybe (Either [Char] [Char])))
    -> ([[Char]] -> [[[Char]]])
    -> [[Char]]
    -> IO (Maybe (Either [Char] [Char]))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[[Char]]] -> [[[Char]]]
    forall a. [a] -> [a]
    Unsafe.tail ([[[Char]]] -> [[[Char]]])
    -> ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Char]] -> [[[Char]]]
    forall a. [a] -> [[a]]
    inits ([[Char]] -> IO (Maybe (Either [Char] [Char])))
    -> [[Char]] -> IO (Maybe (Either [Char] [Char]))
    forall a b. (a -> b) -> a -> b
    $ [[Char]]
    allHeaders) -- inits always contains at least []
                where
                  go :: [[[Char]]] -> IO (Maybe (Either [Char] [Char]))
    go [] = Maybe (Either [Char] [Char]) -> IO (Maybe (Either [Char] [Char]))
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either [Char] [Char])
    forall a. Maybe a
    Nothing       -- cannot happen
                  go ([[Char]]
    hdrs:[[[Char]]]
    hdrsInits) =
                        -- Try just preprocessing first
                        [[Char]]
    -> [[Char]]
    -> IO (Maybe (Either [Char] [Char]))
    -> IO (Maybe (Either [Char] [Char]))
    -> IO (Maybe (Either [Char] [Char]))
    forall {b}. [[Char]] -> [[Char]] -> IO b -> IO b -> IO b
    ifBuildsWith [[Char]]
    hdrs [[Char]]
    cppArgs
                          -- If that works, try compiling too
                          ([[Char]]
    -> [[Char]]
    -> IO (Maybe (Either [Char] [Char]))
    -> IO (Maybe (Either [Char] [Char]))
    -> IO (Maybe (Either [Char] [Char]))
    forall {b}. [[Char]] -> [[Char]] -> IO b -> IO b -> IO b
    ifBuildsWith [[Char]]
    hdrs [[Char]]
    ccArgs
                            ([[[Char]]] -> IO (Maybe (Either [Char] [Char]))
    go [[[Char]]]
    hdrsInits)
                            (Maybe (Either [Char] [Char]) -> IO (Maybe (Either [Char] [Char]))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (Either [Char] [Char]) -> IO (Maybe (Either [Char] [Char])))
    -> ([[Char]] -> Maybe (Either [Char] [Char]))
    -> [[Char]]
    -> IO (Maybe (Either [Char] [Char]))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char] -> Either [Char] [Char])
    -> Maybe [Char] -> Maybe (Either [Char] [Char])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap [Char] -> Either [Char] [Char]
    forall a b. b -> Either a b
    Right (Maybe [Char] -> Maybe (Either [Char] [Char]))
    -> ([[Char]] -> Maybe [Char])
    -> [[Char]]
    -> Maybe (Either [Char] [Char])
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Char]] -> Maybe [Char]
    forall a. [a] -> Maybe a
    safeLast ([[Char]] -> IO (Maybe (Either [Char] [Char])))
    -> [[Char]] -> IO (Maybe (Either [Char] [Char]))
    forall a b. (a -> b) -> a -> b
    $ [[Char]]
    hdrs))
                          (Maybe (Either [Char] [Char]) -> IO (Maybe (Either [Char] [Char]))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (Either [Char] [Char]) -> IO (Maybe (Either [Char] [Char])))
    -> ([[Char]] -> Maybe (Either [Char] [Char]))
    -> [[Char]]
    -> IO (Maybe (Either [Char] [Char]))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char] -> Either [Char] [Char])
    -> Maybe [Char] -> Maybe (Either [Char] [Char])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap [Char] -> Either [Char] [Char]
    forall a b. a -> Either a b
    Left (Maybe [Char] -> Maybe (Either [Char] [Char]))
    -> ([[Char]] -> Maybe [Char])
    -> [[Char]]
    -> Maybe (Either [Char] [Char])
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Char]] -> Maybe [Char]
    forall a. [a] -> Maybe a
    safeLast ([[Char]] -> IO (Maybe (Either [Char] [Char])))
    -> [[Char]] -> IO (Maybe (Either [Char] [Char]))
    forall a b. (a -> b) -> a -> b
    $ [[Char]]
    hdrs)

                  cppArgs :: [[Char]]
    cppArgs = [Char]
    "-E"[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[[Char]]
    commonCppArgs -- preprocess only
                  ccArgs :: [[Char]]
    ccArgs  = [Char]
    "-c"[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[[Char]]
    commonCcArgs  -- don't try to link

            findMissingLibs :: IO [[Char]]
    findMissingLibs = [[Char]] -> [[Char]] -> IO [[Char]] -> IO [[Char]] -> IO [[Char]]
    forall {b}. [[Char]] -> [[Char]] -> IO b -> IO b -> IO b
    ifBuildsWith [] ([[Char]] -> [[Char]]
    makeLdArgs [[Char]]
    allLibs)
                                           ([[Char]] -> IO [[Char]]
    forall (m :: * -> *) a. Monad m => a -> m a
    return [])
                                           (([Char] -> IO Bool) -> [[Char]] -> IO [[Char]]
    forall (m :: * -> *) a.
    Applicative m =>
    (a -> m Bool) -> [a] -> m [a]
    filterM ((Bool -> Bool) -> IO Bool -> IO Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Bool -> Bool
    not (IO Bool -> IO Bool) -> ([Char] -> IO Bool) -> [Char] -> IO Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> IO Bool
    libExists) [[Char]]
    allLibs)

            libExists :: [Char] -> IO Bool
    libExists [Char]
    lib = [Char] -> [[Char]] -> IO Bool
    builds ([[Char]] -> [Char]
    makeProgram []) ([[Char]] -> [[Char]]
    makeLdArgs [[Char]
    lib])

            baseDir :: LocalBuildInfo -> [Char]
    baseDir LocalBuildInfo
    lbi' = [Char] -> Maybe [Char] -> [Char]
    forall a. a -> Maybe a -> a
    fromMaybe [Char]
    "." (ShowS
    takeDirectory ShowS -> Maybe [Char] -> Maybe [Char]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> LocalBuildInfo -> Maybe [Char]
    cabalFilePath LocalBuildInfo
    lbi')

            commonCppArgs :: [[Char]]
    commonCppArgs = LocalBuildInfo -> [[Char]]
    platformDefines LocalBuildInfo
    lbi
                         -- TODO: This is a massive hack, to work around the
                         -- fact that the test performed here should be
                         -- PER-component (c.f. the "I'm Feeling Lucky"; we
                         -- should NOT be glomming everything together.)
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    "-I" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ LocalBuildInfo -> [Char]
    buildDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    "autogen" ]
                         -- `configure' may generate headers in the build directory
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    "-I" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ LocalBuildInfo -> [Char]
    buildDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    dir
                            | [Char]
    dir <- [[Char]] -> [[Char]]
    forall a. Ord a => [a] -> [a]
    ordNub ((BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    includeDirs)
                            , Bool -> Bool
    not ([Char] -> Bool
    isAbsolute [Char]
    dir)]
                         -- we might also reference headers from the
                         -- packages directory.
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    "-I" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ LocalBuildInfo -> [Char]
    baseDir LocalBuildInfo
    lbi [Char] -> ShowS
    </> [Char]
    dir
                            | [Char]
    dir <- [[Char]] -> [[Char]]
    forall a. Ord a => [a] -> [a]
    ordNub ((BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    includeDirs)
                            , Bool -> Bool
    not ([Char] -> Bool
    isAbsolute [Char]
    dir)]
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    "-I" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    dir | [Char]
    dir <- [[Char]] -> [[Char]]
    forall a. Ord a => [a] -> [a]
    ordNub ((BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    includeDirs)
                                          , [Char] -> Bool
    isAbsolute [Char]
    dir]
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [[Char]
    "-I" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ LocalBuildInfo -> [Char]
    baseDir LocalBuildInfo
    lbi]
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ (BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    cppOptions
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ (BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    ccOptions
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    "-I" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    dir
                            | [Char]
    dir <- [[Char]] -> [[Char]]
    forall a. Ord a => [a] -> [a]
    ordNub [ [Char]
    dir
                                            | InstalledPackageInfo
    dep <- [InstalledPackageInfo]
    deps
                                            , [Char]
    dir <- InstalledPackageInfo -> [[Char]]
    IPI.includeDirs InstalledPackageInfo
    dep ]
                                     -- dedupe include dirs of dependencies
                                     -- to prevent quadratic blow-up
                            ]
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    opt
                            | InstalledPackageInfo
    dep <- [InstalledPackageInfo]
    deps
                            , [Char]
    opt <- InstalledPackageInfo -> [[Char]]
    IPI.ccOptions InstalledPackageInfo
    dep ]

            commonCcArgs :: [[Char]]
    commonCcArgs  = [[Char]]
    commonCppArgs
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ (BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    ccOptions
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    opt
                            | InstalledPackageInfo
    dep <- [InstalledPackageInfo]
    deps
                            , [Char]
    opt <- InstalledPackageInfo -> [[Char]]
    IPI.ccOptions InstalledPackageInfo
    dep ]

            commonLdArgs :: [[Char]]
    commonLdArgs  = [ [Char]
    "-L" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    dir
                            | [Char]
    dir <- [[Char]] -> [[Char]]
    forall a. Ord a => [a] -> [a]
    ordNub ((BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    extraLibDirs) ]
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ (BuildInfo -> [[Char]]) -> [[Char]]
    forall {b}. (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [[Char]]
    ldOptions
                         [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [ [Char]
    "-L" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    dir
                            | [Char]
    dir <- [[Char]] -> [[Char]]
    forall a. Ord a => [a] -> [a]
    ordNub [ [Char]
    dir
                                            | InstalledPackageInfo
    dep <- [InstalledPackageInfo]
    deps
                                            , [Char]
    dir <- InstalledPackageInfo -> [[Char]]
    IPI.libraryDirs InstalledPackageInfo
    dep ]
                            ]
                         --TODO: do we also need dependent packages' ld options?
            makeLdArgs :: [[Char]] -> [[Char]]
    makeLdArgs [[Char]]
    libs = [ [Char]
    "-l"[Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++[Char]
    lib | [Char]
    lib <- [[Char]]
    libs ] [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [[Char]]
    commonLdArgs

            makeProgram :: [[Char]] -> [Char]
    makeProgram [[Char]]
    hdrs = [[Char]] -> [Char]
    unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
    forall a b. (a -> b) -> a -> b
    $
                               [ [Char]
    "#include \""  [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    hdr [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\"" | [Char]
    hdr <- [[Char]]
    hdrs ] [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++
                               [[Char]
    "int main(int argc, char** argv) { return 0; }"]

            collectField :: (BuildInfo -> [b]) -> [b]
    collectField BuildInfo -> [b]
    f = (BuildInfo -> [b]) -> [BuildInfo] -> [b]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap BuildInfo -> [b]
    f [BuildInfo]
    allBi
            allBi :: [BuildInfo]
    allBi = PackageDescription -> ComponentRequestedSpec -> [BuildInfo]
    enabledBuildInfos PackageDescription
    pkg (LocalBuildInfo -> ComponentRequestedSpec
    componentEnabledSpec LocalBuildInfo
    lbi)
            deps :: [InstalledPackageInfo]
    deps = InstalledPackageIndex -> [InstalledPackageInfo]
    forall a. PackageInstalled a => PackageIndex a -> [a]
    PackageIndex.topologicalOrder (LocalBuildInfo -> InstalledPackageIndex
    installedPkgs LocalBuildInfo
    lbi)

            builds :: [Char] -> [[Char]] -> IO Bool
    builds [Char]
    program [[Char]]
    args = do
                [Char]
    tempDir <- IO [Char]
    getTemporaryDirectory
                [Char] -> [Char] -> ([Char] -> Handle -> IO Bool) -> IO Bool
    forall a. [Char] -> [Char] -> ([Char] -> Handle -> IO a) -> IO a
    withTempFile [Char]
    tempDir [Char]
    ".c" (([Char] -> Handle -> IO Bool) -> IO Bool)
    -> ([Char] -> Handle -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \[Char]
    cName Handle
    cHnd ->
                  [Char] -> [Char] -> ([Char] -> Handle -> IO Bool) -> IO Bool
    forall a. [Char] -> [Char] -> ([Char] -> Handle -> IO a) -> IO a
    withTempFile [Char]
    tempDir [Char]
    "" (([Char] -> Handle -> IO Bool) -> IO Bool)
    -> ([Char] -> Handle -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \[Char]
    oNname Handle
    oHnd -> do
                    Handle -> [Char] -> IO ()
    hPutStrLn Handle
    cHnd [Char]
    program
                    Handle -> IO ()
    hClose Handle
    cHnd
                    Handle -> IO ()
    hClose Handle
    oHnd
                    [Char]
    _ <- Verbosity -> Program -> ProgramDb -> [[Char]] -> IO [Char]
    getDbProgramOutput Verbosity
    verbosity
                      Program
    gccProgram (LocalBuildInfo -> ProgramDb
    withPrograms LocalBuildInfo
    lbi) ([Char]
    cName[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[Char]
    "-o"[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[Char]
    oNname[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[[Char]]
    args)
                    Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
               IO Bool -> (IOException -> IO Bool) -> IO Bool
    forall a. IO a -> (IOException -> IO a) -> IO a
    `catchIO`   (\IOException
    _ -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False)
               IO Bool -> (ExitCode -> IO Bool) -> IO Bool
    forall a. IO a -> (ExitCode -> IO a) -> IO a
    `catchExit` (\ExitCode
    _ -> Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False)

            explainErrors :: Maybe (Either [Char] [Char]) -> [[Char]] -> IO ()
    explainErrors Maybe (Either [Char] [Char])
    Nothing [] = () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return () -- should be impossible!
            explainErrors Maybe (Either [Char] [Char])
    _ [[Char]]
    _
               | Maybe ConfiguredProgram -> Bool
    forall a. Maybe a -> Bool
    isNothing (Maybe ConfiguredProgram -> Bool)
    -> (LocalBuildInfo -> Maybe ConfiguredProgram)
    -> LocalBuildInfo
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Program -> ProgramDb -> Maybe ConfiguredProgram
    lookupProgram Program
    gccProgram (ProgramDb -> Maybe ConfiguredProgram)
    -> (LocalBuildInfo -> ProgramDb)
    -> LocalBuildInfo
    -> Maybe ConfiguredProgram
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LocalBuildInfo -> ProgramDb
    withPrograms (LocalBuildInfo -> Bool) -> LocalBuildInfo -> Bool
    forall a b. (a -> b) -> a -> b
    $ LocalBuildInfo
    lbi

                                  = Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [[Char]] -> [Char]
    unlines
                  [ [Char]
    "No working gcc",
                      [Char]
    "This package depends on foreign library but we cannot "
                   [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "find a working C compiler. If you have it in a "
                   [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "non-standard location you can use the --with-gcc "
                   [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "flag to specify it." ]

            explainErrors Maybe (Either [Char] [Char])
    hdr [[Char]]
    libs = Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [[Char]] -> [Char]
    unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
    forall a b. (a -> b) -> a -> b
    $
                 [ if Bool
    plural
                     then [Char]
    "Missing dependencies on foreign libraries:"
                     else [Char]
    "Missing dependency on a foreign library:"
                 | Bool
    missing ]
              [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ case Maybe (Either [Char] [Char])
    hdr of
                   Just (Left [Char]
    h) -> [[Char]
    "* Missing (or bad) header file: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    h ]
                   Maybe (Either [Char] [Char])
    _             -> []
              [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ case [[Char]]
    libs of
                   []    -> []
                   [[Char]
    lib] -> [[Char]
    "* Missing (or bad) C library: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    lib]
                   [[Char]]
    _     -> [[Char]
    "* Missing (or bad) C libraries: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                             [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ", " [[Char]]
    libs]
              [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ [if Bool
    plural then [Char]
    messagePlural else [Char]
    messageSingular | Bool
    missing]
              [[Char]] -> [[Char]] -> [[Char]]
    forall a. [a] -> [a] -> [a]
    ++ case Maybe (Either [Char] [Char])
    hdr of
                   Just (Left  [Char]
    _) -> [ [Char]
    headerCppMessage ]
                   Just (Right [Char]
    h) -> [ (if Bool
    missing then [Char]
    "* " else [Char]
    "")
                                       [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "Bad header file: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    h
                                     , [Char]
    headerCcMessage ]
                   Maybe (Either [Char] [Char])
    _              -> []

              where
                plural :: Bool
    plural  = [[Char]] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [[Char]]
    libs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    2
                -- Is there something missing? (as opposed to broken)
                missing :: Bool
    missing = Bool -> Bool
    not ([[Char]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [[Char]]
    libs)
                       Bool -> Bool -> Bool
    || case Maybe (Either [Char] [Char])
    hdr of Just (Left [Char]
    _) -> Bool
    True; Maybe (Either [Char] [Char])
    _ -> Bool
    False

            messageSingular :: [Char]
    messageSingular =
                 [Char]
    "This problem can usually be solved by installing the system "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "package that provides this library (you may need the "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\"-dev\" version). If the library is already installed "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "but in a non-standard location then you can use the flags "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "--extra-include-dirs= and --extra-lib-dirs= to specify "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "where it is."
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "If the library file does exist, it may contain errors that "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "are caught by the C compiler at the preprocessing stage. "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "In this case you can re-run configure with the verbosity "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "flag -v3 to see the error messages."
            messagePlural :: [Char]
    messagePlural =
                 [Char]
    "This problem can usually be solved by installing the system "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "packages that provide these libraries (you may need the "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\"-dev\" versions). If the libraries are already installed "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "but in a non-standard location then you can use the flags "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "--extra-include-dirs= and --extra-lib-dirs= to specify "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "where they are."
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "If the library files do exist, it may contain errors that "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "are caught by the C compiler at the preprocessing stage. "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "In this case you can re-run configure with the verbosity "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "flag -v3 to see the error messages."
            headerCppMessage :: [Char]
    headerCppMessage =
                 [Char]
    "If the header file does exist, it may contain errors that "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "are caught by the C compiler at the preprocessing stage. "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "In this case you can re-run configure with the verbosity "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "flag -v3 to see the error messages."
            headerCcMessage :: [Char]
    headerCcMessage =
                 [Char]
    "The header file contains a compile error. "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "You can re-run configure with the verbosity flag "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "-v3 to see the error messages from the C compiler."

    -- | Output package check warnings and errors. Exit if any errors.
    checkPackageProblems :: Verbosity
                         -> FilePath
                            -- ^ Path to the @.cabal@ file's directory
                         -> GenericPackageDescription
                         -> PackageDescription
                         -> IO ()
    checkPackageProblems :: Verbosity
    -> [Char]
    -> GenericPackageDescription
    -> PackageDescription
    -> IO ()
    checkPackageProblems Verbosity
    verbosity [Char]
    dir GenericPackageDescription
    gpkg PackageDescription
    pkg = do
      [PackageCheck]
    ioChecks      <- Verbosity -> PackageDescription -> [Char] -> IO [PackageCheck]
    checkPackageFiles Verbosity
    verbosity PackageDescription
    pkg [Char]
    dir
      let pureChecks :: [PackageCheck]
    pureChecks = GenericPackageDescription
    -> Maybe PackageDescription -> [PackageCheck]
    checkPackage GenericPackageDescription
    gpkg (PackageDescription -> Maybe PackageDescription
    forall a. a -> Maybe a
    Just PackageDescription
    pkg)
          errors :: [[Char]]
    errors   = [ [Char]
    e | PackageBuildImpossible [Char]
    e <- [PackageCheck]
    pureChecks [PackageCheck] -> [PackageCheck] -> [PackageCheck]
    forall a. [a] -> [a] -> [a]
    ++ [PackageCheck]
    ioChecks ]
          warnings :: [[Char]]
    warnings = [ [Char]
    w | PackageBuildWarning    [Char]
    w <- [PackageCheck]
    pureChecks [PackageCheck] -> [PackageCheck] -> [PackageCheck]
    forall a. [a] -> [a] -> [a]
    ++ [PackageCheck]
    ioChecks ]
      if [[Char]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [[Char]]
    errors
        then ([Char] -> IO ()) -> [[Char]] -> IO ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    (a -> f b) -> t a -> f ()
    traverse_ (Verbosity -> [Char] -> IO ()
    warn Verbosity
    verbosity) [[Char]]
    warnings
        else Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    "\n\n" [[Char]]
    errors)

    -- | Preform checks if a relocatable build is allowed
    checkRelocatable :: Verbosity
                     -> PackageDescription
                     -> LocalBuildInfo
                     -> IO ()
    checkRelocatable :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
    checkRelocatable Verbosity
    verbosity PackageDescription
    pkg LocalBuildInfo
    lbi
        = [IO ()] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a.
    (Foldable t, Monad m) =>
    t (m a) -> m ()
    sequence_ [ IO ()
    checkOS
                    , IO ()
    checkCompiler
                    , IO ()
    packagePrefixRelative
                    , IO ()
    depsPrefixRelative
                    ]
      where
        -- Check if the OS support relocatable builds.
        --
        -- If you add new OS' to this list, and your OS supports dynamic libraries
        -- and RPATH, make sure you add your OS to RPATH-support list of:
        -- Distribution.Simple.GHC.getRPaths
        checkOS :: IO ()
    checkOS
            = Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (OS
    os OS -> [OS] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [ OS
    OSX, OS
    Linux ])
            (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Operating system: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ OS -> [Char]
    forall a. Pretty a => a -> [Char]
    prettyShow OS
    os [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                    [Char]
    ", does not support relocatable builds"
          where
            (Platform Arch
    _ OS
    os) = LocalBuildInfo -> Platform
    hostPlatform LocalBuildInfo
    lbi

        -- Check if the Compiler support relocatable builds
        checkCompiler :: IO ()
    checkCompiler
            = Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp CompilerFlavor -> [CompilerFlavor] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [ CompilerFlavor
    GHC ])
            (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Compiler: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Compiler -> [Char]
    forall a. Show a => a -> [Char]
    show Compiler
    comp [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                    [Char]
    ", does not support relocatable builds"
          where
            comp :: Compiler
    comp = LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi

        -- Check if all the install dirs are relative to same prefix
        packagePrefixRelative :: IO ()
    packagePrefixRelative
            = Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (InstallDirs [Char] -> Bool
    relativeInstallDirs InstallDirs [Char]
    installDirs)
            (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Installation directories are not prefix_relative:\n" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                    InstallDirs [Char] -> [Char]
    forall a. Show a => a -> [Char]
    show InstallDirs [Char]
    installDirs
          where
            -- NB: should be good enough to check this against the default
            -- component ID, but if we wanted to be strictly correct we'd
            -- check for each ComponentId.
            installDirs :: InstallDirs [Char]
    installDirs = PackageDescription
    -> LocalBuildInfo -> CopyDest -> InstallDirs [Char]
    absoluteInstallDirs PackageDescription
    pkg LocalBuildInfo
    lbi CopyDest
    NoCopyDest
            p :: [Char]
    p           = InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    installDirs
            relativeInstallDirs :: InstallDirs [Char] -> Bool
    relativeInstallDirs (InstallDirs {[Char]
    mandir :: forall dir. InstallDirs dir -> dir
    libsubdir :: forall dir. InstallDirs dir -> dir
    libexecsubdir :: forall dir. InstallDirs dir -> dir
    includedir :: forall dir. InstallDirs dir -> dir
    htmldir :: forall dir. InstallDirs dir -> dir
    haddockdir :: forall dir. InstallDirs dir -> dir
    flibdir :: forall dir. InstallDirs dir -> dir
    datasubdir :: forall dir. InstallDirs dir -> dir
    sysconfdir :: [Char]
    haddockdir :: [Char]
    htmldir :: [Char]
    mandir :: [Char]
    docdir :: [Char]
    datasubdir :: [Char]
    datadir :: [Char]
    includedir :: [Char]
    libexecsubdir :: [Char]
    libexecdir :: [Char]
    flibdir :: [Char]
    dynlibdir :: [Char]
    libsubdir :: [Char]
    libdir :: [Char]
    bindir :: [Char]
    prefix :: [Char]
    sysconfdir :: forall dir. InstallDirs dir -> dir
    docdir :: forall dir. InstallDirs dir -> dir
    datadir :: forall dir. InstallDirs dir -> dir
    libexecdir :: forall dir. InstallDirs dir -> dir
    dynlibdir :: forall dir. InstallDirs dir -> dir
    libdir :: forall dir. InstallDirs dir -> dir
    bindir :: forall dir. InstallDirs dir -> dir
    prefix :: forall dir. InstallDirs dir -> dir
    ..}) =
              (Maybe [Char] -> Bool) -> [Maybe [Char]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Maybe [Char] -> Bool
    forall a. Maybe a -> Bool
    isJust
                  (([Char] -> Maybe [Char]) -> [[Char]] -> [Maybe [Char]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ([Char] -> [Char] -> Maybe [Char]
    forall a. Eq a => [a] -> [a] -> Maybe [a]
    stripPrefix [Char]
    p)
                        [ [Char]
    bindir, [Char]
    libdir, [Char]
    dynlibdir, [Char]
    libexecdir, [Char]
    includedir, [Char]
    datadir
                        , [Char]
    docdir, [Char]
    mandir, [Char]
    htmldir, [Char]
    haddockdir, [Char]
    sysconfdir] )

        -- Check if the library dirs of the dependencies that are in the package
        -- database to which the package is installed are relative to the
        -- prefix of the package
        depsPrefixRelative :: IO ()
    depsPrefixRelative = do
            [Char]
    pkgr <- Verbosity -> LocalBuildInfo -> PackageDB -> IO [Char]
    GHC.pkgRoot Verbosity
    verbosity LocalBuildInfo
    lbi (PackageDBStack -> PackageDB
    registrationPackageDB (LocalBuildInfo -> PackageDBStack
    withPackageDB LocalBuildInfo
    lbi))
            (InstalledPackageInfo -> IO ()) -> [InstalledPackageInfo] -> IO ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    (a -> f b) -> t a -> f ()
    traverse_ ([Char] -> InstalledPackageInfo -> IO ()
    doCheck [Char]
    pkgr) [InstalledPackageInfo]
    ipkgs
          where
            doCheck :: [Char] -> InstalledPackageInfo -> IO ()
    doCheck [Char]
    pkgr InstalledPackageInfo
    ipkg
              | Bool -> ([Char] -> Bool) -> Maybe [Char] -> Bool
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Bool
    False ([Char] -> [Char] -> Bool
    forall a. Eq a => a -> a -> Bool
    == [Char]
    pkgr) (InstalledPackageInfo -> Maybe [Char]
    IPI.pkgRoot InstalledPackageInfo
    ipkg)
              = [[Char]] -> ([Char] -> IO ()) -> IO ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    t a -> (a -> f b) -> f ()
    for_ (InstalledPackageInfo -> [[Char]]
    IPI.libraryDirs InstalledPackageInfo
    ipkg) (([Char] -> IO ()) -> IO ()) -> ([Char] -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \[Char]
    libdir -> do
                  -- When @prefix@ is not under @pkgroot@,
                  -- @shortRelativePath prefix pkgroot@ will return a path with
                  -- @..@s and following check will fail without @canonicalizePath@.
                  [Char]
    canonicalized <- [Char] -> IO [Char]
    canonicalizePath [Char]
    libdir
                  Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ([Char]
    p [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` [Char]
    canonicalized) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                    Verbosity -> [Char] -> IO ()
    forall a. Verbosity -> [Char] -> IO a
    die' Verbosity
    verbosity ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ ShowS
    forall a. Show a => a -> [Char]
    msg [Char]
    libdir
              | Bool
    otherwise
              = () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            -- NB: should be good enough to check this against the default
            -- component ID, but if we wanted to be strictly correct we'd
            -- check for each ComponentId.
            installDirs :: InstallDirs [Char]
    installDirs   = PackageDescription
    -> LocalBuildInfo -> CopyDest -> InstallDirs [Char]
    absoluteInstallDirs PackageDescription
    pkg LocalBuildInfo
    lbi CopyDest
    NoCopyDest
            p :: [Char]
    p             = InstallDirs [Char] -> [Char]
    forall dir. InstallDirs dir -> dir
    prefix InstallDirs [Char]
    installDirs
            ipkgs :: [InstalledPackageInfo]
    ipkgs         = InstalledPackageIndex -> [InstalledPackageInfo]
    forall a. PackageIndex a -> [a]
    PackageIndex.allPackages (LocalBuildInfo -> InstalledPackageIndex
    installedPkgs LocalBuildInfo
    lbi)
            msg :: a -> [Char]
    msg a
    l         = [Char]
    "Library directory of a dependency: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    l [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                            [Char]
    "\nis not relative to the installation prefix:\n" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                            ShowS
    forall a. Show a => a -> [Char]
    show [Char]
    p

    -- -----------------------------------------------------------------------------
    -- Testing foreign library requirements

    unsupportedForeignLibs :: Compiler -> Platform -> [ForeignLib] -> [String]
    unsupportedForeignLibs :: Compiler -> Platform -> [ForeignLib] -> [[Char]]
    unsupportedForeignLibs Compiler
    comp Platform
    platform =
        (ForeignLib -> Maybe [Char]) -> [ForeignLib] -> [[Char]]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (Compiler -> Platform -> ForeignLib -> Maybe [Char]
    checkForeignLibSupported Compiler
    comp Platform
    platform)

    checkForeignLibSupported :: Compiler -> Platform -> ForeignLib -> Maybe String
    checkForeignLibSupported :: Compiler -> Platform -> ForeignLib -> Maybe [Char]
    checkForeignLibSupported Compiler
    comp Platform
    platform ForeignLib
    flib = CompilerFlavor -> Maybe [Char]
    go (Compiler -> CompilerFlavor
    compilerFlavor Compiler
    comp)
      where
        go :: CompilerFlavor -> Maybe String
        go :: CompilerFlavor -> Maybe [Char]
    go CompilerFlavor
    GHC
          | Compiler -> Version
    compilerVersion Compiler
    comp Version -> Version -> Bool
    forall a. Ord a => a -> a -> Bool
    < [Int] -> Version
    mkVersion [Int
    7,Int
    8] = [[Char]] -> Maybe [Char]
    unsupported [
            [Char]
    "Building foreign libraires is only supported with GHC >= 7.8"
          ]
          | Bool
    otherwise = Platform -> Maybe [Char]
    goGhcPlatform Platform
    platform
        go CompilerFlavor
    _   = [[Char]] -> Maybe [Char]
    unsupported [
            [Char]
    "Building foreign libraries is currently only supported with ghc"
          ]

        goGhcPlatform :: Platform -> Maybe String
        goGhcPlatform :: Platform -> Maybe [Char]
    goGhcPlatform (Platform Arch
    X86_64 OS
    OSX    ) = ForeignLibType -> Maybe [Char]
    goGhcOsx     (ForeignLib -> ForeignLibType
    foreignLibType ForeignLib
    flib)
        goGhcPlatform (Platform Arch
    _      OS
    Linux  ) = ForeignLibType -> Maybe [Char]
    goGhcLinux   (ForeignLib -> ForeignLibType
    foreignLibType ForeignLib
    flib)
        goGhcPlatform (Platform Arch
    I386   OS
    Windows) = ForeignLibType -> Maybe [Char]
    goGhcWindows (ForeignLib -> ForeignLibType
    foreignLibType ForeignLib
    flib)
        goGhcPlatform (Platform Arch
    X86_64 OS
    Windows) = ForeignLibType -> Maybe [Char]
    goGhcWindows (ForeignLib -> ForeignLibType
    foreignLibType ForeignLib
    flib)
        goGhcPlatform Platform
    _ = [[Char]] -> Maybe [Char]
    unsupported [
            [Char]
    "Building foreign libraries is currently only supported on OSX, "
          , [Char]
    "Linux and Windows"
          ]

        goGhcOsx :: ForeignLibType -> Maybe String
        goGhcOsx :: ForeignLibType -> Maybe [Char]
    goGhcOsx ForeignLibType
    ForeignLibNativeShared
          | Bool -> Bool
    not ([[Char]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ForeignLib -> [[Char]]
    foreignLibModDefFile ForeignLib
    flib)) = [[Char]] -> Maybe [Char]
    unsupported [
                [Char]
    "Module definition file not supported on OSX"
              ]
          | Bool -> Bool
    not (Maybe LibVersionInfo -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ForeignLib -> Maybe LibVersionInfo
    foreignLibVersionInfo ForeignLib
    flib)) = [[Char]] -> Maybe [Char]
    unsupported [
                [Char]
    "Foreign library versioning not currently supported on OSX"
              ]
          | Bool
    otherwise =
              Maybe [Char]
    forall a. Maybe a
    Nothing
        goGhcOsx ForeignLibType
    _ = [[Char]] -> Maybe [Char]
    unsupported [
            [Char]
    "We can currently only build shared foreign libraries on OSX"
          ]

        goGhcLinux :: ForeignLibType -> Maybe String
        goGhcLinux :: ForeignLibType -> Maybe [Char]
    goGhcLinux ForeignLibType
    ForeignLibNativeShared
          | Bool -> Bool
    not ([[Char]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ForeignLib -> [[Char]]
    foreignLibModDefFile ForeignLib
    flib)) = [[Char]] -> Maybe [Char]
    unsupported [
                [Char]
    "Module definition file not supported on Linux"
              ]
          | Bool -> Bool
    not (Maybe LibVersionInfo -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ForeignLib -> Maybe LibVersionInfo
    foreignLibVersionInfo ForeignLib
    flib))
              Bool -> Bool -> Bool
    && Bool -> Bool
    not (Maybe Version -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ForeignLib -> Maybe Version
    foreignLibVersionLinux ForeignLib
    flib)) = [[Char]] -> Maybe [Char]
    unsupported [
                [Char]
    "You must not specify both lib-version-info and lib-version-linux"
              ]
          | Bool
    otherwise =
              Maybe [Char]
    forall a. Maybe a
    Nothing
        goGhcLinux ForeignLibType
    _ = [[Char]] -> Maybe [Char]
    unsupported [
            [Char]
    "We can currently only build shared foreign libraries on Linux"
          ]

        goGhcWindows :: ForeignLibType -> Maybe String
        goGhcWindows :: ForeignLibType -> Maybe [Char]
    goGhcWindows ForeignLibType
    ForeignLibNativeShared
          | Bool -> Bool
    not Bool
    standalone = [[Char]] -> Maybe [Char]
    unsupported [
                [Char]
    "We can currently only build standalone libraries on Windows. Use\n"
              , [Char]
    "  if os(Windows)\n"
              , [Char]
    "    options: standalone\n"
              , [Char]
    "in your foreign-library stanza."
              ]
          | Bool -> Bool
    not (Maybe LibVersionInfo -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ForeignLib -> Maybe LibVersionInfo
    foreignLibVersionInfo ForeignLib
    flib)) = [[Char]] -> Maybe [Char]
    unsupported [
                [Char]
    "Foreign library versioning not currently supported on Windows.\n"
              , [Char]
    "You can specify module definition files in the mod-def-file field."
              ]
          | Bool
    otherwise =
             Maybe [Char]
    forall a. Maybe a
    Nothing
        goGhcWindows ForeignLibType
    _ = [[Char]] -> Maybe [Char]
    unsupported [
            [Char]
    "We can currently only build shared foreign libraries on Windows"
          ]

        standalone :: Bool
        standalone :: Bool
    standalone = ForeignLibOption
    ForeignLibStandalone ForeignLibOption -> [ForeignLibOption] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` ForeignLib -> [ForeignLibOption]
    foreignLibOptions ForeignLib
    flib

        unsupported :: [String] -> Maybe String
        unsupported :: [[Char]] -> Maybe [Char]
    unsupported = [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just ([Char] -> Maybe [Char])
    -> ([[Char]] -> [Char]) -> [[Char]] -> Maybe [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Char]] -> [Char]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat