{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Distribution.Simple.LocalBuildInfo (
LocalBuildInfo(..),
localComponentId,
localUnitId,
localCompatPackageKey,
Component(..),
ComponentName(..),
LibraryName(..),
defaultLibName,
showComponentName,
componentNameString,
ComponentLocalBuildInfo(..),
componentBuildDir,
foldComponent,
componentName,
componentBuildInfo,
componentBuildable,
pkgComponents,
pkgBuildableComponents,
lookupComponent,
getComponent,
allComponentsInBuildOrder,
depLibraryPaths,
allLibModules,
withAllComponentsInBuildOrder,
withLibLBI,
withExeLBI,
withBenchLBI,
withTestLBI,
enabledTestLBIs,
enabledBenchLBIs,
module Distribution.Simple.InstallDirs,
absoluteInstallDirs, prefixRelativeInstallDirs,
absoluteInstallCommandDirs,
absoluteComponentInstallDirs, prefixRelativeComponentInstallDirs,
substPathTemplate,
) where
import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Types.Component
import Distribution.Types.PackageId
import Distribution.Types.UnitId
import Distribution.Types.ComponentName
import Distribution.Types.UnqualComponentName
import Distribution.Types.PackageDescription
import Distribution.Types.ComponentLocalBuildInfo
import Distribution.Types.LocalBuildInfo
import Distribution.Types.TargetInfo
import Distribution.Simple.InstallDirs hiding (absoluteInstallDirs,
prefixRelativeInstallDirs,
substPathTemplate, )
import qualified Distribution.Simple.InstallDirs as InstallDirs
import Distribution.PackageDescription
import qualified Distribution.InstalledPackageInfo as Installed
import Distribution.Package
import Distribution.ModuleName
import Distribution.Simple.Compiler
import Distribution.Simple.PackageIndex
import Distribution.Simple.Utils
import Distribution.Pretty
import qualified Distribution.Compat.Graph as Graph
import Data.List (stripPrefix)
import System.FilePath
import System.Directory (doesDirectoryExist, canonicalizePath)
componentBuildDir :: LocalBuildInfo -> ComponentLocalBuildInfo -> FilePath
componentBuildDir :: LocalBuildInfo -> ComponentLocalBuildInfo -> String
componentBuildDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
= LocalBuildInfo -> String
buildDir LocalBuildInfo
lbi String -> String -> String
</>
case ComponentLocalBuildInfo -> ComponentName
componentLocalName ComponentLocalBuildInfo
clbi of
CLibName LibraryName
LMainLibName ->
if forall a. Pretty a => a -> String
prettyShow (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi) forall a. Eq a => a -> a -> Bool
== forall a. Pretty a => a -> String
prettyShow (ComponentLocalBuildInfo -> ComponentId
componentComponentId ComponentLocalBuildInfo
clbi)
then String
""
else forall a. Pretty a => a -> String
prettyShow (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi)
CLibName (LSubLibName UnqualComponentName
s) ->
if forall a. Pretty a => a -> String
prettyShow (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi) forall a. Eq a => a -> a -> Bool
== forall a. Pretty a => a -> String
prettyShow (ComponentLocalBuildInfo -> ComponentId
componentComponentId ComponentLocalBuildInfo
clbi)
then UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
s
else forall a. Pretty a => a -> String
prettyShow (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi)
CFLibName UnqualComponentName
s -> UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
s
CExeName UnqualComponentName
s -> UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
s
CTestName UnqualComponentName
s -> UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
s
CBenchName UnqualComponentName
s -> UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
s
withLibLBI :: PackageDescription -> LocalBuildInfo
-> (Library -> ComponentLocalBuildInfo -> IO ()) -> IO ()
withLibLBI :: PackageDescription
-> LocalBuildInfo
-> (Library -> ComponentLocalBuildInfo -> IO ())
-> IO ()
withLibLBI PackageDescription
pkg LocalBuildInfo
lbi Library -> ComponentLocalBuildInfo -> IO ()
f =
PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' PackageDescription
pkg LocalBuildInfo
lbi forall a b. (a -> b) -> a -> b
$ \TargetInfo
target ->
case TargetInfo -> Component
targetComponent TargetInfo
target of
CLib Library
lib -> Library -> ComponentLocalBuildInfo -> IO ()
f Library
lib (TargetInfo -> ComponentLocalBuildInfo
targetCLBI TargetInfo
target)
Component
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
withExeLBI :: PackageDescription -> LocalBuildInfo
-> (Executable -> ComponentLocalBuildInfo -> IO ()) -> IO ()
withExeLBI :: PackageDescription
-> LocalBuildInfo
-> (Executable -> ComponentLocalBuildInfo -> IO ())
-> IO ()
withExeLBI PackageDescription
pkg LocalBuildInfo
lbi Executable -> ComponentLocalBuildInfo -> IO ()
f =
PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' PackageDescription
pkg LocalBuildInfo
lbi forall a b. (a -> b) -> a -> b
$ \TargetInfo
target ->
case TargetInfo -> Component
targetComponent TargetInfo
target of
CExe Executable
exe -> Executable -> ComponentLocalBuildInfo -> IO ()
f Executable
exe (TargetInfo -> ComponentLocalBuildInfo
targetCLBI TargetInfo
target)
Component
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
withBenchLBI :: PackageDescription -> LocalBuildInfo
-> (Benchmark -> ComponentLocalBuildInfo -> IO ()) -> IO ()
withBenchLBI :: PackageDescription
-> LocalBuildInfo
-> (Benchmark -> ComponentLocalBuildInfo -> IO ())
-> IO ()
withBenchLBI PackageDescription
pkg LocalBuildInfo
lbi Benchmark -> ComponentLocalBuildInfo -> IO ()
f =
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [ Benchmark -> ComponentLocalBuildInfo -> IO ()
f Benchmark
bench ComponentLocalBuildInfo
clbi | (Benchmark
bench, ComponentLocalBuildInfo
clbi) <- PackageDescription
-> LocalBuildInfo -> [(Benchmark, ComponentLocalBuildInfo)]
enabledBenchLBIs PackageDescription
pkg LocalBuildInfo
lbi ]
withTestLBI :: PackageDescription -> LocalBuildInfo
-> (TestSuite -> ComponentLocalBuildInfo -> IO ()) -> IO ()
withTestLBI :: PackageDescription
-> LocalBuildInfo
-> (TestSuite -> ComponentLocalBuildInfo -> IO ())
-> IO ()
withTestLBI PackageDescription
pkg LocalBuildInfo
lbi TestSuite -> ComponentLocalBuildInfo -> IO ()
f =
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [ TestSuite -> ComponentLocalBuildInfo -> IO ()
f TestSuite
test ComponentLocalBuildInfo
clbi | (TestSuite
test, ComponentLocalBuildInfo
clbi) <- PackageDescription
-> LocalBuildInfo -> [(TestSuite, ComponentLocalBuildInfo)]
enabledTestLBIs PackageDescription
pkg LocalBuildInfo
lbi ]
enabledTestLBIs :: PackageDescription -> LocalBuildInfo
-> [(TestSuite, ComponentLocalBuildInfo)]
enabledTestLBIs :: PackageDescription
-> LocalBuildInfo -> [(TestSuite, ComponentLocalBuildInfo)]
enabledTestLBIs PackageDescription
pkg LocalBuildInfo
lbi =
[ (TestSuite
test, TargetInfo -> ComponentLocalBuildInfo
targetCLBI TargetInfo
target)
| TargetInfo
target <- PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' PackageDescription
pkg LocalBuildInfo
lbi
, CTest TestSuite
test <- [TargetInfo -> Component
targetComponent TargetInfo
target] ]
enabledBenchLBIs :: PackageDescription -> LocalBuildInfo
-> [(Benchmark, ComponentLocalBuildInfo)]
enabledBenchLBIs :: PackageDescription
-> LocalBuildInfo -> [(Benchmark, ComponentLocalBuildInfo)]
enabledBenchLBIs PackageDescription
pkg LocalBuildInfo
lbi =
[ (Benchmark
bench, TargetInfo -> ComponentLocalBuildInfo
targetCLBI TargetInfo
target)
| TargetInfo
target <- PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' PackageDescription
pkg LocalBuildInfo
lbi
, CBench Benchmark
bench <- [TargetInfo -> Component
targetComponent TargetInfo
target] ]
withAllComponentsInBuildOrder :: PackageDescription -> LocalBuildInfo
-> (Component -> ComponentLocalBuildInfo -> IO ())
-> IO ()
withAllComponentsInBuildOrder :: PackageDescription
-> LocalBuildInfo
-> (Component -> ComponentLocalBuildInfo -> IO ())
-> IO ()
withAllComponentsInBuildOrder PackageDescription
pkg LocalBuildInfo
lbi Component -> ComponentLocalBuildInfo -> IO ()
f =
PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' PackageDescription
pkg LocalBuildInfo
lbi forall a b. (a -> b) -> a -> b
$ \TargetInfo
target ->
Component -> ComponentLocalBuildInfo -> IO ()
f (TargetInfo -> Component
targetComponent TargetInfo
target) (TargetInfo -> ComponentLocalBuildInfo
targetCLBI TargetInfo
target)
allComponentsInBuildOrder :: LocalBuildInfo
-> [ComponentLocalBuildInfo]
allComponentsInBuildOrder :: LocalBuildInfo -> [ComponentLocalBuildInfo]
allComponentsInBuildOrder LocalBuildInfo
lbi =
forall a. Graph a -> [a]
Graph.topSort (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi)
depLibraryPaths :: Bool
-> Bool
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> IO [FilePath]
depLibraryPaths :: Bool
-> Bool -> LocalBuildInfo -> ComponentLocalBuildInfo -> IO [String]
depLibraryPaths Bool
inplace Bool
relative LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi = do
let pkgDescr :: PackageDescription
pkgDescr = LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi
installDirs :: InstallDirs String
installDirs = PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteComponentInstallDirs PackageDescription
pkgDescr LocalBuildInfo
lbi (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi) CopyDest
NoCopyDest
executable :: Bool
executable = case ComponentLocalBuildInfo
clbi of
ExeComponentLocalBuildInfo {} -> Bool
True
ComponentLocalBuildInfo
_ -> Bool
False
relDir :: String
relDir | Bool
executable = forall dir. InstallDirs dir -> dir
bindir InstallDirs String
installDirs
| Bool
otherwise = forall dir. InstallDirs dir -> dir
libdir InstallDirs String
installDirs
let
internalDeps :: [UnitId]
internalDeps = [ UnitId
uid
| (UnitId
uid, MungedPackageId
_) <- ComponentLocalBuildInfo -> [(UnitId, MungedPackageId)]
componentPackageDeps ComponentLocalBuildInfo
clbi
, TargetInfo
sub_target <- PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' PackageDescription
pkgDescr LocalBuildInfo
lbi
, ComponentLocalBuildInfo -> UnitId
componentUnitId (TargetInfo -> ComponentLocalBuildInfo
targetCLBI (TargetInfo
sub_target)) forall a. Eq a => a -> a -> Bool
== UnitId
uid ]
internalLibs :: [String]
internalLibs = [ ComponentLocalBuildInfo -> String
getLibDir (TargetInfo -> ComponentLocalBuildInfo
targetCLBI TargetInfo
sub_target)
| TargetInfo
sub_target <- PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder'
PackageDescription
pkgDescr LocalBuildInfo
lbi [UnitId]
internalDeps ]
getLibDir :: ComponentLocalBuildInfo -> String
getLibDir ComponentLocalBuildInfo
sub_clbi
| Bool
inplace = LocalBuildInfo -> ComponentLocalBuildInfo -> String
componentBuildDir LocalBuildInfo
lbi ComponentLocalBuildInfo
sub_clbi
| Bool
otherwise = forall dir. InstallDirs dir -> dir
dynlibdir (PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteComponentInstallDirs PackageDescription
pkgDescr LocalBuildInfo
lbi (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
sub_clbi) CopyDest
NoCopyDest)
let external_ipkgs :: [InstalledPackageInfo]
external_ipkgs = forall a. (a -> Bool) -> [a] -> [a]
filter forall {pkg}. HasUnitId pkg => pkg -> Bool
is_external (forall a. PackageIndex a -> [a]
allPackages (LocalBuildInfo -> InstalledPackageIndex
installedPkgs LocalBuildInfo
lbi))
is_external :: pkg -> Bool
is_external pkg
ipkg = Bool -> Bool
not (forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId pkg
ipkg forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [UnitId]
internalDeps)
getDynDir :: InstalledPackageInfo -> [String]
getDynDir InstalledPackageInfo
pkg = case InstalledPackageInfo -> [String]
Installed.libraryDynDirs InstalledPackageInfo
pkg of
[] -> InstalledPackageInfo -> [String]
Installed.libraryDirs InstalledPackageInfo
pkg
[String]
d -> [String]
d
allDepLibDirs :: [String]
allDepLibDirs = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap InstalledPackageInfo -> [String]
getDynDir [InstalledPackageInfo]
external_ipkgs
allDepLibDirs' :: [String]
allDepLibDirs' = [String]
internalLibs forall a. [a] -> [a] -> [a]
++ [String]
allDepLibDirs
[String]
allDepLibDirsC <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse String -> IO String
canonicalizePathNoFail [String]
allDepLibDirs'
let p :: String
p = forall dir. InstallDirs dir -> dir
prefix InstallDirs String
installDirs
prefixRelative :: String -> Bool
prefixRelative String
l = forall a. Maybe a -> Bool
isJust (forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix String
p String
l)
libPaths :: [String]
libPaths
| Bool
relative Bool -> Bool -> Bool
&&
String -> Bool
prefixRelative String
relDir = forall a b. (a -> b) -> [a] -> [b]
map (\String
l ->
if String -> Bool
prefixRelative String
l
then String -> String -> String
shortRelativePath String
relDir String
l
else String
l
) [String]
allDepLibDirsC
| Bool
otherwise = [String]
allDepLibDirsC
forall (m :: * -> *) a. Monad m => a -> m a
return [String]
libPaths
where
canonicalizePathNoFail :: String -> IO String
canonicalizePathNoFail String
p = do
Bool
exists <- String -> IO Bool
doesDirectoryExist String
p
if Bool
exists
then String -> IO String
canonicalizePath String
p
else forall (m :: * -> *) a. Monad m => a -> m a
return String
p
allLibModules :: Library -> ComponentLocalBuildInfo -> [ModuleName]
allLibModules :: Library -> ComponentLocalBuildInfo -> [ModuleName]
allLibModules Library
lib ComponentLocalBuildInfo
clbi =
forall a. Ord a => [a] -> [a]
ordNub forall a b. (a -> b) -> a -> b
$
Library -> [ModuleName]
explicitLibModules Library
lib forall a. [a] -> [a] -> [a]
++
case ComponentLocalBuildInfo
clbi of
LibComponentLocalBuildInfo { componentInstantiatedWith :: ComponentLocalBuildInfo -> [(ModuleName, OpenModule)]
componentInstantiatedWith = [(ModuleName, OpenModule)]
insts } -> forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(ModuleName, OpenModule)]
insts
ComponentLocalBuildInfo
_ -> []
absoluteInstallDirs :: PackageDescription -> LocalBuildInfo
-> CopyDest
-> InstallDirs FilePath
absoluteInstallDirs :: PackageDescription
-> LocalBuildInfo -> CopyDest -> InstallDirs String
absoluteInstallDirs PackageDescription
pkg LocalBuildInfo
lbi CopyDest
copydest =
PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteComponentInstallDirs PackageDescription
pkg LocalBuildInfo
lbi (LocalBuildInfo -> UnitId
localUnitId LocalBuildInfo
lbi) CopyDest
copydest
absoluteComponentInstallDirs :: PackageDescription -> LocalBuildInfo
-> UnitId
-> CopyDest
-> InstallDirs FilePath
absoluteComponentInstallDirs :: PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteComponentInstallDirs PackageDescription
pkg LocalBuildInfo
lbi UnitId
uid CopyDest
copydest =
PackageId
-> UnitId
-> CompilerInfo
-> CopyDest
-> Platform
-> InstallDirs PathTemplate
-> InstallDirs String
InstallDirs.absoluteInstallDirs
(forall pkg. Package pkg => pkg -> PackageId
packageId PackageDescription
pkg)
UnitId
uid
(Compiler -> CompilerInfo
compilerInfo (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi))
CopyDest
copydest
(LocalBuildInfo -> Platform
hostPlatform LocalBuildInfo
lbi)
(LocalBuildInfo -> InstallDirs PathTemplate
installDirTemplates LocalBuildInfo
lbi)
absoluteInstallCommandDirs :: PackageDescription -> LocalBuildInfo
-> UnitId
-> CopyDest
-> InstallDirs FilePath
absoluteInstallCommandDirs :: PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteInstallCommandDirs PackageDescription
pkg LocalBuildInfo
lbi UnitId
uid CopyDest
copydest =
InstallDirs String
dirs {
datadir :: String
datadir = forall dir. InstallDirs dir -> dir
datadir InstallDirs String
dirs',
docdir :: String
docdir = forall dir. InstallDirs dir -> dir
docdir InstallDirs String
dirs',
htmldir :: String
htmldir = forall dir. InstallDirs dir -> dir
htmldir InstallDirs String
dirs',
haddockdir :: String
haddockdir = forall dir. InstallDirs dir -> dir
haddockdir InstallDirs String
dirs'
}
where
dirs :: InstallDirs String
dirs = PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteComponentInstallDirs PackageDescription
pkg LocalBuildInfo
lbi UnitId
uid CopyDest
copydest
dirs' :: InstallDirs String
dirs' = PackageDescription
-> LocalBuildInfo -> CopyDest -> InstallDirs String
absoluteInstallDirs PackageDescription
pkg LocalBuildInfo
lbi CopyDest
copydest
prefixRelativeInstallDirs :: PackageId -> LocalBuildInfo
-> InstallDirs (Maybe FilePath)
prefixRelativeInstallDirs :: PackageId -> LocalBuildInfo -> InstallDirs (Maybe String)
prefixRelativeInstallDirs PackageId
pkg_descr LocalBuildInfo
lbi =
PackageId -> LocalBuildInfo -> UnitId -> InstallDirs (Maybe String)
prefixRelativeComponentInstallDirs PackageId
pkg_descr LocalBuildInfo
lbi (LocalBuildInfo -> UnitId
localUnitId LocalBuildInfo
lbi)
prefixRelativeComponentInstallDirs :: PackageId -> LocalBuildInfo
-> UnitId
-> InstallDirs (Maybe FilePath)
prefixRelativeComponentInstallDirs :: PackageId -> LocalBuildInfo -> UnitId -> InstallDirs (Maybe String)
prefixRelativeComponentInstallDirs PackageId
pkg_descr LocalBuildInfo
lbi UnitId
uid =
PackageId
-> UnitId
-> CompilerInfo
-> Platform
-> InstallDirs PathTemplate
-> InstallDirs (Maybe String)
InstallDirs.prefixRelativeInstallDirs
(forall pkg. Package pkg => pkg -> PackageId
packageId PackageId
pkg_descr)
UnitId
uid
(Compiler -> CompilerInfo
compilerInfo (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi))
(LocalBuildInfo -> Platform
hostPlatform LocalBuildInfo
lbi)
(LocalBuildInfo -> InstallDirs PathTemplate
installDirTemplates LocalBuildInfo
lbi)
substPathTemplate :: PackageId -> LocalBuildInfo
-> UnitId
-> PathTemplate -> FilePath
substPathTemplate :: PackageId -> LocalBuildInfo -> UnitId -> PathTemplate -> String
substPathTemplate PackageId
pkgid LocalBuildInfo
lbi UnitId
uid = PathTemplate -> String
fromPathTemplate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ( PathTemplateEnv -> PathTemplate -> PathTemplate
InstallDirs.substPathTemplate PathTemplateEnv
env )
where env :: PathTemplateEnv
env = PackageId -> UnitId -> CompilerInfo -> Platform -> PathTemplateEnv
initialPathTemplateEnv
PackageId
pkgid
UnitId
uid
(Compiler -> CompilerInfo
compilerInfo (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi))
(LocalBuildInfo -> Platform
hostPlatform LocalBuildInfo
lbi)