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

    -----------------------------------------------------------------------------

    -- |
    -- Module      :  Distribution.Simple.Install
    -- Copyright   :  Isaac Jones 2003-2004
    -- License     :  BSD3
    --
    -- Maintainer  :  cabal-devel@haskell.org
    -- Portability :  portable
    --
    -- This is the entry point into installing a built package. Performs the
    -- \"@.\/setup install@\" and \"@.\/setup copy@\" actions. It moves files into
    -- place based on the prefix argument. It does the generic bits and then calls
    -- compiler-specific functions to do the rest.
    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

    -- | Perform the \"@.\/setup install@\" and \"@.\/setup copy@\"
    --  actions.  Move files into place based on the prefix argument.
    --
    --  This does NOT register libraries, you should call 'register'
    --  to do that.
    install
      :: PackageDescription
      -- ^ information from the .cabal file
      -> LocalBuildInfo
      -- ^ information from the configure step
      -> CopyFlags
      -- ^ flags sent to copy or install
      -> 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

      -- It's not necessary to do these in build-order, but it's harmless
      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

    -- | Copy package global files.
    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
        -- This is a bit of a hack, to handle files which are not
        -- per-component (data files and Haddock files.)
        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

      -- Install (package-global) data files
      Verbosity -> PackageDescription -> String -> IO ()
    installDataFiles Verbosity
    verbosity PackageDescription
    pkg_descr String
    dataPref

      -- Install (package-global) Haddock files
      -- TODO: these should be done per-library
      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
        )

      -- TODO: this is a bit questionable, Haddock files really should
      -- be per library (when there are convenience libraries.)
      when docExists $ do
        createDirectoryIfMissingVerbose verbosity True htmlPref
        installDirectoryContents
          verbosity
          (haddockPref ForDevelopment distPref pkg_descr)
          htmlPref
        -- setPermissionsRecursive [Read] htmlPref
        -- The haddock interface file actually already got installed
        -- in the recursive copy, but now we install it where we actually
        -- want it to be (normally the same place). We could remove the
        -- copy in htmlPref first.
        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
        -- We only generate the haddock interface file for libs, So if the
        -- package consists only of executables there will not be one:
        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)

    -- | Copy files associated with a component.
    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)

      -- install include files for all compilers - they may be needed to compile
      -- haskell files (using the CPP extension)
      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
          -- the installers know how to find the actual location of the
          -- binaries
          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))

    -- Nothing to do for benchmark/testsuite
    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 ()

    -- | Install the files listed in data-files
    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

    -- | Install the files listed in install-includes for a library
    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