-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.Build.Macros
-- Copyright   :  Isaac Jones 2003-2005,
--                Ross Paterson 2006,
--                Duncan Coutts 2007-2008
--
-- Maintainer  :  cabal-devel@haskell.org
-- Portability :  portable
--
-- Generating the Paths_pkgname module.
--
-- This is a module that Cabal generates for the benefit of packages. It
-- enables them to find their version number and find any installed data files
-- at runtime. This code should probably be split off into another module.
--
module Distribution.Simple.Build.PathsModule (
    generatePathsModule, pkgPathEnvVar
  ) where

import Prelude ()
import Distribution.Compat.Prelude

import Distribution.System
import Distribution.Simple.Compiler
import Distribution.Package
import Distribution.PackageDescription
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.BuildPaths
import Distribution.Simple.Utils
import Distribution.Pretty
import Distribution.Version

import System.FilePath ( pathSeparator )

-- ------------------------------------------------------------
-- * Building Paths_<pkg>.hs
-- ------------------------------------------------------------

generatePathsModule :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> String
generatePathsModule :: PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> String
generatePathsModule pkg_descr :: PackageDescription
pkg_descr lbi :: LocalBuildInfo
lbi clbi :: ComponentLocalBuildInfo
clbi =
   let pragmas :: String
pragmas =
            String
cpp_pragma
         String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
no_rebindable_syntax_pragma
         String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ffi_pragmas
         String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
warning_pragmas

       cpp_pragma :: String
cpp_pragma
         | Bool
supports_cpp = "{-# LANGUAGE CPP #-}\n"
         | Bool
otherwise    = ""

       -- -XRebindableSyntax is problematic because when paired with
       -- -XOverloadedLists, 'fromListN' is not in scope,
       -- or -XOverloadedStrings 'fromString' is not in scope,
       -- so we disable 'RebindableSyntax'.
       no_rebindable_syntax_pragma :: String
no_rebindable_syntax_pragma
         | Bool
supports_rebindable_syntax = "{-# LANGUAGE NoRebindableSyntax #-}\n"
         | Bool
otherwise                  = ""

       ffi_pragmas :: String
ffi_pragmas
        | Bool
absolute = ""
        | Bool
supports_language_pragma =
          "{-# LANGUAGE ForeignFunctionInterface #-}\n"
        | Bool
otherwise =
          "{-# OPTIONS_GHC -fffi #-}\n"

       warning_pragmas :: String
warning_pragmas =
        "{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}\n"

       foreign_imports :: String
foreign_imports
        | Bool
absolute = ""
        | Bool
otherwise =
          "import Foreign\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "import Foreign.C\n"

       reloc_imports :: String
reloc_imports
        | Bool
reloc =
          "import System.Environment (getExecutablePath)\n"
        | Bool
otherwise = ""

       header :: String
header =
        String
pragmasString -> String -> String
forall a. [a] -> [a] -> [a]
++
        "module " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ModuleName -> String
forall a. Pretty a => a -> String
prettyShow ModuleName
paths_modulename String -> String -> String
forall a. [a] -> [a] -> [a]
++ " (\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "    version,\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "    getDataFileName, getSysconfDir\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "  ) where\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        String
foreign_importsString -> String -> String
forall a. [a] -> [a] -> [a]
++
        "import qualified Control.Exception as Exception\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "import Data.Version (Version(..))\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "import System.Environment (getEnv)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        String
reloc_imports String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "import Prelude\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        (if Bool
supports_cpp
         then
           ("#if defined(VERSION_base)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "#if MIN_VERSION_base(4,0,0)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "#else\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "#endif\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "#else\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
            "#endif\n")
         else
           "catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a\n")String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "catchIO = Exception.catch\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "version :: Version"String -> String -> String
forall a. [a] -> [a] -> [a]
++
        "\nversion = Version " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Int] -> String
forall a. Show a => a -> String
show [Int]
branch String -> String -> String
forall a. [a] -> [a] -> [a]
++ " []"
          where branch :: [Int]
