module Distribution.Simple.Build (
build,
initialBuildSteps,
writeAutogenFiles,
) where
import qualified Distribution.Simple.GHC as GHC
import qualified Distribution.Simple.JHC as JHC
import qualified Distribution.Simple.LHC as LHC
import qualified Distribution.Simple.NHC as NHC
import qualified Distribution.Simple.Hugs as Hugs
import qualified Distribution.Simple.UHC as UHC
import qualified Distribution.Simple.Build.Macros as Build.Macros
import qualified Distribution.Simple.Build.PathsModule as Build.PathsModule
import Distribution.Package
( Package(..), PackageName(..), PackageIdentifier(..)
, thisPackageVersion )
import Distribution.Simple.Compiler
( CompilerFlavor(..), compilerFlavor, PackageDB(..) )
import Distribution.PackageDescription
( PackageDescription(..), BuildInfo(..), Library(..), Executable(..)
, TestSuite(..), TestSuiteInterface(..), Component(..) )
import qualified Distribution.InstalledPackageInfo as IPI
import qualified Distribution.ModuleName as ModuleName
import Distribution.Simple.Setup
( BuildFlags(..), fromFlag )
import Distribution.Simple.PreProcess
( preprocessComponent, PPSuffixHandler )
import Distribution.Simple.LocalBuildInfo
( LocalBuildInfo(compiler, buildDir, withPackageDB)
, ComponentLocalBuildInfo(..), withComponentsLBI
, inplacePackageId )
import Distribution.Simple.BuildPaths
( autogenModulesDir, autogenModuleName, cppHeaderName )
import Distribution.Simple.Register
( registerPackage, inplaceInstalledPackageInfo )
import Distribution.Simple.Test ( stubFilePath, stubName )
import Distribution.Simple.Utils
( createDirectoryIfMissingVerbose, rewriteFile
, die, info, setupMessage )
import Distribution.Verbosity
( Verbosity )
import Distribution.Text
( display )
import Data.Maybe
( maybeToList )
import Control.Monad
( unless )
import System.FilePath
( (</>), (<.>) )
import System.Directory
( getCurrentDirectory )
build :: PackageDescription
-> LocalBuildInfo
-> BuildFlags
-> [ PPSuffixHandler ]
-> IO ()
build pkg_descr lbi flags suffixes = do
let distPref = fromFlag :: Flag a -> afromFlag (buildDistPref :: BuildFlags -> Flag FilePathbuildDistPref flags :: BuildFlagsflags)
verbosity = fromFlag :: Flag a -> afromFlag (buildVerbosity :: BuildFlags -> Flag VerbositybuildVerbosity flags :: BuildFlagsflags)
initialBuildSteps ::
FilePath
-> PackageDescription
-> LocalBuildInfo
-> Verbosity
-> IO ()initialBuildSteps distPref :: FilePathdistPref pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi verbosity :: Verbosityverbosity
setupMessage :: Verbosity -> String -> PackageIdentifier -> IO ()setupMessage verbosity :: Verbosityverbosity "Building" (packageId :: Package pkg => pkg -> PackageIdentifierpackageId pkg_descr :: PackageDescriptionpkg_descr)
internalPackageDB <- createInternalPackageDB :: FilePath -> IO PackageDBcreateInternalPackageDB distPref :: FilePathdistPref
let pre c = preprocessComponent ::
PackageDescription
-> Component
-> LocalBuildInfo
-> Bool
-> Verbosity
-> [PPSuffixHandler]
-> IO ()preprocessComponent pkg_descr :: PackageDescriptionpkg_descr c :: Componentc lbi :: LocalBuildInfolbi False :: BoolFalse verbosity :: Verbosityverbosity suffixes :: [PPSuffixHandler]suffixes
lbi' = lbi :: LocalBuildInfolbi {withPackageDB = withPackageDB :: LocalBuildInfo -> PackageDBStackwithPackageDB lbi :: LocalBuildInfolbi (++) :: [a] -> [a] -> [a]++ [internalPackageDB :: PackageDBinternalPackageDB]}
withComponentsLBI ::
LocalBuildInfo
-> (Component -> ComponentLocalBuildInfo -> IO ())
-> IO ()withComponentsLBI lbi :: LocalBuildInfolbi ($) :: (a -> b) -> a -> b$ \comp clbi -> do
pre :: Component -> IO ()pre comp :: Componentcomp
case comp :: Componentcomp of
CLib lib -> do
info :: Verbosity -> String -> IO ()info verbosity :: Verbosityverbosity "Building library..."
buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()buildLib verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
pwd <- getCurrentDirectory :: IO FilePathgetCurrentDirectory
let installedPkgInfo =
(inplaceInstalledPackageInfo ::
FilePath
-> FilePath
-> PackageDescription
-> Library
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> InstalledPackageInfoinplaceInstalledPackageInfo pwd :: FilePathpwd distPref :: FilePathdistPref pkg_descr :: PackageDescriptionpkg_descr lib :: Librarylib lbi :: LocalBuildInfolbi clbi :: ComponentLocalBuildInfoclbi) {
IPI.installedPackageId = inplacePackageId :: PackageId -> InstalledPackageIdinplacePackageId (packageId :: Package pkg => pkg -> PackageIdentifierpackageId installedPkgInfo :: InstalledPackageInfo_ ModuleNameinstalledPkgInfo)
}
registerPackage ::
Verbosity
-> InstalledPackageInfo
-> PackageDescription
-> LocalBuildInfo
-> Bool
-> PackageDBStack
-> IO ()registerPackage verbosity :: Verbosityverbosity
installedPkgInfo :: InstalledPackageInfo_ ModuleNameinstalledPkgInfo pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi True :: BoolTrue
(withPackageDB :: LocalBuildInfo -> PackageDBStackwithPackageDB lbi :: LocalBuildInfolbi (++) :: [a] -> [a] -> [a]++ [internalPackageDB :: PackageDBinternalPackageDB])
CExe exe -> do
info :: Verbosity -> String -> IO ()info verbosity :: Verbosityverbosity ($) :: (a -> b) -> a -> b$ "Building executable " (++) :: [a] -> [a] -> [a]++ exeName :: Executable -> StringexeName exe :: Executableexe (++) :: [a] -> [a] -> [a]++ "..."
buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi' :: LocalBuildInfolbi' exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
CTst test -> do
case testInterface :: TestSuite -> TestSuiteInterfacetestInterface test :: TestSuitetest of
TestSuiteExeV10 _ f -> do
let exe = Executable
{ exeName = testName :: TestSuite -> StringtestName test :: TestSuitetest
, modulePath = f :: FilePathf
, buildInfo = testBuildInfo :: TestSuite -> BuildInfotestBuildInfo test :: TestSuitetest
}
info :: Verbosity -> String -> IO ()info verbosity :: Verbosityverbosity ($) :: (a -> b) -> a -> b$ "Building test suite " (++) :: [a] -> [a] -> [a]++ testName :: TestSuite -> StringtestName test :: TestSuitetest (++) :: [a] -> [a] -> [a]++ "..."
buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi' :: LocalBuildInfolbi' exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
TestSuiteLibV09 _ m -> do
pwd <- getCurrentDirectory :: IO FilePathgetCurrentDirectory
let lib = Library
{ exposedModules = [ m :: ModuleNamem ]
, libExposed = True :: BoolTrue
, libBuildInfo = testBuildInfo :: TestSuite -> BuildInfotestBuildInfo test :: TestSuitetest
}
pkg = pkg_descr :: PackageDescriptionpkg_descr
{ package = (package :: PackageDescription -> PackageIdentifierpackage pkg_descr :: PackageDescriptionpkg_descr)
{ pkgName = PackageName :: String -> PackageNamePackageName ($) :: (a -> b) -> a -> b$ testName :: TestSuite -> StringtestName test :: TestSuitetest
}
, buildDepends = targetBuildDepends :: BuildInfo -> [Dependency]targetBuildDepends ($) :: (a -> b) -> a -> b$ testBuildInfo :: TestSuite -> BuildInfotestBuildInfo test :: TestSuitetest
, executables = [] :: [a][]
, testSuites = [] :: [a][]
, library = Just :: a -> Maybe aJust lib :: Librarylib
}
ipi = (inplaceInstalledPackageInfo ::
FilePath
-> FilePath
-> PackageDescription
-> Library
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> InstalledPackageInfoinplaceInstalledPackageInfo
pwd :: FilePathpwd distPref :: FilePathdistPref pkg :: PackageDescriptionpkg lib :: Librarylib lbi :: LocalBuildInfolbi clbi :: ComponentLocalBuildInfoclbi)
{ IPI.installedPackageId = inplacePackageId :: PackageId -> InstalledPackageIdinplacePackageId ($) :: (a -> b) -> a -> b$ packageId :: Package pkg => pkg -> PackageIdentifierpackageId ipi :: InstalledPackageInfo_ ModuleNameipi
}
testDir = buildDir :: LocalBuildInfo -> FilePathbuildDir lbi' :: LocalBuildInfolbi' (</>) :: FilePath -> FilePath -> FilePath</> stubName :: TestSuite -> FilePathstubName test :: TestSuitetest
(</>) :: FilePath -> FilePath -> FilePath</> stubName :: TestSuite -> FilePathstubName test :: TestSuitetest (++) :: [a] -> [a] -> [a]++ "-tmp"
testLibDep = thisPackageVersion :: PackageIdentifier -> DependencythisPackageVersion ($) :: (a -> b) -> a -> b$ package :: PackageDescription -> PackageIdentifierpackage pkg :: PackageDescriptionpkg
exe = Executable
{ exeName = stubName :: TestSuite -> FilePathstubName test :: TestSuitetest
, modulePath = stubFilePath :: TestSuite -> FilePathstubFilePath test :: TestSuitetest
, buildInfo = (testBuildInfo :: TestSuite -> BuildInfotestBuildInfo test :: TestSuitetest)
{ hsSourceDirs = [ testDir :: FilePathtestDir ]
, targetBuildDepends = testLibDep :: DependencytestLibDep
(:) :: a -> [a] -> [a]: (targetBuildDepends :: BuildInfo -> [Dependency]targetBuildDepends ($) :: (a -> b) -> a -> b$ testBuildInfo :: TestSuite -> BuildInfotestBuildInfo test :: TestSuitetest)
}
}
exeClbi = clbi :: ComponentLocalBuildInfoclbi
{ componentPackageDeps =
(installedPackageId :: InstalledPackageInfo_ m -> InstalledPackageIdIPI.installedPackageId ipi :: InstalledPackageInfo_ ModuleNameipi, packageId :: Package pkg => pkg -> PackageIdentifierpackageId ipi :: InstalledPackageInfo_ ModuleNameipi)
(:) :: a -> [a] -> [a]: (filter :: (a -> Bool) -> [a] -> [a]filter (\(_, x) -> let PackageName name = pkgName :: PackageIdentifier -> PackageNamepkgName x :: PackageIdentifierx in name :: Stringname (==) :: Eq a => a -> a -> Bool== "Cabal" (||) :: Bool -> Bool -> Bool|| name :: Stringname (==) :: Eq a => a -> a -> Bool== "base")
($) :: (a -> b) -> a -> b$ componentPackageDeps ::
ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]componentPackageDeps clbi :: ComponentLocalBuildInfoclbi)
}
info :: Verbosity -> String -> IO ()info verbosity :: Verbosityverbosity ($) :: (a -> b) -> a -> b$ "Building test suite " (++) :: [a] -> [a] -> [a]++ testName :: TestSuite -> StringtestName test :: TestSuitetest (++) :: [a] -> [a] -> [a]++ "..."
buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()buildLib verbosity :: Verbosityverbosity pkg :: PackageDescriptionpkg lbi' :: LocalBuildInfolbi' lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
registerPackage ::
Verbosity
-> InstalledPackageInfo
-> PackageDescription
-> LocalBuildInfo
-> Bool
-> PackageDBStack
-> IO ()registerPackage verbosity :: Verbosityverbosity ipi :: InstalledPackageInfo_ ModuleNameipi pkg :: PackageDescriptionpkg lbi' :: LocalBuildInfolbi' True :: BoolTrue ($) :: (a -> b) -> a -> b$ withPackageDB :: LocalBuildInfo -> PackageDBStackwithPackageDB lbi' :: LocalBuildInfolbi'
buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi' :: LocalBuildInfolbi' exe :: Executableexe exeClbi :: ComponentLocalBuildInfoexeClbi
TestSuiteUnsupported tt -> die :: String -> IO adie ($) :: (a -> b) -> a -> b$ "No support for building test suite "
(++) :: [a] -> [a] -> [a]++ "type " (++) :: [a] -> [a] -> [a]++ display :: Text a => a -> Stringdisplay tt :: TestTypett
createInternalPackageDB :: FilePath -> IO PackageDB
createInternalPackageDB distPref = do
let dbFile = distPref :: FilePathdistPref (</>) :: FilePath -> FilePath -> FilePath</> "package.conf.inplace"
packageDB = SpecificPackageDB :: FilePath -> PackageDBSpecificPackageDB dbFile :: FilePathdbFile
writeFile :: FilePath -> String -> IO ()writeFile dbFile :: FilePathdbFile "[]"
return :: Monad m => forall a. a -> m areturn packageDB :: PackageDBpackageDB
buildLib :: Verbosity -> PackageDescription -> LocalBuildInfo
-> Library -> ComponentLocalBuildInfo -> IO ()
buildLib verbosity pkg_descr lbi lib clbi =
case compilerFlavor :: Compiler -> CompilerFlavorcompilerFlavor (compiler :: LocalBuildInfo -> Compilercompiler lbi :: LocalBuildInfolbi) of
GHC -> buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()GHC.buildLib verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
JHC -> buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()JHC.buildLib verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
LHC -> buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()LHC.buildLib verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
Hugs -> buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()Hugs.buildLib verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
NHC -> buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()NHC.buildLib verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
UHC -> buildLib ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO ()UHC.buildLib verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi lib :: Librarylib clbi :: ComponentLocalBuildInfoclbi
_ -> die :: String -> IO adie "Building is not supported with this compiler."
buildExe :: Verbosity -> PackageDescription -> LocalBuildInfo
-> Executable -> ComponentLocalBuildInfo -> IO ()
buildExe verbosity pkg_descr lbi exe clbi =
case compilerFlavor :: Compiler -> CompilerFlavorcompilerFlavor (compiler :: LocalBuildInfo -> Compilercompiler lbi :: LocalBuildInfolbi) of
GHC -> buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()GHC.buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
JHC -> buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()JHC.buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
LHC -> buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()LHC.buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
Hugs -> buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()Hugs.buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
NHC -> buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()NHC.buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
UHC -> buildExe ::
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO ()UHC.buildExe verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi exe :: Executableexe clbi :: ComponentLocalBuildInfoclbi
_ -> die :: String -> IO adie "Building is not supported with this compiler."
initialBuildSteps :: FilePath
-> PackageDescription
-> LocalBuildInfo
-> Verbosity
-> IO ()
initialBuildSteps _distPref pkg_descr lbi verbosity = do
let buildInfos =
map :: (a -> b) -> [a] -> [b]map libBuildInfo :: Library -> BuildInfolibBuildInfo (maybeToList :: Maybe a -> [a]maybeToList (library :: PackageDescription -> Maybe Librarylibrary pkg_descr :: PackageDescriptionpkg_descr)) (++) :: [a] -> [a] -> [a]++
map :: (a -> b) -> [a] -> [b]map buildInfo :: Executable -> BuildInfobuildInfo (executables :: PackageDescription -> [Executable]executables pkg_descr :: PackageDescriptionpkg_descr)
unless :: Monad m => Bool -> m () -> m ()unless (any :: (a -> Bool) -> [a] -> Boolany buildable :: BuildInfo -> Boolbuildable buildInfos :: [BuildInfo]buildInfos) ($) :: (a -> b) -> a -> b$ do
let name = display :: Text a => a -> Stringdisplay (packageId :: Package pkg => pkg -> PackageIdentifierpackageId pkg_descr :: PackageDescriptionpkg_descr)
die :: String -> IO adie ("Package " (++) :: [a] -> [a] -> [a]++ name :: Stringname (++) :: [a] -> [a] -> [a]++ " can't be built on this system.")
createDirectoryIfMissingVerbose ::
Verbosity -> Bool -> FilePath -> IO ()createDirectoryIfMissingVerbose verbosity :: Verbosityverbosity True :: BoolTrue (buildDir :: LocalBuildInfo -> FilePathbuildDir lbi :: LocalBuildInfolbi)
writeAutogenFiles ::
Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()writeAutogenFiles verbosity :: Verbosityverbosity pkg_descr :: PackageDescriptionpkg_descr lbi :: LocalBuildInfolbi
writeAutogenFiles :: Verbosity
-> PackageDescription
-> LocalBuildInfo
-> IO ()
writeAutogenFiles verbosity pkg lbi = do
createDirectoryIfMissingVerbose ::
Verbosity -> Bool -> FilePath -> IO ()createDirectoryIfMissingVerbose verbosity :: Verbosityverbosity True :: BoolTrue (autogenModulesDir :: LocalBuildInfo -> StringautogenModulesDir lbi :: LocalBuildInfolbi)
let pathsModulePath = autogenModulesDir :: LocalBuildInfo -> StringautogenModulesDir lbi :: LocalBuildInfolbi
(</>) :: FilePath -> FilePath -> FilePath</> toFilePath :: ModuleName -> FilePathModuleName.toFilePath (autogenModuleName :: PackageDescription -> ModuleNameautogenModuleName pkg :: PackageDescriptionpkg) (<.>) :: FilePath -> String -> FilePath<.> "hs"
rewriteFile :: FilePath -> String -> IO ()rewriteFile pathsModulePath :: FilePathpathsModulePath (generate :: PackageDescription -> LocalBuildInfo -> StringBuild.PathsModule.generate pkg :: PackageDescriptionpkg lbi :: LocalBuildInfolbi)
let cppHeaderPath = autogenModulesDir :: LocalBuildInfo -> StringautogenModulesDir lbi :: LocalBuildInfolbi (</>) :: FilePath -> FilePath -> FilePath</> cppHeaderName :: StringcppHeaderName
rewriteFile :: FilePath -> String -> IO ()rewriteFile cppHeaderPath :: FilePathcppHeaderPath (generate :: PackageDescription -> LocalBuildInfo -> StringBuild.Macros.generate pkg :: PackageDescriptionpkg lbi :: LocalBuildInfolbi)