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

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

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

    initialBuildSteps,
    createInternalPackageDB,
    componentInitialBuildSteps,
    writeAutogenFiles,
  ) where

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

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

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

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

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

import Distribution.Simple.Setup
import Distribution.Simple.BuildTarget
import Distribution.Simple.BuildToolDepends
import Distribution.Simple.PreProcess
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program.Types
import Distribution.Simple.Program.Db
import Distribution.Simple.ShowBuildInfo
import Distribution.Simple.BuildPaths
import Distribution.Simple.Configure
import Distribution.Simple.Register
import Distribution.Simple.Test.LibV09
import Distribution.Simple.Utils
import Distribution.Simple.Utils.Json

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

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

import Control.Monad
import qualified Data.Set as Set
import System.FilePath ( (</>), (<.>), takeDirectory )
import System.Directory ( getCurrentDirectory )

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

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

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

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

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


showBuildInfo :: PackageDescription  -- ^ Mostly information from the .cabal file
  -> LocalBuildInfo      -- ^ Configuration information
  -> BuildFlags          -- ^ Flags that the user passed to build
  -> IO String
showBuildInfo :: PackageDescription -> LocalBuildInfo -> BuildFlags -> IO String
showBuildInfo PackageDescription
pkg_descr LocalBuildInfo
lbi BuildFlags
flags = do
  let verbosity :: Verbosity
verbosity = Flag Verbosity -> Verbosity
forall a. WithCallStack (Flag a -> a)
fromFlag (BuildFlags -> Flag Verbosity
buildVerbosity BuildFlags
flags)
  [TargetInfo]
targets <- Verbosity
-> PackageDescription
-> LocalBuildInfo
-> [String]
-> IO [TargetInfo]
readTargetInfos Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi (BuildFlags -> [String]
buildArgs BuildFlags
flags)
  let targetsToBuild :: [TargetInfo]
targetsToBuild = PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi ((TargetInfo -> UnitId) -> [TargetInfo] -> [UnitId]
forall a b. (a -> b) -> [a] -> [b]
map TargetInfo -> UnitId
forall a. IsNode a => a -> Key a
nodeKey [TargetInfo]
targets)
      doc :: Json
doc = PackageDescription
-> LocalBuildInfo -> BuildFlags -> [TargetInfo] -> Json
mkBuildInfo PackageDescription
pkg_descr LocalBuildInfo
lbi BuildFlags
flags [TargetInfo]
targetsToBuild
  String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ Json -> String -> String
renderJson Json
doc String
""


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

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

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

  let lbiForComponent :: Component -> LocalBuildInfo -> LocalBuildInfo
lbiForComponent Component
comp LocalBuildInfo
lbi' =
        LocalBuildInfo
lbi' {
          withPackageDB :: PackageDBStack
withPackageDB = LocalBuildInfo -> PackageDBStack
withPackageDB LocalBuildInfo
lbi PackageDBStack -> PackageDBStack -> PackageDBStack
forall a. [a] -> [a] -> [a]
++ [PackageDB
internalPackageDB],
          withPrograms :: ProgramDb
withPrograms  = PackageDescription
-> LocalBuildInfo -> BuildInfo -> ProgramDb -> ProgramDb
addInternalBuildTools PackageDescription
pkg_descr LocalBuildInfo
lbi'
                            (Component -> BuildInfo
componentBuildInfo Component
comp) (LocalBuildInfo -> ProgramDb
withPrograms LocalBuildInfo
lbi')
        }

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

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


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

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

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

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

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

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

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


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


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


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


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


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


-- | Add extra C sources generated by preprocessing to build
-- information.
addExtraCSources :: BuildInfo -> [FilePath] -> BuildInfo
addExtraCSources :: BuildInfo -> [String] -> BuildInfo
addExtraCSources BuildInfo
bi [String]
extras = BuildInfo
bi { cSources :: [String]
cSources = [String]
new }
  where new :: [String]
new = Set String -> [String]
forall a. Set a -> [a]
Set.toList (Set String -> [String]) -> Set String -> [String]
forall a b. (a -> b) -> a -> b
$ Set String
old Set String -> Set String -> Set String
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` Set String
exs
        old :: Set String
old = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList ([String] -> Set String) -> [String] -> Set String
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [String]
cSources BuildInfo
bi
        exs :: Set String
exs = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [String]
extras


-- | Add extra C++ sources generated by preprocessing to build
-- information.
addExtraCxxSources :: BuildInfo -> [FilePath] -> BuildInfo
addExtraCxxSources :: BuildInfo -> [String] -> BuildInfo
addExtraCxxSources BuildInfo
bi [String]
extras = BuildInfo
bi { cxxSources :: [String]
cxxSources = [String]
new }
  where new :: [String]
new = Set String -> [String]
forall a. Set a -> [a]
Set.toList (Set String -> [String]) -> Set String -> [String]
forall a b. (a -> b) -> a -> b
$ Set String
old Set String -> Set String -> Set String
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` Set String
exs
        old :: Set String
old = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList ([String] -> Set String) -> [String] -> Set String
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [String]
cxxSources BuildInfo
bi
        exs :: Set String
exs = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [String]
extras


-- | Add extra C-- sources generated by preprocessing to build
-- information.
addExtraCmmSources :: BuildInfo -> [FilePath] -> BuildInfo
addExtraCmmSources :: BuildInfo -> [String] -> BuildInfo
addExtraCmmSources BuildInfo
bi [String]
extras = BuildInfo
bi { cmmSources :: [String]
cmmSources = [String]
new }
  where new :: [String]
new = Set String -> [String]
forall a. Set a -> [a]
Set.toList (Set String -> [String]) -> Set String -> [String]
forall a b. (a -> b) -> a -> b
$ Set String
old Set String -> Set String -> Set String
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` Set String
exs
        old :: Set String
old = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList ([String] -> Set String) -> [String] -> Set String
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [String]
cmmSources BuildInfo
bi
        exs :: Set String
exs = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [String]
extras


-- | Add extra ASM sources generated by preprocessing to build
-- information.
addExtraAsmSources :: BuildInfo -> [FilePath] -> BuildInfo
addExtraAsmSources :: BuildInfo -> [String] -> BuildInfo
addExtraAsmSources BuildInfo
bi [String]
extras = BuildInfo
bi { asmSources :: [String]
asmSources = [String]
new }
  where new :: [String]
new = Set String -> [String]
forall a. Set a -> [a]
Set.toList (Set String -> [String]) -> Set String -> [String]
forall a b. (a -> b) -> a -> b
$ Set String
old Set String -> Set String -> Set String
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` Set String
exs
        old :: Set String
old = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList ([String] -> Set String) -> [String] -> Set String
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [String]
asmSources BuildInfo
bi
        exs :: Set String
exs = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [String]
extras


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

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

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


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


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


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


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


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

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

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

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

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


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

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


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

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

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

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

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

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

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

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

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

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

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

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

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