branch = Version -> [Int]
versionNumbers (Version -> [Int]) -> Version -> [Int]
forall a b. (a -> b) -> a -> b
$ PackageDescription -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion PackageDescription
pkg_descr

       body :: String
body
        | Bool
reloc =
          "\n\nbindirrel :: FilePath\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "bindirrel = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_bindirreloc String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\ngetBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getBinDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOrReloc "bindir" String
flat_bindirrelocString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOrReloc "libdir" String
flat_libdirrelocString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDynLibDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOrReloc "libdir" String
flat_dynlibdirrelocString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOrReloc "datadir" String
flat_datadirrelocString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibexecDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOrReloc "libexecdir" String
flat_libexecdirrelocString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getSysconfDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOrReloc "sysconfdir" String
flat_sysconfdirrelocString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataFileName :: FilePath -> IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataFileName name = do\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "  dir <- getDataDir\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "  return (dir `joinFileName` name)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          String
get_prefix_reloc_stuffString -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          String
filename_stuff
        | Bool
absolute =
          "\nbindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\nbindir     = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_bindir String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\nlibdir     = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_libdir String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\ndynlibdir  = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_dynlibdir String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\ndatadir    = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_datadir String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\nlibexecdir = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_libexecdir String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\nsysconfdir = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_sysconfdir String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\ngetBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getBinDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOr "bindir" "return bindir"String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOr "libdir" "return libdir"String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDynLibDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOr "dynlibdir" "return dynlibdir"String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOr "datadir" "return datadir"String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibexecDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOr "libexecdir" "return libexecdir"String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getSysconfDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> String -> String
mkGetEnvOr "sysconfdir" "return sysconfdir"String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataFileName :: FilePath -> IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataFileName name = do\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "  dir <- getDataDir\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "  return (dir ++ "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
path_sepString -> String -> String
forall a. [a] -> [a] -> [a]
++" ++ name)\n"
        | Bool
otherwise =
          "\nprefix, bindirrel :: FilePath" String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\nprefix        = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
flat_prefix String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\nbindirrel     = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show (String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
forall a. HasCallStack => String -> a
error "PathsModule.generate") Maybe String
flat_bindirrel) String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getBinDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getBinDir = getPrefixDirRel bindirrel\n\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> Maybe String -> String
forall a a. (Show a, Show a) => a -> Maybe a -> String
mkGetDir String
flat_libdir Maybe String
flat_libdirrelString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDynLibDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDynLibDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> Maybe String -> String
forall a a. (Show a, Show a) => a -> Maybe a -> String
mkGetDir String
flat_dynlibdir Maybe String
flat_dynlibdirrelString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataDir =  "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String -> String
mkGetEnvOr "datadir"
                              (String -> Maybe String -> String
forall a a. (Show a, Show a) => a -> Maybe a -> String
mkGetDir String
flat_datadir Maybe String
flat_datadirrel)String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibexecDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getLibexecDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> Maybe String -> String
forall a a. (Show a, Show a) => a -> Maybe a -> String
mkGetDir String
flat_libexecdir Maybe String
flat_libexecdirrelString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getSysconfDir :: IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getSysconfDir = "String -> String -> String
forall a. [a] -> [a] -> [a]
++String -> Maybe String -> String
forall a a. (Show a, Show a) => a -> Maybe a -> String
mkGetDir String
flat_sysconfdir Maybe String
flat_sysconfdirrelString -> String -> String
forall a. [a] -> [a] -> [a]
++"\n\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataFileName :: FilePath -> IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "getDataFileName name = do\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "  dir <- getDataDir\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "  return (dir `joinFileName` name)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          String
get_prefix_stuffString -> String -> String
forall a. [a] -> [a] -> [a]
++
          "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
          String
filename_stuff
   in String
headerString -> String -> String
forall a. [a] -> [a] -> [a]
++String
body

 where
        cid :: UnitId
