{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Distribution.Simple.Install
( install
) where
import Distribution.Compat.Prelude
import Prelude ()
import Distribution.Types.ExecutableScope
import Distribution.Types.ForeignLib
import Distribution.Types.LocalBuildInfo
import Distribution.Types.PackageDescription
import Distribution.Types.TargetInfo
import Distribution.Types.UnqualComponentName
import Distribution.Package
import Distribution.PackageDescription
import Distribution.Simple.BuildPaths (haddockName, haddockPref)
import Distribution.Simple.BuildTarget
import Distribution.Simple.Compiler
( CompilerFlavor (..)
, compilerFlavor
)
import Distribution.Simple.Flag
( fromFlag
)
import Distribution.Simple.Glob (matchDirFileGlob)
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Setup.Copy
( CopyFlags (..)
)
import Distribution.Simple.Setup.Haddock
( HaddockTarget (ForDevelopment)
)
import Distribution.Simple.Utils
( createDirectoryIfMissingVerbose
, dieWithException
, info
, installDirectoryContents
, installOrdinaryFile
, isInSearchPath
, noticeNoWrap
, warn
)
import Distribution.Utils.Path (getSymbolicPath)
import Distribution.Compat.Graph (IsNode (..))
import Distribution.Simple.Errors
import qualified Distribution.Simple.GHC as GHC
import qualified Distribution.Simple.GHCJS as GHCJS
import qualified Distribution.Simple.HaskellSuite as HaskellSuite
import qualified Distribution.Simple.UHC as UHC
import System.Directory
( doesDirectoryExist
, doesFileExist
)
import System.FilePath
( isRelative
, takeDirectory
, takeFileName
, (</>)
)
import Distribution.Pretty
( prettyShow
)
import Distribution.Verbosity
install
:: PackageDescription
-> LocalBuildInfo
-> CopyFlags
-> IO ()
install :: PackageDescription -> LocalBuildInfo -> CopyFlags -> IO ()
install PackageDescription
pkg_descr LocalBuildInfo
lbi CopyFlags
flags = do
IO ()
checkHasLibsOrExes
targets <- Verbosity
-> PackageDescription
-> LocalBuildInfo
-> [String]
-> IO [TargetInfo]
readTargetInfos Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi (CopyFlags -> [String]
copyArgs CopyFlags
flags)
copyPackage verbosity pkg_descr lbi distPref copydest
withNeededTargetsInBuildOrder' pkg_descr lbi (map nodeKey targets) $ \TargetInfo
target ->
let comp :: Component
comp = TargetInfo -> Component
targetComponent TargetInfo
target
clbi :: ComponentLocalBuildInfo
clbi = TargetInfo -> ComponentLocalBuildInfo
targetCLBI TargetInfo
target
in Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Component
-> ComponentLocalBuildInfo
-> CopyDest
-> IO ()
copyComponent Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi Component
comp ComponentLocalBuildInfo
clbi CopyDest
copydest
where
distPref :: String
distPref = Flag String -> String
forall a. WithCallStack (Flag a -> a)
fromFlag (CopyFlags -> Flag String
copyDistPref CopyFlags
flags)
verbosity :: Verbosity
verbosity = Flag Verbosity -> Verbosity
forall a. WithCallStack (Flag a -> a)
fromFlag (CopyFlags -> Flag Verbosity
copyVerbosity CopyFlags
flags)
copydest :: CopyDest
copydest = Flag CopyDest -> CopyDest
forall a. WithCallStack (Flag a -> a)
fromFlag (CopyFlags -> Flag CopyDest
copyDest CopyFlags
flags)
checkHasLibsOrExes :: IO ()
checkHasLibsOrExes =
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (PackageDescription -> Bool
hasLibs PackageDescription
pkg_descr Bool -> Bool -> Bool
|| PackageDescription -> Bool
hasForeignLibs PackageDescription
pkg_descr Bool -> Bool -> Bool
|| PackageDescription -> Bool
hasExes PackageDescription
pkg_descr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
Verbosity -> CabalException -> IO ()
forall a1 a.
(HasCallStack, Show a1, Typeable a1,
Exception (VerboseException a1)) =>
Verbosity -> a1 -> IO a
dieWithException Verbosity
verbosity CabalException
NoLibraryFound
copyPackage
:: Verbosity
-> PackageDescription
-> LocalBuildInfo
-> FilePath
-> CopyDest
-> IO ()
copyPackage :: Verbosity
-> PackageDescription
-> LocalBuildInfo
-> String
-> CopyDest
-> IO ()
copyPackage Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi String
distPref CopyDest
copydest = do
let
InstallDirs
{ datadir :: forall dir. InstallDirs dir -> dir
datadir = String
dataPref
, docdir :: forall dir. InstallDirs dir -> dir
docdir = String
docPref
, htmldir :: forall dir. InstallDirs dir -> dir
htmldir = String
htmlPref
, haddockdir :: forall dir. InstallDirs dir -> dir
haddockdir = String
interfacePref
} = PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteInstallCommandDirs PackageDescription
pkg_descr LocalBuildInfo
lbi (LocalBuildInfo -> UnitId
localUnitId LocalBuildInfo
lbi) CopyDest
copydest
Verbosity -> PackageDescription -> String -> IO ()
installDataFiles Verbosity
verbosity PackageDescription
pkg_descr String
dataPref
docExists <- String -> IO Bool
doesDirectoryExist (String -> IO Bool) -> String -> IO Bool
forall a b. (a -> b) -> a -> b
$ HaddockTarget -> String -> PackageDescription -> String
haddockPref HaddockTarget
ForDevelopment String
distPref PackageDescription
pkg_descr
info
verbosity
( "directory "
++ haddockPref ForDevelopment distPref pkg_descr
++ " does exist: "
++ show docExists
)
when docExists $ do
createDirectoryIfMissingVerbose verbosity True htmlPref
installDirectoryContents
verbosity
(haddockPref ForDevelopment distPref pkg_descr)
htmlPref
let haddockInterfaceFileSrc =
HaddockTarget -> String -> PackageDescription -> String
haddockPref HaddockTarget
ForDevelopment String
distPref PackageDescription
pkg_descr
String -> String -> String
</> PackageDescription -> String
haddockName PackageDescription
pkg_descr
haddockInterfaceFileDest = String
interfacePref String -> String -> String
</> PackageDescription -> String
haddockName PackageDescription
pkg_descr
exists <- doesFileExist haddockInterfaceFileSrc
when exists $ do
createDirectoryIfMissingVerbose verbosity True interfacePref
installOrdinaryFile
verbosity
haddockInterfaceFileSrc
haddockInterfaceFileDest
let lfiles = PackageDescription -> [SymbolicPath PackageDir LicenseFile]
licenseFiles PackageDescription
pkg_descr
unless (null lfiles) $ do
createDirectoryIfMissingVerbose verbosity True docPref
for_ lfiles $ \SymbolicPath PackageDir LicenseFile
lfile' -> do
let lfile :: FilePath
lfile :: String
lfile = SymbolicPath PackageDir LicenseFile -> String
forall from to. SymbolicPath from to -> String
getSymbolicPath SymbolicPath PackageDir LicenseFile
lfile'
Verbosity -> String -> String -> IO ()
installOrdinaryFile Verbosity
verbosity String
lfile (String
docPref String -> String -> String
</> String -> String
takeFileName String
lfile)
copyComponent
:: Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Component
-> ComponentLocalBuildInfo
-> CopyDest
-> IO ()
copyComponent :: Verbosity
-> PackageDescription
-> LocalBuildInfo
-> Component
-> ComponentLocalBuildInfo
-> CopyDest
-> IO ()
copyComponent Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi (CLib Library
lib) ComponentLocalBuildInfo
clbi CopyDest
copydest = do
let InstallDirs
{ libdir :: forall dir. InstallDirs dir -> dir
libdir = String
libPref
, dynlibdir :: forall dir. InstallDirs dir -> dir
dynlibdir = String
dynlibPref
, includedir :: forall dir. InstallDirs dir -> dir
includedir = String
incPref
} = PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteInstallCommandDirs PackageDescription
pkg_descr LocalBuildInfo
lbi (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi) CopyDest
copydest
buildPref :: String
buildPref = LocalBuildInfo -> ComponentLocalBuildInfo -> String
componentBuildDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
case Library -> LibraryName
libName Library
lib of
LibraryName
LMainLibName -> Verbosity -> String -> IO ()
noticeNoWrap Verbosity
verbosity (String
"Installing library in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
libPref)
LSubLibName UnqualComponentName
n -> Verbosity -> String -> IO ()
noticeNoWrap Verbosity
verbosity (String
"Installing internal library " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UnqualComponentName -> String
forall a. Pretty a => a -> String
prettyShow UnqualComponentName
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
libPref)
Verbosity
-> BuildInfo -> LocalBuildInfo -> String -> String -> IO ()
installIncludeFiles Verbosity
verbosity (Library -> BuildInfo
libBuildInfo Library
lib) LocalBuildInfo
lbi String
buildPref String
incPref
case Compiler -> CompilerFlavor
compilerFlavor (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi) of
CompilerFlavor
GHC -> Verbosity
-> LocalBuildInfo
-> String
-> String
-> String
-> PackageDescription
-> Library
-> ComponentLocalBuildInfo
-> IO ()
GHC.installLib Verbosity
verbosity LocalBuildInfo
lbi String
libPref String
dynlibPref String
buildPref PackageDescription
pkg_descr Library
lib ComponentLocalBuildInfo
clbi
CompilerFlavor
GHCJS -> Verbosity
-> LocalBuildInfo
-> String
-> String
-> String
-> PackageDescription
-> Library
-> ComponentLocalBuildInfo
-> IO ()
GHCJS.installLib Verbosity
verbosity LocalBuildInfo
lbi String
libPref String
dynlibPref String
buildPref PackageDescription
pkg_descr Library
lib ComponentLocalBuildInfo
clbi
CompilerFlavor
UHC -> Verbosity
-> LocalBuildInfo
-> String
-> String
-> String
-> PackageDescription
-> Library
-> ComponentLocalBuildInfo
-> IO ()
UHC.installLib Verbosity
verbosity LocalBuildInfo
lbi String
libPref String
dynlibPref String
buildPref PackageDescription
pkg_descr Library
lib ComponentLocalBuildInfo
clbi
HaskellSuite String
_ ->
Verbosity
-> LocalBuildInfo
-> String
-> String
-> String
-> PackageDescription
-> Library
-> ComponentLocalBuildInfo
-> IO ()
HaskellSuite.installLib
Verbosity
verbosity
LocalBuildInfo
lbi
String
libPref
String
dynlibPref
String
buildPref
PackageDescription
pkg_descr
Library
lib
ComponentLocalBuildInfo
clbi
CompilerFlavor
_ ->
Verbosity -> CabalException -> IO ()
forall a1 a.
(HasCallStack, Show a1, Typeable a1,
Exception (VerboseException a1)) =>
Verbosity -> a1 -> IO a
dieWithException Verbosity
verbosity (CabalException -> IO ()) -> CabalException -> IO ()
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> CabalException
CompilerNotInstalled (Compiler -> CompilerFlavor
compilerFlavor (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi))
copyComponent Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi (CFLib ForeignLib
flib) ComponentLocalBuildInfo
clbi CopyDest
copydest = do
let InstallDirs
{ flibdir :: forall dir. InstallDirs dir -> dir
flibdir = String
flibPref
, includedir :: forall dir. InstallDirs dir -> dir
includedir = String
incPref
} = PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteComponentInstallDirs PackageDescription
pkg_descr LocalBuildInfo
lbi (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi) CopyDest
copydest
buildPref :: String
buildPref = LocalBuildInfo -> ComponentLocalBuildInfo -> String
componentBuildDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
Verbosity -> String -> IO ()
noticeNoWrap Verbosity
verbosity (String
"Installing foreign library " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UnqualComponentName -> String
unUnqualComponentName (ForeignLib -> UnqualComponentName
foreignLibName ForeignLib
flib) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
flibPref)
Verbosity
-> BuildInfo -> LocalBuildInfo -> String -> String -> IO ()
installIncludeFiles Verbosity
verbosity (ForeignLib -> BuildInfo
foreignLibBuildInfo ForeignLib
flib) LocalBuildInfo
lbi String
buildPref String
incPref
case Compiler -> CompilerFlavor
compilerFlavor (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi) of
CompilerFlavor
GHC -> Verbosity
-> LocalBuildInfo
-> String
-> String
-> PackageDescription
-> ForeignLib
-> IO ()
GHC.installFLib Verbosity
verbosity LocalBuildInfo
lbi String
flibPref String
buildPref PackageDescription
pkg_descr ForeignLib
flib
CompilerFlavor
GHCJS -> Verbosity
-> LocalBuildInfo
-> String
-> String
-> PackageDescription
-> ForeignLib
-> IO ()
GHCJS.installFLib Verbosity
verbosity LocalBuildInfo
lbi String
flibPref String
buildPref PackageDescription
pkg_descr ForeignLib
flib
CompilerFlavor
_ -> Verbosity -> CabalException -> IO ()
forall a1 a.
(HasCallStack, Show a1, Typeable a1,
Exception (VerboseException a1)) =>
Verbosity -> a1 -> IO a
dieWithException Verbosity
verbosity (CabalException -> IO ()) -> CabalException -> IO ()
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> CabalException
CompilerNotInstalled (Compiler -> CompilerFlavor
compilerFlavor (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi))
copyComponent Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi (CExe Executable
exe) ComponentLocalBuildInfo
clbi CopyDest
copydest = do
let installDirs :: InstallDirs String
installDirs = PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteComponentInstallDirs PackageDescription
pkg_descr LocalBuildInfo
lbi (ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi) CopyDest
copydest
buildPref :: String
buildPref = LocalBuildInfo -> String
buildDir LocalBuildInfo
lbi
uid :: UnitId
uid = ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi
pkgid :: PackageIdentifier
pkgid = PackageDescription -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId PackageDescription
pkg_descr
binPref :: String
binPref
| ExecutableScope
ExecutablePrivate <- Executable -> ExecutableScope
exeScope Executable
exe = InstallDirs String -> String
forall dir. InstallDirs dir -> dir
libexecdir InstallDirs String
installDirs
| Bool
otherwise = InstallDirs String -> String
forall dir. InstallDirs dir -> dir
bindir InstallDirs String
installDirs
progPrefixPref :: String
progPrefixPref = PackageIdentifier
-> LocalBuildInfo -> UnitId -> PathTemplate -> String
substPathTemplate PackageIdentifier
pkgid LocalBuildInfo
lbi UnitId
uid (LocalBuildInfo -> PathTemplate
progPrefix LocalBuildInfo
lbi)
progSuffixPref :: String
progSuffixPref = PackageIdentifier
-> LocalBuildInfo -> UnitId -> PathTemplate -> String
substPathTemplate PackageIdentifier
pkgid LocalBuildInfo
lbi UnitId
uid (LocalBuildInfo -> PathTemplate
progSuffix LocalBuildInfo
lbi)
progFix :: (String, String)
progFix = (String
progPrefixPref, String
progSuffixPref)
Verbosity -> String -> IO ()
noticeNoWrap
Verbosity
verbosity
( String
"Installing executable "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ UnqualComponentName -> String
forall a. Pretty a => a -> String
prettyShow (Executable -> UnqualComponentName
exeName Executable
exe)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" in "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
binPref
)
inPath <- String -> IO Bool
isInSearchPath String
binPref
when (not inPath) $
warn
verbosity
( "The directory "
++ binPref
++ " is not in the system search path."
)
case compilerFlavor (compiler lbi) of
CompilerFlavor
GHC -> Verbosity
-> LocalBuildInfo
-> String
-> String
-> (String, String)
-> PackageDescription
-> Executable
-> IO ()
GHC.installExe Verbosity
verbosity LocalBuildInfo
lbi String
binPref String
buildPref (String, String)
progFix PackageDescription
pkg_descr Executable
exe
CompilerFlavor
GHCJS -> Verbosity
-> LocalBuildInfo
-> String
-> String
-> (String, String)
-> PackageDescription
-> Executable
-> IO ()
GHCJS.installExe Verbosity
verbosity LocalBuildInfo
lbi String
binPref String
buildPref (String, String)
progFix PackageDescription
pkg_descr Executable
exe
CompilerFlavor
UHC -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
HaskellSuite{} -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
CompilerFlavor
_ ->
Verbosity -> CabalException -> IO ()
forall a1 a.
(HasCallStack, Show a1, Typeable a1,
Exception (VerboseException a1)) =>
Verbosity -> a1 -> IO a
dieWithException Verbosity
verbosity (CabalException -> IO ()) -> CabalException -> IO ()
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> CabalException
CompilerNotInstalled (Compiler -> CompilerFlavor
compilerFlavor (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi))
copyComponent Verbosity
_ PackageDescription
_ LocalBuildInfo
_ (CBench Benchmark
_) ComponentLocalBuildInfo
_ CopyDest
_ = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
copyComponent Verbosity
_ PackageDescription
_ LocalBuildInfo
_ (CTest TestSuite
_) ComponentLocalBuildInfo
_ CopyDest
_ = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
installDataFiles :: Verbosity -> PackageDescription -> FilePath -> IO ()
installDataFiles :: Verbosity -> PackageDescription -> String -> IO ()
installDataFiles Verbosity
verbosity PackageDescription
pkg_descr String
destDataDir =
((String -> IO ()) -> [String] -> IO ())
-> [String] -> (String -> IO ()) -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (PackageDescription -> [String]
dataFiles PackageDescription
pkg_descr) ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \String
glob -> do
let srcDataDirRaw :: String
srcDataDirRaw = PackageDescription -> String
dataDir PackageDescription
pkg_descr
srcDataDir :: String
srcDataDir =
if String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
srcDataDirRaw
then String
"."
else String
srcDataDirRaw
files <- Verbosity -> CabalSpecVersion -> String -> String -> IO [String]
matchDirFileGlob Verbosity
verbosity (PackageDescription -> CabalSpecVersion
specVersion PackageDescription
pkg_descr) String
srcDataDir String
glob
for_ files $ \String
file' -> do
let src :: String
src = String
srcDataDir String -> String -> String
</> String
file'
dst :: String
dst = String
destDataDir String -> String -> String
</> String
file'
Verbosity -> Bool -> String -> IO ()
createDirectoryIfMissingVerbose Verbosity
verbosity Bool
True (String -> String
takeDirectory String
dst)
Verbosity -> String -> String -> IO ()
installOrdinaryFile Verbosity
verbosity String
src String
dst
installIncludeFiles :: Verbosity -> BuildInfo -> LocalBuildInfo -> FilePath -> FilePath -> IO ()
installIncludeFiles :: Verbosity
-> BuildInfo -> LocalBuildInfo -> String -> String -> IO ()
installIncludeFiles Verbosity
verbosity BuildInfo
libBi LocalBuildInfo
lbi String
buildPref String
destIncludeDir = do
let relincdirs :: [String]
relincdirs = String
"." String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
isRelative (BuildInfo -> [String]
includeDirs BuildInfo
libBi)
incdirs :: [String]
incdirs =
[LocalBuildInfo -> String
baseDir LocalBuildInfo
lbi String -> String -> String
</> String
dir | String
dir <- [String]
relincdirs]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
buildPref String -> String -> String
</> String
dir | String
dir <- [String]
relincdirs]
incs <- (String -> IO (String, String))
-> [String] -> IO [(String, String)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ([String] -> String -> IO (String, String)
findInc [String]
incdirs) (BuildInfo -> [String]
installIncludes BuildInfo
libBi)
sequence_
[ do
createDirectoryIfMissingVerbose verbosity True destDir
installOrdinaryFile verbosity srcFile destFile
| (relFile, srcFile) <- incs
, let destFile = String
destIncludeDir String -> String -> String
</> String
relFile
destDir = String -> String
takeDirectory String
destFile
]
where
baseDir :: LocalBuildInfo -> String
baseDir LocalBuildInfo
lbi' = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
"" (String -> String
takeDirectory (String -> String) -> Maybe String -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LocalBuildInfo -> Maybe String
cabalFilePath LocalBuildInfo
lbi')
findInc :: [String] -> String -> IO (String, String)
findInc [] String
file = Verbosity -> CabalException -> IO (String, String)
forall a1 a.
(HasCallStack, Show a1, Typeable a1,
Exception (VerboseException a1)) =>
Verbosity -> a1 -> IO a
dieWithException Verbosity
verbosity (CabalException -> IO (String, String))
-> CabalException -> IO (String, String)
forall a b. (a -> b) -> a -> b
$ String -> CabalException
CantFindIncludeFile String
file
findInc (String
dir : [String]
dirs) String
file = do
let path :: String
path = String
dir String -> String -> String
</> String
file
exists <- String -> IO Bool
doesFileExist String
path
if exists then return (file, path) else findInc dirs file