module Distribution.Simple.GHC.Build where
import Distribution.Compat.Prelude
import Prelude ()
import Control.Monad.IO.Class
import qualified Data.Set as Set
import Distribution.PackageDescription as PD hiding (buildInfo)
import Distribution.Simple.Build.Inputs
import Distribution.Simple.Flag (Flag)
import Distribution.Simple.GHC.Build.ExtraSources
import Distribution.Simple.GHC.Build.Link
import Distribution.Simple.GHC.Build.Modules
import Distribution.Simple.GHC.Build.Utils (withDynFLib)
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program
import Distribution.Simple.Utils
import Distribution.Types.ComponentLocalBuildInfo (componentIsIndefinite)
import Distribution.Types.ParStrat
import Distribution.Utils.NubList (fromNubListR)
import System.Directory hiding (exeExtension)
import System.FilePath
build
:: Flag ParStrat
-> PackageDescription
-> PreBuildComponentInputs
-> IO ()
build :: Flag ParStrat
-> PackageDescription -> PreBuildComponentInputs -> IO ()
build Flag ParStrat
numJobs PackageDescription
pkg_descr PreBuildComponentInputs
pbci = do
let
verbosity :: Verbosity
verbosity = PreBuildComponentInputs -> Verbosity
buildVerbosity PreBuildComponentInputs
pbci
component :: Component
component = PreBuildComponentInputs -> Component
buildComponent PreBuildComponentInputs
pbci
isLib :: Bool
isLib = PreBuildComponentInputs -> Bool
buildIsLib PreBuildComponentInputs
pbci
lbi :: LocalBuildInfo
lbi = PreBuildComponentInputs -> LocalBuildInfo
localBuildInfo PreBuildComponentInputs
pbci
clbi :: ComponentLocalBuildInfo
clbi = PreBuildComponentInputs -> ComponentLocalBuildInfo
buildCLBI PreBuildComponentInputs
pbci
let targetDir_absolute :: FilePath
targetDir_absolute = LocalBuildInfo -> ComponentLocalBuildInfo -> FilePath
componentBuildDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
buildTargetDir_absolute :: FilePath
buildTargetDir_absolute
| Bool
isLib = FilePath
targetDir_absolute
| FilePath
targetDirName : [FilePath]
_ <- [FilePath] -> [FilePath]
forall a. [a] -> [a]
reverse ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ FilePath -> [FilePath]
splitDirectories FilePath
targetDir_absolute =
FilePath
targetDir_absolute FilePath -> FilePath -> FilePath
</> (FilePath
targetDirName FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
"-tmp")
| Bool
otherwise = FilePath -> FilePath
forall a. HasCallStack => FilePath -> a
error FilePath
"GHC.build: targetDir is empty"
IO () -> IO ()
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Verbosity -> Bool -> FilePath -> IO ()
createDirectoryIfMissingVerbose Verbosity
verbosity Bool
True FilePath
targetDir_absolute
Verbosity -> Bool -> FilePath -> IO ()
createDirectoryIfMissingVerbose Verbosity
verbosity Bool
True FilePath
buildTargetDir_absolute
_targetDir <- IO FilePath -> IO FilePath
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO FilePath -> IO FilePath) -> IO FilePath -> IO FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> IO FilePath
makeRelativeToCurrentDirectory FilePath
targetDir_absolute
buildTargetDir <-
if isLib
then liftIO $ makeRelativeToCurrentDirectory buildTargetDir_absolute
else return buildTargetDir_absolute
(ghcProg, _) <- liftIO $ requireProgram verbosity ghcProgram (withPrograms lbi)
let
wantVanilla = if Bool
isLib then LocalBuildInfo -> Bool
withVanillaLib LocalBuildInfo
lbi else Bool
False
wantStatic = if Bool
isLib then LocalBuildInfo -> Bool
withStaticLib LocalBuildInfo
lbi else Bool -> Bool
not (Bool
wantDynamic Bool -> Bool -> Bool
|| Bool
wantProf)
wantDynamic = case Component
component of
CLib{} -> LocalBuildInfo -> Bool
withSharedLib LocalBuildInfo
lbi
CFLib ForeignLib
flib -> ForeignLib -> Bool
withDynFLib ForeignLib
flib
CExe{} -> LocalBuildInfo -> Bool
withDynExe LocalBuildInfo
lbi
CTest{} -> LocalBuildInfo -> Bool
withDynExe LocalBuildInfo
lbi
CBench{} -> LocalBuildInfo -> Bool
withDynExe LocalBuildInfo
lbi
wantProf = if Bool
isLib then LocalBuildInfo -> Bool
withProfLib LocalBuildInfo
lbi else LocalBuildInfo -> Bool
withProfExe LocalBuildInfo
lbi
wantedWays =
[BuildWay] -> Set BuildWay
forall a. Ord a => [a] -> Set a
Set.fromList ([BuildWay] -> Set BuildWay) -> [BuildWay] -> Set BuildWay
forall a b. (a -> b) -> a -> b
$
(if Bool
isLib then [BuildWay] -> [BuildWay]
forall a. a -> a
id else Int -> [BuildWay] -> [BuildWay]
forall a. Int -> [a] -> [a]
take Int
1) ([BuildWay] -> [BuildWay]) -> [BuildWay] -> [BuildWay]
forall a b. (a -> b) -> a -> b
$
[BuildWay
ProfWay | Bool
wantProf]
[BuildWay] -> [BuildWay] -> [BuildWay]
forall a. Semigroup a => a -> a -> a
<> [BuildWay
DynWay | Bool
wantDynamic Bool -> Bool -> Bool
&& Bool -> Bool
not (ComponentLocalBuildInfo -> Bool
componentIsIndefinite ComponentLocalBuildInfo
clbi)]
[BuildWay] -> [BuildWay] -> [BuildWay]
forall a. Semigroup a => a -> a -> a
<> [BuildWay
StaticWay | Bool
wantStatic Bool -> Bool -> Bool
|| Bool
wantVanilla Bool -> Bool -> Bool
|| Bool -> Bool
not (Bool
wantDynamic Bool -> Bool -> Bool
|| Bool
wantProf)]
liftIO $ info verbosity ("Wanted build ways: " ++ show (Set.toList wantedWays))
buildOpts <- buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir_absolute wantedWays pbci
extraSources <- buildAllExtraSources ghcProg buildTargetDir pbci
linkOrLoadComponent ghcProg pkg_descr (fromNubListR extraSources) (buildTargetDir, targetDir_absolute) (wantedWays, buildOpts) pbci