cid = ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi

        InstallDirs {
          prefix :: forall dir. InstallDirs dir -> dir
prefix     = String
flat_prefix,
          bindir :: forall dir. InstallDirs dir -> dir
bindir     = String
flat_bindir,
          libdir :: forall dir. InstallDirs dir -> dir
libdir     = String
flat_libdir,
          dynlibdir :: forall dir. InstallDirs dir -> dir
dynlibdir  = String
flat_dynlibdir,
          datadir :: forall dir. InstallDirs dir -> dir
datadir    = String
flat_datadir,
          libexecdir :: forall dir. InstallDirs dir -> dir
libexecdir = String
flat_libexecdir,
          sysconfdir :: forall dir. InstallDirs dir -> dir
sysconfdir = String
flat_sysconfdir
        } = PackageDescription
-> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs String
absoluteInstallCommandDirs PackageDescription
pkg_descr LocalBuildInfo
lbi UnitId
cid CopyDest
NoCopyDest

        InstallDirs {
          bindir :: forall dir. InstallDirs dir -> dir
bindir     = Maybe String
flat_bindirrel,
          libdir :: forall dir. InstallDirs dir -> dir
libdir     = Maybe String
flat_libdirrel,
          dynlibdir :: forall dir. InstallDirs dir -> dir
dynlibdir  = Maybe String
flat_dynlibdirrel,
          datadir :: forall dir. InstallDirs dir -> dir
datadir    = Maybe String
flat_datadirrel,
          libexecdir :: forall dir. InstallDirs dir -> dir
libexecdir = Maybe String
flat_libexecdirrel,
          sysconfdir :: forall dir. InstallDirs dir -> dir
sysconfdir = Maybe String
flat_sysconfdirrel
        } = PackageId -> LocalBuildInfo -> UnitId -> InstallDirs (Maybe String)
prefixRelativeComponentInstallDirs (PackageDescription -> PackageId
forall pkg. Package pkg => pkg -> PackageId
packageId PackageDescription
pkg_descr) LocalBuildInfo
lbi UnitId
cid

        flat_bindirreloc :: String
flat_bindirreloc = String -> String -> String
shortRelativePath String
flat_prefix String
flat_bindir
        flat_libdirreloc :: String
flat_libdirreloc = String -> String -> String
shortRelativePath String
flat_prefix String
flat_libdir
        flat_dynlibdirreloc :: String
flat_dynlibdirreloc = String -> String -> String
shortRelativePath String
flat_prefix String
flat_dynlibdir
        flat_datadirreloc :: String
flat_datadirreloc = String -> String -> String
shortRelativePath String
flat_prefix String
flat_datadir
        flat_libexecdirreloc :: String
flat_libexecdirreloc = String -> String -> String
shortRelativePath String
flat_prefix String
flat_libexecdir
        flat_sysconfdirreloc :: String
flat_sysconfdirreloc = String -> String -> String
shortRelativePath String
flat_prefix String
flat_sysconfdir

        mkGetDir :: a -> Maybe a -> String
mkGetDir _   (Just dirrel :: a
dirrel) = "getPrefixDirRel " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
dirrel
        mkGetDir dir :: a
dir Nothing       = "return " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
dir

        mkGetEnvOrReloc :: String -> String -> String
mkGetEnvOrReloc var :: String
var dirrel :: String
dirrel = "catchIO (getEnv \""String -> String -> String
forall a. [a] -> [a] -> [a]
++String
var'String -> String -> String
forall a. [a] -> [a] -> [a]
++"\")" String -> String -> String
forall a. [a] -> [a] -> [a]
++
                                     " (\\_ -> getPrefixDirReloc \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
dirrel String -> String -> String
forall a. [a] -> [a] -> [a]
++
                                     "\")"
          where var' :: String
var' = PackageDescription -> String -> String
pkgPathEnvVar PackageDescription
pkg_descr String
var

        mkGetEnvOr :: String -> String -> String
