{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Distribution.Simple.BuildPaths
( defaultDistPref
, srcPref
, buildInfoPref
, haddockDirName
, hscolourPref
, haddockPref
, autogenPackageModulesDir
, autogenComponentModulesDir
, autogenPathsModuleName
, autogenPackageInfoModuleName
, cppHeaderName
, haddockName
, mkGenericStaticLibName
, mkLibName
, mkProfLibName
, mkGenericSharedLibName
, mkSharedLibName
, mkStaticLibName
, mkGenericSharedBundledLibName
, exeExtension
, objExtension
, dllExtension
, staticLibExtension
, getSourceFiles
, getLibSourceFiles
, getExeSourceFiles
, getFLibSourceFiles
, exeBuildDir
, flibBuildDir
) where
import Distribution.Compat.Prelude
import Prelude ()
import Distribution.Compiler
import Distribution.ModuleName as ModuleName
import Distribution.Package
import Distribution.PackageDescription
import Distribution.Pretty
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Setup.Common (defaultDistPref)
import Distribution.Simple.Setup.Haddock (HaddockTarget (..))
import Distribution.Simple.Utils
import Distribution.System
import Distribution.Utils.Path
import Distribution.Verbosity
import Data.List (stripPrefix)
import System.FilePath (normalise, (<.>), (</>))
srcPref :: FilePath -> FilePath
srcPref :: String -> String
srcPref String
distPref = String
distPref String -> String -> String
</> String
"src"
hscolourPref :: HaddockTarget -> FilePath -> PackageDescription -> FilePath
hscolourPref :: HaddockTarget -> String -> PackageDescription -> String
hscolourPref = HaddockTarget -> String -> PackageDescription -> String
haddockPref
buildInfoPref :: FilePath -> FilePath
buildInfoPref :: String -> String
buildInfoPref String
distPref = String
distPref String -> String -> String
</> String
"build-info.json"
haddockDirName :: HaddockTarget -> PackageDescription -> FilePath
haddockDirName :: HaddockTarget -> PackageDescription -> String
haddockDirName HaddockTarget
ForDevelopment = PackageName -> String
forall a. Pretty a => a -> String
prettyShow (PackageName -> String)
-> (PackageDescription -> PackageName)
-> PackageDescription
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName
haddockDirName HaddockTarget
ForHackage = (String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-docs") (String -> String)
-> (PackageDescription -> String) -> PackageDescription -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> String
forall a. Pretty a => a -> String
prettyShow (PackageIdentifier -> String)
-> (PackageDescription -> PackageIdentifier)
-> PackageDescription
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId
haddockPref :: HaddockTarget -> FilePath -> PackageDescription -> FilePath
haddockPref :: HaddockTarget -> String -> PackageDescription -> String
haddockPref HaddockTarget
haddockTarget String
distPref PackageDescription
pkg_descr =
String
distPref String -> String -> String
</> String
"doc" String -> String -> String
</> String
"html" String -> String -> String
</> HaddockTarget -> PackageDescription -> String
haddockDirName HaddockTarget
haddockTarget PackageDescription
pkg_descr
autogenPackageModulesDir :: LocalBuildInfo -> String
autogenPackageModulesDir :: LocalBuildInfo -> String
autogenPackageModulesDir LocalBuildInfo
lbi = LocalBuildInfo -> String
buildDir LocalBuildInfo
lbi String -> String -> String
</> String
"global-autogen"
autogenComponentModulesDir :: LocalBuildInfo -> ComponentLocalBuildInfo -> String
autogenComponentModulesDir :: LocalBuildInfo -> ComponentLocalBuildInfo -> String
autogenComponentModulesDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi = LocalBuildInfo -> ComponentLocalBuildInfo -> String
componentBuildDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi String -> String -> String
</> String
"autogen"
cppHeaderName :: String
= String
"cabal_macros.h"
autogenPathsModuleName :: PackageDescription -> ModuleName
autogenPathsModuleName :: PackageDescription -> ModuleName
autogenPathsModuleName PackageDescription
pkg_descr =
String -> ModuleName
forall a. IsString a => String -> a
ModuleName.fromString (String -> ModuleName) -> String -> ModuleName
forall a b. (a -> b) -> a -> b
$
String
"Paths_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
fixchar (PackageName -> String
forall a. Pretty a => a -> String
prettyShow (PackageDescription -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageDescription
pkg_descr))
where
fixchar :: Char -> Char
fixchar Char
'-' = Char
'_'
fixchar Char
c = Char
c
autogenPackageInfoModuleName :: PackageDescription -> ModuleName
autogenPackageInfoModuleName :: PackageDescription -> ModuleName
autogenPackageInfoModuleName PackageDescription
pkg_descr =
String -> ModuleName
forall a. IsString a => String -> a
ModuleName.fromString (String -> ModuleName) -> String -> ModuleName
forall a b. (a -> b) -> a -> b
$
String
"PackageInfo_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
fixchar (PackageName -> String
forall a. Pretty a => a -> String
prettyShow (PackageDescription -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageDescription
pkg_descr))
where
fixchar :: Char -> Char
fixchar Char
'-' = Char
'_'
fixchar Char
c = Char
c
haddockName :: PackageDescription -> FilePath
haddockName :: PackageDescription -> String
haddockName PackageDescription
pkg_descr = PackageName -> String
forall a. Pretty a => a -> String
prettyShow (PackageDescription -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageDescription
pkg_descr) String -> String -> String
<.> String
"haddock"
getLibSourceFiles
:: Verbosity
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO [(ModuleName.ModuleName, FilePath)]
getLibSourceFiles :: Verbosity
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO [(ModuleName, String)]
getLibSourceFiles Verbosity
verbosity LocalBuildInfo
lbi Library
lib ComponentLocalBuildInfo
clbi = Verbosity -> [String] -> [ModuleName] -> IO [(ModuleName, String)]
getSourceFiles Verbosity
verbosity [String]
searchpaths [ModuleName]
modules
where
bi :: BuildInfo
bi = Library -> BuildInfo
libBuildInfo Library
lib
modules :: [ModuleName]
modules = Library -> ComponentLocalBuildInfo -> [ModuleName]
allLibModules Library
lib ComponentLocalBuildInfo
clbi
searchpaths :: [String]
searchpaths =
LocalBuildInfo -> ComponentLocalBuildInfo -> String
componentBuildDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (SymbolicPath PackageDir SourceDir -> String)
-> [SymbolicPath PackageDir SourceDir] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map SymbolicPath PackageDir SourceDir -> String
forall from to. SymbolicPath from to -> String
getSymbolicPath (BuildInfo -> [SymbolicPath PackageDir SourceDir]
hsSourceDirs BuildInfo
bi)
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [ LocalBuildInfo -> ComponentLocalBuildInfo -> String
autogenComponentModulesDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
, LocalBuildInfo -> String
autogenPackageModulesDir LocalBuildInfo
lbi
]
getExeSourceFiles
:: Verbosity
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO [(ModuleName.ModuleName, FilePath)]
getExeSourceFiles :: Verbosity
-> LocalBuildInfo
-> Executable
-> ComponentLocalBuildInfo
-> IO [(ModuleName, String)]
getExeSourceFiles Verbosity
verbosity LocalBuildInfo
lbi Executable
exe ComponentLocalBuildInfo
clbi = do
[(ModuleName, String)]
moduleFiles <- Verbosity -> [String] -> [ModuleName] -> IO [(ModuleName, String)]
getSourceFiles Verbosity
verbosity [String]
searchpaths [ModuleName]
modules
String
srcMainPath <- Verbosity -> [String] -> String -> IO String
findFileEx Verbosity
verbosity ((SymbolicPath PackageDir SourceDir -> String)
-> [SymbolicPath PackageDir SourceDir] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map SymbolicPath PackageDir SourceDir -> String
forall from to. SymbolicPath from to -> String
getSymbolicPath ([SymbolicPath PackageDir SourceDir] -> [String])
-> [SymbolicPath PackageDir SourceDir] -> [String]
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [SymbolicPath PackageDir SourceDir]
hsSourceDirs BuildInfo
bi) (Executable -> String
modulePath Executable
exe)
[(ModuleName, String)] -> IO [(ModuleName, String)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((ModuleName
ModuleName.main, String
srcMainPath) (ModuleName, String)
-> [(ModuleName, String)] -> [(ModuleName, String)]
forall a. a -> [a] -> [a]
: [(ModuleName, String)]
moduleFiles)
where
bi :: BuildInfo
bi = Executable -> BuildInfo
buildInfo Executable
exe
modules :: [ModuleName]
modules = BuildInfo -> [ModuleName]
otherModules BuildInfo
bi
searchpaths :: [String]
searchpaths =
LocalBuildInfo -> ComponentLocalBuildInfo -> String
autogenComponentModulesDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: LocalBuildInfo -> String
autogenPackageModulesDir LocalBuildInfo
lbi
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: LocalBuildInfo -> Executable -> String
exeBuildDir LocalBuildInfo
lbi Executable
exe
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (SymbolicPath PackageDir SourceDir -> String)
-> [SymbolicPath PackageDir SourceDir] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map SymbolicPath PackageDir SourceDir -> String
forall from to. SymbolicPath from to -> String
getSymbolicPath (BuildInfo -> [SymbolicPath PackageDir SourceDir]
hsSourceDirs BuildInfo
bi)
getFLibSourceFiles
:: Verbosity
-> LocalBuildInfo
-> ForeignLib
-> ComponentLocalBuildInfo
-> IO [(ModuleName.ModuleName, FilePath)]
getFLibSourceFiles :: Verbosity
-> LocalBuildInfo
-> ForeignLib
-> ComponentLocalBuildInfo
-> IO [(ModuleName, String)]
getFLibSourceFiles Verbosity
verbosity LocalBuildInfo
lbi ForeignLib
flib ComponentLocalBuildInfo
clbi = Verbosity -> [String] -> [ModuleName] -> IO [(ModuleName, String)]
getSourceFiles Verbosity
verbosity [String]
searchpaths [ModuleName]
modules
where
bi :: BuildInfo
bi = ForeignLib -> BuildInfo
foreignLibBuildInfo ForeignLib
flib
modules :: [ModuleName]
modules = BuildInfo -> [ModuleName]
otherModules BuildInfo
bi
searchpaths :: [String]
searchpaths =
LocalBuildInfo -> ComponentLocalBuildInfo -> String
autogenComponentModulesDir LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: LocalBuildInfo -> String
autogenPackageModulesDir LocalBuildInfo
lbi
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: LocalBuildInfo -> ForeignLib -> String
flibBuildDir LocalBuildInfo
lbi ForeignLib
flib
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (SymbolicPath PackageDir SourceDir -> String)
-> [SymbolicPath PackageDir SourceDir] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map SymbolicPath PackageDir SourceDir -> String
forall from to. SymbolicPath from to -> String
getSymbolicPath (BuildInfo -> [SymbolicPath PackageDir SourceDir]
hsSourceDirs BuildInfo
bi)
getSourceFiles
:: Verbosity
-> [FilePath]
-> [ModuleName.ModuleName]
-> IO [(ModuleName.ModuleName, FilePath)]
getSourceFiles :: Verbosity -> [String] -> [ModuleName] -> IO [(ModuleName, String)]
getSourceFiles Verbosity
verbosity [String]
dirs [ModuleName]
modules = ((ModuleName -> IO (ModuleName, String))
-> [ModuleName] -> IO [(ModuleName, String)])
-> [ModuleName]
-> (ModuleName -> IO (ModuleName, String))
-> IO [(ModuleName, String)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ModuleName -> IO (ModuleName, String))
-> [ModuleName] -> IO [(ModuleName, 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 [ModuleName]
modules ((ModuleName -> IO (ModuleName, String))
-> IO [(ModuleName, String)])
-> (ModuleName -> IO (ModuleName, String))
-> IO [(ModuleName, String)]
forall a b. (a -> b) -> a -> b
$ \ModuleName
m ->
(String -> (ModuleName, String))
-> IO String -> IO (ModuleName, String)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) ModuleName
m) (IO String -> IO (ModuleName, String))
-> IO String -> IO (ModuleName, String)
forall a b. (a -> b) -> a -> b
$
[String] -> [String] -> String -> IO (Maybe String)
findFileWithExtension [String
"hs", String
"lhs", String
"hsig", String
"lhsig"] [String]
dirs (ModuleName -> String
ModuleName.toFilePath ModuleName
m)
IO (Maybe String) -> (Maybe String -> IO String) -> IO String
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO String -> (String -> IO String) -> Maybe String -> IO String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (ModuleName -> IO String
forall {a} {a}. Pretty a => a -> IO a
notFound ModuleName
m) (String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> (String -> String) -> String -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
normalise)
where
notFound :: a -> IO a
notFound a
module_ = Verbosity -> String -> IO a
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO a) -> String -> IO a
forall a b. (a -> b) -> a -> b
$ String
"can't find source for module " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Pretty a => a -> String
prettyShow a
module_
exeBuildDir :: LocalBuildInfo -> Executable -> FilePath
exeBuildDir :: LocalBuildInfo -> Executable -> String
exeBuildDir LocalBuildInfo
lbi Executable
exe = LocalBuildInfo -> String
buildDir LocalBuildInfo
lbi String -> String -> String
</> String
nm String -> String -> String
</> String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-tmp"
where
nm :: String
nm = UnqualComponentName -> String
unUnqualComponentName (UnqualComponentName -> String) -> UnqualComponentName -> String
forall a b. (a -> b) -> a -> b
$ Executable -> UnqualComponentName
exeName Executable
exe
flibBuildDir :: LocalBuildInfo -> ForeignLib -> FilePath
flibBuildDir :: LocalBuildInfo -> ForeignLib -> String
flibBuildDir LocalBuildInfo
lbi ForeignLib
flib = LocalBuildInfo -> String
buildDir LocalBuildInfo
lbi String -> String -> String
</> String
nm String -> String -> String
</> String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-tmp"
where
nm :: String
nm = UnqualComponentName -> String
unUnqualComponentName (UnqualComponentName -> String) -> UnqualComponentName -> String
forall a b. (a -> b) -> a -> b
$ ForeignLib -> UnqualComponentName
foreignLibName ForeignLib
flib
mkGenericStaticLibName :: String -> String
mkGenericStaticLibName :: String -> String
mkGenericStaticLibName String
lib = String
"lib" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lib String -> String -> String
<.> String
"a"
mkLibName :: UnitId -> String
mkLibName :: UnitId -> String
mkLibName UnitId
lib = String -> String
mkGenericStaticLibName (UnitId -> String
getHSLibraryName UnitId
lib)
mkProfLibName :: UnitId -> String
mkProfLibName :: UnitId -> String
mkProfLibName UnitId
lib = String -> String
mkGenericStaticLibName (UnitId -> String
getHSLibraryName UnitId
lib String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_p")
mkGenericSharedLibName :: Platform -> CompilerId -> String -> String
mkGenericSharedLibName :: Platform -> CompilerId -> String -> String
mkGenericSharedLibName Platform
platform (CompilerId CompilerFlavor
compilerFlavor Version
compilerVersion) String
lib =
[String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
"lib", String
lib, String
"-", String
comp String -> String -> String
<.> Platform -> String
dllExtension Platform
platform]
where
comp :: String
comp = CompilerFlavor -> String
forall a. Pretty a => a -> String
prettyShow CompilerFlavor
compilerFlavor String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
prettyShow Version
compilerVersion
mkSharedLibName :: Platform -> CompilerId -> UnitId -> String
mkSharedLibName :: Platform -> CompilerId -> UnitId -> String
mkSharedLibName Platform
platform CompilerId
comp UnitId
lib =
Platform -> CompilerId -> String -> String
mkGenericSharedLibName Platform
platform CompilerId
comp (UnitId -> String
getHSLibraryName UnitId
lib)
mkStaticLibName :: Platform -> CompilerId -> UnitId -> String
mkStaticLibName :: Platform -> CompilerId -> UnitId -> String
mkStaticLibName Platform
platform (CompilerId CompilerFlavor
compilerFlavor Version
compilerVersion) UnitId
lib =
String
"lib" String -> String -> String
forall a. [a] -> [a] -> [a]
++ UnitId -> String
getHSLibraryName UnitId
lib String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
comp String -> String -> String
<.> Platform -> String
staticLibExtension Platform
platform
where
comp :: String
comp = CompilerFlavor -> String
forall a. Pretty a => a -> String
prettyShow CompilerFlavor
compilerFlavor String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
prettyShow Version
compilerVersion
mkGenericSharedBundledLibName :: Platform -> CompilerId -> String -> String
mkGenericSharedBundledLibName :: Platform -> CompilerId -> String -> String
mkGenericSharedBundledLibName Platform
platform CompilerId
comp String
lib
| String
"HS" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
lib =
Platform -> CompilerId -> String -> String
mkGenericSharedLibName Platform
platform CompilerId
comp String
lib
| Just String
lib' <- String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix String
"C" String
lib =
String
"lib" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lib' String -> String -> String
<.> Platform -> String
dllExtension Platform
platform
| Bool
otherwise =
String -> String
forall a. HasCallStack => String -> a
error (String
"Don't understand library name " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lib)
exeExtension :: Platform -> String
exeExtension :: Platform -> String
exeExtension Platform
platform = case Platform
platform of
Platform Arch
_ OS
Windows -> String
"exe"
Platform Arch
Wasm32 OS
_ -> String
"wasm"
Platform
_ -> String
""
objExtension :: String
objExtension :: String
objExtension = String
"o"
dllExtension :: Platform -> String
dllExtension :: Platform -> String
dllExtension (Platform Arch
_arch OS
os) = case OS
os of
OS
Windows -> String
"dll"
OS
OSX -> String
"dylib"
OS
_ -> String
"so"
staticLibExtension :: Platform -> String
staticLibExtension :: Platform -> String
staticLibExtension (Platform Arch
_arch OS
os) = case OS
os of
OS
Windows -> String
"lib"
OS
_ -> String
"a"