mkGetEnvOr var :: String
var expr :: String
expr = "catchIO (getEnv \""String -> String -> String
forall a. [a] -> [a] -> [a]
++String
var'String -> String -> String
forall a. [a] -> [a] -> [a]
++"\")"String -> String -> String
forall a. [a] -> [a] -> [a]
++
                              " (\\_ -> "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
exprString -> String -> String
forall a. [a] -> [a] -> [a]
++")"
          where var' :: String
var' = PackageDescription -> String -> String
pkgPathEnvVar PackageDescription
pkg_descr String
var

        -- In several cases we cannot make relocatable installations
        absolute :: Bool
absolute =
             PackageDescription -> Bool
hasLibs PackageDescription
pkg_descr        -- we can only make progs relocatable
          Bool -> Bool -> Bool
|| Maybe String -> Bool
forall a. Maybe a -> Bool
isNothing Maybe String
flat_bindirrel -- if the bin dir is an absolute path
          Bool -> Bool -> Bool
|| Bool -> Bool
not (CompilerFlavor -> Bool
supportsRelocatableProgs (Compiler -> CompilerFlavor
compilerFlavor (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi)))

        reloc :: Bool
reloc = LocalBuildInfo -> Bool
relocatable LocalBuildInfo
lbi

        supportsRelocatableProgs :: CompilerFlavor -> Bool
supportsRelocatableProgs GHC  = case OS
buildOS of
                           Windows   -> Bool
True
                           _         -> Bool
False
        supportsRelocatableProgs GHCJS = case OS
buildOS of
                           Windows   -> Bool
True
                           _         -> Bool
False
        supportsRelocatableProgs _    = Bool
False

        paths_modulename :: ModuleName
paths_modulename = PackageDescription -> ModuleName
autogenPathsModuleName PackageDescription
pkg_descr

        get_prefix_stuff :: String
get_prefix_stuff = Bool -> Arch -> String
get_prefix_win32 Bool
supports_cpp Arch
buildArch

        path_sep :: String
path_sep = String -> String
forall a. Show a => a -> String
show [Char
pathSeparator]

        supports_cpp :: Bool
supports_cpp = Bool
supports_language_pragma
        supports_rebindable_syntax :: Bool
supports_rebindable_syntax= Version -> Bool
ghc_newer_than ([Int] -> Version
mkVersion [7,0,1])
        supports_language_pragma :: Bool
supports_language_pragma = Version -> Bool
ghc_newer_than ([Int] -> Version
mkVersion [6,6,1])

        ghc_newer_than :: Version -> Bool
ghc_newer_than minVersion :: Version
minVersion =
          case CompilerFlavor -> Compiler -> Maybe Version
compilerCompatVersion CompilerFlavor
GHC (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi) of
            Nothing -> Bool
False
            Just version :: Version
version -> Version
version Version -> VersionRange -> Bool
`withinRange` Version -> VersionRange
orLaterVersion Version
minVersion

-- | Generates the name of the environment variable controlling the path
-- component of interest.
--
-- Note: The format of these strings is part of Cabal's public API;
-- changing this function constitutes a *backwards-compatibility* break.
pkgPathEnvVar :: PackageDescription
              -> String     -- ^ path component; one of \"bindir\", \"libdir\",
                            -- \"datadir\", \"libexecdir\", or \"sysconfdir\"
              -> String     -- ^ environment variable name
pkgPathEnvVar :: PackageDescription -> String -> String
pkgPathEnvVar pkg_descr :: PackageDescription
pkg_descr var :: String
var =
    PackageName -> String
showPkgName (PackageDescription -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageDescription
pkg_descr) String -> String -> String
forall a. [a] -> [a] -> [a]
++ "_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
var
    where
        showPkgName :: PackageName -> String
showPkgName = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
fixchar (String -> String)
-> (PackageName -> String) -> PackageName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> String
forall a. Pretty a => a -> String
prettyShow
        fixchar :: Char -> Char
fixchar '-' = '_'
        fixchar c :: Char
c   = Char
c

get_prefix_reloc_stuff :: String
get_prefix_reloc_stuff :: String
get_prefix_reloc_stuff =
  "getPrefixDirReloc :: FilePath -> IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "getPrefixDirReloc dirRel = do\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  exePath <- getExecutablePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  let (bindir,_) = splitFileName exePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  return ((bindir `minusFileName` bindirrel) `joinFileName` dirRel)\n"

get_prefix_win32 :: Bool -> Arch -> String
get_prefix_win32 :: Bool -> Arch -> String
get_prefix_win32 supports_cpp :: Bool
supports_cpp arch :: Arch
arch =
  "getPrefixDirRel :: FilePath -> IO FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "getPrefixDirRel dirRel = try_size 2048 -- plenty, PATH_MAX is 512 under Win32.\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  where\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "    try_size size = allocaArray (fromIntegral size) $ \\buf -> do\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "        ret <- c_GetModuleFileName nullPtr buf size\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "        case ret of\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "          0 -> return (prefix `joinFileName` dirRel)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "          _ | ret < size -> do\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "              exePath <- peekCWString buf\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "              let (bindir,_) = splitFileName exePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "              return ((bindir `minusFileName` bindirrel) `joinFileName` dirRel)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "            | otherwise  -> try_size (size * 2)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  (case Bool
supports_cpp of
    False -> ""
    True  -> "#if defined(i386_HOST_ARCH)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
             "# define WINDOWS_CCONV stdcall\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
             "#elif defined(x86_64_HOST_ARCH)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
             "# define WINDOWS_CCONV ccall\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
             "#else\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
             "# error Unknown mingw32 arch\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
             "#endif\n")String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "foreign import " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
cconv String -> String -> String
forall a. [a] -> [a] -> [a]
++ " unsafe \"windows.h GetModuleFileNameW\"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  c_GetModuleFileName :: Ptr () -> CWString -> Int32 -> IO Int32\n"
    where cconv :: String
cconv = if Bool
supports_cpp
                     then "WINDOWS_CCONV"
                     else case Arch
arch of
                            I386 -> "stdcall"
                            X86_64 -> "ccall"
                            _ -> String -> String
forall a. HasCallStack => String -> a
error "win32 supported only with I386, X86_64"

filename_stuff :: String
filename_stuff :: String
filename_stuff =
  "minusFileName :: FilePath -> String -> FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "minusFileName dir \"\"     = dir\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "minusFileName dir \".\"    = dir\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "minusFileName dir suffix =\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  minusFileName (fst (splitFileName dir)) (fst (splitFileName suffix))\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "joinFileName :: String -> String -> FilePath\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "joinFileName \"\"  fname = fname\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "joinFileName \".\" fname = fname\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "joinFileName dir \"\"    = dir\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "joinFileName dir fname\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  | isPathSeparator (last dir) = dir++fname\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  | otherwise                  = dir++pathSeparator:fname\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "splitFileName :: FilePath -> (String, String)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "splitFileName p = (reverse (path2++drive), reverse fname)\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "  where\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "    (path,drive) = case p of\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "       (c:':':p') -> (reverse p',[':',c])\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "       _          -> (reverse p ,\"\")\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "    (fname,path1) = break isPathSeparator path\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "    path2 = case path1 of\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "      []                           -> \".\"\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "      [_]                          -> path1   -- don't remove the trailing slash if \n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "                                              -- there is only one character\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "      (c:path') | isPathSeparator c -> path'\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "      _                             -> path1\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "pathSeparator :: Char\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  (case OS
buildOS of
       Windows   -> "pathSeparator = '\\\\'\n"
       _         -> "pathSeparator = '/'\n") String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  "isPathSeparator :: Char -> Bool\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
  (case OS
buildOS of
       Windows   -> "isPathSeparator c = c == '/' || c == '\\\\'\n"
       _         -> "isPathSeparator c = c == '/'\n")